切割图像上的不规则形状 [英] Cutting irregular shape on image
问题描述
我正在尝试使用canvas clip()方法将图像剪切成特定的形状。
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:
- 绘制一个矩形。
- 在每一边画半圆圈。右半圆和右半圆向外突出,左半圆和上半圆是向内的。
下面提供了代码段:
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)。请帮助我理解我在这里做错了什么。
The image that I am using is of size 800 x 600 (png). Please help me understand what I am doing wrong here.
推荐答案
首先,你为什么要使用 clip
?您目前只是绘制半圆,无需剪辑
。
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.
如果你只是笔划而不是剪辑,它对我来说部分起作用: http://jsfiddle.net/r6yAN/ 。你没有包括顶部的半圆。
If you just stroke instead of clip, it works partially for me: http://jsfiddle.net/r6yAN/. You did not include the top semicircle though.
编辑:看起来你没有使用最好的裁剪方式。您绘制一个矩形,但这也包括半圆形的一条线。如果你像这样画自己的每一条线/弧线你会更好: http://jsfiddle.net/ CH6qB / 6 / 。
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:
首先从(startX,startY)
,然后一行到(startX + lineWidth,startY)
,然后一个弧(startX + rectWidth / 2,startY)
从 pi
到 0
(逆时针)等等。
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();
这篇关于切割图像上的不规则形状的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!