关于canvas:canvas可视化效果之内阴影效果

40次阅读

共计 4015 个字符,预计需要花费 11 分钟才能阅读完成。

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;}
    }

结语

至此文章曾经达到序幕,咱们能够总结一下绘制内暗影成果所用到的技术点

  1. CanvasRenderingContext2D.globalCompositeOperation
  2. CanvasRenderingContext2D.shadowBlur

其中 globalCompositeOperation 是一个有意思的属性,通过设置不同的参数,能够实现很多不同的成果。比方如下的成果就用到了这个属性:

有趣味的读者能够关注往期更多的文章。

如果对可视化感兴趣,能够和我交换,微信 541002349. 另外关注公众号“ITMan 彪叔”能够及时收到更多有价值的文章。

正文完
 0