konvajs/konva

Event was not triggered

zhanghibi opened this issue · 3 comments

https://konvajs.org/docs/sandbox/Web_Worker.html

For the above example, add the following styles:

#canvas {
        position: absolute;
        left: 20px;
        top: 20px;
}

A native event is triggered:

EVENTS.forEach((eventName) => {
        htmlCanvas.addEventListener(eventName, (e) => {
            console.log(''triggered")
            w.postMessage({
              eventName,
              event: {
                clientX: e.clientX,
                clientY: e.clientY,
                type: e.type,
              },
            });
          });
  });

Konva Event was not triggered:

  button.on('mousedown', function () {
  console.log(''not  triggered")
    isAdding = true;
  });

Can you make a final demo to reproduce?

This is a final demo:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Konva Offscreen Canvas Demo</title>
    <style>
      body {
        position: relative;
        margin: 0;
        padding: 0;
        overflow: hidden;
        background-color: #f0f0f0;
      }
  /* Only the following styles have been added ,  left : 0; height : 0   is normal */
      #canvas {
        position: fixed;
        left: 20px;
        top: 20px;
      }
    </style>
  </head>

  <body>
      <canvas id="canvas"></canvas>

    <script>
      var htmlCanvas = document.getElementById('canvas');
      htmlCanvas.width = window.innerWidth;
      htmlCanvas.height = window.innerHeight;

      var hasOffscreenSupport = !!htmlCanvas.transferControlToOffscreen;
      if (hasOffscreenSupport) {
        var offscreen = htmlCanvas.transferControlToOffscreen();

        var w = new Worker('./web_worker2.js');
        // pass canvas into webworker, so we can do all rendering inside it
        w.postMessage({ canvas: offscreen }, [offscreen]);

        // "proxy" all DOM events from canvas into Konva engine
        var EVENTS = [
          'mouseenter',
          'mousedown',
          'mousemove',
          'mouseup',
          'mouseout',
          'wheel',
          'contextmenu',
          'pointerdown',
          'pointermove',
          'pointerup',
          'pointercancel',
          'lostpointercapture',
        ];
        EVENTS.forEach((eventName) => {
          htmlCanvas.addEventListener(eventName, (e) => {
            w.postMessage({
              eventName,
              event: {
                clientX: e.clientX,
                clientY: e.clientY,
                type: e.type,
              },
            });
          });
        });
      } else {
        htmlCanvas
          .getContext('2d')
          .fillText(
            '🛑 Sorry, your browser does not support Offscreen rendering...',
            20,
            20
          );
      }
    </script>
  </body>
</html>

worker code

// load konva framework
importScripts('https://unpkg.com/konva@9/konva.js');

// monkeypatch Konva for offscreen canvas usage
Konva.Util.createCanvasElement = () => {
  const canvas = new OffscreenCanvas(1, 1);
  canvas.style = {};
  return canvas;
};


// now we can create our canvas content
var stage = new Konva.Stage({
  width: 200,
  height: 200,
});

 // Event was not triggered
stage.on('mousedown', function () {
  isAdding = true
})
stage.on('mouseup', function () {
  isAdding = false
})

console.log(stage,stage._pointerdown)
var layer = new Konva.Layer();
stage.add(layer);

var topGroup = new Konva.Group();
layer.add(topGroup);

// counter will show number of bunnies
var counter = new Konva.Text({
  x: 5,
  y: 35,
});
topGroup.add(counter);

// "add more bunnies" button
var button = new Konva.Label({
  x: 5,
  y: 5,
  opacity: 0.75,
});
topGroup.add(button);

button.add(
  new Konva.Tag({
    fill: 'black',
  })
);

button.add(
  new Konva.Text({
    text: 'Push me to add bunnies',
    fontFamily: 'Calibri',
    fontSize: 18,
    padding: 5,
    fill: 'white',
  })
);

// draggable circle to show interactivity
var circle = new Konva.Circle({
  x: stage.width() / 2,
  y: stage.height() / 2,
  radius: 20,
  fill: 'red',
  draggable: true,
});
topGroup.add(circle);

self.onmessage = function (evt) {
  // when canvas is passes we can start our worker
  // we can try to use that canvas for the layer with some manual replacement (and probably better performance)
  // but for simplicity we will just copy layer content into passed canvas
  if (evt.data.canvas) {
    var canvas = evt.data.canvas;
    // adapt stage size
    // we may need to add extra event to resize stage on a fly
    stage.setSize({
      width: canvas.width,
      height: canvas.height,
    });

    const ctx = canvas.getContext('2d');

    // Konva.Layer has support for "draw" event
    // so every time the layer is re-rendered we need to update the canvas
    layer.on('draw', () => {
      // clear content
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      // draw layer content
      ctx.drawImage(layer.getCanvas()._canvas, 0, 0);
    });
  }
  // emulate some drag&drop events
  if (evt.data.eventName === 'mouseup') {
    Konva.DD._endDragBefore(evt.data.event);
  }
  if (evt.data.eventName === 'touchend') {
    Konva.DD._endDragBefore(evt.data.event);
  }
  if (evt.data.eventName === 'mousemove') {
    Konva.DD._drag(evt.data.event);
  }
  if (evt.data.eventName === 'touchmove') {
    Konva.DD._drag(evt.data.event);
  }
  if (evt.data.eventName === 'mouseup') {
    Konva.DD._endDragAfter(evt.data.event);
  }
  if (evt.data.eventName === 'touchend') {
    Konva.DD._endDragAfter(evt.data.event);
  }

  // // pass incoming events into the stage
  if (evt.data.eventName) {
    const event = evt.data.eventName.replace('mouse', 'pointer');
    stage['_' + event](evt.data.event);
  }
};

function requestAnimationFrame(cb) {
  setTimeout(cb, 16);
}

// that function is large and adapted from bunnies demo
// the only interesting part here is how to load images to use for Konva.Image
async function runBunnies() {
  const imgBlob = await fetch('https://konvajs.org/assets/bunny.png').then(
    (r) => r.blob()
  );
  // use "createImageBitmap" instead of "new window.Image()"
  const img = await createImageBitmap(imgBlob);

  var bunnys = [];
  var gravity = 0.75;

  var startBunnyCount = 100;
  var isAdding = false;
  var count = 0;
  var amount = 10;

 // Event was not triggered
  button.on('mousedown', function () {
    console.log('not in')
    isAdding = true;
  });

  button.on('mouseup', function () {
    isAdding = false;
  });

  for (var i = 0; i < startBunnyCount; i++) {
    var bunny = new Konva.Image({
      image: img,
      transformsEnabled: 'position',
      x: 10,
      y: 10,
      listening: false,
    });

    bunny.speedX = Math.random() * 10;
    bunny.speedY = Math.random() * 10 - 5;

    bunnys.push(bunny);
    counter.text('Bunnies number: ' + bunnys.length);
    layer.add(bunny);
  }
  topGroup.moveToTop();

  function update() {
    var maxX = stage.width() - 10;
    var minX = 0;
    var maxY = stage.height() - 10;
    var minY = 0;
    if (isAdding) {
      for (var i = 0; i < amount; i++) {
        var bunny = new Konva.Image({
          image: img,
          transformsEnabled: 'position',
          x: 0,
          y: 0,
          listening: false,
        });
        bunny.speedX = Math.random() * 10;
        bunny.speedY = Math.random() * 10 - 5;
        bunnys.push(bunny);
        layer.add(bunny);
        counter.text('Bunnies number: ' + bunnys.length);
        count++;
      }
      topGroup.moveToTop();
    }

    for (var i = 0; i < bunnys.length; i++) {
      var bunny = bunnys[i];
      bunny.setX(bunny.getX() + bunny.speedX);
      bunny.setY(bunny.getY() + bunny.speedY);
      bunny.speedY += gravity;
      if (bunny.getX() > maxX - img.width) {
        bunny.speedX *= -1;
        bunny.setX(maxX - img.width);
      } else if (bunny.getX() < minX) {
        bunny.speedX *= -1;
        bunny.setX(minX);
      }

      if (bunny.getY() > maxY - img.height) {
        bunny.speedY *= -0.85;
        bunny.setY(maxY - img.height);
        if (Math.random() > 0.5) {
          bunny.speedY -= Math.random() * 6;
        }
      } else if (bunny.getY() < minY) {
        bunny.speedY = 0;
        bunny.setY(minY);
      }
    }
    layer.drawScene();
    requestAnimationFrame(update);
  }
  update();
}

runBunnies();

Sorry, it's me code issue