【问题标题】:canvas shadow with globalCompositeOperation[ destination-out ]带有 globalCompositeOperation[destination-out] 的画布阴影
【发布时间】:2016-03-05 20:47:45
【问题描述】:

..您好,经过很长一段时间后,我再次有机会使用 JavaScript 和画布。

我正在尝试使用画布 [ globalCompositeOperation ] 绘制透明图像,这对我有很大帮助, 我在 draw image[img1] 上获得了成功,并删除了 image[img2] 的重叠部分。

搜索很多但失败:想尝试在画布的输出上投下阴影,如下所示,

请查看并给我您的宝贵建议或解决方案。

$('.bg').one("load", function() {

  var canvas = document.getElementById('canva'),
    context = canvas.getContext('2d'),
    img1 = $('.bg')[0],
    img2 = $('.bgover')[0];

  context.drawImage(img1, 0, 0);
  context.globalCompositeOperation = 'destination-out';
  context.beginPath();
  context.drawImage(img2, 10, 10);
  context.closePath();
  //drop shadow -> Doesn't work
  context.shadowBlur = 5;
  context.shadowOffsetX = 10;
  context.shadowOffsetY = 10;
  context.shadowColor = "black";


});
body {
  background: #E7FF00
}
.bg {
  background: url() center;
  width: 300px;
  height: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>

<img class='bg' src="http://www.qdtricks.org/wp-content/uploads/2015/02/hd-wallpapers-for-mobile.jpg" style='display:none'>

<img class='bgover' src="http://spotremoval.coit.com/sites/spotremoval.coit.com/files/styles/stain_sidebar/public/Feces%20Stain%20Removal%20-%20SPOT%20REMOVAL%20GUIDE.png?itok=j6f96IHQ" style='display:none'>


<canvas id="canva" width="400" height="400" style="position:absolute;left:0;top:0"></canvas>

【问题讨论】:

    标签: javascript html canvas


    【解决方案1】:

    带有目标输出和源顶部的内阴影

    这是我的解决方案。加载图像,然后使用 2D 上下文创建一个副本,以便将其绘制到。然后再创建一个稍大一点的图像以适应阴影、偏移和模糊。使用 comp destination-out 将其设为倒置蒙版。设置原始图像的阴影设置。然后用comp source-atop在上面绘制蒙版图片

    现在图像有了阴影,可以在你想要的地方绘制。

    函数 innerShadow(image,col,offX,offY,blur) 完成了这项工作。代码被注释所以享受:)

    /** CanvasCtx.js begin **/
    var canvas = document.getElementById("canV"); 
    var ctx = canvas.getContext("2d");
    /** CanvasCtx.js end **/
    
    // copies an image adding the 2d context
    function copyImage(img){
        var image = document.createElement("canvas");  
        image.width = img.width;
        image.height = img.height; 
        image.ctx = image.getContext("2d"); 
        image.ctx.drawImage(img,0,0);
        return image;
    }
    
    // creates a blank image with 2d context
    var createImage = function(w,h){
        var image = document.createElement("canvas");  
        image.width = w;
        image.height =h; 
        image.ctx = image.getContext("2d"); 
        return image;
    }  
    
    // load an image from URL. Create a editable copy and then 
    // call the function ready
    var loadImage = function(url,ready){
        function onload(){
            this.removeEventListener("load",onload);
            image = copyImage(this);
            ready(image);
        }
        var image = new Image();
        image.src = url;
        image.addEventListener("load",onload);
    }
    
    
    function innerShadow(image,shadowCol,offX,offY,blur){
        var mx, my, img1; 
        // create a mask image, with pixel alpha the invers of original
        // Needs to be bigger so that the shadow is consistant at edges
        img1 = createImage(image.width+Math.abs(offX)+blur,image.height+Math.abs(offY)+blur);
        // set the shadow colur to requiered but only for alising the edge
        img1.ctx.fillStyle = shadowCol;
        img1.ctx.fillRect(0,0,img1.width,img1.height);  // fill the mask
        img1.ctx.globalCompositeOperation = "destination-out";  // remove dest pixels
        mx = img1.width/2- image.width/2;  // recalculate offsets
        my = img1.height/2- image.height/2;
       // draw it 3 times to remove the slight alpha edge bleading
        img1.ctx.drawImage(image,mx,my);  // cut out the images shape from mask
        img1.ctx.drawImage(image,mx,my);  // cut out the images shape from mask
        img1.ctx.drawImage(image,mx,my);  // cut out the images shape from mask
    
        // set up shadow settings
        image.ctx.shadowColor = shadowCol;
        image.ctx.shadowOffsetX = offX;
        image.ctx.shadowOffsetY = offY;
        image.ctx.shadowBlur = blur;
        // draw the mask with the shadow on original image 
        image.ctx.globalCompositeOperation = "source-atop"; // only visible pixels
        image.ctx.drawImage(img1,-mx,-my);  // draw the shadow
    }
    
    
    // clear the canvas
    ctx.clearRect(0,0,canvas.width,canvas.height)
    // load and add shadow. 
    var imageWithInnerShadow;
    var shadowOffX = 10;
    var shadowOffY = 10;
    var shadowBlur = 10;
    var shadowCol = "Black";
    // load the image
    loadImage("http://i.stack.imgur.com/Jafta.png",function(img){
        // add the shadow
        innerShadow(img,shadowCol,shadowOffX,shadowOffY,shadowBlur);
        ctx.drawImage(img,20,20); // show that it worked
        imageWithInnerShadow = img; // hold the image for use 
    })
    .canC { width:500px;  height:500px;}
    &lt;canvas class="canC" id="canV" width=500 height=500&gt;&lt;/canvas&gt;

    【讨论】:

      【解决方案2】:

      这是一个具有预期效果的dropShadow 函数。

      $('.bg').one("load", function() {
      
        var canvas = document.getElementById('canva'),
          context = canvas.getContext('2d'),
          img1 = $('.bg')[0],
          img2 = $('.bgover')[0];
      
        context.drawImage(img1, 0, 0);
        context.save();
        context.globalCompositeOperation = 'destination-out';
        context.drawImage(img2, 10, 10);
        context.restore();
      
        dropShadow(canvas, "red", 5, 2, 2);
        
      });
      
      // This function draws the image to left of canvas
      // leaving only the shadow then draws the shadow in the
      // empty space.
      function dropShadow(can, color, blur, offsetX, offsetY) {
        var s_can = document.createElement('canvas');
        var s_ctx = s_can.getContext('2d');
        var ctx = can.getContext('2d');
        var w = can.width;
        var h = can.height;
        s_can.width = w;
        s_can.height = h;
        s_ctx.shadowBlur = blur;
        s_ctx.shadowColor = color;
        s_ctx.shadowOffsetX = w;
        s_ctx.shadowOffsetY = 0;
        s_ctx.drawImage(can, 0, 0, w, h,-w,0,w,h);
        
        ctx.save();
        ctx.globalCompositeOperation = 'destination-over';
        ctx.drawImage(s_can, offsetX, offsetY);
        ctx.restore();
      }
      body {
        background: #E7FF00
      }
      .bg {
        background: url() center;
        width: 300px;
        height: 300px;
      }
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
      
      <img class='bg' src="http://www.qdtricks.org/wp-content/uploads/2015/02/hd-wallpapers-for-mobile.jpg" style='display:none'>
      
      <img class='bgover' src="http://spotremoval.coit.com/sites/spotremoval.coit.com/files/styles/stain_sidebar/public/Feces%20Stain%20Removal%20-%20SPOT%20REMOVAL%20GUIDE.png?itok=j6f96IHQ" style='display:none'>
      
      
      <canvas id="canva" width="400" height="400" style="position:absolute;left:0;top:0"></canvas>

      【讨论】:

        猜你喜欢
        • 2017-11-20
        • 2015-10-06
        • 1970-01-01
        • 2020-09-26
        • 2012-11-23
        • 2019-07-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多