codingdir logo sitemap sitemap |

Dynamic Canvas DrawImage Function

By : , Category : javascript

Here’s how to impliment Dave’s good idea of using arrays to organize your canvases:

Create an array that will hold references to all your 25 canvases (do the same for 25 contexts)

var canvases=[];
var contexts=[];

Next, fill the array with all your canvases and contexts:

for(var i=0;i<25;i++){
    var canvas=document.getElementById("can"+(i<10?"0":""));
    var context=canvas.getContext("2d");

If you haven't seen it before: i<10?"0":"" is an inline if/else used here to add a leading zero to your lower-numbered canvases.

Then you can fetch your “can05” canvas like this:

var canvas=canvases[4];    

Why 4 and not 5? Arrays are zero based, so canvases[0] holds can01. Therefore array element 4 contains your 5th canvas “can05”.

So you can fetch the drawing context for your “can05” like this:

var context=contexts[4];

As Dave says, “evals are evil” so here’s how to fetch the context for “can05” and draw the stone image on it.

var context=contexts[4];

This stone drawing can be shortened to:


You can even put this shortened code into a function for easy reuse and modification:

function reImage( canvasIndex, newImage ){
    contexts[ canvasIndex ].drawImage( newImage,0,0 );

Then you can change the image on any of your canvases by calling the function:

reimage( 4,stoneImage );

That’s it!

The evil-evals have been vanquished (warning: never invite them to your computer again!)

Here is example code and a Fiddle:

This code creates 25 canvases dynamically rather than hard-coding 25 html canvas elements.

<!doctype html>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src=""></script>

    body{ background-color: ivory; padding:0px; margin:0px;border:0px; }
    canvas{vertical-align: top; }


    var canvases=[];
    var contexts=[];

    var grass=new Image();

        // the grass is loaded
        // now make 25 canvases and fill them with grass
        // ALSO !!!
        // keep track of them in an array
        // so we can use them later!

        // just a test
        // fill canvas#3 with gold
        // fill canvas#14 with red


    function make25CanvasesFilledWithGrass(){

        // get the div that we will fill with 25 canvases
        var container=document.getElementById("canvasContainer");

        for(var i=0;i<25;i++){
            // create a new html canvas element
            var canvas=document.createElement("canvas");
            // assign the new canvas an id, width and height
            // get the context for this new canvas
            var ctx=canvas.getContext("2d");
            // draw the grass image in the new canvas
            // add this new canvas to the web page
            // add this new canvas to the canvases array
            // add the context for this new canvas to the contexts array


    // test -- just fill the specified canvas with the specified color
    function draw(canvasIndex,newColor){
        var canvas=canvases[canvasIndex];
        var ctx=contexts[canvasIndex];

}); // end $(function(){});


    <div id="canvasContainer"></div>
ReLated :

drawImage is not working on google apps script

If I understand the question correctly, you want to:

  1. draw the map on the hidden canvas;
  2. rotate the visible canvas; and
  3. copy the map from the hidden canvas to the visible canvas?

Assuming your visible canvas has width=800 and height=600 ...

var visibleCanvas = document.getElementById("VisibleCanvas");
var visibleCtx = visibleCanvas.getContext("2d");

Return the canvas coordinate grid to its original position


The drawImage command has the format:

destinationContext.drawImage(sourceElement, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight);

... thus "visibleCtx.drawImage(c,-400,-300,800,600);" is telling the canvas to copy the source using coordinates (-400,-300) - which falls outside of the hidden canvas.

Instead, use this:


Because the visible canvas coordinate system origin point has been set back to the top left hand corner, and you don't want to resize the copied image, you don't need to worry about the destination values.

As I said in my comment, you need to assign the .src attribute of the img after you've assigned the onload handler. Removing the console.log call still doesn't do this. Granted, it does reduce the time between assigning the src and assigning the onload handler, but this is not the way to do it.

Here's your code with the required extra stuff to make it a fully functional example. Note the order of the assignments and the console.log call.

<!DOCTYPE html>
"use strict";
function byId(e){return document.getElementById(e);}
function newEl(tag){return document.createElement(tag);}
function newTxt(txt){return document.createTextNode(txt);}

function toggleClass(elem, className){elem.classList.toggle(className);}
function toggleClassById(targetElemId, className){byId(targetElemId).classList.toggle(className)}

function hasClass(elem, className){return elem.classList.contains(className);}
function addClass(elem, className){return elem.classList.add(className);}
function removeClass(elem, className){return elem.classList.remove(className);}

window.addEventListener('load', onDocLoaded, false);

function onDocLoaded()
    var svgData = byId("svgdiv").innerHTML;
    var url = "data:image/svg+xml;base64," + btoa(svgData);

function getBase64FromImageUrl(URL) 
    var img = new Image();

    // here code not working
    img.onload = function() 
        var canvas = newEl("canvas");
        canvas.width = this.width;
        canvas.height = this.height;

        var ctx = canvas.getContext("2d");
        ctx.drawImage(this, 0, 0);

        var dataURL = canvas.toDataURL("image/png");

        alert(dataURL.replace(/^data:image/(png|jpg);base64,/, ""));

    img.src = URL;

    <div id='svgdiv'>
        <svg id="svgRoot" xmlns="" xmlns:xlink="">
        <rect x="0" y="0" width="100%" height="100%" fill="#009399"/>
        <circle cx="150" cy="75" r="50" fill="blue" onmouseover="this.setAttribute('fill', 'white')" onmouseout="this.setAttribute('fill', 'blue')"/>

temp_paint is jQuery's object, so it can't be .drawImage() first argument. You can use this code instead:

ctx.drawImage(temp_ctx.canvas, 0, 0);

Fiddle example


Message :
Login to Add Your Comments .
How to disable registered OpenCL platforms on Windows?
Is Observable broken in Angular 2 Beta 3?
Cross-thread operation not valid when using Invoke
How to pass an IEnumerable or queryable list of properties from Controller to View
Finding numbers after a certain keyword using Python
Pocketsphinx recognizes random phrases in a silence
Passing non-thread-safe objects through thread-safe containers
React scroll nav
BizTalk WCF-BasicHttp Adapter does not allow Empty string for Service Certificate Props
Why property ''cause" of Exception is repeating forever?
Privacy Policy 2017 © All Rights Reserved .