问题
I know that I can clip a canvas by creating a path with getContext('2d')
and setting globalCompositeOperation
.
I've noticed that sometimes I'm able to clip a canvas with -webkit-clip-path
, or clip-path
on other browsers (I'm on Chrome), and sometimes I'm not able to:
Using this HTML:
<canvas width="300" height="60"></canvas>
and CSS:
canvas {
-webkit-clip-path: polygon(50% 33%, 75% 10%, 80% 80%, 60% 75%, 40% 60%, 20% 10%, 40% 20%, 50% 33%);
}
produces this:
Which appears to be correct.
However, I've noticed that if I change the height of the canvas, it fails to clip:
<canvas width="300" height="250"></canvas>
produces:
My assumption was that it has a problem clipping on floating points (where the percentages clip between pixels instead of on pixels), but changing from percents to pixel coordinates doesn't clip.
*Here are links to their jsfiddle pages respectively:
- http://jsfiddle.net/bozdoz/hMTgc/
- http://jsfiddle.net/bozdoz/5H2Y2/
Does anyone know why one works but the other doesn't?
Is there a stable way to clip canvas elements with CSS, or do I need to use the canvas context methods?
The reason I ask is that I'd like to use less js where possible. I have a string of coordinates which I can easily put into css; whereas, to use the ctx.beginPath()...ctx.moveTo()...ctx.lineTo()...ctx.lineTo()...
method I'll need to do a for loop for the points.
Also, I'm very curious as to why the first example worked, if anyone can explain that. Thanks! :)
回答1:
The clip-path is relative new and could be prone to errors (didn't work for me in Aurora).
For a stable result I would suggest just using canvas' clip()
method (you don't need composite for this).
You can provide the points in this way (here percentages):
var path = [50, 33, 75, 10, 80, 80, 60, 75, 40, 60, 20, 10, 40, 20, 50, 33];
Almost as easy as defining in CSS. Then have a function to parse it:
function addClip(context, path) {
var w = context.canvas.width,
h = context.canvas.height;
context.beginPath();
context.moveTo(path[0] * w / 100, path[1] * h / 100);
for(var i = 2; i < path.length; i+=2) {
context.lineTo(path[i] * w / 100, path[i+1] * h / 100);
}
context.closePath();
context.clip();
}
Result:
DEMO HERE
(The clip is set before the drawing operations take place).
Just put your drawing operations in a function which you can call when window is re-sized as well (shown in demo above).
Update
As to anti-alias: there is actually applied anti-alias to the image but because of the red color it can be hard to detect it depending on type of screen and perhaps browser. An enlarged version:
回答2:
I've never worked with -webkit-clip-path:
, but just on general principles I'd try, as a workaround, applying the clip path to an element containing the canvas instead of the canvas itself.
<div class='canvas-wrapper'><canvas></canvas></div>
.canvas-wrapper {
display: table; /* shrinkwrap around canvas */
-webkit-clip-path: ...;
}
来源:https://stackoverflow.com/questions/17556088/how-to-clip-canvas-with-css-clip-path