<div class='grid'>
  <div>
    <p>Raster Art exported as JPG</p>
  <div class='resizable'>
    <div class='resizers'>
        <img class='fit-to-container' src="https://raw.githubusercontent.com/lyqht/intro-to-svg-slides/main/public/story-raster-vs-vector/draft_done.jpg" />
      <div class='resizer top-left'></div>
      <div class='resizer top-right'></div>
      <div class='resizer bottom-left'></div>
      <div class='resizer bottom-right'></div>
    </div>
  </div>
  </div>
  <div>
    <p>Vector Art exported as PNG</p>
    <div class='resizable'>
      <div class='resizers'>
          <img class='fit-to-container' src="https://raw.githubusercontent.com/lyqht/intro-to-svg-slides/main/public/story-raster-vs-vector/design.png" />
        <div class='resizer top-left'></div>
        <div class='resizer top-right'></div>
        <div class='resizer bottom-left'></div>
        <div class='resizer bottom-right'></div>
      </div>
    </div>
  </div>
  <div>
    <p>Vector Art exported as SVG</p>
    <div class='resizable'>
      <div class='resizers'>
          <img class='fit-to-container' src="https://raw.githubusercontent.com/lyqht/intro-to-svg-slides/main/public/story-raster-vs-vector/design.svg" />
        <div class='resizer top-left'></div>
        <div class='resizer top-right'></div>
        <div class='resizer bottom-left'></div>
        <div class='resizer bottom-right'></div>
      </div>
    </div>
  </div>
</div>
body,
html {
  background: black;
  color: white;
}
.resizable {
  background: white;
  width: 200px;
  height: 200px;
/*   position: absolute;
  top: 100px;
  left: 100px; */
}

.resizable .resizers{
  width: 100%;
  height: 100%;
  border: 3px solid #4286f4;
  box-sizing: border-box;
}

.resizable .resizers .resizer{
  width: 10px;
  height: 10px;
  border-radius: 50%; /*magic to turn square into circle*/
  background: white;
  border: 3px solid #4286f4;
  position: absolute;
}

.resizable .resizers .resizer.top-left {
  left: -5px;
  top: -5px;
  cursor: nwse-resize; /*resizer cursor*/
}
.resizable .resizers .resizer.top-right {
  right: -5px;
  top: -5px;
  cursor: nesw-resize;
}
.resizable .resizers .resizer.bottom-left {
  left: -5px;
  bottom: -5px;
  cursor: nesw-resize;
}
.resizable .resizers .resizer.bottom-right {
  right: -5px;
  bottom: -5px;
  cursor: nwse-resize;
}

.fit-to-container {
  width: 100%;
  height:100%;
}

.grid {
  display: grid;
  place-items: center;
  grid-template-columns: repeat(3, 1fr);
}
interact('.resizable')
  .resizable({
    edges: { top: true, left: true, bottom: true, right: true },
    listeners: {
      move: function (event) {
        let { x, y } = event.target.dataset

        x = (parseFloat(x) || 0) + event.deltaRect.left
        y = (parseFloat(y) || 0) + event.deltaRect.top

        Object.assign(event.target.style, {
          width: `${event.rect.width}px`,
          height: `${event.rect.height}px`,
          transform: `translate(${x}px, ${y}px)`
        })

        Object.assign(event.target.dataset, { x, y })
      }
    }
  })

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://unpkg.com/interactjs/dist/interact.min.js