【问题标题】:Canvas 'Clip' reverse action?帆布'剪辑'反向动作?
【发布时间】:2011-06-16 20:09:31
【问题描述】:

假设我有:

var context = document.getElementById('test').getContext('2d');

// Background
context.fillStyle = '#000';
context.fillRect(0,0,300,300);

// 'P'
context.beginPath();
context.moveTo(90,89);
context.lineTo(161,89);
context.quadraticCurveTo(200,89,200,127);
context.quadraticCurveTo(200,166,148,166);
context.lineTo(115,166);
context.lineTo(108,210);
context.lineTo(69,210);
context.lineTo(90,89);
context.fillStyle = "#eee";
context.fill();
context.closePath();

context.globalCompositeOperation = 'destination-out';

// 'P' hole
context.beginPath();
context.moveTo(124,117);
context.lineTo(146,117);
context.quadraticCurveTo(160,117,160,127);
context.quadraticCurveTo(160,145,146,145);
context.lineTo(120,145);
context.lineTo(124,117);
context.fillStyle = '#ffffff';
context.fill();
context.closePath();

这可行,除了你可以看到“洞”不是剪辑,所以如果背景不是实心的,你根本无法设置洞的“填充”颜色以匹配背景。

因此,我需要将孔夹住。但是,当我这样做时,显示的“P”的唯一部分是由剪辑“孔”绑定的部分。我需要反过来。我需要显示“P”,但用“孔”夹住部分,这样任何背景都会显示出来。

这是我所得到的,但不完全是:

var context = document.getElementById('test').getContext('2d');

// Background
context.fillStyle = '#000';
context.fillRect(0,0,300,300);

// 'P' hole clip
context.beginPath();
context.moveTo(124,117);
context.lineTo(146,117);
context.quadraticCurveTo(160,117,160,127);
context.quadraticCurveTo(160,145,146,145);
context.lineTo(120,145);
context.lineTo(124,117);
context.clip();
context.closePath();

// 'P'
context.beginPath();
context.moveTo(90,89);
context.lineTo(161,89);
context.quadraticCurveTo(200,89,200,127);
context.quadraticCurveTo(200,166,148,166);
context.lineTo(115,166);
context.lineTo(108,210);
context.lineTo(69,210);
context.lineTo(90,89);
context.fillStyle = "#eee";
context.fill();
context.closePath();

感谢您的帮助!

【问题讨论】:

    标签: html canvas clip


    【解决方案1】:

    我知道你刚才问过这个问题,但我有一个答案。

    您的第一个示例只对了一半。使用destination-out 会起作用,但是为了不打扰您要在其上绘制的画布,我们创建一个新的画布并在其中进行绘制。

    然后,一旦我们用我们的切口在那里绘制了我们的形状,然后我们将整个画布绘制到原始画布上。由于新画布没有背景,它将保持透明。

    var canvas = document.getElementById('test'),
        context = canvas.getContext('2d'),
    
        // New canvas - we will draw the letter P on here
        newCanvas = document.createElement('canvas'),
        newContext = newCanvas.getContext('2d');
    
    // Make sure you have enough room on your new canvas
    newCanvas.width = canvas.width;
    newCanvas.height = canvas.height;
    
    with(newContext) {
        // 'P'
        beginPath();
        moveTo(90,89);
        lineTo(161,89);
        quadraticCurveTo(200,89,200,127);
        quadraticCurveTo(200,166,148,166);
        lineTo(115,166);
        lineTo(108,210);
        lineTo(69,210);
        lineTo(90,89);
        fillStyle = "#eee";
        fill();
        closePath();
    
        globalCompositeOperation = 'destination-out';
    
        // 'P' hole
        beginPath();
        moveTo(124,117);
        lineTo(146,117);
        quadraticCurveTo(160,117,160,127);
        quadraticCurveTo(160,145,146,145);
        lineTo(120,145);
        lineTo(124,117);
        fillStyle = '#000';
        fill();
        closePath();
    }
    
    with(context) {
        // Background
        fillStyle = '#000';
        fillRect(0,0,300,300);
    
        // Simply reference the canvas element when drawing
        drawImage(newCanvas, 0, 0);
    }
    

    【讨论】:

      【解决方案2】:

      我知道这已经很老了,但是...您在第二次尝试中没有正确使用剪辑。剪辑之后的所有内容都将仅在剪辑区域上绘制。

      所以你可以:

      • 剪下洞并重绘背景

      var context = document.getElementById('test').getContext('2d');
      
      // Background
      context.fillStyle = '#000';
      context.fillRect(0,0,300,300);
      
      
      // 'P'
      context.beginPath();
      context.moveTo(90,89);
      context.lineTo(161,89);
      context.quadraticCurveTo(200,89,200,127);
      context.quadraticCurveTo(200,166,148,166);
      context.lineTo(115,166);
      context.lineTo(108,210);
      context.lineTo(69,210);
      context.lineTo(90,89);
      context.fillStyle = "#eee";
      context.fill();
      
      
      // 'P' hole clip
      context.beginPath();
      context.moveTo(124,117);
      context.lineTo(146,117);
      context.quadraticCurveTo(160,117,160,127);
      context.quadraticCurveTo(160,145,146,145);
      context.lineTo(120,145);
      context.lineTo(124,117);
      context.clip();
      
      // Redraw Background in the clipped area
      context.fillStyle = '#000';
      context.fillRect(0,0,300,300);
      <canvas id="test" width="300" height="300">
      • 夹住孔的外侧部分并画出P

      var context = document.getElementById('test').getContext('2d');
      
      // Background
      context.fillStyle = '#000';
      context.fillRect(0,0,300,300);
      
      // inverse 'P' hole clip
      context.beginPath();
      context.rect(0, 0, 300, 300);
      context.lineTo(124,117);
      context.lineTo(120,145);
      context.lineTo(146,145);
      context.quadraticCurveTo(160,145,160,127);
      context.quadraticCurveTo(160,117,146,117);
      context.lineTo(124,117);
      context.clip();
      
      // 'P'
      context.beginPath();
      context.moveTo(90,89);
      context.lineTo(161,89);
      context.quadraticCurveTo(200,89,200,127);
      context.quadraticCurveTo(200,166,148,166);
      context.lineTo(115,166);
      context.lineTo(108,210);
      context.lineTo(69,210);
      context.lineTo(90,89);
      context.fillStyle = "#eee";
      context.fill();
      <canvas id="test" width="300" height="300">

      另外,你不需要在这里使用closePath

      【讨论】:

        猜你喜欢
        • 2014-04-05
        • 2021-07-06
        • 1970-01-01
        • 2021-08-23
        • 1970-01-01
        • 2023-04-07
        • 2017-08-10
        • 2018-07-22
        • 1970-01-01
        相关资源
        最近更新 更多