Artikel ini memperkenalkan kode implementasi teks Canvas ke efek partikel dan membagikannya kepada semua orang. Saya harap dapat bermanfaat bagi semua orang. Detailnya adalah sebagai berikut:
Menggambar teks melalui partikel terasa menarik, dan mencocokkan pergerakan partikel akan membuat efeknya semakin keren. Artikel ini memperkenalkan cara menggambar teks melalui partikel di kanvas.
Prinsip implementasiSecara umum, membuat efek mengubah teks menjadi tampilan partikel sangat sederhana. Prinsip penerapannya adalah dengan menggunakan dua kanvas salah satu yang dapat dilihat pengguna. Kanvas B yang diperoleh digunakan untuk menghasilkan partikel berdasarkan data teks A. Representasi intuitif ditunjukkan pada gambar:
Buat kanvas di luar layarHTML hanya perlu ditempatkan di kanvas utama:
<!-- Struktur HTML--><html><head> ...</head><body> <canvas id=stage></canvas></body></html>
Kemudian buat kanvas di luar layar dan gambar teks:
const WIDTH = window.innerWidth;const HEIGHT = window.innerHeight;const offscreenCanvas = document.createElement('canvas');const offscreenCtx = offscreenCanvas.getContext('2d');offscreenCanvas.width = WIDTH;offscreenCanvas.height = TINGGI; offscreenCtx.font = '100 piksel PingFang SC';offscreenCtx.textAlign = 'center';offscreenCtx.baseline = 'tengah';offscreenCtx.fillText('Halo', LEBAR / 2, TINGGI / 2);Tidak ada yang terjadi di halaman saat ini, namun Anda sebenarnya dapat membayangkannya di kanvas di luar layar. Seharusnya seperti yang ditunjukkan pada gambar:
Metode inti getImageData Dengan menggunakan metode getImageData kanvas, Anda bisa mendapatkan objek ImageData , yang digunakan untuk mendeskripsikan data piksel di area kanvas tertentu. Dengan kata lain, kita bisa mendapatkan posisi dan warna setiap piksel teks Hello, dan kita bisa menghasilkan partikel di lokasi yang ditentukan. Efek akhirnya adalah partikel-partikel tersebut disatukan menjadi teks.
Untuk mendapatkan informasi piksel, Anda perlu menggunakan atribut data dari objek ImageData , 像素点数量* 4 menyebarkan nilai rgba dari semua piksel ke dalam sebuah array. Setiap piksel memiliki empat nilai rgba .
Misalkan saya memilih area 3 * 4 , maka totalnya ada 12 piksel, setiap piksel memiliki empat nilai rgba, sehingga array data akan memiliki 12 * 4 = 48 elemen.
Jika Anda mencetak datanya, Anda dapat melihat rgba piksel tersebut disusun dari kiri ke kanan dan atas ke bawah.
Tentu saja, area yang ingin kita peroleh harus berisi teks, jadi kita harus mendapatkan seluruh area kanvas di luar layar:
const imgData = offscreenCtx.getImageData(0, 0, LEBAR, TINGGI).data;Menghasilkan partikel
Setelah mendapatkan ImageData, dengan menelusuri larik data, Anda dapat menentukan titik mana di kanvas di luar layar yang berwarna (di tengah teks) dan titik mana yang tidak berwarna (bukan pada teks), dan meletakkan piksel berwarna tersebut. catat posisinya, lalu buat partikel di kanvas utama, dan Anda siap melakukannya.
Pertama buat kelas partikel:
class Particle { konstruktor (pilihan = {}) { const { x = 0, y = 0, warna = '#fff', radius = 5} = pilihan; = y; ini.warna = warna; } menggambar (ctx) { ctx.beginPath(); Matematika.PI, salah); ctx.fillStyle = ini.warna; ctx.fill();Melalui data, kita dapat menentukan apakah piksel ada dalam teks berdasarkan transparansi, yaitu apakah elemen keempat dalam rgba bukan 0.
partikel const = [];const lewati = 4;untuk (var y = 0; y < TINGGI; y += lewati) { untuk (var x = 0; x < LEBAR; x += lewati) { var opacityIndex = (x + y * LEBAR) * 4 + 3; if (imgData[opacityIndex] > 0) { partikel.push(Partikel baru({ x, y, radius: 1, warna: '#2EA9DF' })); Kami menggunakan susunan particles untuk menyimpan semua partikel. Fungsi skip di sini adalah ukuran langkah traversal. Jika kita memindai piksel demi piksel, partikel yang pada akhirnya akan menyatukan teks akan sangat padat partikel yang dihasilkan akan semakin sedikit.
Terakhir, buat kanvas utama dan gambarlah:
const kanvas = document.querySelector('#stage');kanvas.lebar = LEBAR;kanvas.tinggi = TINGGI;const ctx = kanvas.getContext('2d');for (konstan partikel partikel) { partikel.draw(ctx );}Efeknya adalah sebagai berikut:
Untuk kode selengkapnya, lihat 01-basic-text-to-particles
Tambahkan efekSetelah memahami prinsip implementasi, selanjutnya adalah menambahkan beberapa efek animasi pada partikel. Pertama, Anda dapat memindahkan partikel secara acak agar tidak terlihat terlalu rapi.
partikel const = [];const lewati = 4;untuk (var y = 0; y < TINGGI; y += lewati) { untuk (var x = 0; x < LEBAR; x += lewati) { var opacityIndex = (x + y * WIDTH) * 4 + 3; if (imgData[opacityIndex] > 0) { // Tambahkan perpindahan acak saat membuat partikel partikel.push(baru Partikel({ x: x + Math.random() * 6 - 3, y: y + Math.random() * 6 - 3, radius: 1, warna: '#2EA9DF' }));Efeknya adalah sebagai berikut:
Jika Anda ingin mendapatkan efek yang lebih besar, seperti:
Bagaimana cara menerapkannya? Pertama, Anda perlu membuat ukuran partikel secara acak. Ini hanya memerlukan pengacakan radius saat membuat partikel. Selain itu, jika Anda ingin radius partikel berubah secara dinamis, Anda perlu membedakan radius rendering partikel dan radius awal, serta menggunakan requestAnimationFrame untuk rendering animasi:
class Particle { konstruktor (pilihan = {}) { const { x = 0, y = 0, warna = '#fff', radius = 5} = pilihan ini.radius = radius; radius; // Tambahkan properti DynamicRadius} draw (ctx) { // ... ctx.arc(this.x, this.y, this.dynamicRadius, 0, 2 * Math.PI, false); Ganti dengan DynamicRadius // ... } update () { // TODO }}requestAnimationFrame(function loop() { requestAnimationFrame(loop); ctx.fillStyle = '#fff'; ctx.fillRect(0, 0, WIDTH, HEIGHT ); for (konstanta partikel) { partikel.update(); partikel.draw(ctx }}); Maka kuncinya terletak pada bagaimana menerapkan metode update partikel. Misalkan kita ingin jari-jari partikel berubah secara lancar dan siklis dari 1 menjadi 5. Mudah untuk memikirkan fungsi trigonometri, seperti:
Sumbu horizontal harus berhubungan dengan waktu. Anda dapat mempertahankan variabel dan menambahkannya setiap kali Anda memanggil pembaruan. Anda juga dapat menggunakan stempel waktu untuk menghitungnya dengan sederhana. Contoh metode update adalah sebagai berikut:
perbarui () { this.dynamicRadius = 3 + 2 * Math.sin(Tanggal baru() / 1000 % 1000 * this.radius);}Untuk kode selengkapnya, lihat 02-teks-ke-partikel-dengan-perubahan ukuran
Di atas adalah keseluruhan isi artikel ini, saya harap dapat bermanfaat untuk pembelajaran semua orang. Saya juga berharap semua orang mendukung VeVb Wulin Network.