0

I have been trying to save data/object from HTML5 Canvas' drawing feature, how would I save to mySQL table by x and y coordinate points, instead of converting it into a JPEG or an image file?.

The goal is to save the strokes as data file instead of image file. How can I do this?

var canvas = document.getElementById('canvas'),
    coord = document.getElementById('coord'),
    ctx = canvas.getContext('2d'), // get 2D context
    imgCat = new Image();

  /*********** draw image *************/
  imgCat.src = 'http://c.wearehugh.com/dih5/openclipart.org_media_files_johnny_automatic_1360.png';
  imgCat.onload = function() { // wait for image load
    ctx.drawImage(imgCat, 0, 0); // draw imgCat on (0, 0)
  };

  /*********** handle mouse events on canvas **************/
  var mousedown = false;
  ctx.strokeStyle = '#0000FF';
  ctx.lineWidth = 2;
  canvas.onmousedown = function(e) {
    var pos = fixPosition(e, canvas);
    mousedown = true;
    ctx.beginPath();
    ctx.moveTo(pos.x, pos.y);
    return false;
  };

  canvas.onmousemove = function(e) {
    var pos = fixPosition(e, canvas);
    coord.innerHTML = '(' + pos.x + ',' + pos.y + ')';
    if (mousedown) {
      ctx.lineTo(pos.x, pos.y);
      ctx.stroke();
    }
  };

  canvas.onmouseup = function(e) {
    mousedown = false;
  };

  /********** utils ******************/
  // Thanks to http://stackoverflow.com/questions/55677/how-do-i-get-the-coordinates-of-a-mouse-click-on-a-canvas-element/4430498#4430498
  function fixPosition(e, gCanvasElement) {
    var x;
    var y;
    if (e.pageX || e.pageY) {
      x = e.pageX;
      y = e.pageY;
    } else {
      x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
      y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
    }
    x -= gCanvasElement.offsetLeft;
    y -= gCanvasElement.offsetTop;
    return {
      x: x,
      y: y
    };
  }
  ``
<div id="left_col">
  <canvas id="canvas" width="900" height="900" style='background-image:url(http://www.robertshadbolt.com/content/01-articles/01-900x900/900x900.gif);' center cetner no-repeat></canvas>
  <div id="coord" hidden></div>

Fiddle

Junny
  • 1
  • 1
  • You can save the data returned from the canvas using canvas.toDataURL() (which is nothing but a base64 string) directly to your DB :) – AkshayJ Jun 05 '15 at 05:05
  • @AkshayJ that will save the canvas as an image which is what OP wants to avoid. That string contains the binary image encoded as base-64, not vector points –  Jun 05 '15 at 05:06
  • 1
    Yea...K3N got you nw :) – AkshayJ Jun 05 '15 at 05:12

1 Answers1

0

Canvas cannot handle vector graphics in the sense it will rasterize anything drawn to it. Therefor canvas will only provide you with bitmaps (raw or encoded as an image). The canvas can only show the result of those vectors being rasterized, but can never provide them in raw form afterwards.

To obtain the effect of dealing with vectors you need to do the following:

Track and collect the points in a serializeable format such as an array with literal objects. In other words: you need to "record" these points in your mouse handlers parallel to rendering them to canvas.

You will also need to separate "strokes" (a stroke is from mouse down to mouse up, then create a new array for the next stroke etc. meaning you will need an object with two levels, one to collect stroke arrays, and one array per stroke).

When done you can serialize the array using JSON.stringify() and send to your database.

To restore, read that string back and use JSON.parse() to restore the array.

Simplified Example

// some dummy point in a serializeable format:
var points = [
      {x: 10, y: 10},
      {x: 20, y: 50},
      {x: 100, y: 10}
    ];

// serialize
var str = JSON.stringify(points);
document.write("To server: " + str + "<br>");

// send str to database here...

// RESTORE

// read from database here

var restoredPoints = JSON.parse(str);
document.write("Point from restored array - x: " +
               restoredPoints[1].x + " y: " +
               restoredPoints[1].y);

In a more real example your object would look like (pseudo code):

var strokes = [];

onmousedown: 
   create new array -> strokes.push([]);
   index = strokes.length - 1;
   add point to current stroke -> strokes[index].push({x:x, y:y});

onmousemove:
   add point to current stroke -> strokes[index].push({x:x, y:y});
  • @ K3N how can you fetch those points from canvas??.The later part is aggreed. – AkshayJ Jun 05 '15 at 05:14
  • @AkshayJ by recording them –  Jun 05 '15 at 05:15
  • Haha...abit tedious but it will work i guess :)Cheers – AkshayJ Jun 05 '15 at 05:17
  • 1
    @AkshayJ it's actually the only way to save vectors from canvas (technically the canvas is not involved as it only handles bitmaps, but it renders the points you would record and save) –  Jun 05 '15 at 05:19
  • yeah :)canvas is basically used to deal with bitmaps – AkshayJ Jun 05 '15 at 05:26
  • Thanks K3N, this is awesome! I believe this (https://sketchboard.me/hzoSiqrSXsOk) uses the same method you proposed above, it recognizes each of the vectors from mousedown to mouseup and treat it as a single object. – Junny Jun 05 '15 at 06:04