Dalam proyek terbaru, saya ingin mengimplementasikan papan gambar bergaya piksel, di mana kisi-kisi piksel kecil dapat dihapus, pilihan bingkai berubah warna, dan berbagai grafik dapat dihapus hal-hal.
Gambarlah kotak pikselPertama-tama mari kita tentukan kelas kisi piksel
Piksel = fungsi (opsi) { ini.x = opsi.x; ini.y = opsi.y; ini.bentuk = opsi.bentuk; ini.ukuran = opsi.ukuran ||
x dan y mewakili koordinat titik pusat. Ini yang saya lakukan di awal.
createPath: function (ctx) {if (this.shape === 'circle') {this.createCircle(ctx);} else if (this.shape === 'rect') {this.createRect(ctx);} else {this.createCircle(ctx);}},createCircle: function (ctx) {var radius = this.size / 2;ctx.arc(this.x,this.y,radius,0,Math.PI*2);},createRect: function (ctx) {var points = this.getPoints(); points.forEach(function (point , i) { ctx[i == 0 ? 'moveTo' : 'lineTo'](titik.x, titik.y }) ctx.lineTo(titik[0].x, poin[0].y);},
Grid piksel mendukung lingkaran dan persegi panjang. Setelah jalur ditentukan, jalur tersebut kemudian digambar.
menggambar: fungsi (ctx) {ctx.save();ctx.lineWidth=this.lineWidth;ctx.strokeStyle=this.strokeStyle;ctx.fillStyle=this.fillStyle;ctx.beginPath();this.createPath(ctx); ctx.stroke();if(this.isFill){ctx.fill();}ctx.restore();}
Kemudian buat kisi piksel secara berkelompok melalui satu lingkaran:
for (var i = stepX + .5; i < canvas.width; i+=stepX) {for (var j = stepY + .5; j < canvas.height; j+=stepY) {var pixel = new Pixel({x : i,y: j,bentuk: 'lingkaran'})box.push(pixel);pixel.draw(ctx);}}
Ini tampaknya sempurna, tetapi ada kelemahan besar. Setiap kali piksel digambar, piksel tersebut ditarik kembali ke konteksnya, dan status kanvas berubah setiap saat. Hal ini akan menyebabkan kinerja rendering yang buruk karena jumlahnya banyak piksel. Jika kanvas relatif besar, kinerjanya sangat mengkhawatirkan, dan ada beberapa operasi pada papan gambar. Tidak pantas untuk terlalu sering mengubah keadaan kanvas.
Oleh karena itu, pendekatan yang benar adalah: kita harus mendefinisikan semua jalur, dan yang terbaik adalah menggambarnya ke dalam kanvas secara berkelompok sekaligus;
//Tentukan posisi piksel untuk (var i = stepX + .5; i < canvas.width; i+=stepX) {for (var j = stepY + .5; j < canvas.height; j+=stepY) { var piksel = Piksel baru({x: i,y: j,bentuk: 'circle'})box.push(pixel);}}//Gambar kumpulan console.time('time');ctx.beginPath();for (var c = 0; c < box.length; c++) {var lingkaran = kotak[c];ctx.moveTo(lingkaran.x + 3, lingkaran.y);lingkaran.createPath(ctx);}ctx.closePath();ctx.stroke();console.timeEnd('time');
Anda dapat melihat bahwa efisiensi rendering ini sangat cepat, dan keadaan kanvas diubah sesedikit mungkin, karena setiap kali keadaan konteks diubah, kanvas akan digambar ulang, dan keadaan ini adalah keadaan global.
Interaksi jaringan pikselPersyaratan proyek ini adalah piksel dapat dihapus dengan menekan dan menggerakkan mouse di atas kanvas. Hal ini berisi dua poin pengetahuan, satu adalah cara mendapatkan kisi piksel pada jalur pergerakan mouse, dan yang kedua adalah masalah kinerja, karena dari kebutuhan kita Syaratnya adalah menggambar 80.000 poin. Belum lagi yang lainnya, perulangan saja akan memakan waktu puluhan atau ratusan milidetik, belum lagi menggambar dan rendering. Mari kita lihat pertanyaan pertama terlebih dahulu:
Dapatkan grid di bawah jalur pergerakan mouseMelihat masalah ini, kita dapat dengan mudah memikirkan untuk menulis fungsi untuk mendapatkan posisi mouse melalui posisi mouse, yang berisi grid, dan kemudian memperbarui kembali perhitungan posisi setiap kali bergerak, dengan cara ini, persyaratannya dapat dipenuhi, tetapi jika mouse bergerak Tidak mungkin melakukannya dengan cepat. Posisi setiap titik dapat dihitung, dan efeknya akan tidak konsisten. Mari kita ubah pemikiran kita. Kita dapat dengan jelas mengetahui titik awal dan akhir dari jalur yang dilalui mouse. Kita bayangkan seluruh jalur gambar sebagai sebuah ruas garis. Kemudian permasalahan tersebut menjadi suatu algoritma untuk memotong ruas garis tersebut dengan garis aslinya segmen adalah Ketebalan kuas dan jalur yang dilalui segmen garis adalah jalur pergerakan mouse, dan lingkaran yang berpotongan dengannya adalah kisi-kisi yang perlu diubah. Dikonversi menjadi kode adalah sebagai berikut:
fungsi kuadrat(x) { kembalikan x * x } fungsi dist2(p1, p2) { kembalikan kuadrat(p1.x - p2.x) + kuadrat(p1.y - p2.y) } fungsi distToSegmentSquared(p, v, w ) { var l2 = dist2(v, w); jika (l2 == 0) kembalikan dist2(p, v); ((px - vx) * (wx - vx) + (py - vy) * (wy - vy)) / l2; jika (t < 0) kembalikan dist2(p, v); (p, w); kembalikan dist2(p, { x: vx + t * (wx - vx), y: vy + t * (wy - vy) }); @keterangan Hitung apakah ruas garis memotong lingkaran* @param {x: num, y: num} p titik pusat lingkaran* @param {x: num, y: num} v titik awal ruas garis* @param {x : num, y: num } w titik ujung ruas garis*/ function distToSegment(p, v, w) { var offset = pathHeight; var minX = Math.min(vx, wx) - offset; var maxX = Matematika.max(vx, wx) + offset; var minY = Matematika.min(vy, wy) - offset; ||. px > maxX) && (py < minY || py > maxY)) { mengembalikan Nomor.MAX_VALUE } mengembalikan Math.sqrt(distToSegmentSquared(p, v, w)); }
Logika spesifiknya tidak akan diuraikan. Pembaca dapat membaca kodenya sendiri. Kemudian, dengan mendapatkan grid yang berpotongan, hapus data di dalam kotak, dan render lagi, Anda dapat melihat efeknya.
Dengan cara yang sama, kita dapat membuat efek pewarnaan, dan kemudian kita dapat menerapkan demo kecil papan gambar piksel kanvas. Namun untuk membuat efek pewarnaan harus menggunakan cara menggambar yang pertama.Setiap piksel harus berupa objek, karena keadaan setiap objek bersifat independen.Namun, tidak perlu mengkhawatirkan performanya pada dasarnya tidak akan ada rasa lag. Efeknya kira-kira sebagai berikut:
Saya agak malas akhir-akhir ini, jadi saya biarkan seperti ini dulu. Saya punya waktu untuk menambahkan fungsi untuk mengunggah gambar, membuat piksel gambar, dan fungsi ekspor nanti.
Di atas adalah keseluruhan isi artikel ini, saya harap dapat bermanfaat untuk pembelajaran semua orang. Saya juga berharap semua orang mendukung VeVb Wulin Network.