Почему метод drawFunc Kinetic.Shape вызывается дважды?

При попытке создать пользовательскую форму с помощью KineticJS (v4.5.4) я заметил, что метод drawFunc класса Kinetic.Shape вызывается дважды, на один раз больше, чем я ожидал, учитывая приведенный ниже код (адаптировано из http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-shape-tutorial/< /а>). Когда я запускаю приведенный ниже код, я вижу, что в консоли моего браузера «DEBUG» печатается дважды, указывая на то, что рассматриваемый метод вызывается дважды, почему это??

<!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.4.min.js"></script>
    <script defer="defer">
      var stage = new Kinetic.Stage({
        container: 'container',
        width: 578,
        height: 200
      });
      var layer = new Kinetic.Layer();

      /*
       * create a triangle shape by defining a
       * drawing function which draws a triangle
       */
      var triangle = new Kinetic.Shape({
        drawFunc: function(canvas) {
          console.log('DEBUG');
          var context = canvas.getContext();
          context.beginPath();
          context.moveTo(200, 50);
          context.lineTo(420, 80);
          context.quadraticCurveTo(300, 100, 260, 170);
          context.closePath();
          canvas.fillStroke(this);
        },
        fill: '#00D2FF',
        stroke: 'black',
        strokeWidth: 4
      });

      // add the triangle shape to the layer
      layer.add(triangle);

      // add the layer to the stage
      stage.add(layer);

    </script>
  </body>
</html>

Ваше здоровье


person Community    schedule 02.07.2013    source источник


Ответы (1)


KineticJS может вызывать drawFunc в любое время по своему выбору. Вы должны спроектировать drawFunc своей фигуры так, чтобы она вызывалась многократно и в любое время. Конкретный вопрос о том, почему drawFunc вызывается в определенное время, беспокоит разработчиков библиотек, которые усердно работают над тем, чтобы вам никогда не приходилось беспокоиться о таких вопросах, как когда и как часто drawFunc должен вызываться drawFunc. вызывается.

Но раз вы спрашиваете... я собрал модификацию вашего кода, который фиксирует аргумент canvas для каждого вызова drawFunc.

  • Похоже, что первый вызов на самом деле рисует фигуру на холсте страницы: canvas.element.parentNode — это контейнер <div>, так что это явно холст на странице.
  • Второй вызов, однако, рисует фигуру на внестраничном холсте: canvas.element.parentNode равно null, что означает, что холст в данный момент не присоединен к DOM.

KineticJS может иметь рабочий холст вне страницы по ряду причин:

  • Возможно, он использует его для быстрой анимации (то есть, чтобы следующий кадр можно было нарисовать на холсте вне страницы, а затем быстро поменять его местами)
  • Возможно, он использует закадровые холсты как «штампы» изображений сложных форм (т. е. вместо перерисовки фигуры, которая может иметь тысячи линий и заливок, он рисует фигуру один раз на закадровом холсте, а затем использует drawImage для быстрого рисовать всю фигуру, вместо того, чтобы перерисовывать каждую отдельную линию)

ИЗМЕНИТЬ

В конкретном случае KinecticJS скрытый холст, по-видимому, используется для обнаружения событий (например, определение того, попал клик в границы нарисованного объекта или нет):

Каждый слой имеет два средства визуализации холста, средство визуализации сцены и средство визуализации графа попаданий. Средство визуализации сцены — это то, что вы можете видеть, а средство визуализации графа попаданий — это специальный скрытый холст, который используется для высокопроизводительного обнаружения событий.

person apsillers    schedule 02.07.2013
comment
Спасибо вам всем! Я предполагаю, что второй элемент холста, который вы упомянули, — это средство визуализации графа попаданий, как описано здесь: github.com/ Эрикдроуэлл/KineticJS/wiki. Пожалуйста, отредактируйте свой ответ, чтобы я отметил его как принятый ответ. - person ; 02.07.2013
comment
@theeDude Хорошее исследование - я добавил его в свой ответ. - person apsillers; 02.07.2013