【发布时间】:2017-09-29 13:21:19
【问题描述】:
我正在做一个简单的拖动以在画布上绘制脚本。问题是当我绘制一条线来连接鼠标位置的点时,画布会从一些随机点绘制额外的线,但总是从初始点开始。
这是一个查看问题的示例:http://sktch.io/988111
我在一次这样的鼠标移动中获取了数据,并手动绘制了每个点,我可以确认问题没有得到解决。让我恼火的是,如果我手动对某些任意点执行 moveTo 和 lineTo ,代码就可以工作。鼠标拖动点有一些问题。据我所知,收集的积分没有问题。
任何指针表示赞赏。我已经尝试了各种修改,例如,beginPath、moveto、lineto 和 stroke 在每个循环迭代或 beginpath 中,以及在循环中 - moveto、lineto,然后在循环外描边。结果相同。
有问题的代码包含在底部。
var App = (function() {
var canvas, currentLayer, paint = false, context, socket, room, currentTool = 'line',
keysrt = function(key,desc) {
return function(a,b){
return desc ? ~~(a[key] < b[key]) : ~~(a[key] > b[key]);
}
},
reDraw = function() {
if (context) {
context.clearRect(0, 0, canvas.offsetWidth, canvas.offsetHeight);
Object.keys(layers).sort().forEach(function(key) {
let layer = layers[key];
switch(layer.getTool()) {
case 'line':
var data = layer.getData().sort(keysrt('time'));
if(data.length > 1) {
for(var i = 1; i < data.length; i++) {
context.beginPath();
context.moveTo(data[i-1]['value'][0], data[i-1]['value'][1]);
context.lineTo(data[i]['value'][0], data[i]['value'][1]);
context.stroke();
}
}
break;
case 'eraser':
var data = layer.getData().sort(keysrt('time'));
if(data.length > 0) {
for(var i = 0; i < data.length; i++) {
context.clearRect(data[i][0], data[i][1], 4, 4);
}
}
break;
case 'clear':
context.clearRect(0, 0, canvas.offsetWidth, canvas.offsetHeight);
break;
}
});
}
},
Layer = function() {
var data = [], tool, id = new Date().getTime();
return {
push: function(time, value) {
data.push({time: time, value: value})
},
toJSON: function() {
return {
data: data,
tool: tool,
id: id
}
},
setTool: function(t) {
tool = t;
},
getTool: function() {
return tool;
},
getData: function() {
return data;
},
getId: function() {
return id;
},
setId: function(i) {
id = i;
},
setData: function(d) {
data = d;
}
};
},
layers = {},
events = 0;
press = function (e) {
var mouseX = (e.changedTouches ? e.changedTouches[0].pageX : e.pageX) - this.offsetLeft, mouseY = (e.changedTouches ? e.changedTouches[0].pageY : e.pageY) - this.offsetTop;
// add a layer
paint = true;
currentLayer = Layer();
currentLayer.setTool(currentTool);
layers[currentLayer.getId()] = currentLayer;
events = 1;
},
drag = function (e) {
var mouseX = (e.changedTouches ? e.changedTouches[0].pageX : e.pageX) - this.offsetLeft, mouseY = (e.changedTouches ? e.changedTouches[0].pageY : e.pageY) - this.offsetTop;
if (paint) {
events = events + 1;
currentLayer.push(new Date().getTime() * 10 + events, [mouseX, mouseY]);
reDraw()
}
e.preventDefault();
},
release = function () {
paint = false;
if(currentLayer) {
events = 0;
reDraw();
}
currentLayer = null;
},
init = function(id, appendTo, width, height) {
room = id;
canvas = document.createElement('canvas');
canvas.setAttribute('width', width);
canvas.setAttribute('height', height);
canvas.setAttribute('id', 'canvas');
appendTo.appendChild(canvas);
context = canvas.getContext("2d");
canvas.addEventListener("mousedown", press, false);
canvas.addEventListener("mousemove", drag, false);
canvas.addEventListener("mouseup", release);
canvas.addEventListener("mouseout", release, false);
// Add touch event listeners to canvas element
canvas.addEventListener("touchstart", press, false);
canvas.addEventListener("touchmove", drag, false);
canvas.addEventListener("touchend", release, false);
canvas.addEventListener("touchcancel", release, false);
document.getElementById('clear').addEventListener("click", function() {
layer = Layer();
layer.setTool('clear');
layers[layer.getId()] = layer;
reDraw();
}, false);
}
return {
init: init
}
})();
【问题讨论】:
-
你不见了
context.clearRect(0,0,canvasWidth,canvasHeight); -
@Rayon 它就在那里。在重绘方法中。第 10 行。
-
@Kaiido 在包含链接的框中单击并拖动是stackoverflow.com/help/mcve
标签: javascript html canvas drawing