开发者

Cutting irregular shape on image

开发者 https://www.devze.com 2023-03-20 04:01 出处:网络
I am trying to cut an image into a particular shape using the canvas clip() method. I have followed the following steps to do so:

I am trying to cut an image into a particular shape using the canvas clip() method.

I have followed the following steps to do so:

  1. Draw a rectangle.
  2. Draw semi circles on each side. The right and bottom semi circles protrude outwards and the left and top semi circles are inwards.

The code snippet is provided below:

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

va开发者_运维知识库r 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();

The image that I am using is of size 800 x 600 (png). Please help me understand what I am doing wrong here.


Firstly, why are you using clip? You are currently just drawing semicircles, which works without clip.

Secondly, you are creating paths and clipping, but you never stroke the path. As a result, you won't see anything on the screen.

If you just stroke instead of clip, it works partially for me: http://jsfiddle.net/r6yAN/. You did not include the top semicircle though.

Edit: It seems like you're not using the best way of clipping. You draw a rectangle, but this also includes a line in the semicircle. You'd be better off if you draw each line/arc yourself like this: http://jsfiddle.net/CH6qB/6/.

The main idea is to move from point to point as in this image:

Cutting irregular shape on image

So first start at (startX, startY), then a line to (startX + lineWidth, startY), then an arc at (startX + rectWidth / 2, startY) from pi to 0 (counterclockwise), etc.

If you want to stroke the path as well after having drawn the image, it is a good idea to unclip again. Otherwise, the stroke will not be of great quality.

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();
0

精彩评论

暂无评论...
验证码 换一张
取 消