美文网首页
Canvas的globalCompositeOperation属

Canvas的globalCompositeOperation属

作者: 风雅欢乐 | 来源:发表于2019-05-09 15:57 被阅读0次

    在canvas绘图的时候,globalCompositeOperation属性是ctx上设置图案叠加时的效果的,它的说明网上有很多资料,摘取其中一个如下:


    canvas的globalCompositeOperation属性说明.jpg
    第一个坑

    比如,destination-out类型的时候,按照说明的理解,那么如果我第二次画的是一个足够大的“遮罩层”,那么canvas上应该什么都看不见。
    但是!注意!!!如果这个遮罩层是带透明度的,那么其实是可以看见上一次画的内容的!!!
    并且,这个遮罩的透明度假设为a=0.5,destination-out下,效果类似于 “将已经存在的图像透明度削去a”
    而在destination-in下,效果则类似于 “将已经存在的图像透明度削成(变成)a”。如图:

    透明度为1的原图像,变成了类似于透明度0.5的图像.jpg
    代码:
    var c=document.getElementById("myCanvas");
    var ctx=c.getContext("2d");
    
    ctx.globalCompositeOperation="lighter";
    
    function draw() {
      
      // 先画一个粉红色框
      ctx.fillStyle='rgba(255, 2, 255, 1)';
      ctx.fillRect(0,0,100,100);
      
      // 罩上一个同样大小的遮罩
      ctx.globalCompositeOperation="destination-out";
      ctx.fillStyle="rgba(180, 160, 80, 0.5)";
      ctx.fillRect(0,0,100,100);
      ctx.globalCompositeOperation="lighter";
      
      
      // 蓝色  
    //   ctx.fillStyle='rgba(155, 155, 255, 0.1)';
      
      // 透明度0.25的粉红色  
    //   ctx.fillStyle='rgba(255, 2, 255, 0.25)';
      
      // 透明度0.24的粉红色
    //   ctx.fillStyle='rgba(255, 2, 255, 0.24)';
    
    //   ctx.fillRect(0,0,100,100);
    //   requestAnimationFrame(draw);
    }
    
    draw();
    
    第二个坑

    当属性设为lighter时,按照资料解释,是将两次绘制图像的颜色值叠加,但是具体是怎么叠加的,没有给出说明。于是,就发现了这么个现象:
    1、我准备画一个颜色值为rgba(255, 2, 255, 0.25)的粉色矩形,注意它的透明度0.25!!。当我无限循环的时候,它的颜色会逐渐叠加至白色。如图:

    0.25透明度的粉红色逐渐叠加成白色.jpg
    代码:
    var c=document.getElementById("myCanvas");
    var ctx=c.getContext("2d");
    
    ctx.globalCompositeOperation="lighter";
    
    function draw() {
      
      // 先画一个粉红色框
    //   ctx.fillStyle='rgba(255, 2, 255, 1)';
    //   ctx.fillRect(0,0,100,100);
      
    //   // 罩上一个同样大小的遮罩
    //   ctx.globalCompositeOperation="destination-out";
    //   ctx.fillStyle="rgba(180, 160, 80, 0.5)";
    //   ctx.fillRect(0,0,100,100);
    //   ctx.globalCompositeOperation="lighter";
      
      
      // 蓝色  
    //   ctx.fillStyle='rgba(155, 155, 255, 0.1)';
      
      // 透明度0.25的粉红色  
      ctx.fillStyle='rgba(255, 2, 255, 0.25)';
      
      // 透明度0.24的粉红色
    //   ctx.fillStyle='rgba(255, 2, 255, 0.24)';
    
      ctx.fillRect(0,0,100,100);
      requestAnimationFrame(draw);
    }
    
    draw();
    

    2、当我画同样颜色的矩形,但是透明度变为0.24的时候,它就永远不会叠加成白色。如图:

    0.24透明度的粉红色不会叠加成白色.jpg
    并且,叠加后的图案,比单独画一次要更深。
    代码:
    var c=document.getElementById("myCanvas");
    var ctx=c.getContext("2d");
    
    ctx.globalCompositeOperation="lighter";
    
    function draw() {
      
      // 先画一个粉红色框
    //   ctx.fillStyle='rgba(255, 2, 255, 1)';
    //   ctx.fillRect(0,0,100,100);
      
    //   // 罩上一个同样大小的遮罩
    //   ctx.globalCompositeOperation="destination-out";
    //   ctx.fillStyle="rgba(180, 160, 80, 0.5)";
    //   ctx.fillRect(0,0,100,100);
    //   ctx.globalCompositeOperation="lighter";
      
      
      // 蓝色  
    //   ctx.fillStyle='rgba(155, 155, 255, 0.1)';
      
      // 透明度0.25的粉红色  
    //   ctx.fillStyle='rgba(255, 2, 255, 0.25)';
      
      // 透明度0.24的粉红色
      ctx.fillStyle='rgba(255, 2, 255, 0.24)';
    
      ctx.fillRect(0,0,100,100);
      requestAnimationFrame(draw);
    }
    
    draw();
    

    3、当我要画一个颜色值为rgba(155, 155, 255, 0.1)的蓝色矩形,注意透明度为0.1,发现,它很快就被叠加成了白色,如图:

    0.1透明度的蓝色很快叠加成了白色.jpg
    代码:
    var c=document.getElementById("myCanvas");
    var ctx=c.getContext("2d");
    
    ctx.globalCompositeOperation="lighter";
    
    function draw() {
      
      // 先画一个粉红色框
    //   ctx.fillStyle='rgba(255, 2, 255, 1)';
    //   ctx.fillRect(0,0,100,100);
      
    //   // 罩上一个同样大小的遮罩
    //   ctx.globalCompositeOperation="destination-out";
    //   ctx.fillStyle="rgba(180, 160, 80, 0.5)";
    //   ctx.fillRect(0,0,100,100);
    //   ctx.globalCompositeOperation="lighter";
      
      
      // 蓝色  
      ctx.fillStyle='rgba(155, 155, 255, 0.1)';
      
      // 透明度0.25的粉红色  
    //   ctx.fillStyle='rgba(255, 2, 255, 0.25)';
      
      // 透明度0.24的粉红色
    //   ctx.fillStyle='rgba(255, 2, 255, 0.24)';
    
      ctx.fillRect(0,0,100,100);
      requestAnimationFrame(draw);
    }
    
    draw();
    

    4、如果,在循环中,先罩上一个带透明度的遮罩,然后再绘制上述矩形,那么神奇的是:蓝色、粉色矩形再也不会被叠加成白色了!!并且,颜色略有加深,仿佛多次绘制矩形叠加一样。如图:


    先遮罩透明度罩子再绘制矩形.jpg

    代码:

    var c=document.getElementById("myCanvas");
    var ctx=c.getContext("2d");
    
    ctx.globalCompositeOperation="lighter";
    
    function draw() {
      
      // 先画一个粉红色框
    //   ctx.fillStyle='rgba(255, 2, 255, 1)';
    //   ctx.fillRect(0,0,100,100);
      
      // 罩上一个同样大小的遮罩
      ctx.globalCompositeOperation="destination-out";
      ctx.fillStyle="rgba(180, 160, 80, 0.2)";
      ctx.fillRect(0,0,100,100);
      ctx.globalCompositeOperation="lighter";
      
      
      // 蓝色  
      ctx.fillStyle='rgba(155, 155, 255, 0.1)';
      
      // 透明度0.25的粉红色  
    //   ctx.fillStyle='rgba(255, 2, 255, 0.25)';
      
      // 透明度0.24的粉红色
    //   ctx.fillStyle='rgba(255, 2, 255, 0.24)';
    
      ctx.fillRect(0,0,100,100);
      requestAnimationFrame(draw);
    }
    
    draw();
    
    总结

    目前还搞不清楚为什么带透明度的遮罩,就罩不住原图像了;同样,也搞不清楚为什么先遮罩、后绘制,就不会使得图案叠加成白色。但是,这种用法在用canvas绘制一些特效的时候,可以用到。具体示例见canvas特效库中的《发光loading特效》。

    相关文章

      网友评论

          本文标题:Canvas的globalCompositeOperation属

          本文链接:https://www.haomeiwen.com/subject/spiwoqtx.html