是否有一种简单的方法可以使用KineticJS从另一个形状(或层)中“标记”透明部分?
例如,使用以下代码:
var stage = new Kinetic.Stage({
container: 'canvas',
width: 100,
height: 100
});
var layer = new Kinetic.Layer();
var rect = new Kinetic.Rect({
x: 1,
y: 1,
width: 96,
height: 96,
fill: 'green',
stroke: 'black',
strokeWidth: 2
});
layer.add(rect);
var star = new Kinetic.Star({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
numPoints: 5,
innerRadius: 15,
outerRadius: 40,
fill: 'yellow'
});
layer.add(star);
stage.add(layer);
如何使绿色框内的星形透明,以便画布后面的元素可见。这是一个小例子:http://jsfiddle.net/ZPVxa/
我已经查看了过滤器,我认为这可能是要走的路,但我似乎无法找到我在文档中寻找的内容。
答案 0 :(得分:1)
您可以使用动态形状对象进行自定义绘图,包括明星剪裁
Shape允许您访问上下文,使您可以访问所有画布操作。
从背景中“切割”你的星星所需的操作是globalCompositeOperation。
“目的地”合成将从任何现有图纸(绿色矩形)中剪切下一个绘制的形状(您的星星)。
以下是如何绘制绿色矩形并使用合成来切割星形。
var rect = new Kinetic.Shape({
drawFunc: function(canvas){
context=canvas.getContext("2d");
context.save();
context.beginPath();
context.rect(0,0,96,96);
context.fillStyle="green";
context.fill();
context.globalCompositeOperation="destination-out";
drawStar(context,45,50,5,40,15);
canvas.fillStroke(this);
context.restore();
},
width: 96,
height: 96,
fill: 'green',
stroke: 'black',
strokeWidth: 2
});
由于星形不是原生帆布形状,因此您还需要使用此代码绘制星形:
function drawStar(ctx,cx,cy,spikes,outerRadius,innerRadius){
var rot=Math.PI/2*3;
var x=cx;
var y=cy;
var step=Math.PI/spikes;
ctx.strokeSyle="#000";
ctx.beginPath();
ctx.moveTo(cx,cy-outerRadius)
for(i=0;i<spikes;i++){
x=cx+Math.cos(rot)*outerRadius;
y=cy+Math.sin(rot)*outerRadius;
ctx.lineTo(x,y)
rot+=step
x=cx+Math.cos(rot)*innerRadius;
y=cy+Math.sin(rot)*innerRadius;
ctx.lineTo(x,y)
rot+=step
}
ctx.lineTo(cx,cy-outerRadius)
ctx.closePath();
ctx.fill();
}
这就是它!
这是代码和小提琴:http://jsfiddle.net/m1erickson/VVrZT/
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.3.min.js"></script>
<script defer="defer">
var stage = new Kinetic.Stage({
container: 'container',
width: 300,
height: 300
});
var layer = new Kinetic.Layer();
stage.add(layer);
var rect = new Kinetic.Shape({
drawFunc: function(canvas){
context=canvas.getContext("2d");
context.save();
context.beginPath();
context.rect(0,0,96,96);
context.fillStyle="green";
context.fill();
context.globalCompositeOperation="destination-out";
drawStar(context,45,50,5,40,15);
canvas.fillStroke(this);
context.restore();
},
width: 96,
height: 96,
fill: 'green',
stroke: 'black',
strokeWidth: 2
});
layer.add(rect);
layer.draw();
function drawStar(ctx,cx,cy,spikes,outerRadius,innerRadius){
var rot=Math.PI/2*3;
var x=cx;
var y=cy;
var step=Math.PI/spikes;
ctx.strokeSyle="#000";
ctx.beginPath();
ctx.moveTo(cx,cy-outerRadius)
for(i=0;i<spikes;i++){
x=cx+Math.cos(rot)*outerRadius;
y=cy+Math.sin(rot)*outerRadius;
ctx.lineTo(x,y)
rot+=step
x=cx+Math.cos(rot)*innerRadius;
y=cy+Math.sin(rot)*innerRadius;
ctx.lineTo(x,y)
rot+=step
}
ctx.lineTo(cx,cy-outerRadius)
ctx.closePath();
ctx.fill();
}
</script>
</body>
</html>