开发Canvas 绘画应用(二):实现绘画

开发Canvas 绘画应用(一):搭好框架 中我们已经把基本框架及基础功能实现了,现在要实现本应用的重点:绘画功能。

首先分析一下,我们要实现绘画,需要具备的理论知识如下:

(1)获取触摸点的坐标

类似于获取鼠标在屏幕上的位置,我们现在需要获取手指在绘图板上的位置,这就需要用到触摸事件的跟踪触摸的属性:

  • touches:表示当前跟踪的触摸操作的 Touch 对象的数组。
  • targetTouches:特定于事件目标的 Touch 对象的数组。
  • changedTouches:表示自上次触摸以来发生了什么改变的 Touch 对象的数组。

可以将有几个 Touch 对象看成有几个手指,每个手指的触摸点对应一系列属性。

注意:与 changedTouches 不同,touchestargetTouchestouchend 触发时均没有 Touch 数组,length 为0,即触摸点数为0。可以在浏览器上打印输出进行对比。

其中,每个 Touch 对象包含下列属性:

  • clientX:触摸目标在视口中的 x 坐标。
  • clientY:触摸目标在视口中的 y 坐标。
  • identifier:标识触摸的唯一 ID。
  • pageX:触摸目标在页面中的 x 坐标。
  • pageY:触摸目标在页面中的 y 坐标。
  • screenX:触摸目标在屏幕中的 x 坐标。
  • screenY:触摸目标在屏幕中的 y 坐标。
  • target:触摸的 DOM 节点目标。

(2)Canvas 绘制路径的方法

  • beginPath():绘制路径前必须调用,表示要开始绘制新路径。
  • lineTo(x,y):从上一点开始绘制一条直线。
  • moveTo(x,y):从绘图游标开始移动到(x,y),不画线。
  • closePath():创建路径之后,绘制一条连接到起点的线条。
  • fill():对路径进行填充。
  • stroke():对路径进行描边。
  • clip():在路径上创建一个剪切区域。

绘画实现

OK,理论知识已经具备了,接下去就要开始搬砖了。

① 初始化数据

initData() {
    this.lastX = 0;
    this.lastY = 0;
    this.isPaint = false;

    return this;
}

② 实现绘画函数

/**
 * 绘画函数
 * @param  {[type]} x 触摸点x坐标
 * @param  {[type]} y 触摸点y坐标
 * @return {[type]}   将当前坐标赋给上一个点坐标
 */
draw(x, y) {
    if (this.isPaint) {
        this.ctx.beginPath(); // 开始绘制路径,必须调用
        this.ctx.moveTo(this.lastX, this.lastY); // 将绘图游标移动到到上一点
        this.ctx.lineTo(x, y); // 从上一点开始绘制一条到(x,y)的直线
        this.ctx.stroke(); // 描边路径
    }

    // 上面必须判断 this.isPaint
    // 当 'touchstart' 时,先移动到触摸点
    this.lastX = x;
    this.lastY = y;
}

③ 完善事件处理函数(★重点)

// 触摸事件处理函数
touchF(e) {
    e.preventDefault(); // 阻止浏览器默认行为
    const touches = e.changedTouches; // 获取 Touch 对象list
    const point = touches[0]; // 获取第一个 Touch 对象

    // 获取元素宽、高及距窗口上下左右距离
    const rect = this.cva.getBoundingClientRect();
    // 相当于const rect = $('.painter').offset();
    // 相当于const rect = { left: this.cva.offsetLeft, top: this.cva.offsetTop }

    switch (e.type) {
        case 'touchstart':

            // 获取触摸点的x,y坐标,传入draw函数
            this.draw(point.clientX - rect.left, point.clientY - rect.top);
            this.isPaint = true;

            break;
        case 'touchmove':
            this.draw(point.clientX - rect.left, point.clientY - rect.top);

            break;
        case 'touchend':
            this.isPaint = false;

            break;
        default:
            this.isPaint = false;

            break;
    }
}

这里需要获取 canvas 在视口中距离左边及顶部的距离,有3种方式:

(1) this.cva.getBoundingClientRect():返回一个对象,包含元素的宽、高及距窗口上下左右距离;

console.log(this.cva.getBoundingClientRect());

ClientRect

(2) 采用 jQuery 方法 $('.painter').offset():同样返回一个对象,但只包含left值和top值;

console.log($('.painter').offset());

offset

(3) 采用js原生方法获取坐标

console.log(this.cva.offsetWidth);  // 800
console.log(this.cva.offsetHeight); // 600
console.log(this.cva.offsetLeft);   // 90
console.log(this.cva.offsetTop);    // 137

注意:原生 js 只有上述4个方法,没有 offsetRight 和 offsetBottom。

大功告成!至此,已经可以在我们的画布上进行类似于铅笔的绘画了~~当然,这是绘图板最最基本的功能,接下去要实现更多的功能,还会用到更多的 Canvas API,需要进行迭代开发啦,有木有很兴奋,嘿嘿;-)

实现基础绘画

要知下回如何,请继续阅读 开发Canvas绘画应用(三)-对照绘画

✈ Github:paintApp

✎ 参考:

HTML5实例教程——创意画板

使用html5 canvas制作涂鸦画板

JS | 移动端“刮刮卡式”蒙层画板 Canvas


posted on 2017-03-27 22:13  Ruth92  阅读(675)  评论(0编辑  收藏  举报

导航