设为首页 加入收藏

TOP

用HTML5 Canvas 做擦除及扩散效果(二)
2015-07-16 12:57:41 来源: 作者: 【 】 浏览:50
Tags:HTML5 Canvas 扩散 效果
就是将方案一中的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就可以了,即简单,又高效,并且即使快速移动鼠标也不会出现锯齿边缘了,因此这个改进的方案完全替代了方案一。效果如下:



?


新需求,新方案


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


先来点简单的


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


  稍微变一下,是需要展示雾霾扩散效果,这将会是相对来说比较容易实现的,因为雾霾可以理解为均匀的灰色,即使不是均匀,也可以表示为自圆心向边缘不同程度的灰色渐变,上文说到过canvas的strokeStyle可以设置为渐变的,因此正好利用渐变就可以实现边缘的模糊。(并且还可以给canvas设置一些css3的动画,比如从小变大,或者由暗变明)。


HTML结构基本不变,主体JS代码如下:


function CanvasFade(canvas){
? ? this.canvas=canvas;
? ? this.ctx=canvas.getContext("2d");
? ? this.width=canvas.width;
? ? this.height=canvas.height;
}


CanvasFade.prototype={
? ? draw:function(config){
? ? ? ? var _self=this;
? ? ? ? var cfg=config?config:{x:200,y:200,r:120};
? ? ? ? var ratio=cfg.r/2;
? ? ? ? var grd = _self.ctx.createRadialGradient(cfg.x, cfg.y, 0.000, cfg.x, cfg.y, cfg.r);
? ? ? ? grd.addColorStop(0.000, 'rgba(255, 0, 0, 0.900)');
? ? ? ? grd.addColorStop(0.5, 'rgba(255, 0, 0, 0.600)');
? ? ? ? grd.addColorStop(1.0, 'rgba(255, 0, 0, 0.000)');
? ? ? ? _self.ctx.fillStyle = grd;
? ? ? ? _self.ctx.arc(cfg.x, cfg.y, cfg.r,0,Math.PI*2,true);
? ? ? ? _self.ctx.fill();
? ? }
};
var canvasFade=new CanvasFade(Jquery('#theCanvas')[0]);
canvasFade.draw({x:100,y:200y,r:20r});


可以看出实现起来非常简单,这段代码是测试使用的,颜色值是红色,看起来就像热区图,要实现雾霾扩散,只需要更改颜色值即可,实际效果如下:



ps. 这里是多次调用了draw的最终效果。


?


硬骨头


 仅从视觉上看,这两个需求非常接近,因此很容易误以为目标就要实现了。程序开发的一大特点就是[There is more to it then meets the eyes]。那些看起来很炫酷的交互对于开发者可能非常容易实现,因为厂商可能在底层已经实现了。而那些看起来很简单的东西,可能需要花费更多的力气,这也常常成为产品人员和开发人员摩擦的一个原因。


  我们来分析需求,雾霾本身覆盖在地图上,并不是均匀的(当然也可以简化成均匀的,这里不是主要困难点),主要问题就是雾霾驱散之后显示出来的是没有雾霾覆盖的地图,而不是纯颜色(可以参看文末gif图片)。边缘的模糊效果就很难实现,因为在设置strokeStyle的时候,如果设置为渐变色,很容易实现边缘模糊,但是就只能用颜色值,如果

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Qt Creator自定义编译运行步骤 下一篇Linux下获得线程ID syscall(224)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: