2013-06-05 54 views
0

有沒有簡單的方法使用KineticJS從另一個形狀(或圖層)中「戳記」透明部分?如何使用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/

我已經看過濾器,我認爲這可能是要走的路,但我似乎無法找到我在文檔中尋找什麼。

回答

1

您可以使用動力學形狀對象做自定義繪製,包括你的星切割出

形狀,您可以訪問它,您可以訪問全系列帆布操作的上下文。

從您的背景中「剪切」您的明星所需的操作是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> 
+0

globalCompositeOperation就是我一直在尋找。對於我的使用,理想的解決方案將允許兩個KineticJS形狀對象(即Kinetic.Rect和Kinetic.Star)的組合,只是爲了便於編碼,但是這回答了我發佈的問題,所以我會接受它。 – Divey