码字,杂谈

JavaScript 之 canvas(三)-- 使用鼠标实时绘制图形

JavaScript 之 canvas(一)中理解了canvas的绘图原理。
JavaScript 之 canvas(二)中掌握了基本图形的函数,但是这些图形绘好之后是不会改变的。这并不符合我要做的这个绘图工具的最基本功能。

那么这篇文章来实现利用鼠标位置实时绘图。


首先我们需要了解动态绘图的思路,canvas在同一时刻,只能显示一张图片,也就是说,canvas是静态的,要实现实时绘图,就要不停切换canvas显示的图片内容,从而达到我们要的效果。

《JavaScript 之 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之后,基本可以区分绘制。

具体代码见https://github.com/jeremyjone/CanvasPaint

点赞
  1. GreggHeilm说道:

    Интересно!

    1. jeremyjone说道:

      спасибо

发表评论

电子邮件地址不会被公开。 必填项已用*标注