Untuk melacak apa yang sedang digambar, banyak aplikasi, seperti aplikasi menggambar, sistem desain berbantuan komputer (sistem CAD), dan permainan, menyimpan daftar objek yang sedang ditampilkan. Biasanya, aplikasi ini memungkinkan pengguna untuk memanipulasi objek yang sedang ditampilkan di layar. Misalnya, dalam aplikasi CAD, kita dapat memilih, memindahkan, memperbesar, dll elemen dalam desain
-"Teknologi Inti Kanvas HTML5"
Hal yang sama berlaku 实现拖拽
di Canvas. Canvas menyediakan API yang disebut isPointInPath(x, y)
untuk menentukan apakah 点(x, y)
ada di jalurnya. Mengembalikan nilai benar jika berada dalam jalur. Jadi kita dapat memiliki ide-ide berikut:
Pertahankan 数组
yang dapat mendeskripsikan setiap jalur, dan gunakan ispointInPath(x, y)
untuk menentukan apakah posisi yang diklik berada di jalur tertentu. Jika berada di jalur ini, pilih jalur ini, lakukan operasi (memindahkan, memperbesar, dll.) , lalu gambar grafiknya
Pada artikel ini, saya menggunakan 多边形拖拽为例进行说明
. Demonya adalah sebagai berikut (alasan di balik jejak tersebut adalah perangkat lunak perekaman layar: japanese_ogre :):
CodePen terbuka
Cara menggambar poligon di Demo sudah dirangkum sebelumnya, jadi saya tidak akan panjang lebar lagi: ghost:: Gambar poligon kanvas
Penjelasan ideGambar di bawah ini memberikan gambaran kasar dan kode semu. Idenya tidak sulit, tetapi ada beberapa detail yang perlu diperhatikan.
Struktur kode tercantum di sini dan idenya ditandai. Komentar kode yang lebih detail ada di CodePen.
Karena artikel ini berfokus pada drag, maka deskripsi bagian gambarnya akan lebih sedikit.
//Menggambar fungsi jalur poligon fungsi drawPolygonPath//Kelas definisi kelas poligon Poligon{ ...}//Mengembalikan posisi di kanvas sesuai dengan fungsi kejadian klik positoinInCanvas//Mendapatkan jarak garis lurus antara dua titik fungsi getDistance// Pada tahap awal, rekam drag Drag objek canvas.onmousedown//Drag fase, gambar path, guratan canvas.onmousemove//End fase, update posisi objek drag canvas.onmouseupDeskripsi bagian-bagian penting
Selanjutnya, mulailah memproses bagian-bagian penting dan detail kode
Cara memelihara array objek dragSelama inisialisasi program, kami mendefinisikan array polygonArray
susunan poligon = []
Setiap kali poligon baru digambar, objek poligon baru akan dimasukkan ke dalam array untuk pemeliharaan.
const polygon = new Polygon(mouseStart.get('x'), mouseStart.get('y'), sideNum, radius);polygonArray.push(polygon);//Rekam objek jalur
Dalam operasi klik berikutnya, penting untuk menentukan apakah posisi klik berada di jalur berdasarkan informasi terkait.
Cara memilih objek yang akan diseret saat diklik Pertama, dapatkan posisi yang sesuai canvas中
saat diklik. Kode saya menggunakan mouseStart
untuk mencatat x
dan y
Kemudian lintasi polygon
di polygonArray
, panggil polygon.createPath()
selama traversal, dan gunakan isPointInPath()
untuk menentukan apakah ada jalur pada posisi yang diklik. Jika ya, draggingPolygon = polygon
mengakhiri fungsinya.
const pos = positionInCanvas(e, canvasLeft, canvasTop);//Dapatkan posisi piksel di kanvas//Rekam titik awal mouse smouseStart.set('x', pos.x);mouseStart.set('y', pos. y);...untuk (biarkan poligon dari polygonArray) { polygon.createPath(); jika (ctx.isPointInPath(mouseStart.get('x'), mouseStart.get('y'))) { menyeretPolygon = poligon;Perhitungan saat menyeret
Bagian ini harus dipahami sepenuhnya. Disarankan agar Anda melakukan debug berdasarkan dua console.log(draggingPolygon)
dan kode di Demo, karena kita berada dalam tahap mousemove
, dan fungsinya sangat sering dipicu pada tahap ini.
Saya mencoba mengungkapkannya dengan jelas dengan kata-kata
Pertama, hitung jarak dari mouseStart
saat move
, yang dicatat sebagai diff. Ada offsetX
pada sumbu x dan offsetY
pada sumbu y.
const pos = positionInCanvas(e, canvasLeft, canvasTop), diff = Peta baru([ ['offsetX', pos.x - mouseStart.get('x')], ['offsetY', pos.y - mouseStart.get( 'kamu')] ]);
Kemudian catat centerX
dan centerY
dari objek drag saat ini, dicatat sebagai temp
biarkan tempCenterX = menyeretPolygon.centerX, tempCenterY = menyeretPolygon.centerY;
Ini adalah poin yang sulit untuk dipahami. Teruslah membaca, Anda akan menggunakannya nanti.
Atur posisi tengah baru dari dragPolygon sesuai dengan offset di diff
menyeretPolygon.centerX += diff.get('offsetX'); menyeretPolygon.centerY += diff.get('offsetY');
Kemudian bersihkan kanvas dan gambar jalur dan guratan baru
ctx.clearRect(0, 0, canvas.width, canvas.height);for (biarkan poligon dari polygonArray) { drawPolygonPath(polygon.sideNum, polygon.radius, polygon.centerX, polygon.centerY, ctx.stroke(); );}
Terakhir, tempCenterX
dan tempCenterY
yang disebutkan di atas digunakan:
menyeretPolygon.centerX = tempCenterX; menyeretPolygon.centerY = tempCenterY;
Mengapa kita perlu melakukan ini?
Karena drag kita 基于多边形的原位置
, dan tahap mousemove
不能确定函数的最终位置
. Jika tidak ada pemulihan saat ini, akan terjadi 漂移
efeknya adalah sebagai berikut:
Jika saya tidak menjelaskannya, saya menyarankan semua orang untuk memodifikasi dan men-debug kode.
Memproses setelah menyeret Setelah penyeretan selesai, ia berada dalam tahap mouseup
. Saat ini, kami telah menentukan posisi akhir dari dragginPolygon dan dapat memperbaruinya. Terakhir, disetel ke null untuk mengecualikan 在没有拖拽多边形情况下,鼠标在画布上移动触发对应代码
const pos = positionInCanvas(e, canvasLeft, canvasTop), offsetMap = Peta baru([ ['offsetX', pos.x - mouseStart.get('x')], ['offsetY', pos.y - mouseStart.get( 'y')] ]); menyeretPolygon.centerX += offsetMap.get('offsetX'); menyeretPolygon.centerY += offsetMap.get('offsetY'); menyeretPolygon = null;Kesimpulan
Faktanya, tidak sulit untuk mengimplementasikan fungsi ini. Kuncinya adalah memahami sebuah konsep: pelacakan dicapai dengan memelihara daftar objek yang sedang ditampilkan dan membuat penilaian dengan isPointInPath.
Terakhir, sambut semua orang untuk bertukar dan belajar
Referensi"Teknologi Inti Kanvas HTML5"
Di atas adalah keseluruhan isi artikel ini, saya harap dapat bermanfaat untuk pembelajaran semua orang. Saya juga berharap semua orang mendukung VeVb Wulin Network.