Baru-baru ini, karena proyek perlu menyesuaikan fungsi rentetan, saya mencoba menggunakan kanvas untuk mengembangkan komponen. Setelah pengujian pada beberapa mesin kelas bawah, tidak ada jeda yang jelas. Izinkan saya berbagi dengan Anda.
Efek rentetan Pengenalan fungsimenggunakan
npm i vue-barrage
Konfigurasi parameter
nama | jenis | bawaan | deskripsi |
---|---|---|---|
Daftar penghalang | Himpunan | [] | Data rentetan |
kecepatan | Nomor | 4 | Kecepatan gulir rentetan |
lingkaran | Boolean | BENAR | Apakah akan menggulir dalam satu lingkaran |
saluran | Nomor | 2 | Jumlah jalur rentetan |
gaya html
<templat> <div class=barrage-container> <div class=container :style={height: barrageHeight/2+'px'}> <canvas id=canvas ref=canvas :width=barrageWidth :height=barrageHeight :style= {'lebar': barrageWidth/2 + 'px','height': penghalangTinggi/2 + 'px'}/> </div> </div></template>implementasi js
Dengarkan sumber data
tonton: { barrageList (val) { if (val.length !== 0) { this.initData() // Inisialisasi data this.render() // Mulai rendering} }}
Inisialisasi data
barrageArray
digunakan untuk menyimpan data rentetan, termasuk daftar rentetan default dan item rentetan baru.
/** * Inisialisasi data*/initData () { for (let i = 0; i < this.barrageList.length; i++) { // Hanya 40 karakter yang ditampilkan di sini let content = this.barrageList[i]. panjang > 40 ? `${this.barrageList[i].content.substring(0, 40)}...` : this.barrageList[i].content this.pushMessage(content, this.barrageList[i].color) }},/** * Tambahkan data* @param content * @param color */pushMessage (content, color) { biarkan posisi = this.getPosition() / / Tentukan posisi runway let x = this.barrageWidth // Posisi awal let offsetWidth = 0 for (let i = 0, len = this.barrageArray.length; i < len; i++) { let item = this.barrageArray[i] if (position === item.position) { // Jika keduanya berada di jalur yang sama, pindah ke belakang offsetWidth += Math.floor(this.ctx.measureText( item.content) .width * 3 + 60) } } this.barrageArray.push({ konten: konten, // Rentetan konten x: x + offsetWidth, // Tentukan posisi awal setiap komentar originX: x + offsetWidth, // Menyimpan posisi komentar saat ini sehingga dapat digunakan saat perulangan posisi: position, width: this.ctx.measureText(content).width * 3, / / Warna lebar konten gambar kanvas: warna ||.this.getColor() // Warna khusus})},
Yang perlu diolah dalam data inisialisasi adalah menghitung lintasan, posisi, dan lebar rentetan arus agar dapat digunakan saat menggambar canvas
.
Gambarlah canvas
/** * Render*/render () { this.ctx.clearRect(0, 0, this.barrageWidth, this.barrageHeight) this.ctx.font = '30px Microsoft YaHei' this.draw() window.requestAnimationFrame(ini .render) // Render setiap 16,6 milidetik. Jika Anda menggunakan setInterval, ini akan sedikit lamban pada model kelas bawah},/** * Mulai menggambar teks dan latar belakang*/gambar () { for (let i = 0, len = this.barrageArray.length; i < len; i++) { let barrage = this.barrageArray[i] coba { barrage.x -= this .speed if (barrage.x < -barrage.width - 100) { // Tentukan waktu hilangnya rentetan di sini if (i === this.barrageArray.length - 1) { // Logika penilaian ketika serangan terakhir menghilang if (!this.loop) { // Jika bukan loop, batalkan gambar untuk menentukan apakah itu loop, dan jalankan cancelAnimationFrame tanpa loop cancelAnimationFrame(this.render) return } if (this.addArray .length !== 0) { // Tentukan logika penambahan rentetan di sini this.barrageArray = this.barrageArray.concat(this.addArray) this.addArray = [] } for (let j = 0; j < this.barrageArray.length j++) { // Beri setiap rentetan nilai awal x this.barrageArray[j].x = this.barrageArray[j].originX } } } if (barrage.x <= 2 * document.body.clientWidth + barrage.width) { // Tentukan kapan mulai menggambar. Jika tidak, maka akan menyebabkan rentetan gulir terhenti // Gambarkan latar belakang this.drawRoundRect(this.ctx, barrage.x - 15, barrage.position - 30, barrage.width + 30, 40, 20, `rgba(0,0,0,0.75)`) // Gambarkan SMS ini .ctx.fillStyle = `${barrage.color}` this.ctx.fillText(barrage.content, rentetan.x, rentetan.posisi) } } tangkapan (e) { konsol.log(e) } }},
Logika penarikan gambar dinilai di sini, termasuk kapan harus membatalkan, menilai kapan rentetan tembakan mulai ditarik, dan menilai kapan rentetan tembakan menghilang.
Fungsi lainnya
/** * Mendapatkan posisi teks * Gunakan pathWayIndex untuk mengonfirmasi trek di mana setiap rentetan berada * Mengembalikan jarak dari atas * @TODO Ini juga dapat dioptimalkan untuk menentukan lokasi rentetan berikutnya berdasarkan jarak setiap trek */ getPosition () { let range = this.channels let top = (this.pathWayIndex % range) * 50 + 40 this.pathWayIndex++ return top},/** * Dapatkan warna acak*/getColor () { return '#' + ('00000' + (Math.random() * 0x1000000 << 0).toString(16)).slice(-6);},/** * Menggambar persegi panjang membulat* @ konteks param * @param x * @param y * @param lebar * @param tinggi * @param radius * @param warna */drawRoundRect (konteks, x, y, lebar, tinggi, radius, warna) { konteks.beginPath() konteks.fillStyle = warna konteks.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 3 / 2) konteks.lineTo (lebar - jari-jari + x, y) konteks.arc(lebar - jari-jari + x, jari-jari + y, jari-jari, Matematika.PI * 3/2, Matematika.PI * 2) konteks.lineTo(lebar + x, tinggi + y - radius) konteks.arc(lebar - radius + x, tinggi - radius + y, radius, 0, Math.PI / 2) konteks.lineTo(radius + x, tinggi + y) konteks.arc (radius + x, tinggi - radius + y, radius, Math.PI / 2, Math.PI) konteks.isi() konteks.closePath()}
Berikut adalah fungsi layanan rentetan
menggunakan
<barrage ref=barrage class=barrage :barrage-list=barrageList :speed=speed :loop=loop :channels=channels/> import Barrage from 'vue-barrage'// Inisialisasi data rentetan this.barrageList = [{ content: ' Data uji nomor uji data uji nomor data uji', warna: 'putih'}]// Tambahkan rentetan baru ini.$refs.barrage.add({ isi: 'Tambahkan rentetan baruTambahkan rentetan baru', warna: 'putih'})Kesimpulan
Secara keseluruhan, komponen ini masih memiliki ruang untuk optimasi, dan akan terus saya perbaiki di masa mendatang.
Di atas adalah keseluruhan isi artikel ini, saya harap dapat bermanfaat untuk pembelajaran semua orang. Saya juga berharap semua orang mendukung VeVb Wulin Network.