chart3r
chart3r

Reputation: 1

Drag Stage Only With SpaceBar

Creating a image annotator, however for usability purposes I would like to drag around the canvas(stage) without accidentally moving the elements on the screen. I thought that it would be cool to implement a transparant layer called "stageDragOverlay" that appears only when the user presses the "space-bar" and allows the user to explicitly drag the stage and prevents drag events on canvas elements from being triggered.

This is what I got so far. It works! However I was wondering if there's a better way because this took me way too long.

<!doctype html>
<html>
  <head>
    <title>Trying out Stage Only Drag</title>
    <script src="https://unpkg.com/konva@9/konva.min.js" defer></script>
    <script src="app.js" type="module" defer></script>
  </head>
  <body>
    <div id="container"></div>
    <div id="stageDragOverlay"></div>
  </body>
</html>

let width = window.innerWidth;
let height = window.innerHeight;

//=== let's add some shapes in the container behind the stageDragOverlay so we have something to look at ===//
window.Storage = {};
let s = window.Storage;

s.stage = new Konva.Stage({
  container: "container",
  width: width,
  height: height,
  draggable: true,
});

let rect1 = new Konva.Rect({
  x: width / 2 - 25, // oh did you know that unlike styling in javascript the unit is not required??
  y: 200,
  width: 50,
  height: 50,
  fill: "red",
  stroke: "black",
  draggable: true,
});

let layer = new Konva.Layer();

//=== combine the Konva items above together
layer.add(rect1);
s.stage.add(layer);

//=== this is just creating the stageDragOverlay part with space press fuctionality ===//
let stageDragOverlay = document.getElementById("stageDragOverlay");

stageDragOverlay.style.backgroundColor = "rgba(0, 50, 50, 0.5)";
stageDragOverlay.style.top = "0px";
stageDragOverlay.style.left = "0px";
stageDragOverlay.style.width = `${width}px`;
stageDragOverlay.style.height = `${height}px`;
stageDragOverlay.style.position = "absolute";
stageDragOverlay.style.visibility = "hidden";

let spacebarHeld = false; // keydown toggles multiple times while I'm holding space. But I only want to make overlay visible once.

document.addEventListener("keydown", (e) => {
  if (e.code !== "Space") return;
  e.preventDefault();

  if (spacebarHeld === false) {
    spacebarHeld = true;
    stageDragOverlay.style.visibility = "visible";
  }
});

document.addEventListener("keyup", (e) => {
  if (e.code !== "Space") return;
  e.preventDefault();

  if (spacebarHeld === true) {
    spacebarHeld = false;
    stageDragOverlay.style.visibility = "hidden";
  }
});

//=== finally implement stage.startDrag() if stageDragOverlay is clicked ===//
stageDragOverlay.addEventListener("mousedown", (e) => {
  e.preventDefault();
  s.stage.startDrag();
});


Upvotes: 0

Views: 27

Answers (0)

Related Questions