在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