我正在尝试用HTML和JavaScript创建一个简单的绘图脚本。我这样做是通过在整个窗口上创建一个div,然后通过使该div的onmousemove事件调用updateFunc()来跟踪鼠标的位置,以便当您按住鼠标左键时,会创建一个红色的圆形div元素,并按更新以类似于画笔。
问题在于onmousemove事件的更新太慢,以至于如果您将光标移动得太突然,则每个创建的div元素之间都有很大的距离。理想情况下,无论您移动光标的速度如何,创建一条线都应尽可能平滑。是否可以使用此方法来执行此操作,还是应该尝试其他方法?
<div onmousemove="updateFunc();" id="background" style="position:fixed;width:100%;height:100%;z-index:100%;" onmousedown="isDown = true;" onmouseup="isDown = false;"></div>
<div id="test1" style="width:10px;height:10px;background-color:red;"></div>
<script>
var test1 = document.getElementById("test1");
var isDown = false;
function updateFunc() {
x = event.clientX;
y = event.clientY;
document.getElementById("test1").style.left = (x - (Number(test1.style.width.slice(0,-2)) / 2)) + "px";
document.getElementById("test1").style.top = (y - (Number(test1.style.height.slice(0,-2)) / 2)) + "px";
if (isDown) {
var div = document.createElement("div");
div.style.position = "absolute";
div.style.top = (y - (Number(test1.style.height.slice(0,-2)) / 2)) + "px";
div.style.left = (x - (Number(test1.style.width.slice(0,-2)) / 2)) + "px";
div.style.backgroundColor = "red";
div.style.width = "10px";
div.style.height = "10px";
div.style.borderRadius = "200px 200px 200px 200px";
var body = document.querySelector("body");
body.appendChild(div);
}
}
</script>
答案 0 :(得分:2)
无法 加速 浏览器触发mousemove
事件。
您可以使用一些基本的三角函数,在创建两个点之后,只需将两个点与缺少的DIV连接起来...等等,我只是说过DIV吗?
使用canvas
不能将DOM用于绘制应用程序(嗯,除非您要创建32x32 favicon生成器,否则……)。入门非常容易。
画布将具有相同的“问题”。它会 将您的鼠标移动点与一条线连接起来,但是如果您的鼠标速度很快,则该线将看起来像多边形的边缘。在这种情况下,一些贝塞尔曲线或二次曲线可能会有所帮助。最终结果将是一个更快,更UX体验的应用程序。一旦创造性地用尽,用户还可以下载自己的图形(另存为图像)。
这是一个使用canvas
和quadraticCurveTo
的演示:
var pen = {
color: "rgba(255, 0, 0, 1.0)", // Set desired color
size: 3 // Set desired size
};
var pts = [];
var isDown = false;
var isTouch = false;
var cvs = document.getElementById('canvas');
var cvs2 = document.createElement('canvas');
var ctx = cvs.getContext('2d');
var ctx2 = cvs2.getContext('2d');
function setCvsSize() {
cvs.width = cvs2.width = document.documentElement.clientWidth;
cvs.height = cvs2.height = document.documentElement.clientHeight;
}
function penDown(ev) {
ev.preventDefault();
isTouch = ev.type === "touchstart";
ev = isTouch ? ev.touches[0] : ev;
isDown = true;
pts.push({
x: ev.clientX,
y: ev.clientY
});
drawPoints();
}
function penMove(ev) {
ev.preventDefault();
ev = isTouch ? ev.touches[0] : ev;
if (isDown) {
ctx.clearRect(0, 0, cvs.width, cvs.height);
ctx.drawImage(cvs2, 0, 0); // Draw to inmemory cvs2
pts.push({
x: ev.clientX,
y: ev.clientY
});
drawPoints();
}
}
function penUp(ev) {
ev.preventDefault();
isDown = isTouch = false;
pts = [];
// Save state to in-memory cvs2
ctx2.clearRect(0, 0, cvs.width, cvs.height);
ctx2.drawImage(cvs, 0, 0);
}
function clear() {
ctx.clearRect(0, 0, cvs.width, cvs.height);
ctx2.clearRect(0, 0, cvs.width, cvs.height);
}
function drawPoints() {
var i = 0;
var i2 = pts.length > 1 ? 1 : 0;
ctx.beginPath();
ctx.lineWidth = pen.size;
ctx.lineJoin = 'round';
ctx.lineCap = 'round';
ctx.moveTo(pts[0].x, pts[0].y);
for (; i < pts.length - i2; i++) {
ctx.quadraticCurveTo(
pts[i].x,
pts[i].y,
(pts[i].x + pts[i + i2].x) / 2,
(pts[i].y + pts[i + i2].y) / 2
);
}
ctx.strokeStyle = pen.color;
ctx.stroke();
ctx.closePath();
}
// EVENTS
cvs.addEventListener('touchstart', penDown);
cvs.addEventListener('mousedown', penDown);
cvs.addEventListener('touchmove', penMove);
cvs.addEventListener('mousemove', penMove);
cvs.addEventListener('touchend', penUp);
cvs.addEventListener('mouseup', penUp);
window.addEventListener('resize', setCvsSize);
// INIT
setCvsSize();
*{margin: 0;}
#canvas {
display: block;
}
<canvas id='canvas'></canvas>