JSFiddle - React, Tailwind, and code Playground

by kassiomaia

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/svg.js/2.7.1/svg.min.js"></script>
<div id="board">
</div>

CSS

body {
  background-color: black;
}

svg {
  background-color: white;
}

JavaScript

function Board(w, h) {
  var startingPoint = { x: 0, y: 0 };
	this.zoom = 1;
	this.scroll = { x: 0, y: 0 };
	this.enablePanning = false;
	
	this.width = w;
  this.height = h;
  this.center = {
  	x: w / 2,
    y: h / 2
  };
  this.draw = SVG('board').size(w, h);
  this.elements = this.draw.group();

  const transformX = (x) => {
    return this.scroll.x + (x - startingPoint.x);
  }

  const transformY = (y) => {
    return this.scroll.y + (y - startingPoint.y);
  }

  const transform = (evt) => {
			this.elements
        .transform({
          a: this.zoom,
          b: 0,
          c: 0,
          d: this.zoom,
          e: transformX(evt.x),
          f: transformY(evt.y),
        });
  }

  this.draw.on('mousedown', (initialEvent) => {
    startingPoint = {
      x: initialEvent.x,
      y: initialEvent.y
    };
    this.enablePanning = true;
  });

  this.draw.on('mousemove', (evt) => {
    if (this.enablePanning) {
      transform(evt);
    }
  }); 

  this.draw.on('mouseup', (evt) => {
    this.enablePanning = false;
    this.scroll = {
      x: transformX(evt.x),
      y: transformY(evt.y),
    };
    startingPoint = { x: 0, y: 0 };
  });

  this.draw.on('wheel', (evt) => {
    var X, Y;
    evt.preventDefault();
    if (evt.ctrlKey) {
      this.zoom -= evt.deltaY * 0.01;
			transform(evt);
    }
  }); 
  
  return this;
}

var board = new Board(550, 750);

board.elements
  .rect(100,100)
  .move(170, 170)
  .fill('#f03');

board.elements
  .rect(50,50)
  .move(70, 70)
  .fill('#a09');
 
board.elements.circle(5).fill('#00');