在ECharts中看到過這種圓形擴散效果,相似css3,恰好項目中想把它用上,but我又不想引入整個echart.js文件,更重要的是想弄明白它的原理,因此本身動手。在這篇文章中咱們就來分析實現這種效果的兩種方法,先上效果圖:javascript
經過不斷的改變圓的半徑大小,不斷重疊達到運動的效果,在運動的過程當中,設置當前canvas的透明度context.globalAlpha=0.95
,使得canvas上的圓逐漸透明直至爲0,從而實現這種擴散、漸變的效果。css
1. 關鍵技術點context.globalAlpha = 0.95
; //設置主canvas的繪製透明度。
建立臨時canvas來緩存主canas的歷史圖像,再疊加到主canvas上。html
2. 繪製過程
首先,咱們先來寫一個繪製圓的方法:java
//畫圓 var drawCircle = function() { context.beginPath(); context.arc(150, 100, radius, 0, Math.PI * 2); context.closePath(); context.lineWidth = 2; //線條寬度 context.strokeStyle = 'rgba(250,250,50,1)'; //顏色 context.stroke(); radius += 0.5; //每一幀半徑增長0.5 //半徑radius大於30時,重置爲0 if (radius > 30) { radius = 0; } };
而後,咱們建立一個臨時canvas用來緩存主canvas上的歷史圖像,設置主canvas的透明度context.globalAlpha=0.95
(關鍵一步),在每次調用drawCircle
方法繪製一個新圓以前都把主canvas上的圖像,也就是以前的圖像給繪製到臨時的canvas中,等到drawCircle
方法繪製完新圓後,再把臨時canvas的圖像繪製回主canvas中。css3
核心代碼以下:git
//建立一個臨時canvas來緩存主canvas的歷史圖像 var backCanvas = document.createElement('canvas'), backCtx = backCanvas.getContext('2d'); backCanvas.width = width; backCanvas.height = height; //設置主canvas的繪製透明度 context.globalAlpha = 0.95; //顯示即將繪製的圖像,忽略臨時canvas中已存在的圖像 backCtx.globalCompositeOperation = 'copy'; var render = function() { //1.先將主canvas的圖像緩存到臨時canvas中 backCtx.drawImage(canvas, 0, 0, width, height); //2.清除主canvas上的圖像 context.clearRect(0, 0, width, height); //3.在主canvas上畫新圓 drawCircle(); //4.等新圓畫完後,再把臨時canvas的圖像繪製回主canvas中 context.drawImage(backCanvas, 0, 0, width, height); };
與上一種方法相比,這種方法更加簡單,一樣是用到了透明度逐漸減少直到爲0的原理,不一樣的是這裏並無建立臨時canvas,而是運用了context.globalCompositeOperation
屬性值source-over
和destination-in
來配合使用,查看globalCompositeOperation屬性介紹github
核心代碼以下:canvas
var render = function() { //默認值爲source-over var prev = context.globalCompositeOperation; //只顯示canvas上原圖像的重疊部分 context.globalCompositeOperation = 'destination-in'; //設置主canvas的繪製透明度 context.globalAlpha = 0.95; //這一步目的是將canvas上的圖像變的透明 context.fillRect(0, 0, width, height); //在原圖像上重疊新圖像 context.globalCompositeOperation = prev; //在主canvas上畫新圓 drawCircle(); };
這裏我採用的是第二種方式,將擴散、漸變效果運用到了百度地圖上,感受還比較炫,查看更多demo緩存
圓形擴散動畫動畫
方法1、二都能實現一樣的效果,若是動畫繪製、操做canvas比較頻繁,建議採用第一種方式,用臨時canvas來緩存歷史圖像,效率更高。