【问题标题】:Make rectangle overlay image with canvas用画布制作矩形覆盖图像
【发布时间】:2013-12-16 13:37:45
【问题描述】:

我想用 HTML5 画布达到以下效果:

我的代码:jsfiddle

// Options
var maxImageWidth = 250,
    maxImageHeight = 196,
    radius = 50;

var canvas = $('#ddayCanvas'),
    canvasWidth = canvas.width(),
    canvasHeight = canvas.height(),
    sectorColor = $('.product-box').css('background-color'),
    context = canvas[0].getContext('2d'),
    imageSrc = canvas.data('image');  


function drawDday (option) {

    var imageObj = new Image();
    imageObj.onload = function() {

        if (option == 'clip'){
            context.save();
            context.clip();
        }

        var imageWidth = imageObj.width,
            imageHeight = imageObj.height;

        if (imageWidth > maxImageWidth){
            imageHeight = imageHeight - (imageWidth - maxImageWidth);
            imageWidth = maxImageWidth;
        }

        if (imageHeight > maxImageHeight) {
            imageWidth = imageWidth - (imageHeight - maxImageHeight);
            imageHeight = maxImageHeight;
        }

        context.drawImage(imageObj, Math.ceil((canvasWidth - imageWidth) / 2), Math.ceil((canvasHeight - imageHeight) / 2), imageWidth, imageHeight);

    };

    imageObj.src = imageSrc;  

}

drawDday(); 

// Why does this rectangle not overlay the previous image?
context.fillStyle = sectorColor;
context.fillRect(0, 0, canvasWidth, canvasHeight);

drawDday('clip');      

context.restore();
context.moveTo(0, 0);
context.beginPath();
context.fillStyle = '#fff';
context.arc(canvasWidth / 2, canvasHeight/2, radius, 0, 2*Math.PI);
context.fill();

为什么我正在绘制的矩形没有覆盖上一张图片? 有时在重新加载网站时画布的绘制方式有所不同,这也很奇怪..

【问题讨论】:

    标签: javascript jquery css html canvas


    【解决方案1】:

    您在异步回调 onload 中绘制了图像。结果将根据是先加载图像还是先调用画布绘制而改变。

    尝试将您的绘图代码移动到相同的回调中。

    为了更有效的剪裁,您可以使用非零缠绕顺序规则:http://blogs.adobe.com/webplatform/2013/01/30/winding-rules-in-canvas/

    TLDR:连续的画布绘制调用将根据点的顺序是顺时针还是逆时针来添加或减去先前的调用。

    见:http://jsfiddle.net/jJjt7/2/

    context.fillStyle = sectorColor;
    context.rect(0, 0, canvasWidth, canvasHeight);
    context.arc(canvasWidth/2, canvasHeight/2, radius, 0, Math.PI*2, true);
    context.fill();
    

    上面的例子用顺时针点顺序画了一个矩形,然后用逆时针点顺序减去圆弧(圆)。 arc 方法的最后一个参数定义了“逆时针”。在这种情况下是正确的。

    编辑:这消除了绘制两次的需要。效率,FTW。

    【讨论】:

      【解决方案2】:

      您需要更改绘制对象的顺序。

      // Why does this rectangle not overlay the previous image?
      context.fillStyle = sectorColor;
      context.fillRect(0, 0, canvasWidth, canvasHeight);
      
      drawDday('clip');      
      drawDday(); 
      

      【讨论】:

      • @DamianFrizzi 我想我复制了原件而不是修改后的行。这是你的变化:jsfiddle.net/3zHQv
      • 不幸的是,这没有任何区别。您使用哪种浏览器?加载 jsfiddle 时,有时图像会被剪切,有时不会。此外,“背面的透明图像”永远不可见(甚至绘制)。
      • @DamianFrizzi 我试过 Chrome 和 FF。我再看看它是否在我身上交替出现。
      • @DamianFrizzi 我没有看到我链接的新小提琴交替显示,但 user3094783 的答案看起来更像你想要的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-27
      • 1970-01-01
      • 2017-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多