canvas教程

用HTML5 Canvas 做擦除及扩散效果(2)

字号+ 作者:H5之家 来源:H5之家 2016-01-16 08:01 我要评论( )

代码比较简单,核心部分就是render方法,根据当前鼠标或者手指的位置在canvas的上下文中绘制一个圆形,然后裁剪,这样在下一步drawImage的时候就会在上下文中绘制一个圆形的局部图形而不是整个图片。这样在鼠标或者

  代码比较简单,核心部分就是render方法,根据当前鼠标或者手指的位置在canvas的上下文中绘制一个圆形,然后裁剪,这样在下一步drawImage的时候就会在上下文中绘制一个圆形的局部图形而不是整个图片。这样在鼠标或者手指移动的时候就会动态绘制很多小圆,连起来就像是擦除了。

  requesetAnimFrame相信大家不会陌生,是个循环调用。这里为了节省性能,设置了一个变量requireLoop来表示是否需要重绘,只有在鼠标按下或者手指接触的时候设置为真,在每个循环中开始重绘canvas(即调用render),结束的时候则设置为假,停止绘制。

  这个方案是最原始的方案,有两大缺陷:

    一是循环调用,尽管有一个requireLoop可以确定是否重绘,在交互发生的时候始终是在循环,性能并不好;

    二是循环调用和用户的交互速度是不同步的,理想状况是手指或者鼠标每发生变化就重绘一次,但是现实并非如此,在非常快速滑动的时候,每次动态获取的坐标并不是紧紧相连的,就造成擦除的效果不是连续的,体验会变差。

方案二:No more loops

  方案一的可优化点最明显的就是循环,其两大缺陷都是基于此的。因此方案二的主要思路放弃了clip方法。而是利用了canvas上下文的strokeStyle属性,该属性是指在canvas中绘制矢量图形的时候矢量线的绘制样式,其值可以为color(颜色值)、gradient(渐变对象)、pattern(pattern对象)。这个方案就是将方案一中的drawImg方式改为将canvas上下文的strokeStyle设置为图片,然后在绘制的时候直接画线就可以了,因为矢量线的背景就是需要展示的图片,这样就实现了擦除的效果。HTML结构不变,JS代码如下:

function CanvasDoodle(canvas){
        this.canvas=canvas;
        this.ctx=canvas.getContext("2d");
        this.imgSrc=canvas.getAttribute("imgsrc");
        this.width=canvas.width;
        this.height=canvas.height;
        this.left=parseInt(canvas.style.left);
        this.top=parseInt(canvas.style.top);
        this.touchX=0;
        this.touchY=0;
        this.needDraw=false;
        this.init();
    }

    CanvasDoodle.prototype={
        init:function(){
            var _self=this;

            var img=new Image();
            img.onload=function(){
                var pat=_self.ctx.createPattern(img,"no-repeat");
                _self.ctx.strokeStyle=pat;
                _self.ctx.lineCap="round";
                _self.ctx.lineJoin="round";
                _self.ctx.lineWidth="25";
            }
            img.src=this.imgSrc;
        this.canvas.addEventListener('mousedown',function(e){
                e.preventDefault();
                _self.needDraw=true;
               
                _self.ctx.beginPath();
                _self.ctx.moveTo(e.clientX-_self.left,e.clientY-_self.top);
            },false);

        this.canvas.addEventListener('mousemove',function(e){
            e.preventDefault();
            if(_self.needDraw){
                _self.ctx.lineTo(e.clientX-_self.left,e.clientY-_self.top);
                _self.ctx.stroke();
            }
        },false);

            this.canvas.addEventListener('mouseup',function(e){
                e.preventDefault();
                _self.needDraw=false;
            });

        }
    };
    new CanvasDoodle(document.getElementById('CanvasDoodle'));

可以看到,已经没有循环调用了,只是在初始化的时候就设置strokeStyle为图片,在鼠标移动的时候直接lineTo然后stroke就可以了,即简单,又高效,并且即使快速移动鼠标也不会出现锯齿边缘了,因此这个改进的方案完全替代了方案一。效果如下:

 

新需求,新方案

  相信今年年初的雾霾应该是妇孺皆知的了,因为一位前央视记者自费做了一个长期调查然后做了一次演讲,掀起了轩然大波。这个需求正是在这个时期提出的。希望在地图上动态显示雾霾的驱散效果。

先来点简单的

  这里我们先分析另外一个略微简单一些的需求,循序渐进。

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • HTML5 Canvas 绘图实例教程

    HTML5 Canvas 绘图实例教程

    2017-04-28 13:09

  • 学习笔记:HTML5 Canvas绘制简单图形

    学习笔记:HTML5 Canvas绘制简单图形

    2017-04-27 13:03

  • HTML5 canvas 作画板画图 可以做电子白板

    HTML5 canvas 作画板画图 可以做电子白板

    2017-04-27 12:02

  • 利用HTML5 Canvas制作一个简单的打飞机游戏

    利用HTML5 Canvas制作一个简单的打飞机游戏

    2017-04-26 09:05

网友点评