TAGS :Viewed: 9 - Published at: a few seconds ago

[ merging canvas and background ]

I have a canvas that has a GIF background. I need for the user to upload the drawing and the BG, so another user can see where the drawing is in relation to the BG. The canvas.toDataURL(); code only shows the canvas area with the user drawings, but not the BG. How to flatten or "merge layers", so I can upload to database.

var mousePressed = false;
var lastX, lastY;
var ctx;

function InitThis() {
  ctx = document.getElementById('myCanvas').getContext("2d");

  $('#myCanvas').mousedown(function(e) {
    mousePressed = true;
    Draw(e.pageX - $(this).offset().left, e.pageY - $(this).offset().top, false);
  });

  $('#myCanvas').mousemove(function(e) {
    if (mousePressed) {
      Draw(e.pageX - $(this).offset().left, e.pageY - $(this).offset().top, true);
    }
  });

  $('#myCanvas').mouseup(function(e) {
    mousePressed = false;
  });
  $('#myCanvas').mouseleave(function(e) {
    mousePressed = false;
  });
}

function Draw(x, y, isDown) {
  if (isDown) {
    ctx.beginPath();
    ctx.strokeStyle = $('#selColor').val();
    ctx.lineWidth = $('#selWidth').val();
    ctx.lineJoin = "round";
    ctx.moveTo(lastX, lastY);
    ctx.lineTo(x, y);
    ctx.closePath();
    ctx.stroke();
  }
  lastX = x;
  lastY = y;
}

function clearArea() {
  // Use the identity matrix while clearing the canvas
  ctx.setTransform(1, 0, 0, 1, 0, 0);
  ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
}
<pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="jscripts/JsCode.js"&gt;
  var dataURL = canvas.toDataURL();
&lt;/script&gt;

&lt;!--canvas drawing and upload mySQL--&gt;
&lt;div align="center"&gt;
  &lt;img src="graphics/teethDrawing.gif" width="705" style="position: absolute; z-index: -1" /&gt;
  &lt;canvas id="myCanvas" width="700" height="965" style="border:2px solid black"&gt;&lt;/canvas&gt;

  &lt;br /&gt;
  &lt;br /&gt;
  &lt;button onclick="javascript:clearArea();return false;"&gt;Clear Area&lt;/button&gt;
  Line width :
  &lt;select id="selWidth"&gt;
    &lt;option value="1"&gt;1&lt;/option&gt;
    &lt;option value="3" selected="selected"&gt;3&lt;/option&gt;
    &lt;option value="5"&gt;5&lt;/option&gt;

  &lt;/select&gt;
  Color :
  &lt;select id="selColor"&gt;
    &lt;option value="black" selected="selected"&gt;black&lt;/option&gt;
    &lt;option value="blue"&gt;blue&lt;/option&gt;
    &lt;option value="red"&gt;red&lt;/option&gt;


  &lt;/select&gt;
&lt;/div&gt;
&lt;/div&gt;

The image isn't shown but does show on page.

Help

Answer 1


You can add your background image "behind" the existing canvas drawings using compositing.

// give the image an id so it's more easily fetched
<img id='bk' src="graphics/teethDrawing.gif" 
     width="705" style="position: absolute; z-index: -1" />

// fetch a reference to the bk image
var bk=document.getElementById('bk');

// causes new drawings to be drawn behind existing drawings
ctx.globalCompositeOperation='destination-over';

// draw the img to the canvas (behind existing lines)
ctx.drawImage(bk,0,0);

// always clean up! Reset to default.
ctx.globalCompositeOperation='source-over';

This process will permanently add the bk image to the canvas. If you need the bk and canvas-drawings separated then you can create a second in-memory canvas to flatten your content by drawing both the bk-image and your canvas-drawings to the in-memory canvas.

// create a temporary canvas 
var mem=document.createElement('canvas');
var mctx=mem.getContext('2d');
mem.width=canvas.width;
mem.height=canvas.height;

// draw the bk to the mem canvas
mctx.drawImage(bk,0,0);

// draw the main canvas to the mem canvas
mctx.drawImage(canvas,0,0);