Konva rules and draggable stage

Konva rules and draggable stage

by Semih Muyaoğlu

HTML

<!DOCTYPE html>
<html>

<head>
	<script src="https://unpkg.com/[email protected]/konva.min.js"></script>
	<meta charset="utf-8" />
	<title>Konva Snapping of shapes Demo</title>
</head>

<body>
	<div id="container"></div>
</body>

</html>

CSS

body {
  margin: 0;
  padding: 0;
  overflow: hidden;
  background-color: #f0f0f0;
}

JavaScript

var width = window.innerWidth;
var height = window.innerHeight;
var GUIDELINE_OFFSET = 5;

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

var layer = new Konva.Layer();
stage.add(layer);

// first generate random rectangles

layer.add(
  new Konva.Rect({	
    x: 200,
    y: 200,
    width: 100,
    height: 100,
    fill: Konva.Util.getRandomColor(),
    rotation: Math.random() * 360,
    draggable: true,
    name: 'object'
  })
);
layer.add(
new Konva.Circle({
  x: 250,
  y: 250,
  radius: 100,
  fill: Konva.Util.getRandomColor(),
  stroke: "black",
  strokeWidth: 4,
  draggable: true,
  name: 'object'
})
);






// were can we snap our objects?
function getLineGuideStops(skipShape) {
  // we can snap to stage borders and the center of the stage
  var vertical = [0, stage.width() / 2, stage.width()];
  var horizontal = [0, stage.height() / 2, stage.height()];

  // and we snap over edges and center of each object on the canvas
  stage.find('.object').forEach(guideItem => {
    if (guideItem === skipShape) {
      return;
    }
    var box = guideItem.getClientRect({
      relativeTo: stage
    });
    // and we can snap to all edges of shapes
    vertical.push([box.x, box.x + box.width, box.x + box.width / 2]);
    horizontal.push([box.y, box.y + box.height, box.y + box.height / 2]);
  });
  return {
    vertical: vertical.flat(),
    horizontal: horizontal.flat()
  };
}

// what points of the object will trigger to snapping?
// it can be just center of the object
// but we will enable all edges and center
function getObjectSnappingEdges(node) {
  var box = node.getClientRect({
    relativeTo: stage
  });
  return {
    vertical: [{
        guide: Math.round(box.x),
        offset: Math.round(node.x() - box.x),
        snap: 'start'
      },
      {
        guide: Math.round(box.x + box.width / 2),
        offset: Math.round(node.x() - box.x - box.width / 2),
        snap: 'center'
      },
     ...