我有三个arrys:
clickX = [],
clickY = [],
clickDrag = [];
当您点击时会发生这种情况:
$('#canvasCursor').mousedown(function (e) {
console.log('down');
mouseX = e.pageX - this.offsetLeft;
mouseY = e.pageY - this.offsetTop;
paint = true;
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop);
redraw();
});
这里它将点击添加到数组并绘制。:
function redraw(){ ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height); //清除画布
ctx.strokeStyle = "green";
ctx.lineJoin = "round";
ctx.lineWidth = brushSize*2;
for (var i = 0; i < clickX.length; i++) {
ctx.beginPath();
if (clickDrag[i] && i) {
ctx.moveTo(clickX[i - 1], clickY[i - 1]);
} else {
ctx.moveTo(clickX[i] - 1, clickY[i]);
}
ctx.lineTo(clickX[i], clickY[i]);
ctx.closePath();
ctx.stroke();
}
}
我正在尝试摆脱现在这样做的数组方式,因为当我使用滑块动态更改var brushSize时,它会重新绘制新大小的整个图片,而不是当时的大小。我不知道如何保存数组中任何特定对象的大小,然后将它们分开绘制。
我不介意,只要我能修复画笔大小的变化,我就不能实现这种方式给我的撤销功能。在这里你可以看到我在撒谎! http://www.taffatech.com/Paint.html
- 它似乎更慢并且我猜测它因为它从数组中绘制
答案 0 :(得分:1)
编辑:抱歉,修正了一些拼写错误 编辑2 :再次。测试有点困难。
每次都没有理由重新绘制每个点。您可以修改您的监听器来执行此操作:
var prevMouseX=null,prevMouseY=null;
$('#canvasCursor').mousedown(function (e) {
paint = true;
console.log('down');
//get current mouse coords
mouseX = e.pageX - this.offsetLeft;
mouseY = e.pageY - this.offsetTop;
if (prevMouseX==null) {
//store these coordinates for next time if they haven't been defined yet
prevMouseX = mouseX;
prevMouseY = mouseY;
}
});
$('#canvasCursor').mousemove(function (e) {
//get current mouse coords
mouseX = e.pageX - this.offsetLeft;
mouseY = e.pageY - this.offsetTop;
if (prevMouseX==null) {
//store these coordinates for next time if they haven't been defined yet
prevMouseX = mouseX;
prevMouseY = mouseY;
}
if (paint) {drawline(mouseX,mouseY,prevMouseX,prevMouseY);}
//store these coordinates for next time
prevMouseX = mouseX;
prevMouseY = mouseY;
});
函数drawLine定义为:
function drawline(x1,y1,x2,y2) {
ctx.strokeStyle = "green";
ctx.lineJoin = "round";
ctx.lineWidth = brushSize*2;
ctx.beginPath();
ctx.moveTo(x1,y1);
ctx.lineTo(x2,y2);
ctx.closePath();
ctx.stroke();
}
答案 1 :(得分:1)
不要将绘画存储到数组
它严重减慢了绘图速度。只需绘制最新的一行而不清除画布。这样lineWeight更改不会影响到绘图之前。因此,请删除ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
和for
循环。您也可能只想在发生更改时更改上下文样式(lineWidth等),而不是每次运行redraw()
函数时都更改。
撤消支持
为每个鼠标按下会话制作不同的画布并将它们一起绘制,您可以轻松地进行撤消功能。通过按下撤消,它只是将最新的画布拼接出画布阵列。 Google要了解有关绘制到临时画布的更多信息。
答案 2 :(得分:1)
以下是如何使用画布绘制像Paint
如果您想要撤消功能,最佳选择是记录用户绘制的所有线段。
这是通过包含用户绘制的所有点(折线)的点阵来完成的。
要跟踪画笔大小和画笔颜色,您还需要在数组中包含此信息。
因此,数组的每个元素都将包含有关每个线段的信息:
它是如何运作的?
当用户拖动绘制线段时,每个mousemove事件都会使用context.lineTo
和context.stroke
扩展当前线段。
当用户选择新的BrushSize或BrushColor时,context.beginPath将启动context.beginPath
。
当用户按住“撤消”按钮时,最后一个线段中的最后一个点将从点阵列中弹出。然后重绘所有幸存的线段。按住按钮时,每按1/10秒触发一次。
这是代码和小提琴:http://jsfiddle.net/m1erickson/AEYYq/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<!--[if lt IE 9]><script type="text/javascript" src="../excanvas.js"></script><![endif]-->
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var lastX;
var lastY;
var mouseX;
var mouseY;
var canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var isMouseDown=false;
var brushSize=20;
var brushColor="#ff0000";
var points=[];
function handleMouseDown(e){
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// Put your mousedown stuff here
ctx.beginPath();
if(ctx.lineWidth!=brushSize){ctx.lineWidth=brushSize;}
if(ctx.strokeStyle!=brushColor){ctx.strokeStyle=brushColor;}
ctx.moveTo(mouseX,mouseY);
points.push({x:mouseX,y:mouseY,size:brushSize,color:brushColor,mode:"begin"});
lastX=mouseX;
lastY=mouseY;
isMouseDown=true;
}
function handleMouseUp(e){
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// Put your mouseup stuff here
isMouseDown=false;
points.push({x:mouseX,y:mouseY,size:brushSize,color:brushColor,mode:"end"});
}
function handleMouseMove(e){
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// Put your mousemove stuff here
if(isMouseDown){
ctx.lineTo(mouseX,mouseY);
ctx.stroke();
lastX=mouseX;
lastY=mouseY;
// command pattern stuff
points.push({x:mouseX,y:mouseY,size:brushSize,color:brushColor,mode:"draw"});
}
}
function redrawAll(){
if(points.length==0){return;}
ctx.clearRect(0,0,canvas.width,canvas.height);
for(var i=0;i<points.length;i++){
var pt=points[i];
var begin=false;
if(ctx.lineWidth!=pt.size){
ctx.lineWidth=pt.size;
begin=true;
}
if(ctx.strokeStyle!=pt.color){
ctx.strokeStyle=pt.color;
begin=true;
}
if(pt.mode=="begin" || begin){
ctx.beginPath();
ctx.moveTo(pt.x,pt.y);
}
ctx.lineTo(pt.x,pt.y);
if(pt.mode=="end" || (i==points.length-1)){
ctx.stroke();
}
}
ctx.stroke();
}
function undoLast(){
points.pop();
redrawAll();
}
ctx.lineJoin = "round";
ctx.fillStyle=brushColor;
ctx.lineWidth=brushSize;
$("#brush5").click(function(){ brushSize=5; });
$("#brush10").click(function(){ brushSize=10; });
// Important! Brush colors must be defined in 6-digit hex format only
$("#brushRed").click(function(){ brushColor="#ff0000"; });
$("#brushBlue").click(function(){ brushColor="#0000ff"; });
$("#canvas").mousedown(function(e){handleMouseDown(e);});
$("#canvas").mousemove(function(e){handleMouseMove(e);});
$("#canvas").mouseup(function(e){handleMouseUp(e);});
// hold down the undo button to erase the last line segment
var interval;
$("#undo").mousedown(function() {
interval = setInterval(undoLast, 100);
}).mouseup(function() {
clearInterval(interval);
});
}); // end $(function(){});
</script>
</head>
<body>
<p>Drag to draw. Use buttons to change lineWidth/color</p>
<canvas id="canvas" width=300 height=300></canvas><br>
<button id="undo">Hold this button down to Undo</button><br><br>
<button id="brush5">5px Brush</button>
<button id="brush10">10px Brush</button>
<button id="brushRed">Red Brush</button>
<button id="brushBlue">Blue Brush</button>
</body>
</html>