在QQ空间中,我们最近经常可以看到某州学院的广告,当你滑下去时,会有一个圆形蒙版出现,并且会随着手指的滑动而变大或者变小。
依赖技术
这里的主要实现是利用canvas的2D绘图能力,会主要讲解drawImage与clip两个API的作用与原理。
效果
实现过程
canvas绘制的准备
在网上有很多的canvas的基础教程,这里不做过多讲解。直接
Ctrl+c
Ctrl+v
<div class="view" id="bb">//用来做背景层的显示 <canvas id="canvas" ></canvas> </div>
背景的图层显示使用css显示,因为背景层不需要重绘,所以使用css来显示,减少canvas的渲染调用。
初始化我们的画布
var canvas = document.getElementById("cas"), ctx = canvas.getContext("2d"); canvas.width = 800;//设置画布的宽 canvas.height = 600;//设置画布的高
在这里有人在设置画布的时候会习惯性使用
px
来作为宽高的单位,然后发现屁效果都没了,如果想使用px
作为单位,则需要对宽高的设置方法进行调整。canvas.style.width=600+'px'
设置蒙版层
function Circle(x,y,r,msk=new Image()) { this.x=x; this.y=y; this.r=r; this.ctx={}; this.msk=msk; } Circle.prototype.render = function(cxt) { this.ctx=ctx; ctx.save(); ctx.beginPath(); ctx.arc(this.x,this.y,this.r,0,Math.PI*2); ctx.closePath(); ctx.clearRect(0,0,canvas.width,canvas.height); ctx.clip(); ctx.drawImage(this.msk,0,0); ctx.restore(); }; Circle.prototype.big = function() { //蒙版变大,每次r++ this.r++; this.render(this.ctx); }; Circle.prototype.small = function() { //蒙版变小,每次r-- if(this.r>0){ this.r--; }else{ } this.render(this.ctx); };
这里我定义了一个圆形蒙版层的类,并且给了它渲染以及变大/小的方法,这里的主要逻辑是如下。
ctx.beginPath(); ctx.arc(this.x,this.y,this.r,0,Math.PI*2); ctx.closePath(); //闭合圆形路径选取区 ctx.clip(); //生成剪裁选取 ctx.drawImage(this.msk,0,0); //将蒙版层进行绘制
clip
在canvas是里用作剪裁的小工具,可以将之前绘制的路径区生成选取,并且将后来的图层当作蒙版层来做剪裁。 在以上的代码中,我使用了
save
与restore
这两个小东西,相信在很多canvas的开发中都会见到,百度也能知道是为了存储画布上下文的绘制环境与还原,那么为什么我们即使相同的绘制情况下也要使用它们呢。这涉及到canvas的绘制原理问题,这里不做过多介绍,后面会专门讲解。万恶之源
当我们的蒙版层加载完毕后,一切都将开始运行。
var cir; const img=new Image(); img.src='pic2.jpg'; img.onload=function(){ canvas.addEventListener('click',function(e){ //将鼠标的点击坐标坐标转换成canvas坐标 var x= e.x-canvas.getBoundingClientRect().left; var y= e.y-canvas.getBoundingClientRect().top; //生成蒙版 渲染蒙版 cir= new Circle(x,y,200,img); cir.render(ctx); //开始动起来 requestAnimFrame(scal); }) } function scal() { //变大吧 萌版 cir.big(); requestAnimFrame(scal); } window.requestAnimFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function( callback ){ window.setTimeout(callback, 1000 / 60); }; })();
开坑说明
不定期更新canvas与svg的相关技术教程,有实战型,也会有主原理型的,2d 2.5d 3d都会包含到,同时涉及的有 线性代数 物理 图形学等相关的基础知识。我会尽力把这一系列内容做好。
欢迎诸位客官收藏关注 打赏投硬币!!!
本处源码:https://github.com/dxiaoqi/canvas-svg-/tree/master/canvas/clip%E6%95%88%E6%9E%9C