DazBaldwin
DazBaldwin

Reputation: 4305

how to add scrollbars to (a potentially infinite) canvas using fabric.js

I could be missing something here (I'm by no means an expert with HTML or CSS and have only just started using fabric).

It would seem that fabric is a nice tool for creating shape (object) based drawing applications but I can't figure out how to use it in such a way that a user can't lose objects by placing them off the canvas.

none of the demos have any functionality to prevent this but this seems like it would be a massive limitation to the framework. does anybody know of a way of solving this?

essentially, I want to allow users to arbitrarily add objects to the canvas and for usability, these objects will have to be spaced out and so the canvas will have to be potentially infinite. Obviously, the interaction area for the canvas will have to be of a fixed size.

Any help to get this sorted would be much apreciated

Upvotes: 2

Views: 6620

Answers (2)

Hossein Mirzapour
Hossein Mirzapour

Reputation: 70

Adding to Benicks answer - you can call the canvas.on("object:moving", function(e) {}) which is triggered when an object is moved. So the wrapper will have the follwing css:

  #wrapper{
    position: absolute;
    overflow: auto;
    max-height: 600px;
    max-width: 800px;
   }

with an index file:

<div id="wrapper">
  <canvas id="c2"></canvas>
</div>

To expand the canvas as an object is dragged to the edge of the wrapper you can do the following(done in coffee script):

 canvas.on "object:moving", (e) -> 
  currentCanvasHeight = canvas.height
  currentCanvasWidth = canvas.width

  # e.target returns the selected canvas object
  # Once the objects offset left value + the objects width is greater than the canvas
  # width, expand the canvas width
  if (e.target.left + e.target.currentWidth) > currentCanvasWidth
    canvas.setWidth currentCanvasWidth + 50
    $("#wrapper").scrollLeft e.target.left # scroll alongside the canvas expansion
    $('#wrapper').on 'scroll', canvas.calcOffset.bind(canvas) # to fix the mouse 
    #position bug issue 

  # do the same for the top
  if (e.target.top + e.target.currentHeight) > currentCanvasHeight
    canvas.setHeight currentCanvasHeight + 50
    $("#wrapper").scrollTop e.target.top 
    $('#wrapper').on 'scroll', canvas.calcOffset.bind(canvas)

Upvotes: 3

py66WJAm
py66WJAm

Reputation: 648

we sort of had the same problem and solved by creating a viewport. We created a div around the canvas div. <div id="viewport"> <div id="canvas"></div> </div>

CSS:

#viewport {
  height: 500px;
  left: 0;
  position: absolute;
  top: 0;
  width: 500px; 
  overflow: auto;
}

JS to create the canvas:

var canvas = new fabric.Canvas('canvas');
 canvas.setWidth(1000);
 canvas.setHeight(1000);
 canvas.renderAll();

Now you should be able the scroll through the canvas. However you will realize that your mouseposition is not correct anymore. You can fix that using the canvas.calcOffset() method and bind it to the scroll event of the viewport for example. Hope this helps.

Upvotes: 3

Related Questions