簡體   English   中英

如何在html5畫布中用它的連接線拖動點?

[英]How to drag points with it's connecting line in html5 canvas?

以下是我的代碼。 當我拖動一個點時,我遇到了問題。 問題是,每當我拖動點時,所有線都連接到一個點。 我需要在 html5 Canvas 中有可拖動的點。 但我有一個補充約束:這 2 個點必須用一條線連接起來。 當我拖動一個點時,這條線必須是動態繪制的,並且仍然鏈接到這兩個點。

 let points= []; let drag_point= -1; let pointSize= 6; let canvas = document.querySelector("#myCanvas"); let w = canvas.width; let h = canvas.height; var ctx = canvas.getContext("2d"); $("#myCanvas").mousedown(function (e) { var pos = getPosition(e); drag_point = getPointAt(pos.x, pos.y); console.log("pos", drag_point); if (drag_point == -1) { // no point at that position, add new point drawlines(pos.x, pos.y); points.push(pos); } }); $("#myCanvas").mousemove(function (e) { if (drag_point != -1) { // if currently dragging a point... var pos = getPosition(e); //...update that.points position... points[drag_point].x = pos.x; points[drag_point].y = pos.y; redraw(); // ... and redraw myCanvas } }); $("#myCanvas").mouseup(function (e) { drag_point = -1; }); function getPosition(event) { var rect = canvas.getBoundingClientRect(); var x = event.clientX - rect.left; var y = event.clientY - rect.top; console.log(x, y); return { x: x, y: y }; } function getPointAt(x, y) { for (var i = 0; i < points.length; i++) { if ( Math.abs(points[i].x - x) < pointSize && Math.abs(points[i].y - y) < pointSize ) // check if x,y is inside points bounding box. replace with pythagoras theorem if you like. return i; } return -1; // no point at x,y } function redraw() { ctx.clearRect(0, 0, canvas.width, canvas.height); // clear canvas for (var i = 0; i < points.length; i++) { // draw all points again drawlines(points[i].x, points[i].y); } } function drawlines(x, y) { drawImages(x, y); if (points.length > 0) { var last = points[points.length - 1]; ctx.beginPath(); ctx.moveTo(last.x, last.y); ctx.lineTo(x, y); ctx.strokeStyle = "blue"; ctx.stroke(); } } function drawImages(x, y) { var ctx = document.getElementById("myCanvas").getContext("2d"); ctx.beginPath(); ctx.arc(x, y, pointSize, 0, Math.PI * 2, true); ctx.strokeStyle = "red"; ctx.stroke(); }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <canvas id="myCanvas" width="1000" height="1000" style="border: 1px solid #d3d3d3" ></canvas>

.

請參閱下面的代碼...

我重構了你的drawlinesdrawImages以獨立調用而不是在一個公共循環中,在我的代碼中我們繪制所有線條,然后我們繪制所有圓圈,這樣我們就不必一直來回改變顏色並防止任何重疊在圓圈上的線條中,另一個變化是 mousedown 我稱之為重繪而不是繪制線。

查看您的代碼有根據的猜測問題出在您的:
var last = points[points.length - 1];
看起來很不對勁,從技術上講,這使得最后一個總是一樣的

 let points = [{x:10,y:10},{x:55,y:50},{x:100,y:10}]; let drag_point = -1; let pointSize = 6; let canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); canvas.onmousedown = function(e) { var pos = getPosition(e); drag_point = getPointAt(pos.x, pos.y); if (drag_point == -1) { points.push(pos); redraw(); } }; canvas.onmousemove = function(e) { if (drag_point != -1) { var pos = getPosition(e); points[drag_point].x = pos.x; points[drag_point].y = pos.y; redraw(); } }; canvas.onmouseup = function(e) { drag_point = -1; }; function getPosition(event) { var rect = canvas.getBoundingClientRect(); var x = event.clientX - rect.left; var y = event.clientY - rect.top; return {x, y}; } function getPointAt(x, y) { for (var i = 0; i < points.length; i++) { if ( Math.abs(points[i].x - x) < pointSize && Math.abs(points[i].y - y) < pointSize ) return i; } return -1; } function redraw() { if (points.length > 0) { ctx.clearRect(0, 0, canvas.width, canvas.height); drawLines() drawCircles() } } function drawLines() { ctx.beginPath(); ctx.moveTo(points[0].x, points[0].y); ctx.strokeStyle = "blue"; ctx.lineWidth = 2; points.forEach((p) => { ctx.lineTo(px, py); }) ctx.stroke(); } function drawCircles() { ctx.strokeStyle = "red"; ctx.lineWidth = 4; points.forEach((p) => { ctx.beginPath(); ctx.arc(px, py, pointSize, 0, Math.PI * 2, true); ctx.stroke(); }) } redraw()
 <canvas id="myCanvas" width=160 height=160 style="border: 1px solid"></canvas>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM