我正在尝试使用鼠标移动事件模拟钢笔绘图工具。
elCanvas.on("mousedown", function(e){
moving = true;
var position = getPos(e);
points = [];
points.push(position);
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.beginPath();
ctx.moveTo(position.x, position.y);
}
elCanvas.on("mousemove", function(e){
if (moving) {
var curr = getPos(e);
points.push(curr);
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
var p1 = points[0];
var p2 = points[1];
ctx.beginPath();
ctx.moveTo(p1.x, p1.y);
for (var i = 1, len = points.length; i < len; i++) {
var midPoint = midPointBtw(p1, p2);
ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);
p1 = points[i];
p2 = points[i + 1];
}
ctx.lineTo(p1.x, p1.y);
ctx.stroke();
}
现在这段代码在Safari中正常运行。但是鼠标在macView上的webView严重滞后。我目前正在用iMac 5K显示器进行测试。
还有一件事我注意到,代码工作正常(没有延迟)与更新的webView类OSX提供(WKWebView)。但它有64位的要求。
所以我希望它能用4k或5k显示器在mac webview上工作。
此外,我将结果与www.awwapp.com进行比较,该网站在同一个webView中使用相同的设置。
注意:为了平滑,我需要重绘整个逻辑点。如果我们在每次移动后盲目地划动,将导致粗略绘制。由于这段代码在Safari中运行良好,我主要担心的是为什么webView中的代码很慢?
答案 0 :(得分:2)
如果不清除画布,这会做同样的事情并且应该表现得更好。
<强>更新强>
使用requestAnimationFrame添加了一个动画循环来绘制点。这可能会带来额外的加速。您可以切换动画循环以查看它是否有所作为。
var elCanvas = document.getElementById('can');
var ctx = elCanvas.getContext('2d');
var moving = false;
var points = [];
function getPos(evt) {
var rect = elCanvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
function midPointBtw(p1, p2) {
return {
x: p1.x + (p2.x - p1.x) / 2,
y: p1.y + (p2.y - p1.y) / 2
};
}
elCanvas.addEventListener("mousedown", function(e) {
moving = true;
var position = getPos(e);
points = [];
points.push(position);
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.beginPath();
ctx.moveTo(position.x, position.y);
});
elCanvas.addEventListener("mousemove", function(e) {
if (moving) {
// collect point
var curr = getPos(e);
points.push(curr);
if (ani_status == "off") {
// no animaion loop.. draw here.
draw();
} else {
requestAnimationFrame(draw);
}
}
});
function draw() {
if (points.length < 2) return;
// Draw all the points we've collected since the last draw.
var p1 = points[0];
var p2 = points[1];
ctx.beginPath();
ctx.moveTo(p1.x, p1.y);
for (var i = 1, len = points.length; i < len; i++) {
var midPoint = midPointBtw(p1, p2);
ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);
p1 = points[i];
p2 = points[i + 1];
}
ctx.lineTo(p1.x, p1.y);
ctx.stroke();
// Keep the last point for next draw.
points = [points[points.length-1]]
}
var ani_status = "off";
function toggleAni(value) {
ani_status = value;
}
&#13;
#can {
border: 1px solid #777777;
}
&#13;
<form>
animation-loop<br>
on<input type=radio name=ani-loop value='on'
onclick='toggleAni(this.value)'>
off<input type=radio name=ani-loop value='off' checked onclick='toggleAni(this.value)'></form>
<canvas id='can' width=600 height=400></canvas>
&#13;