3

I'm using canvas to make shapes. These shapes are draggable. How can the location of the shapes be saved so when I return to the page the shapes is in the same location I dragged it to?

Joshua Pinter
  • 45,245
  • 23
  • 243
  • 245
  • I thought HTML5's `canvas` element doesn't keep track of the positions of whatever is drawn to it, it just functions as a drawable surface. – JAB Jun 21 '13 at 20:16
  • 1
    @JAB Nope, you can get the positions of what's drawn. You can actually put each drawn object, like a rectangle or an arrow, on their own layer and provide each layer a unique name to access them and their attributes, like position, at a later time, such as to save it to persistent storage. – Joshua Pinter Jun 10 '15 at 19:42
  • @JoshPinter Well that's interesting. It seems like a bit overkill to do that for individually-drawn objects given that the vector nature of SVGs seems to make it much easier to manipulate and select specific objects, but I guess even now not all browsers that support `canvas` support SVG and it's probably a good choice for situations where you only have a few objects in a scene, or you're placing overlays on a graph or other image that can be rendered from scratch or composed from existing bitmaps. – JAB Jun 12 '15 at 20:39

4 Answers4

2

localStorage

The most simple solution is to use Web Storage (localStorage / sessionStorage).

To make this work you can use a serializeable object to store the shape information in, for example:

var myShapeStack = []; //all objects here

function myShape(x, y, width, height) {
    this.type = 'rectangle';
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
    //...
    return this;
}

//...
//get the coords from drawing, then
var shape1 = new shape1(x, y, w, h);
myShapeStack.push(shape1);

Now you can store the whole stack using Web Storage:

localStorage.setItem('shapes', JSON.stringify(myShapeStack);

Next time you load and init:

myShapeStack = localStorage.getItem('shapes');
myShapeStack = (myShapeStack !== null) ? JSON.parse(myShapeStack) : [];

If you later want to remove it:

localStorage.removeItem('shapes');

or brute-force everything:

localStorage.clear();

If the browser support canvas natively it most likely has Web Storage as well.

0

Depending on your use case you could store the shape metadata in a cookie on the client side, in the session variable on the server side. Or persist it in a database on the server.

Dave Rager
  • 8,002
  • 3
  • 33
  • 52
0

You can save your data on the server in some persistent storage (not session because that's temporary). Database or file is a good start.

Alternatively, since you're using HTML5, you could use HTML5's local persistent storage to save your shapes.

Matt Houser
  • 33,983
  • 6
  • 70
  • 88
0

jCanvas and a Database Backend.

@K3N Gave you a great run down of storing to localStorage.

Here is a simple example that we're using to store dragged objects to a database.

Couple things:

  1. We're using jCanvas to abstract and clean up the interaction with the canvas. It's incredible. Not only does it provide a nicer interface but it also adds some great functionality on top of what you get with canvas.

    This also implies we are using jQuery.

  2. We're using a Rails backend to store the position to a record in the database.

Here is the basic code to get this working:

$('canvas').drawRect({
  layer: true,
  name: 'myRect-1',
  draggable: true,
  fillStyle: '#6c1',
  x: 100, y: 100,
  width: 100, height: 100,
  
  dragstop: function(layer) {      
    var path = '/objects/1/';
    
    var payload = { id: 1, x: layer.x, y: layer.y };
    
    $.post( path, { _method: 'PUT', payload } );
  }
});

And here is the sandbox for the dragging interaction and code:

Sanbox

Once you get this interaction down and having the position data being sent via AJAX to the backend, you'll need to obviously update your backend to handle the data being sent and update the record that stores the position of the object.

Hope that helps.

JP

Community
  • 1
  • 1
Joshua Pinter
  • 45,245
  • 23
  • 243
  • 245