在以前的一個軌道交通可視化項目中,運用到了不少繪製技巧。 能夠參考 以前的一篇文章 《利用canvas陰影功能與雙線技巧繪製軌道交通大屏項目效果》javascript
效果圖中的軌道,就同時存在外發光和內發光效果的效果。java
咱們知道外發光效果是很容易實現的,直接經過設置陰影效果便可達到。好比咱們隨便繪製一條線段,加上陰影效果,看起來就是外發光的效果:canvas
ctx.clearRect(0,0,canvas.width,canvas.height); ctx.shadowBlur= 20; ctx.shadowOffsetX = 0; ctx.shadowOffsetY = 0; ctx.shadowColor="red"; ctx.lineCap = "round"; ctx.lineJoin = "round"; ctx.lineWidth = 10; ctx.strokeStyle = "blue"; ctx.beginPath(); ctx.moveTo(300,300); ctx.lineTo(750,300); ctx.quadraticCurveTo(800,300,800,350); ctx.lineTo(800,450); ctx.quadraticCurveTo(800,500,750,500); ctx.lineTo(300,500); ctx.stroke();
效果圖以下:微信
若是繪製圓形效果以下:
code
上面的代碼都容易理解,就是經過shadowBlur產生漸變陰影的效果。 默認的陰影,咱們稱之爲外陰影,意思都是圖像嚮往展開的陰影效果。blog
接下來的問題可能就變得有點難度。若是咱們須要以下的一個內陰影的效果呢?ip
有人說,簡單,一個漸變就搞定了。 那再看看下面這個圖像呢?
get
仍是沒問題,仍是能夠經過漸變來搞定,只是漸變的stop設置要麻煩一點罷了。 若是在複雜一些的圖形呢,好比下面的線段效果:it
對於上面的線段的內陰影效果,就很難使用簡單的漸變來實現了。io
要實現上面的內陰影效果,首先仍是使用shadowBlur參數,而後把ctx的globalCompositeOperation參數設置爲「source-out」 便可。 試試以下代碼:
ctx.globalCompositeOperation = 'source-out'; ctx.beginPath(); ctx.beginPath(); ctx.moveTo(300,300); ctx.lineTo(750,300); ctx.quadraticCurveTo(800,300,800,350); ctx.lineTo(800,450); ctx.quadraticCurveTo(800,500,750,500); ctx.lineTo(300,500); ctx.lineCap = "round"; ctx.shadowBlur =15; ctx.lineWidth = 20; ctx.shadowColor="blue"; ctx.fillStyle = 'red'; ctx.strokeStyle = 'red'; ctx.stroke();
最終繪製的效果就是上面的線段圖的效果:
若是修改globalCompositeOperation爲「xor」,咱們還能夠獲得既有內陰影又有外陰影的效果。 代碼以下:
ctx.globalCompositeOperation = 'xor'; ctx.beginPath(); ctx.beginPath(); ctx.moveTo(300,300); ctx.lineTo(750,300); ctx.quadraticCurveTo(800,300,800,350); ctx.lineTo(800,450); ctx.quadraticCurveTo(800,500,750,500); ctx.lineTo(300,500); ctx.lineCap = "round"; ctx.shadowBlur =15; ctx.lineWidth = 20; ctx.shadowColor="red"; ctx.fillStyle = 'red'; ctx.strokeStyle = 'red'; ctx.stroke();
繪製的效果以下:
上述方法實現的內陰影顏色的顏色只能和繪製主體同樣的顏色,而不能像外陰影的顏色同樣,能夠自由定義。 好比把上述代碼中的shadowColor改爲blue,只有外陰影的顏色改變了:
ctx.globalCompositeOperation = 'xor'; ctx.beginPath(); ctx.beginPath(); ctx.moveTo(300,300); ctx.lineTo(750,300); ctx.quadraticCurveTo(800,300,800,350); ctx.lineTo(800,450); ctx.quadraticCurveTo(800,500,750,500); ctx.lineTo(300,500); ctx.lineCap = "round"; ctx.shadowBlur =15; ctx.lineWidth = 20; ctx.shadowColor="red"; ctx.fillStyle = 'red'; ctx.strokeStyle = 'red'; ctx.stroke();
最終的效果以下圖所示:
從圖上能夠看出只有外陰影顏色改變了,內陰影使用的本體的顏色。
基於上面的實現,咱們能夠實現一個陰影閃爍的效果,只須要不斷更改shadowBlur的值,代碼以下:
···
setInterval(()=>{
xor();
},10)
let shadowBlur = 5; let offset = 0.5; function xor(){ ctx.clearRect(0,0,canvas.width,canvas.height); ctx.globalCompositeOperation = 'xor'; ctx.shadowBlur= shadowBlur; ctx.shadowOffsetX = 0; ctx.shadowOffsetY = 0; ctx.shadowColor="red"; ctx.lineCap = "round"; ctx.lineJoin = "round"; ctx.lineWidth = 10; ctx.strokeStyle = "blue"; ctx.beginPath(); ctx.moveTo(300,300); ctx.lineTo(750,300); ctx.quadraticCurveTo(800,300,800,350); ctx.lineTo(800,450); ctx.quadraticCurveTo(800,500,750,500); ctx.lineTo(300,500); ctx.stroke(); // ctx.stroke(); ctx.globalCompositeOperation = 'xor'; ctx.shadowBlur=shadowBlur / 10.0; ctx.shadowOffsetX=0; ctx.shadowOffsetY=0; ctx.shadowColor="blue"; ctx.lineWidth =1; // ctx.stroke(); shadowBlur += offset; if(shadowBlur > 15 || shadowBlur < 1){ offset *= -1; } }
···
若是作一些疊加繪製,還能夠實現以下效果:
function xor(){ ctx.clearRect(0,0,canvas.width,canvas.height); ctx.globalCompositeOperation = 'xor'; ctx.shadowBlur= shadowBlur; ctx.shadowOffsetX = 0; ctx.shadowOffsetY = 0; ctx.shadowColor="red"; ctx.lineCap = "round"; ctx.lineJoin = "round"; ctx.lineWidth = 20; ctx.strokeStyle = "red"; ctx.beginPath(); ctx.moveTo(300,300); ctx.lineTo(750,300); ctx.quadraticCurveTo(800,300,800,350); ctx.lineTo(800,450); ctx.quadraticCurveTo(800,500,750,500); ctx.lineTo(300,500); ctx.stroke(); // ctx.stroke(); ctx.globalCompositeOperation = 'destination-out'; ctx.shadowBlur=shadowBlur / 10.0; ctx.shadowOffsetX=0; ctx.shadowOffsetY=0; ctx.shadowColor="red"; ctx.lineWidth =5; ctx.stroke(); shadowBlur += offset; if(shadowBlur > 15 || shadowBlur < 1){ offset *= -1; } }
至此文章已經到達尾聲,咱們能夠總結一下繪製內陰影效果所用到的技術點
其中globalCompositeOperation是一個有意思的屬性,經過設置不一樣的參數,能夠實現不少不一樣的效果。好比以下的效果就用到了這個屬性:
有興趣的讀者能夠關注往期更多的文章。
若是對可視化感興趣,能夠和我交流,微信541002349. 另外關注公衆號「ITMan彪叔」 能夠及時收到更多有價值的文章。