i am not getting the exact position of x and y co-ordinates in the ipad. Can some explain what am i doing wrong? this s a painting app for children where they can color on an image using canvas. its coloring but error being that its on starting on the point where the user touches the screen, its slightly below the point of contact. you can test this on your mobile or tablet..thie link is http://talentedash.co.uk/color/paint.html . Dont try this on desktop as it wont work
<script type="text/javascript">
var canvas = null; //canvas object
var context = null; //canvas's context object
var clearBtn = null; //clear button object
var defaultColor="#3577BB";
var defaultShape="round";
var defaultWidth=50;
/*boolean var to check if the touchstart event
is caused and then record the initial co-ordinate*/
var buttonDown = false;
//onLoad event register
window.addEventListener('load', initApp, false);
function initApp() {
setTimeout(function() { window.scrollTo(0, 1); }, 10); //hide the address bar of the browser.
canvas = document.getElementById('paintBox');
clearBtn = document.getElementById('clearBtn');
initializeEvents();
context = canvas.getContext('2d'); //get the 2D drawing context of the canvas
context.strokeStyle = defaultColor;
context.lineJoin = defaultShape;
context.lineWidth = defaultWidth;
/*Main image*/
function loadImages(sources, callback) {
var images = {};
var loadedImages = 0;
var numImages = 0;
// get num of sources
for(var src in sources) {
numImages++;
}
for(var src in sources) {
images[src] = new Image();
images[src].onload = function() {
if(++loadedImages >= numImages) {
callback(images);
}
};
images[src].src = sources[src];
}
}
var sources = {
main: 'transparent-charac1.png',
};
loadImages(sources, function(images) {
context.drawImage(images.main, 0, 0, 400, 800);
context.globalCompositeOperation = "destination-atop";
});
}
function initializeEvents() {
canvas.addEventListener('touchstart', startPaint, false);
canvas.addEventListener('touchmove', continuePaint, false);
canvas.addEventListener('touchend', stopPaint, false);
clearBtn.addEventListener('touchend', clearCanvas,false);
}
function clearCanvas() {
context.clearRect(0,0,canvas.width,canvas.height);
}
function startPaint(evt) {
if(!buttonDown)
{
context.beginPath();
context.moveTo(evt.touches[0].pageX, evt.touches[0].pageY);
buttonDown = true;
}
evt.preventDefault();
}
function continuePaint(evt) {
if(buttonDown)
{
context.lineTo(evt.touches[0].pageX ,evt.touches[0].pageY);
context.stroke();
}
}
function setColor(col)
{
context.strokeStyle = col;
}
function setSize(px)
{
context.lineWidth=px;
}
function stopPaint() {
buttonDown = false;
}
</script>
Related
I draw 3 elements on my canvas and it works fine on my page (https://lodysreizen.nl/route2.html). But when I implement that page in a index page(https://lodysreizen.nl/ route2 button), where I load in into a div, only the outline that I draw in my html code are shown.
The other 2 lines and the dot don't show. What am I doing wrong?
I changed the order of the code(first script and then html and the other way around)
function draw() {
var canvas = document.getElementById('japan_canvas');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.strokeStyle = "red";
<!--2 lijnen-->
ctx.beginPath();
ctx.moveTo(125, 125); <!--tekst-->
ctx.lineTo(125, 45);
ctx.lineTo(45, 125);
ctx.lineTo(63, 200);
ctx.lineTo(200, 210);
<!--ctx.closePath(); dit trekt een lijn vanaf het laatste punt naar het begin punt-->
ctx.lineWidth = 2; <!--dikte van de lijn-->
ctx.lineJoin = "round" <!--hoe de lijn er uitziek waar ze een knik maakt.-->
ctx.stroke();
<!--de circels-->
ctx.strokeStyle = "red"; <!--deze kleur werkt nog niet-->
ctx.beginPath();
ctx.arc(125, 45, 5, 0, 2 * Math.PI); <!--circel met centrumpunt 125,45)-->
ctx.fill(); <!--de circel vullen-->
<!--Path2D-->
}
}
canvas {
border: 1px solid black;
}
<body onload="draw();">
<canvas id="japan_canvas" width="300" height="300"></canvas></body>
function createPaint(parent) {
var canvas = elt('canvas', {});
var cx = canvas.getContext('2d');
var toolbar = elt('div', {class: 'toolbar'});
// calls the every function in controls, passing in context,
// then appending the returned results to the toolbar
for (var name in controls)
toolbar.appendChild(controls[name](cx));
var panel = elt('div', {class: 'picturepanel'}, canvas);
parent.appendChild(elt('div', null, panel, toolbar));
}
/************************************************************************
* helper functions
***********************************************************************/
// creates an element with a name and object (attributes)
// appends all further arguments it gets as child nodes
// string arguments create text nodes
// ex: elt('div', {class: 'foo'}, 'Hello, world!');
function elt(name, attributes) {
var node = document.createElement(name);
if (attributes) {
for (var attr in attributes)
if (attributes.hasOwnProperty(attr))
node.setAttribute(attr, attributes[attr]);
}
for (var i = 2; i < arguments.length; i++) {
var child = arguments[i];
// if this argument is a string, create a text node
if (typeof child == 'string')
child = document.createTextNode(child);
node.appendChild(child);
}
return node;
}
// figures out canvas relative coordinates for accurate functionality
function relativePos(event, element) {
var rect = element.getBoundingClientRect();
return {x: Math.floor(event.clientX - rect.left),
y: Math.floor(event.clientY - rect.top)};
}
// registers and unregisters listeners for tools
function trackDrag(onMove, onEnd) {
function end(event) {
removeEventListener('mousemove', onMove);
removeEventListener('mouseup', end);
if (onEnd)
onEnd(event);
}
addEventListener('mousemove', onMove);
addEventListener('mouseup', end);
}
// loads an image from a URL and replaces the contents of the canvas
function loadImageURL(cx, url) {
var image = document.createElement('img');
image.addEventListener('load', function() {
var color = cx.fillStyle, size = cx.lineWidth;
cx.canvas.width = image.width;
cx.canvas.height = image.height;
cx.drawImage(image, 0, 0);
cx.fillStyle = color;
cx.strokeStyle = color;
cx.lineWidth = size;
});
image.src = url;
}
// used by tools.Spray
// randomly positions dots
function randomPointInRadius(radius) {
for (;;) {
var x = Math.random() * 2 - 1;
var y = Math.random() * 2 - 1;
// uses the Pythagorean theorem to test if a point is inside a circle
if (x * x + y * y <= 1)
return {x: x * radius, y: y * radius};
}
}
/************************************************************************
* controls
***********************************************************************/
// holds static methods to initialize the various controls;
// Object.create() is used to create a truly empty object
var controls = Object.create(null);
controls.tool = function(cx) {
var select = elt('select');
// populate the tools
for (var name in tools)
select.appendChild(elt('option', null, name));
// calls the particular method associated with the current tool
cx.canvas.addEventListener('mousedown', function(event) {
// is the left mouse button being pressed?
if (event.which == 1) {
// the event needs to be passed to the method to determine
// what the mouse is doing and where it is
tools[select.value](event, cx);
// don't select when user is clicking and dragging
event.preventDefault();
}
});
return elt('span', null, 'Tool: ', select);
};
// color module
controls.color = function(cx) {
var input = elt('input', {type: 'color'});
// on change, set the new color style for fill and stroke
input.addEventListener('change', function() {
cx.fillStyle = input.value;
cx.strokeStyle = input.value;
});
return elt('span', null, 'Color: ', input);
};
// save
controls.save = function(cx) {
// MUST open in a new window because of iframe security stuff
var link = elt('a', {href: 'currentTab'}, 'Save');
function update() {
try {
link.href = cx.canvas.toDataURL();
} catch(e) {
// some browsers choke on big data URLs
// also, if the server response doesn't include a header that tells the browser it
// can be used on other domains, the script won't be able to look at it;
// this is in order to prevent private information from leaking to a script;
// pixel data, data URL or otherwise, cannot be extracted from a "tainted canvas"
// and a SecurityError is thrown
if (e instanceof SecurityError)
link.href = 'javascript:alert(' +
JSON.stringify('Can\'t save: ' + e.toString()) + ')';
else
window.alert("Nope.");
throw e;
}
}
link.addEventListener('mouseover', update);
link.addEventListener('focus', update);
return link;
};
/************************************************************************
* tools
***********************************************************************/
// drawing tools
var tools = Object.create(null);
// line tool
// onEnd is for the erase function, which uses it to reset
// the globalCompositeOperation to source-over
tools.Line = function(event, cx, onEnd) {
cx.lineCap = 'round';
// mouse position relative to the canvas
var pos = relativePos(event, cx.canvas);
trackDrag(function(event) {
cx.beginPath();
// move to current mouse position
cx.moveTo(pos.x, pos.y);
// update mouse position
pos = relativePos(event, cx.canvas);
// line to updated mouse position
cx.lineTo(pos.x, pos.y);
// stroke the line
cx.stroke();
}, onEnd);
};
// erase tool
tools.Erase = function(event, cx) {
// globalCompositeOperation determines how drawing operations
// on a canvas affect what's already there
// 'destination-out' makes pixels transparent, 'erasing' them
// NOTE: this has been deprecated
cx.globalCompositeOperation = 'destination-out';
tools.Line(event, cx, function() {
cx.globalCompositeOperation = 'source-over';
});
};
// initialize the app
var appDiv = document.querySelector('#paint-app');
createPaint(appDiv);
canvas {
border: 1px solid black;
}
<div id="paint-app"></div>
I have two canvas first canvas is original size second canvas is twice bigger. At the same time i drawing on the both canvas, but on the second canvas i draw twice bigger elements it's looks like on zoomed first canvas.
How look like:
Problem is when i try redraw from big canvas to small canvas i got my paintings a little brighter, but only brighter is where use pencil:
smallCtx.clearRect(0, 0, smallCanvas.width, smallCanvas.height);
smallCtx.drawImage(bigCanvas, 0, 0, paperFullWidth, paperFullHeight);
Full code:
$(document).ready(function() {
function Pencil(smallCtx, bigCtx, size, color, opacity, moreTimes) {
this.init(smallCtx, bigCtx, size, color, opacity, moreTimes);
}
Pencil.prototype = {
smallCtx: null, moreTimes: null,
prevMouseX: null, prevMouseY: null,
moreTimes: 1,
color: '0, 0, 0',
opacity: 1,
init: function(smallCtx, bigCtx, size, color, opacity, moreTimes) {
this.smallCtx = smallCtx;
this.bigCtx = bigCtx;
this.setSize(size);
this.setColor(color);
this.setOpacity(opacity);
this.moreTimes = moreTimes;
},
stroke: function(mouseX, mouseY, scale) {
/* in first canvas drawing */
this.smallCtx.beginPath();
this.smallCtx.moveTo(this.prevMouseX, this.prevMouseY);
this.smallCtx.lineTo(mouseX, mouseY);
this.smallCtx.closePath();
this.smallCtx.stroke();
/* in second canvas drawing scaled */
this.bigCtx.lineWidth = this.smallCtx.lineWidth * this.moreTimes;
this.bigCtx.beginPath();
this.bigCtx.moveTo( this.prevMouseX * this.moreTimes, this.prevMouseY * this.moreTimes);
this.bigCtx.lineTo( mouseX * this.moreTimes, mouseY * this.moreTimes );
this.bigCtx.closePath();
this.bigCtx.stroke();
this.move(mouseX, mouseY);
},
move: function(mouseX, mouseY) {
this.prevMouseX = mouseX;
this.prevMouseY = mouseY;
},
/* GETTERS */
getSize: function() {
return this.smallCtx.lineWidth;
},
getColor: function() {
return this.color;
},
getOpacity: function() {
return this.opacity;
},
/* SETTERS */
setSize: function(size) {
this.smallCtx.lineWidth = size;
},
setColor: function(color) {
this.color = color; //rgb like: 255,0,0
this.bigCtx.shadowBlur = this.smallCtx.shadowBlur = 0;
this.setStrokeStyle();
},
setOpacity: function(opacity) {
this.opacity = opacity;
this.setStrokeStyle();
},
setStrokeStyle: function() {
this.bigCtx.strokeStyle = this.smallCtx.strokeStyle =
this.bigCtx.fillStyle = this.smallCtx.fillStyle = 'rgba(' + this.getColor() + ', ' + this.getOpacity() +')';
},
}
var smallCanvas = document.getElementById("smallCanvas");
var smallCtx = smallCanvas.getContext("2d");
var bigCanvas = document.getElementById("bigCanvas");
var bigCtx = bigCanvas.getContext("2d");
var paperFullWidth = 150;
var paperFullHeight = 150;
var moreTimes = 2;
var scale = 100;
smallCanvas.width = paperFullWidth;
smallCanvas.height = paperFullHeight;
bigCanvas.width = paperFullWidth * moreTimes;
bigCanvas.height = paperFullHeight * moreTimes;
fillCanvas('rgba(255,255,255,1)');
drawSquare(); //draw a square
pencil = new Pencil(smallCtx, bigCtx, 1, "0,0,0", 0.3, moreTimes);
pointerPos = {}; //for pointer position
var isCanDraw = false;
/****** MOUSE EVENTS FOR CANVAS ******/
$('#smallCanvas').on('mousedown', function(e) {
pointerPos = getMousePos(smallCanvas, e);
isCanDraw = true;
pencil.move(pointerPos.x, pointerPos.y);
});
$('#smallCanvas').on('mouseup', function(e) {
pointerPos = getMousePos(smallCanvas, e);
isCanDraw = false;;
});
$('#smallCanvas').on('mousemove', function(e) {
if(isCanDraw) {
pointerPos = getMousePos(smallCanvas, e);
pencil.stroke( pointerPos.x, pointerPos.y, scale );
}
});
$('#redraw').click(function() {
smallCtx.clearRect(0, 0, smallCanvas.width, smallCanvas.height);
smallCtx.drawImage(bigCanvas, 0, 0, paperFullWidth, paperFullHeight);
});
function fillCanvas(color) {
var tempFillStyle = smallCtx.fillStyle;
bigCtx.fillStyle = smallCtx.fillStyle = color;
smallCtx.fillRect(0, 0, smallCanvas.width, smallCanvas.height);
bigCtx.fillRect(0, 0, bigCanvas.width, bigCanvas.height);
bigCtx.fillStyle = smallCtx.fillStyle = tempFillStyle;
}
function getMousePos(canvas, evt) {
evt = evt.originalEvent || window.event || evt;
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
function drawSquare() {
smallCtx.fillStyle = bigCtx.fillStyle = 'rgba(0,0,0,0.3)';
smallCtx.fillRect(0,0,60,60);
bigCtx.fillRect(0,0,60*moreTimes,60*moreTimes);
}
});
*{
background-color:#CECECE;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<canvas id='smallCanvas' style='z-index: 1;'></canvas>
<canvas id="bigCanvas"></canvas>
<input type='button' id='redraw' value='Redraw'>
You are making the context.lineWidth twice as wide on the big canvas by setting moreTimes=2.
That makes the stroke on the bigger canvas appear darker.
I'm adding multiple png transparent images to an html5 canvas one above the other but they don't stack in the right sequence (defined by the array containing the url of these images)
I read in other discussions that it may be a closure problem but no solution as far.
This is my code:
function drawCanvas() {
var canvas;
var context;
var imgArray = [
'images/img1.png',
'images/img2.png',
'images/img3.png',
'images/img4.png',
'images/img5.png',
'images/img6.png'
];
canvas = document.getElementById('myCanvas');
context = canvas.getContext("2d");
for (var i = 0; i < imgArray.length; i++) {
var img = new Image();
img.src = imgArray[i];
var drawTee = function(i, context, canvas) {
return function() {
console.log(i, 'loaded')
context.drawImage(this, 0, 0);
}
};
img.onload = drawTee(i, context, canvas);
}
};
Can anyone help me?
The problem is that the order of images on the canvas is determined by the order in which the images finish loading.
Solution: Wait for all the images to finish loading and then add them to the canvas
function drawCanvas() {
var canvas;
var context;
var imgArray = [
'images/img1.png',
'images/img2.png',
'images/img3.png',
'images/img4.png',
'images/img5.png',
'images/img6.png'
];
var images = [];
canvas = document.getElementById('myCanvas');
context = canvas.getContext("2d");
var loadCount = 0;
for (var i = 0; i < imgArray.length; i++) {
var img = new Image();
img.src = imgArray[i];
images.push(img);
img.onload = function() {
if(++loadCount == imgArray.length) {
for(var i=0; i < imgArray.length; i++) {
context.drawImage(images[i], 0, 0);
}
}
};
}
};
I want to drag and drop multiple images from one canvas to another using HTML5. The tutorial that I found by googling shows how to drag and drop only one image.
Below is the code that I tried. In that I am not able to add multiple images. I am able to drag and drop one image one but not able to add many image to that canvas.
<script>
window.onload = function ()
{
var canvas1 = document.getElementById("cvs1");
var canvas2 = document.getElementById("cvs2");
var context1 = canvas1.getContext('2d');
var context2 = canvas2.getContext('2d');
var imageXY = {x: 5, y: 5};
/**
* This draws the image to the canvas
*/
function Draw ()
{
//Clear both canvas first
context1.clearRect(0,0,canvas1.width,canvas1.height);
context2.clearRect(0,0,canvas2.width,canvas2.height);
//Draw a red rectangle around the image
if (state && state.dragging) {
state.canvas.getContext('2d').strokeStyle = 'red';
state.canvas.getContext('2d').strokeRect(imageXY.x - 2.5,
imageXY.y - 2.5,
state.image.width + 5,
state.image.height + 5);
}
// Now draw the image
state.canvas.getContext('2d').drawImage(state.image, imageXY.x, imageXY.y);
}
canvas2.onclick =
canvas1.onclick = function (e)
{
if (state && state.dragging) {
state.dragging = false;
Draw();
return;
}
var mouseXY = RGraph.getMouseXY(e);
state.canvas = e.target;
if ( mouseXY[0] > imageXY.x
&& mouseXY[0] < (imageXY.x + state.image.width)
&& mouseXY[1] > imageXY.y
&& mouseXY[1] < (imageXY.y + state.image.height)) {
state.dragging = true;
state.originalMouseX = mouseXY[0];
state.originalMouseY = mouseXY[1];
state.offsetX = mouseXY[0] - imageXY.x;
state.offsetY = mouseXY[1] - imageXY.y;
}
}
canvas1.onmousemove =
canvas2.onmousemove = function (e)
{
if (state.dragging) {
state.canvas = e.target;
var mouseXY = RGraph.getMouseXY(e);
// Work how far the mouse has moved since the mousedon event was triggered
var diffX = mouseXY[0] - state.originalMouseX;
var diffY = mouseXY[1] - state.originalMouseY;
imageXY.x = state.originalMouseX + diffX - state.offsetX;
imageXY.y = state.originalMouseY + diffY - state.offsetY;
Draw();
e.stopPropagation();
}
}
/**
* Load the image on canvas1 initially and set the state up with some defaults
*/
state = {}
state.dragging = false;
state.canvas = document.getElementById("cvs1");
state.image = new Image();
state.image.src = 'images/logo.png';
state.offsetX = 0;
state.offsetY = 0;
state.image.onload = function ()
{
Draw();
}
}
</script>
<canvas id="cvs1" width="400" height="125" style="float: left">[No canvas support]</canvas>
<canvas id="cvs2" width="400" height="125" style="float: left; margin-left: 100px">[No canvas support]</canvas>
I'm trying to place a background image on the back of this canvas script I found. I know it's something to do with the context.fillstyle but not sure how to go about it. I'd like that line to read something like this:
context.fillStyle = "url('http://www.samskirrow.com/background.png')";
Here is my current code:
var waveform = (function() {
var req = new XMLHttpRequest();
req.open("GET", "js/jquery-1.6.4.min.js", false);
req.send();
eval(req.responseText);
req.open("GET", "js/soundmanager2.js", false);
req.send();
eval(req.responseText);
req.open("GET", "js/soundcloudplayer.js", false);
req.send();
eval(req.responseText);
req.open("GET", "js/raf.js", false);
req.send();
eval(req.responseText);
// soundcloud player setup
soundManager.usePolicyFile = true;
soundManager.url = 'http://www.samskirrow.com/client-kyra/js/';
soundManager.flashVersion = 9;
soundManager.useFlashBlock = false;
soundManager.debugFlash = false;
soundManager.debugMode = false;
soundManager.useHighPerformance = true;
soundManager.wmode = 'transparent';
soundManager.useFastPolling = true;
soundManager.usePeakData = true;
soundManager.useWaveformData = true;
soundManager.useEqData = true;
var clientID = "345ae40b30261fe4d9e6719f6e838dac";
var playlistUrl = "https://soundcloud.com/kyraofficial/sets/kyra-ft-cashtastic-good-love";
var waveLeft = [];
var waveRight = [];
// canvas animation setup
var canvas;
var context;
function init(c) {
canvas = document.getElementById(c);
context = canvas.getContext("2d");
soundManager.onready(function() {
initSound(clientID, playlistUrl);
});
aniloop();
}
function aniloop() {
requestAnimFrame(aniloop);
drawWave();
}
function drawWave() {
var step = 10;
var scale = 60;
// clear
context.fillStyle = "#ff19a7";
context.fillRect(0, 0, canvas.width, canvas.height);
// left wave
context.beginPath();
for ( var i = 0; i < 256; i++) {
var l = (i/(256-step)) * 1000;
var t = (scale + waveLeft[i] * -scale);
if (i == 0) {
context.moveTo(l,t);
} else {
context.lineTo(l,t); //change '128' to vary height of wave, change '256' to move wave up or down.
}
}
context.stroke();
// right wave
context.beginPath();
context.moveTo(0, 256);
for ( var i = 0; i < 256; i++) {
context.lineTo(4 * i, 255 + waveRight[i] * 128.);
}
context.lineWidth = 0.5;
context.strokeStyle = "#000";
context.stroke();
}
function updateWave(sound) {
waveLeft = sound.waveformData.left;
}
return {
init : init
};
})();
Revised code - currently just showing black as the background, not an image:
// canvas animation setup
var backgroundImage = new Image();
backgroundImage.src = 'http://www.samskirrow.com/images/main-bg.jpg';
var canvas;
var context;
function init(c) {
canvas = document.getElementById(c);
context = canvas.getContext("2d");
soundManager.onready(function() {
initSound(clientID, playlistUrl);
});
aniloop();
}
function aniloop() {
requestAnimFrame(aniloop);
drawWave();
}
function drawWave() {
var step = 10;
var scale = 60;
// clear
context.drawImage(backgroundImage, 0, 0);
context.fillRect(0, 0, canvas.width, canvas.height);
// left wave
context.beginPath();
for ( var i = 0; i < 256; i++) {
var l = (i/(256-step)) * 1000;
var t = (scale + waveLeft[i] * -scale);
if (i == 0) {
context.moveTo(l,t);
} else {
context.lineTo(l,t); //change '128' to vary height of wave, change '256' to move wave up or down.
}
}
context.stroke();
// right wave
context.beginPath();
context.moveTo(0, 256);
for ( var i = 0; i < 256; i++) {
context.lineTo(4 * i, 255 + waveRight[i] * 128.);
}
context.lineWidth = 0.5;
context.strokeStyle = "#ff19a7";
context.stroke();
}
function updateWave(sound) {
waveLeft = sound.waveformData.left;
}
return {
init : init
};
})();
Theres a few ways you can do this. You can either add a background to the canvas you are currently working on, which if the canvas isn't going to be redrawn every loop is fine. Otherwise you can make a second canvas underneath your main canvas and draw the background to it. The final way is to just use a standard <img> element placed under the canvas. To draw a background onto the canvas element you can do something like the following:
Live Demo
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d");
canvas.width = 903;
canvas.height = 657;
var background = new Image();
background.src = "http://www.samskirrow.com/background.png";
// Make sure the image is loaded first otherwise nothing will draw.
background.onload = function(){
ctx.drawImage(background,0,0);
}
// Draw whatever else over top of it on the canvas.
Why don't you style it out:
<canvas id="canvas" width="800" height="600" style="background: url('./images/image.jpg')">
Your browser does not support the canvas element.
</canvas>
Make sure that in case your image is not in the dom, and you get it from local directory or server, you should wait for the image to load and just after that to draw it on the canvas.
something like that:
function drawBgImg() {
let bgImg = new Image();
bgImg.src = '/images/1.jpg';
bgImg.onload = () => {
gCtx.drawImage(bgImg, 0, 0, gElCanvas.width, gElCanvas.height);
}
}
Canvas does not using .png file as background image. changing to other file extensions like gif or jpg works fine.