修身养性,知行合一

  • 首页
  • 爱码
    • 系统
    • 数据库
    • JavaScript
    • CSharp
    • Python
  • 生活
    • 文化
    • 美食
  • 杂谈
  • 关于
修身养性,知行合一
码字,杂谈
  1. 首页
  2. 爱码
  3. 前端
  4. JavaScript
  5. 正文

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

2019年9月16日 6771点热度 5人点赞 2条评论

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

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

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
标签: canvas JavaScript
最后更新:2019年9月16日

jeremyjone

这个人很懒,什么都没留下

打赏 点赞
< 上一篇
下一篇 >

文章评论

  • GreggHeilm

    Интересно!

    2019年10月17日
    回复
    • jeremyjone

      @GreggHeilm спасибо

      2019年10月25日
      回复
  • 取消回复

    最新 热点 随机
    最新 热点 随机
    推一个vscode纯黑主题 vue 的递归插槽穿透 Github Pages SPA 重定向 行间距引出的 DOCTYPE 怪异行为 写个小彩蛋 绘制一个可重用的线条阴影
    vue 的递归插槽穿透推一个vscode纯黑主题
    rgb 颜色小数兼容问题 Vim使用指南 Navicat 12 安装与破解 前端优化的几个点 MySql的BLOB格式 双十一 京东养红包攻略

    (っ•̀ω•́)っ✎⁾⁾ 开心每一天

    COPYRIGHT © 2021 jeremyjone.com. ALL RIGHTS RESERVED.

    THEME KRATOS MADE BY VTROIS

    京ICP备19012859号-1

    京公网安备 11010802028585号