canvas可视化成果之内暗影成果
楔子
在之前的一个轨道交通可视化我的项目中,使用到了很多绘制技巧。 能够参考 之前的一篇文章 《利用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();
效果图如下:
如果绘制圆形成果如下:
下面的代码都容易了解,就是通过shadowBlur产生突变暗影的成果。 默认的暗影,咱们称之为外暗影,意思都是图像向往开展的暗影成果。
内暗影
接下来的问题可能就变得有点难度。如果咱们须要如下的一个内暗影的成果呢?
有人说,简略,一个突变就搞定了。 那再看看上面这个图像呢?
还是没问题,还是能够通过突变来搞定,只是突变的stop设置要麻烦一点罢了。 如果在简单一些的图形呢,比方上面的线段成果:
对于下面的线段的内暗影成果,就很难应用简略的突变来实现了。
如何绘制内暗影成果
要实现下面的内暗影成果,首先还是应用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; } }
结语
至此文章曾经达到序幕,咱们能够总结一下绘制内暗影成果所用到的技术点
- CanvasRenderingContext2D.globalCompositeOperation
- CanvasRenderingContext2D.shadowBlur
其中globalCompositeOperation是一个有意思的属性,通过设置不同的参数,能够实现很多不同的成果。比方如下的成果就用到了这个属性:
有趣味的读者能够关注往期更多的文章。
如果对可视化感兴趣,能够和我交换,微信541002349. 另外关注公众号“ITMan彪叔” 能够及时收到更多有价值的文章。