【问题标题】:Cutting irregular shape on image在图像上切割不规则形状
【发布时间】:2011-10-04 08:48:43
【问题描述】:

我正在尝试使用 canvas clip() 方法将图像剪切成特定形状。

我已按照以下步骤进行操作:

  1. 画一个矩形。
  2. 在每一边画半圆。右半圆和下半圆向外突出,左半圆和上半圆向内。

下面提供代码sn-p:

var canvasNode = this.hasNode();
var ctx = canvasNode && canvasNode.getContext('2d');

var image = new Image();
image.onload = function() {
  ctx.drawImage(image, 0, 0, 512, 384);
};

image.src = "images/image.png";
var startX = 200;
var startY = 0;

var rectWidth = 150;
var rectHeight = 150;
var radius = 30;

//Main Rect
ctx.rect(startX, startY, rectWidth, rectHeight);

//Right arc
ctx.moveTo(startX+=rectWidth, startY+=(rectHeight/2));
ctx.arc(startX, startY, radius, 3 * Math.PI / 2, Math.PI / 2, false);

//Left arc
ctx.moveTo(startX-=(rectWidth / 2), startY+=(rectHeight / 2));
ctx.arc(startX, startY, radius, 0, Math.PI, true);

ctx.moveTo(startX-=(rectWidth / 2), startY-=(rectWidth / 2));
ctx.arc(startX, startY, radius, 3 * Math.PI / 2, Math.PI / 2, false);

ctx.clip();

我使用的图像尺寸为 800 x 600 (png)。请帮助我理解我在这里做错了什么。

【问题讨论】:

    标签: javascript drawing shape html5-canvas


    【解决方案1】:

    首先,你为什么使用clip?您目前只是在绘制半圆,没有clip 也可以。

    其次,您正在创建路径和剪辑,但您从不描边路径。因此,您不会在屏幕上看到任何内容。

    如果您只是描边而不是剪辑,它对我来说部分有效:http://jsfiddle.net/r6yAN/。不过,您没有包括上半圆。

    编辑:您似乎没有使用最好的剪辑方式。您绘制一个矩形,但这也包括半圆中的一条线。如果您像这样自己绘制每条线/弧线会更好:http://jsfiddle.net/CH6qB/6/

    主要思想是从一个点移动到另一个点,如下图所示:

    所以首先从(startX, startY) 开始,然后是一条线到(startX + lineWidth, startY),然后是从pi0 的弧线(startX + rectWidth / 2, startY)(逆时针),等等。

    如果您想在绘制完图像后也对路径进行描边,最好再次取消剪辑。否则,笔画质量不会很好。

    var canvasNode = document.getElementById('cv');
    var ctx = canvasNode && canvasNode.getContext('2d');
    
    var image = new Image();
    image.onload = function() {
        // draw the image, region has been clipped
        ctx.drawImage(image, startX, startY);
    
        // restore so that a stroke is not affected by clip
        // (restore removes the clipping because we saved the path without clip below)
        ctx.restore();
        ctx.stroke();
    };
    
    image.src = "http://www.lorempixum.com/200/200/";
    
    var startX = 200;
    var startY = 0;
    
    var rectWidth = 150;
    var rectHeight = 150;
    var radius = 30;
    
    var lineWidth  = rectWidth  / 2 - radius;
    var lineHeight = rectHeight / 2 - radius;
    
    // typing pi is easier than Math.PI each time
    var pi = Math.PI;
    
    ctx.moveTo(startX, startY);
    
    ctx.lineTo(startX + lineWidth, startY);
    ctx.arc(startX + rectWidth / 2, startY,
            radius,
            pi, 0, true);
    ctx.lineTo(startX + rectWidth, startY);
    
    ctx.lineTo(startX + rectWidth, startY + lineHeight);
    ctx.arc(startX + rectWidth, startY + rectHeight / 2,
            radius,
            -pi / 2, pi / 2, false);
    ctx.lineTo(startX + rectWidth, startY + rectHeight);
    
    ctx.lineTo(startX + rectWidth - lineWidth, startY + rectHeight);
    ctx.arc(startX + rectWidth / 2, startY + rectHeight,
            radius,
            0, pi, false);
    ctx.lineTo(startX, startY + rectHeight);
    
    ctx.lineTo(startX, startY + rectHeight - lineHeight);
    ctx.arc(startX, startY + rectHeight / 2,
            radius,
            pi/2, pi*3/2, true);
    ctx.lineTo(startX, startY);
    
    ctx.save(); // Save the current state without clip
    
    ctx.clip();
    

    【讨论】:

    • 感谢您的回复。我正在尝试将图像切割成特定形状。抱歉错过了顶部弧线代码,这是修改后的 sn-p,顶部弧线绘制 jsfiddle.net/CH6qB 我不知道如何在 jsfiddle 中包含图像 :( 所以图像不存在。当我应用剪辑时,左弧并且顶部的弧线不会从图像中剪掉。我试图剪掉的这条路径是拼图游戏的一部分。我正在生成一个图案,以便我可以复制它们。
    • @quad_damage:我明白你的意思。我没有注意到您正在绘制的图像...抱歉。
    • @quad_damage:在这种情况下,您能否投票/接受这个答案?
    猜你喜欢
    • 1970-01-01
    • 2015-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-11
    • 2018-01-20
    相关资源
    最近更新 更多