Back to Demos

This demo shows how you can draw on scene canvas with an external canvas.

Clara.io demo resources:

Visit Base Scene


var api = claraplayer('player');
var sceneId = '81453484-6b64-48a9-9b35-b3dacf65be99';
api.sceneIO.fetchAndUse(sceneId);
var sourceCanvas = document.getElementById('sourceCanvas');
var sourceCtx = sourceCanvas.getContext('2d');
var cleanText = false;
var isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(window.navigator.userAgent);

api.on('loaded', function(){
  var canvasId = api.scene.find({name:'Canvas'});
  sourceCtx.font = '20px Georgia';
  sourceCtx.fillText('Draw inside canvas',40,40);
  draw (canvasId, 2, 'green');
  document.getElementById('baseScene').setAttribute('href','https://clara.io/view/'+sceneId);
});

function draw (sceneCanvasId, width, color ) {

  // this function are use to drawing in the source canvas,
  // to transfor marks from source canvas to the scene canvas you have to:
  // 1. set the External ID of the scene canvas to the DOM id of the course canvas
  // 2. use api.sceneGraph.touch function to transform the makrs

  if( isMobile ) {
    sourceCanvas.addEventListener('touchmove', function (ev) {findxy('move', ev)}, false);
    sourceCanvas.addEventListener('touchstart', function (ev) {findxy('down', ev)}, false);
    sourceCanvas.addEventListener('touchend', function (ev) {findxy('up', ev)}, false);
  } else {
    sourceCanvas.addEventListener('mousemove', function (ev) {findxy('move', ev)}, false);
    sourceCanvas.addEventListener("mousedown", function (ev) {findxy('down', ev)}, false);
    sourceCanvas.addEventListener("mouseup", function (ev) {findxy('up', ev)}, false);
    sourceCanvas.addEventListener("mouseout", function (ev) {findxy('out', ev)}, false);
  }

  var drawFlag = false;
  var currX = 0;
  var currY = 0;
  var prevX = 0;
  var prevY = 0;
  sourceCtx.fillStyle = sourceCtx.strokeStyle = color;
  sourceCtx.lineWidth = width;
  sourceCtx.lineCap = 'square';

  function findxy(res, ev){
    if (res === 'up' || res === 'out') {
      drawFlag = false;
      return;
    };
    prevX = currX;
    prevY = currY;
    var coords = relCoords(sourceCanvas, event);
    currX = coords.x;
    currY = coords.y;

    if (res === 'down') {
      if (!cleanText) {
        sourceCtx.clearRect(0, 0, sourceCanvas.width, sourceCanvas.height);
        cleanText = true;
      }
      drawFlag = true;
      sourceCtx.fillRect(currX, currY, width, width);

      //mark the draw in the sceneCanvas
      api.sceneGraph.touch(sceneCanvasId);
    } 

    if (res === 'move' && drawFlag) {
      sourceCtx.beginPath();
      sourceCtx.moveTo(prevX, prevY);
      sourceCtx.lineTo(currX, currY);
      sourceCtx.stroke();
      sourceCtx.closePath();

      //mark the draw in the sceneCanvas
      api.sceneGraph.touch(sceneCanvasId);
    }
  };
};

//return the canvas relative coordinate of mouse/touch event
function relCoords(canvas, ev){
  var totalOffsetX = 0;
  var totalOffsetY = 0;
  var canvasX = 0;
  var canvasY = 0;
  do {
    totalOffsetX += canvas.offsetLeft - canvas.scrollLeft;
    totalOffsetY += canvas.offsetTop - canvas.scrollTop;
  } while(canvas = canvas.offsetParent)
  var clientX = isMobile ? ev.targetTouches[0].clientX : ev.clientX;
  var clientY = isMobile ? ev.targetTouches[0].clientY : ev.clientY;
  canvasX = clientX - totalOffsetX;
  canvasY = clientY - totalOffsetY;

  return {x:canvasX, y:canvasY}
}