[英]how to draw a dynamic line in threejs with mouse down between two points using buffergeometry
[英]Draw a straight line between two points selected in a mouse down event
我有一个代码,当我在单击鼠标时移动鼠标(mousedown 事件和 mousemove 事件)时会画一条线。
我还希望从点的开始(我第一次单击该点,mousedown 事件)到结束(我解除鼠标事件,mouseup 事件)绘制一条直线。
(function() { var canvas = document.querySelector('#paint'); var ctx = canvas.getContext('2d'); var sketch = document.querySelector('#sketch'); var sketch_style = getComputedStyle(sketch); canvas.width = parseInt(sketch_style.getPropertyValue('width')); canvas.height = parseInt(sketch_style.getPropertyValue('height')); var mouse = { x: 0, y: 0 }; var last_mouse = { x: 0, y: 0 }; /* Mouse Capturing Work */ canvas.addEventListener('mousemove', function(e) { last_mouse.x = mouse.x; last_mouse.y = mouse.y; mouse.x = e.pageX - this.offsetLeft; mouse.y = e.pageY - this.offsetTop; }, false); /* Drawing on Paint App */ ctx.lineWidth = 5; ctx.lineJoin = 'round'; ctx.lineCap = 'round'; ctx.strokeStyle = 'black'; canvas.addEventListener('mousedown', function(e) { canvas.addEventListener('mousemove', onPaint, false); }, false); canvas.addEventListener('mouseup', function() { canvas.removeEventListener('mousemove', onPaint, false); }, false); var onPaint = function() { ctx.beginPath(); ctx.moveTo(last_mouse.x, last_mouse.y); ctx.lineTo(mouse.x, mouse.y); ctx.closePath(); ctx.stroke(); }; }());
#sketch{ width: 100%; height: 200px; background-color: #CCCCCC; }
<div id="sketch"> <canvas id="paint"> </canvas> </div>
您想存储mouseDown
事件的坐标,然后使用它们在mouseUp
事件的坐标上画一条线。 我修改了您的代码以显示一种可以完成的方法:
(function() { var canvas = document.querySelector('#paint'); var ctx = canvas.getContext('2d'); var sketch = document.querySelector('#sketch'); var sketch_style = getComputedStyle(sketch); canvas.width = parseInt(sketch_style.getPropertyValue('width')); canvas.height = parseInt(sketch_style.getPropertyValue('height')); var mouse = { x: 0, y: 0 }; var last_mouse = { x: 0, y: 0 }; /* Mouse Capturing Work */ canvas.addEventListener('mousemove', function(e) { last_mouse.x = mouse.x; last_mouse.y = mouse.y; mouse.x = e.pageX - this.offsetLeft; mouse.y = e.pageY - this.offsetTop; }, false); /* Drawing on Paint App */ ctx.lineWidth = 5; ctx.lineJoin = 'round'; ctx.lineCap = 'round'; ctx.strokeStyle = 'black'; canvas.addEventListener('mousedown', function(e) { initialPoint = {x:mouse.x, y:mouse.y} canvas.addEventListener('mousemove', onPaint, false); }, false); canvas.addEventListener('mouseup', function() { drawStraightLine() canvas.removeEventListener('mousemove', onPaint, false); }, false); var onPaint = function() { ctx.beginPath(); ctx.moveTo(last_mouse.x, last_mouse.y); ctx.lineTo(mouse.x, mouse.y); ctx.strokeStyle = "#000000"; ctx.closePath(); ctx.stroke(); }; let initialPoint const drawStraightLine = function() { ctx.beginPath(); ctx.moveTo(initialPoint.x, initialPoint.y); ctx.lineTo(mouse.x, mouse.y); ctx.strokeStyle = "#FF000077"; ctx.stroke(); } }());
#sketch{ width: 100%; height: 180px; background-color: #DDDDDD; }
<div id="sketch"> <canvas id="paint" /> </div>
initialPoint
是按下按钮时鼠标 position 和drawStarightLine()
是释放所述按钮时执行的方法。 还在线条中添加了不同的 colors 以使其明显。
只需添加另一个 position object 例如
const mouseDownAt = {x: 0, y: 0};
然后当鼠标按下事件发生时记录 position
canvas.addEventListener('mousedown', function(e) {
mouseDownAt.x = e.pageX - this.offsetLeft;
mouseDownAt.y = e.pageY - this.offsetTop;
canvas.addEventListener('mousemove', onPaint, false);
}, false);
在鼠标向上事件中绘制结束线
canvas.addEventListener('mouseup', function() {
lastMouse.x = mouse.x;
lastMouse.y = mouse.y;
mouse.x = e.pageX - this.offsetLeft;
mouse.y = e.pageY - this.offsetTop;
// if mouse has moved?? draw the last little bit
if (mouse.x !== last_mouse.x || mouse.y !== last_mouse.y) {
onPaint();
}
// set the end position
lastMouse.x = mouse.x;
lastMouse.y = mouse.y;
// use the mouse down at pos as the new position
mouse.x = mouseDownAt.x;
mouse.y = mouseDownAt.y;
// draw the line
onPaint();
canvas.removeEventListener('mousemove', onPaint, false);
}, false);
顺便说一句,我不确定您是否知道像您一样使用closePath
会两次渲染路径段并降低线条的质量(抗锯齿上的 alpha 太强)。 closePath
类似于lineTo
(绘制线段),与ctx.beginPath
function onPaint () {
ctx.beginPath();
ctx.lineTo(lastMouse.x, lastMouse.y); // after beginPath lineTo is the same
// moveTo
ctx.lineTo(mouse.x, mouse.y);
ctx.stroke();
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.