javascript 带圆角的画布绘图图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19585999/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Canvas drawimage with round corners
提问by tbutcaru
I'm using this coverflowscript on my website and I don't know how to output the canvas with rounded corners.
我在我的网站上使用这个 Coverflow脚本,但我不知道如何输出带圆角的画布。
This is the code that draws the image
这是绘制图像的代码
ctx.drawImage(image, cropLeft, cropTop, wid-2*cropLeft, hei-2*cropTop, 0, 0, newWidth, newHeight);
I read some tutorials using arc() or arcTo() functions but none of them we're using an image as object.
我阅读了一些使用 arc() 或 arcTo() 函数的教程,但没有一个我们使用图像作为对象。
UPDATE1: I see that drawimage() has only the following parameters for drawing: ? Images the same size and composition as the original ? Images that are resized from the original ? Images that are cropped from the original
UPDATE1:我看到 drawimage() 只有以下绘图参数: ? 图像的大小和构图与原始图像相同吗?从原始图像调整大小的图像?从原始裁剪的图像
So, I guess, it's not possible to draw images with rounded corners through canvas..
所以,我想,不可能通过画布绘制带圆角的图像。
回答by markE
You can use context.clip()
to draw an image that's clipped inside a rounded rectangle
您可以使用context.clip()
绘制在圆角矩形内剪裁的图像
First draw a rectangle with rounded corners (no need to stroke or fill):
首先画一个带圆角的矩形(不需要描边或填充):
// draw a rounded rectangle
ctx.beginPath();
ctx.moveTo(x + radius, y);
ctx.lineTo(x + width - radius, y);
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
ctx.lineTo(x + width, y + height - radius);
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
ctx.lineTo(x + radius, y + height);
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
ctx.lineTo(x, y + radius);
ctx.quadraticCurveTo(x, y, x + radius, y);
ctx.closePath();
Then call context.clip which will cause all future drawings to be clipped inside the rect
然后调用 context.clip 这将导致所有未来的绘图被剪裁在矩形内
ctx.clip();
Finally, draw your image inside that rectangle and your image will be clipped round.
最后,在该矩形内绘制您的图像,您的图像将被裁剪为圆形。
ctx.drawImage(img,10,10,102,77);
Here is example code and a Fiddle: http://jsfiddle.net/m1erickson/FLaee/
这是示例代码和小提琴:http: //jsfiddle.net/m1erickson/FLaee/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var img=new Image();
img.onload=function(){
ctx.save();
roundedImage(10,10,102,77,10);
ctx.clip();
ctx.drawImage(img,10,10,102,77);
ctx.restore();
}
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/sky-bg2.jpg";
function roundedImage(x,y,width,height,radius){
ctx.beginPath();
ctx.moveTo(x + radius, y);
ctx.lineTo(x + width - radius, y);
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
ctx.lineTo(x + width, y + height - radius);
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
ctx.lineTo(x + radius, y + height);
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
ctx.lineTo(x, y + radius);
ctx.quadraticCurveTo(x, y, x + radius, y);
ctx.closePath();
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
回答by Jesús Carrera
The problem with the clip() solution is that Chrome will render it with the borders non antialiased, as demonstrated in this question.
clip() 解决方案的问题在于 Chrome 将使用非抗锯齿的边框呈现它,如本问题所示。
One solution would be to do it with globalCompositeOperation as Daniel says in his answer:
一种解决方案是使用 globalCompositeOperation 来做到这一点,正如 Daniel 在他的回答中所说:
//set-up - probably only needs to be done once
var scratchCanvas = document.createElement('canvas');
scratchCanvas.width = 100;
scratchCanvas.height = 100;
var scratchCtx = scratchCanvas.getContext('2d');
//drawing code
scratchCtx.clearRect(0, 0, scratchCanvas.width, scratchCanvas.height);
scratchCtx.globalCompositeOperation = 'source-over'; //default
//Do whatever drawing you want. In your case, draw your image.
scratchCtx.drawImage(imageToCrop, ...);
//As long as we can represent our clipping region as a single path,
//we can perform our clipping by using a non-default composite operation.
//You can think of destination-in as "write alpha". It will not touch
//the color channel of the canvas, but will replace the alpha channel.
//(Actually, it will multiply the already drawn alpha with the alpha
//currently being drawn - meaning that things look good where two anti-
//aliased pixels overlap.)
//
//If you can't represent the clipping region as a single path, you can
//always draw your clip shape into yet another scratch canvas.
scratchCtx.fillStyle = '#fff'; //color doesn't matter, but we want full opacity
scratchCtx.globalCompositeOperation = 'destination-in';
scratchCtx.beginPath();
scratchCtx.arc(50, 50, 50, 0, 2 * Math.PI, true);
scratchCtx.closePath();
scratchCtx.fill();
//Now that we have a nice, cropped image, we can draw it in our
//actual canvas. We can even draw it over top existing pixels, and
//everything will look great!
ctx.drawImage(scratchCanves, ...);