Как я могу создать прозрачную фигуру в существующей фигуре, используя 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 ответ

Решение

Вы можете использовать Kinetic Shape Object для создания пользовательского рисунка, в том числе вашего звездного выреза

Форма дает вам доступ к контексту, который дает вам доступ ко всему диапазону операций холста.

Операция, необходимая для "вырезания" вашей звезды из фона - 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>
Другие вопросы по тегам