我正在制作一个简单的拖动来在画布上绘制脚本。问题在于,当我绘制一条线来连接鼠标位置的点时,画布会从一些随机点绘制额外的线条,但始终从初始点开始。
以下是查看问题的示例:http://sktch.io/988111
我在一次这样的鼠标移动中捕获了数据,并手动完成了每个点的绘制,我可以确认问题没有得到解决。令我恼火的是,如果我手动执行moveTo和lineTo以获取某些任意点,则代码可以正常工作。鼠标拖拽点存在一些问题。据我所知,收集的积分没有问题。
任何指针都表示赞赏。我已经在每个单循环迭代或者beginpath中尝试了各种修改,例如beginPath,moveto,lineto和stroke,并且在循环中 - 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
}
})();
答案 0 :(得分:0)
错误在于您的排序功能,它只返回0
或1
。
将您的keysrt
更改为更具可读性
keysrt = function(key,desc) {
return function(a,b){
if(desc){
if(a[key] < b[key]) return 1;
if(a[key] > b[key]) return -1;
return 0;
}
else{
if(a[key] < b[key]) return -1;
if(a[key] > b[key]) return 1;
return 0;
}
}
解决了这个问题:
var App = (function() {
var canvas, currentLayer, paint = false,
context, socket, room, currentTool = 'line',
keysrt = function(key, desc) {
return function(a, b) {
if (desc) {
if (a[key] < b[key]) return 1;
if (a[key] > b[key]) return -1;
return 0;
} else {
if (a[key] < b[key]) return -1;
if (a[key] > b[key]) return 1;
return 0;
}
}
},
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);
}
return {
init: init
}
})();
App.init('', document.body, 800, 800)