Why is Kinetic.Shape's drawFunc method called

2019-07-06 15:24发布

While trying to create a custom shape using KineticJS (v4.5.4) I noticed that the Kinetic.Shape class drawFunc method is called twice, one more time than what I was expecting given the code below (adapted from http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-shape-tutorial/). When I run the code below I can see that on my browser console "DEBUG" is printed twice, indicating that the method in question is called twice, why is that??

<!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>

Cheers

1条回答
仙女界的扛把子
2楼-- · 2019-07-06 16:19

KineticJS may invoke the drawFunc any time it chooses. You should design your shape's drawFunc to be invoked repeatedly and at any time. The exact question of why drawFunc is invoked at any particular time is a concern for the library designers, who work hard to make sure you never need to worry about such questions as when and how often drawFunc ought to be invoked.

But since you're asking... I put together a modification of your code that captures the canvas argument for each call to drawFunc.

  • It appears that the first call actually draws the shape on the page's canvas: canvas.element.parentNode is the container <div>, so this is clearly the on-page canvas.
  • The second call, however, draws the shape to an off-page canvas: canvas.element.parentNode is null, which means that the canvas is not currently attached to the DOM.

KineticJS could have a working off-page canvas for a number of reasons:

  • Perhaps it uses it for rapid animation (i.e., so it can have the next frame drawn on an off-page canvas and then quickly swap it in)
  • Perhaps it uses off-screen canvases as image "stamps" of complex shapes (i.e., instead of redrawing a shape that may have thousands of lines and fills, it draws the shape once to an off-screen canvas, and then uses drawImage to quickly draw the whole shape, instead of redrawing each separate line)

EDIT

In the specific case of KinecticJS, the hidden canvas seems to be used for event detection (e.g., determining whether a click has fallen in the bounds of a drawn object or not):

Each layer has two canvas renderers, a scene renderer and a hit graph renderer. The scene renderer is what you can see, and the hit graph renderer is a special hidden canvas that's used for high performance event detection.

查看更多
登录 后发表回答