Venk
Venk

Reputation: 240

Resizing a canvas element via dragging the edges

I'm trying to make it so users of my site can resize their canvas by simply dragging the sides of it. I'm using Fabric.js which allows me to resize elements from within the canvas but I need to resize the actual canvas itself. I'm fine with using any new libraries you recommend.

This image should help you understand a bit more of what I want.

As a side note, the Fabric.js team have an interactive toolbox here for you to experiment if you need it.

Upvotes: 2

Views: 3845

Answers (2)

shkaper
shkaper

Reputation: 5018

  1. Put your fabric.js canvas in a wrapper div.
  2. Make the wrapper resizable. Here I'm using CSS resize. It only adds a bottom-left corner as a resize control but it's good enough for the sake of the demo. To have all the edges as controls you can try something like this.
  3. Detect the wrapper's size change. Ideally, you would use something like ResizeObserver. However, since browser support is still about 80% at the time of posting this, you might feel the need to use a polyfill or write something specific to your case. A simple setInterval with size check might prove to be sufficient.
  4. When the wrapper's size changes, set new fabric.js canvas dimensions via setWidth() and setHeight().

const canvas = new fabric.Canvas('c')

canvas.add(new fabric.Rect({
  width: 100,
  height: 100,
  fill: 'red',
  left: 100,
  top: 50,
}))

const canvasWrapper = document.getElementById('wrapper')
// initial dimensions
canvasWrapper.style.width = '300px'
canvasWrapper.style.height = '150px'

let width
let height
setInterval(() => {
  const newWidth = canvasWrapper.clientWidth
  const newHeight = canvasWrapper.clientHeight
  if (newWidth !== width || newHeight !== height) {
    width = newWidth
    height = newHeight
    canvas.setWidth(newWidth)
    canvas.setHeight(newHeight)
  }
}, 100)
#wrapper {
    border: solid 1px black;
    resize: both;
    overflow: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.6.2/fabric.min.js"></script>
<div id="wrapper">
  <canvas id="c"></canvas>
</div>

Upvotes: 3

Splox
Splox

Reputation: 771

This isn't something that's going to be easy, but it's definitely possible. First, you may wonder about the native browser element resize CSS property and ResizeObserver, however those have poor support right now. Your best option is to:

  1. Create a canvas element
  2. Detect mousemoves on the canvas:
    • If the mousemove happens around the edge of the canvas, set the cursor to be the resize icon in the proper direction
    • If the mouse is currently down, resize the canvas based on the mouse's position.

Remember that every time you resize a canvas, the current image on the canvas is wiped.

Upvotes: 1

Related Questions