在JavaScript 之 canvas(一)中理解了canvas的绘图原理。
在JavaScript 之 canvas(二)中掌握了基本图形的函数,但是这些图形绘好之后是不会改变的。这并不符合我要做的这个绘图工具的最基本功能。
那么这篇文章来实现利用鼠标位置实时绘图。
首先我们需要了解动态绘图的思路,canvas
在同一时刻,只能显示一张图片,也就是说,canvas
是静态的,要实现实时绘图,就要不停切换canvas
显示的图片内容,从而达到我们要的效果。
如图效果,让图片按照我们的鼠标移动而改变大小,这样就需要刷新canvas
,现在就来实现这个效果。
第一步,加载图片和清空canvas
canvas.loadImage = function () {
let self = this;
let img = new Image();
img.src = self.lastImage; // 将最后保存的图片赋值给img
context.drawImage(img, 0, 0, canvas.width, canvas.height); // 将img展示在canvas中
}
canvas.initCanvas = function () {
context.clearRect(0, 0, canvas.width, canvas.height); // 清空canvas
canvas.loadImage(); // 将最近的图片展示到canvas中
}
有了这两个函数,我们就可以自由的清空和加载图片,那么图片从哪里来,何时保存,看第二步。
第二步,获取鼠标事件
canvas.onmousedown = function mouseDownAction(e) {
let self = this;
self.X1 = e.offsetX; // 鼠标按下时保存当前位置,为起始位置
self.Y1 = e.offsetY;
self.isMouseDown = true; // 将按下的flag表示为true,拖动鼠标时使用
self.loadImage();
};
canvas.onmousemove = function mouseMoveAction(e) {
let self = this;
if (self.isMouseDown) {
self.X2 = e.offsetX;
self.Y2 = e.offsetY;
self.drawing(self.X1, self.Y1, self.X2, self.Y2, e);
}
};
canvas.onmouseup = function mouseUpAction(e) {
let self = this;
self.lastImage = canvas.toDataURL('image/png');
self.isMouseDown = false;
};
当鼠标按下时,获取事件,保存鼠标当前位置为起始位置(x1, y1)
,并且将一个按下的flag变为true
,这样在移动鼠标时,可以判断是否应该绘图,同时加载背景图片。
当鼠标按下且移动时,调用自定义的绘图函数drawing
,并且保存鼠标移动时的当前位置,该位置在移动时不停切换,作为绘图的结束位置(x2, y2)
,图片会不停的绘制。
当鼠标抬起时,停止绘图,将移动flag变为false
,同时保存最后一张图片,这样就获取到了我们需要的最后的图片,后续可以加载为背景。
绘图
有了上面的前序工作,我们就可以很自然的开始绘图工作。
canvas.drawing = function (x1, y1, x2, y2, e) {
let self = this;
if (!context) {
return;
} else {
// 设置画笔的颜色和大小
context.fillStyle = "red"; // 填充颜色为红色
context.strokeStyle = "blue"; // 画笔的颜色
context.lineWidth = 5; // 指定描边线的宽度
context.save();
context.beginPath();
self.initCanvas(); // 每次需要调用初始化函数,以清空canvas
// 绘制空心矩形
context.strokeRect(x1, y1, x2 - x1, y2 - y1);
context.restore();
context.closePath();
}
};
这个就是我们在鼠标按下且移动时调用的绘图函数,它可以帮主我们不停的绘图,注意每次调用前都需要初始化,也就是清空canvas
,这样就能愉快地使用鼠标绘图了。
如果需要绘制其他图形,只需要修改drawing
函数即可。
至此,我们稍加修改前一篇文章的基本图形,就可以根据我们的鼠标进行动态绘图了。
比如画笔工具:
canvas.drawing = function (x1, y1, x2, y2, e) {
let self = this;
if (!context) {
return;
} else {
// 设置画笔的颜色和大小
context.fillStyle = "red"; // 填充颜色为红色
context.strokeStyle = "blue"; // 画笔的颜色
context.lineWidth = 5; // 指定描边线的宽度
context.save();
context.beginPath();
// 画笔需要保留之前的移动轨迹,所以不需要初始化清除。
context.moveTo(x1, y1);
context.lineTo(x2, y2);
context.stroke();
// 画笔功能,需要动态实时将当前位置赋给初始位置,以实现连续笔记,否则就是直线。
self.X1 = self.X2;
self.Y1 = self.Y2;
context.restore();
context.closePath();
这样的方式有助于理解重载和初始化canvas
,可以更好的帮助我们了解canvas
的工作方式。
至此,基本的绘画板已经可以实现。添加button
和对应的flag之后,基本可以区分绘制。
文章评论
Интересно!
@GreggHeilm спасибо