I start on KineticJS (and on Canvas) and i'm creating a small game for learn...
Right now, I have just 2 layers :
First with a map composed by Kinetic.Image
Second with the last time who game as draw.
I want refresh display X time per second but after 20 or 30 times the game are really slow.. And it's the same when I flood event click ( who launch the draw function too)...
Moreover, i can see in the second layer : the old text are never clean, the new are added on top... :/
var stage;
var layers = {};
var CANEVAS_WIDTH = 800;
var CANEVAS_HEIGHT = 600;
var MAP_WIDTH = 10;
var MAP_HEIGHT = 10;
var MAPPING_WIDTH = 150;
var MAPPING_HEIGHT = 88;
var LEFT_X = 0;
var LEFT_Y = MAP_WIDTH*MAPPING_HEIGHT/2;
var TOP_X = MAP_WIDTH/2*MAPPING_WIDTH;
var TOP_Y = 0;
var VIEW_X = 0;
var VIEW_Y = 0;
var CURSOR_X = 6;
var CURSOR_Y = 0;
var images = {};
function loadImages(sources, callback)
{
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[src].src = sources[src];
}
}
function getMouseInfo(mousePos)
{
var info = {screen_x : mousePos.x,
screen_y : mousePos.y,
mouse_x : mousePos.x+VIEW_X,
mouse_y : mousePos.y+VIEW_Y-LEFT_Y,
onMap : 0,
map_x : -1,
map_y : -1};
map_x = -(info.mouse_y - ((LEFT_Y * info.mouse_x) / TOP_X)) / MAPPING_HEIGHT;
map_y = -(-info.mouse_y - ((LEFT_Y * info.mouse_x) / TOP_X)) / MAPPING_HEIGHT;
if(map_x >= 0 && map_x < MAP_WIDTH && map_y >= 0 && map_y < MAP_HEIGHT)
{
info.map_y = parseInt(map_y);
info.map_x = parseInt(map_x);
info.onMap = 1;
}
return info;
}
function draw()
{
drawMap();
drawFPS();
stage.add(layers.mapLayer);
stage.add(layers.fpsLayer);
}
function drawFPS()
{
layers.fpsLayer.clear();
var fps = new Kinetic.Shape(function(){
var date = new Date();
var time = date.getTime();
var context = this.getContext();
context.beginPath();
context.font = "12pt Calibri";
context.fillStyle = "red";
context.fillText("FPS : "+time, 10, 20);
});
layers.fpsLayer.add(fps);
}
function drawMap()
{
var x=0,y=0;
layers.mapLayer.clear();
var s = new Kinetic.Shape(function(){
var context = this.getContext();
context.beginPath();
context.rect(0, 0, CANEVAS_WIDTH, CANEVAS_HEIGHT);
context.fillStyle = "#000";
context.fill();
context.closePath();
});
layers.mapLayer.add(s);
for(x=0; x<MAP_WIDTH; x++)
for(y=0;y<MAP_HEIGHT; y++)
{
var img = new Kinetic.Image({
image: ((x==CURSOR_X && y==CURSOR_Y)?images.testMapCursor:images.testMap)
});
img.x = x*MAPPING_WIDTH/2 + y*MAPPING_WIDTH/2 - VIEW_X;
img.y = (MAP_WIDTH-1)*MAPPING_HEIGHT/2 - x*MAPPING_HEIGHT/2 + y*MAPPING_HEIGHT/2 - VIEW_Y;
layers.mapLayer.add(img);
}
}
function changeCursorPosition(cursor_x, cursor_y)
{
CURSOR_X = cursor_x;
CURSOR_Y = cursor_y;
draw();
}
function initStage()
{
layers.mapLayer = new Kinetic.Layer();
layers.fpsLayer = new Kinetic.Layer();
draw();
}
/*
* INIT
*/
window.onload = function(){
stage = new Kinetic.Stage("container", <?=CANEVAS_WIDTH;?>, <?=CANEVAS_HEIGHT;?>);
stage.on("mousemove", function(){
var mouseInfo = getMouseInfo(stage.getMousePosition());
if(mouseInfo.onMap)
document.body.style.cursor = "pointer";
else
document.body.style.cursor = "default";
});
stage.on("mousedown", function(){
var mouseInfo = getMouseInfo(stage.getMousePosition());
if(mouseInfo.onMap)
changeCursorPosition(mouseInfo.map_x, mouseInfo.map_y);
});
var sources = {
testMap : "testMap.png",
testMapCursor : "testMapCursor.png"
};
loadImages(sources, initStage);
};
Sorry, my english are realy bad.
Thank all.
I know someone who is trying out KineticJS. I haven't used it myself, so I apologize that I cannot provide more specific help.
Unfortunately, it is very difficult to get good performance with canvas, and it depends greatly on the browser. Last I checked, Opera 12 and IE 9 performed significantly faster than other browsers, since their 2D rendering is 3D accelerated (using OpenGL and Direct3D, respectively)
I am not sure if this applies to KineticJS, but one technique you can use to improve performance with canvas is to use multiple canvas elements, and transform their positions rather than blitting on a single surface.
I've been pretty happy with the results I've gotten using Jeash, which is wired into NME's command-line tools. The development is similar to working with Flash, but it will create an HTML5 Canvas application using your code. The same application will also be able to publish to Windows, Mac, Linux, iOS, Android, webOS and Flash, as either native C++ and OpenGL, or as SWF bytecode. This gives you a lot of options for providing the best experience for each user.
http://www.haxenme.org
Related
I'm trying to convert one of the Paper.js library examples (http://paperjs.org/examples/smoothing/) from PaperScript to Javascript. Following the documentation, I have
Made the scope global
Installed the event handlers onFrame and onResize
Created a tool and installed the event handlers onMouseMove and onMouseDown
But the canvas is not shown. I only see a couple of small blue lines: AFAIK the problem lies in the view.onFrame() function, since commenting that out at least I can see the shape, but not interact with it. The JS console dosen't show any error. What is missing?
// Make the paper scope global, by injecting it into window
paper.install(window);
window.onload = function () {
// Setup directly from canvas id:
paper.setup('myCanvas');
// Create tool
tool = new Tool();
var width, height, center;
var points = 10;
var smooth = true;
var path = new Path();
var mousePos = view.center / 2;
var pathHeight = mousePos.y;
path.fillColor = 'black';
initializePath();
function initializePath() {
center = view.center;
width = view.size.width;
height = view.size.height / 2;
path.segments = [];
path.add(view.bounds.bottomLeft);
for (var i = 1; i < points; i++) {
var point = new Point(width / points * i, center.y);
path.add(point);
}
path.add(view.bounds.bottomRight);
path.fullySelected = true;
}
view.onFrame = function (event) {
pathHeight += (center.y - mousePos.y - pathHeight) / 10;
for (var i = 1; i < points; i++) {
var sinSeed = event.count + (i + i % 10) * 100;
var sinHeight = Math.sin(sinSeed / 200) * pathHeight;
var yPos = Math.sin(sinSeed / 100) * sinHeight + height;
path.segments[i].point.y = yPos;
}
if (smooth)
path.smooth({ type: 'continuous' });
}
tool.onMouseMove = function (event) {
mousePos = event.point;
}
tool.onMouseDown = function (event) {
smooth = !smooth;
if (!smooth) {
// If smooth has been turned off, we need to reset
// the handles of the path:
for (var i = 0, l = path.segments.length; i < l; i++) {
var segment = path.segments[i];
segment.handleIn = segment.handleOut = null;
}
}
}
// Reposition the path whenever the window is resized:
view.onResize = function (event) {
initializePath();
}
}
To try it: https://jsfiddle.net/1rtkbp9s/
Found the solution (credits to Stefan Krüger of the Paper.js Google Group):
var mousePos = view.center / 2;
Should have been:
var mousePos = view.center.divide(2);
The fact is that Math functions should be used instead of operators for Point and Size object... and I didn't realize that view.center IS a Point object: http://paperjs.org/reference/view/#center
I just started using Canvas for my web game project and faced a problem.
I'm using this code to render the game:
function render(f){
if(charoffset.x == null) charoffset.x = charpos.x*tilescale;
if(charoffset.y == null) charoffset.y = charpos.y*tilescale;
if(!tiles) tiles = [];
if(f){
log("Welcome.","gold");
}
var canPassthrough = function (){
if ((def.passable(this.type))&&(typeof this.type !== 'undefined')){
return true;
}
else {
return false;
}
};
if(!f) lighting.update();
canvas.getContext("2d").clearRect(0,0,sq,sq);
for (var i = 0; i < map[charlvl].length; i++){
if(!tiles[i]) tiles[i] = [];
for (var j = 0; j < map[charlvl][i].length; j++){
if(!tiles[i][j]) tiles[i][j] = placetile(i,j);
drawtile(tiles[i][j]);
placeitem(i,j);
}
}
ui.overlay.text("casting shadows...");
//shadowcaster(20);
var tex = document.createElement("img");
tex.src = "../img/charplaceholder.png";
var hero = canvas.getContext("2d");
hero.globalAlpha = 1.0;
if(charoffset.x>=map_scroll.x&&charoffset.y*tilescale>=map_scroll.y){
var pos = {
x: charoffset.x - map_scroll.x - tilescale,
y: charoffset.y - map_scroll.y - tilescale
};
hero.drawImage(tex,pos.x,pos.y,tilescale,tilescale);
}
function placetile(x,y){
var obj = {};
obj.type = map[charlvl][x][y].id;
obj.canPassthrough = canPassthrough;
obj.state = {explored: false, lit: false};
obj.coords = {x:x,y:y};
obj.offset = {x:x*tilescale,y:y*tilescale};
return obj;
}
function drawtile(t){
if(t.offset.x>=map_scroll.x&&t.offset.y>=map_scroll.y){
var pos = {
x: t.offset.x - map_scroll.x - tilescale,
y: t.offset.y - map_scroll.y - tilescale
};
if(!t.state.explored&&!t.state.lit){
return false;
}
else if(t.state.lit&&t.state.explored){
var tex = document.createElement("img");
var tile = canvas.getContext("2d");
tex.src = def.css.tile(t.type);
tile.globalAlpha = 1.0;
tile.drawImage(tex,pos.x,pos.y,tilescale,tilescale);
return true;
}
else if(t.state.explored&&!t.state.lit){
var tex = document.createElement("img");
var tile = canvas.getContext("2d");
tex.src = def.css.tile(t.type);
tile.globalAlpha = 0.25;
tile.drawImage(tex,pos.x,pos.y,tilescale,tilescale);
return true;
}
}
}
function placeitem(x,y){
return;
if (loot[charlvl][x][y]){
for(var i=0;i<loot[charlvl][x][y].length;i++){
var tile = document.createElement("div");
var tileid = loot[charlvl][x][y][i].type;
tile.className = def.css.item(tileid);
tile.coords = {x:x,y:y};
document.getElementById("x" + x + "y" + y).appendChild(tile);
}
}
}
if(f){
camera.center(charpos.x,charpos.y);
ui.overlay.text("loading the dungeon...");
ui.overlay.hide();
}
}
Function render() is fired by various events, such as character moving, map dragging, lighting update, etc.
This is the result:
I would like to add inset shadows to walls so it's more clearly visible those are walls. I tried experimenting with canvas context shadows, and used this:
It's supposed to draw a transparent rectangle and a shadow for it at 100, 100 with size 20, 20, however this applies shadow to every drawn tile instead.
I feel like I'm using drawing wrong. Can anyone explain how to effectively
use canvas to achieve desired effect?
Do not use the 2D API shadow options , they are very very slow ( and that is an understatement of how bad they are). You are much better off creating the shadows as part of the tile set and rendering them with either ctx.globalAlpha set to less than 1 and/or use one of the many composite modes. Eg ctx.globalCompositeOperation = "multiply"; Or overlay, color-burn, hard-light, and soft-light. You can even use a combination to get a very good shadow effect.
Creating the shadows as part of the tile set will give a much more realistic effect as the shadow API is just for shadows cast from flat object floating above a flat surface, not for 3D objects protruding from the screen that may have sloped sides in the z direction.
If you do not wish to create the shadows as part of the tile set consider creating the shadow tile set at onload using an off screen canvas via the shadow API options. Then render from that to the canvas using alpha and composite options
The Problem
I am creating a game using the HTML5 Canvas, the game has a main menu, the main menu has multiple buttons for you to choose. I am finding it difficult and confusing how I would, for example if the user presses the 'Play' button, to show the game. Here is an image of the main menu:
The Question
The question is how would I get from this page to another in my game?
I think you get the idea. I deliberately created the menu using the canvas, I know I could of made the menu using HTML for example but I cant as this is an example for students of what Canvas can do, whats good and bad etc.
The Code
<html>
<head>
<title>Sean Coyne</title>
</head>
<body onload="start_game()">
<body>
<div style id="canvas">
<canvas id="myCanvas" style="border:5px solid #410b11" height="320" width="480">
<p>Your browser does not support HTML5!</p>
</canvas>
<script type="text/javascript">
//Referencing the canvas
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var width = canvas.getAttribute('width');
var height = canvas.getAttribute('height');
//Finding the position of the mouse
var mouseX;
var mouseY;
//Images
var bgImage = new Image();
var logoImage = new Image();
var playImage = new Image();
var instructImage = new Image();
var settingsImage = new Image();
var aboutImage = new Image();
var peaceImage = new Image();
var backgroundY = 0;
var speed = 1;
//Arrays below used for mouse over function
var buttonX = [130,110,130,160];
var buttonY = [100,140,180,220];
var buttonWidth = [96,260,182,160];
var buttonHeight = [40,40,40,40];
var peaceX = [0,0];
var peaceY = [0,0];
var peaceWidth = 35;
var peaceHeight = 35;
var peaceVisible = false;
var peaceSize = peaceWidth;
var peaceRotate = 0;
var frames = 30;
var timerId = 0;
var fadeId = 0;
var time = 0.0;
peaceImage.src = "Images/peace.png";
bgImage.onload = function(){
context.drawImage(bgImage, 0, backgroundY);
};
bgImage.src = "Images/background.png";
logoImage.onload = function(){
context.drawImage(logoImage, 50, -10);
}
logoImage.src = "Images/logo.png";
playImage.onload = function(){
context.drawImage(playImage, buttonX[0], buttonY[0]);
}
playImage.src = "Images/play.png";
instructImage.onload = function(){
context.drawImage(instructImage, buttonX[1], buttonY[1]);
}
instructImage.src = "Images/instructions.png";
settingsImage.onload = function(){
context.drawImage(settingsImage, buttonX[2], buttonY[2]);
}
settingsImage.src = "Images/settings.png";
aboutImage.onload = function(){
context.drawImage(aboutImage, buttonX[3], buttonY[3]);
}
aboutImage.src = "Images/about.png";
timerId = setInterval("update()", 1000/frames);
canvas.addEventListener("mousemove", checkPos);
canvas.addEventListener("mouseup", checkClick);
function update() {
clear();
move();
draw();
}
function clear() {
context.clearRect(0, 0, width, height);
}
function move(){
backgroundY -= speed;
if(backgroundY == -1 * height){
backgroundY = 0;
}
if(peaceSize == peaceWidth){
peaceRotate = -1;
}
if(peaceSize == 0){
peaceRotate = 1;
}
peaceSize += peaceRotate;
}
function draw(){
context.drawImage(bgImage, 0, backgroundY);
context.drawImage(logoImage, 50,-10);
context.drawImage(playImage, buttonX[1], buttonY[0]);
context.drawImage(instructImage, buttonX[2], buttonY[1]);
context.drawImage(settingsImage, buttonX[2], buttonY[2]);
context.drawImage(aboutImage, buttonX[3], buttonY[3]);
if(peaceVisible == true){
context.drawImage(peaceImage, peaceX[0] - (peaceSize/2), peaceY[0], peaceSize, peaceHeight);
context.drawImage(peaceImage, peaceX[2] - (peaceSize/2), peaceY[2], peaceSize, peaceHeight);
}
}
function checkPos(mouseEvent){
if(mouseEvent.pageX || mouseEvent.pageY == 0){
mouseX = mouseEvent.pageX - this.offsetLeft;
mouseY = mouseEvent.pageY - this.offsetTop;
}else if(mouseEvent.offsetX || mouseEvent.offsetY == 0){
mouseX = mouseEvent.offsetX;
mouseY = mouseEvent.offsetY;
}
for(i = 0; i < buttonX.length; i++){
if(mouseX > buttonX[i] && mouseX < buttonX[i] + buttonWidth[i]){
if(mouseY > buttonY[i] && mouseY < buttonY[i] + buttonHeight[i]){
peaceVisible = true;
peaceX[0] = buttonX[i] - (peaceWidth/2) - 2;
peaceY[0] = buttonY[i] + 2;
peaceX[1] = buttonX[i] + buttonWidth[i] + (peaceWidth/2);
peaceY[1] = buttonY[i] + 2;
}
}else{
peaceVisible = false;
}
}
}
function checkClick(mouseEvent){
for(i = 0; i < buttonX.length; i++){
if(mouseX > buttonX[i] && mouseX < buttonX[i] + buttonWidth[i]){
if(mouseY > buttonY[i] && mouseY < buttonY[i] + buttonHeight[i]){
fadeId = setInterval("fadeOut()", 1000/frames);
clearInterval(timerId);
canvas.removeEventListener("mousemove", checkPos);
canvas.removeEventListener("mouseup", checkClick);
}
}
}
}
function fadeOut(){
context.fillStyle = "rgba(0,0,0, 0.2)";
context.fillRect (0, 0, width, height);
time += 0.1;
if(time >= 2){
clearInterval(fadeId);
time = 0;
timerId = setInterval("update()", 1000/frames);
canvas.addEventListener("mousemove", checkPos);
canvas.addEventListener("mouseup", checkClick);
}
}
</script>
</body>
</html>
What I usually do is have a switch statement inside the draw loop, and a state variable which holds the current game state (menu, playing, etc...).
Then, based on the current game state you only draw the objects required for the current scene.
Something like this:
var STATES = {
Menu: 0,
PauseMenu: 1,
Playing: 2
};
var currentState = STATES.Menu;
...
function draw() {
switch(currentState) {
case STATES.Menu:
// Draw buttons, etc..
break;
case STATES.Playing:
// Draw the game screen, the player, etc...
break;
}
}
When the user presses the Play button the only thing you have to do is:
function onPlayButtonClick() {
currentState = STATES.Playing;
// Starting the next frame the new state will be "magically" drawn
}
If you don't like the switch statement, you can create a State class that has a draw method. Then you can simply create new states, each with it's own drawing method and in the main draw loop only call the draw method of the current state.
Same goes for the update function, each state has it's own update function (in the main menu you update buttons or animate things, while playing the game you update the game world and run your physics). So, based on the current state your update function is actually different. It's up to you how you structure your code and how you call different functions based on the current state.
In each text option, you should create a smaller Canvas, only with the option text and add a 'click' event with the callbacks.
Tip: You don't need another page, just erase the main canvas and draw what you want.
its very confused i`m designing a 2d game and i use this code to draw images to canvas the alert method return background.x = 0 ! but when i change x to z or any letter its return the number 400 i ! why background.x always equal to zero ???
var canvas = document.getElementById('game');
var context = canvas.getContext('2d');
function loadResources(){
background = new Image();
background.src = "11.jpg";
background.width = 128;
background.height = 128;
background.x = 400;
background.y = 450;
}
function drawimage(){
alert(background.x);
context.drawImage(background,background.x,background.y,background.width,background.height);
}
function gameLoop() {
drawimage();
}
loadResources();
setInterval(gameLoop, 1000/60);
Unlike other objects, you are actually not able to set properties of an Image object that do not belong to it. As you've seen, when you try to access them after setting them, the properties will not be available. You can slightly rework your code as follows to get the behavior you're looking for:
var canvas = document.getElementById('game');
var context = canvas.getContext('2d');
var resources = {};
function loadResources(){
resources.background = new Image();
resources.background.src = "11.jpg";
resources.background.width = 128;
resources.background.height = 128;
resources.backgroundx = 400;
resources.backgroundy = 450;
}
function drawimage(){
console.log(resources.backgroundx);
context.drawImage(resources.background,resources.backgroundx,resources.backgroundy,resources.background.width,resources.background.height);
}
function gameLoop() {
drawimage();
}
loadResources();
setInterval(gameLoop, 1000/60);
I'm working on a proof of concept on an HTML5 canvas. I was able to get this working like a charm in Chrome and IE9, but in Firefox 4 I'm getting constant flicker as it redraws the canvas. I've tried a few techniques mentioned on this site like double buffering but I'm still getting a large amount of flicker. Any insight on this would be appreciated!
<!DOCTYPE HTML>
<html>
<head>
<style type="text/css">
body
{
margin:0px;
padding:0px;
text-align:center;
}
canvas
{
outline:0;
border:1px solid #000;
margin-top: 10px;
margin-left: auto;
margin-right: auto;
}
</style>
<script type="text/javascript">
var canvasWidth = 640;
var thisXPos = 0;
var canvasHeight = 820;
var thisYPos = 0;
var canvas = null;
var context = null;
var gLoop = null;
var rain = [];
var rainImg = "images/raindrop.gif";
var bgImg = null;
var i;
for (i = 0; i < howManyLetters; i++)
{
rain.push([Math.floor(Math.random() * canvasWidth), Math.floor(Math.random() * canvasHeight),rainImg]);
}
var DrawRain = function()
{
for (i = 0; i < 10; i++)
{
thisXPos = rain[i][0];
thisYPos = rain[i][1];
imgSrc = rain[i][2];
letterImg = new Image();
letterImg.setAtX = thisXPos;
letterImg.setAtY = thisYPos;
letterImg.onload = function()
{
context.drawImage(this, this.setAtX, this.setAtY);
}
letterImg.src = imgSrc;
}
};
var MoveRain = function(e)
{
for (i = 0; i < 10; i++)
{
if ((rain[i][1] - 5) > canvasHeight)
{
randomnumber = Math.floor(Math.random()*26);
rain[i][0] = Math.random() * canvasWidth;
rain[i][1] = 0;
rain[i][2] = rainImg;
}
else
{
rain[i][1] += e;
}
}
};
var clear = function()
{
context.beginPath();
context.rect(0, 0, canvasWidth, canvasHeight);
context.closePath();
bgImg = new Image();
bgImg.src = "images/bg.png";
bgImg.onload = function()
{
context.drawImage(bgImg,0,0);
}
}
var GameLoop = function()
{
context.save();
clear();
MoveRain(1);
DrawRain();
context.restore();
gLoop = setTimeout(GameLoop, 10);
}
function loadGame()
{
canvas = document.getElementById("gameCanvas");
context = canvas.getContext("2d");
canvas.width = canvasWidth;
canvas.height = canvasHeight;
GameLoop();
}
</script>
</head>
<body onload="loadGame();">
<canvas id="gameCanvas"></canvas>
</body>
</html>
I have distilled your example down to this:
http://jsfiddle.net/sPm3b/6/
And it works very fast in Firefox and Chrome.
So we know that the problem lies in the images.
You need to optimize how they are created and loaded. Right now, each clear() creates a new image and waits for it to load! That image should be created only once, in your loadGame() and then reused over and over.
Same exact deal with letterImg in DrawRain(). Move the creation of it to loadGame()
That will probably fix the problem.
EDIT:
like this:
At the top add:
var letterImg = new Image();
var bgImg = new Image();
Then
function loadGame()
{
canvas = document.getElementById("gameCanvas");
context = canvas.getContext("2d");
canvas.width = canvasWidth;
canvas.height = canvasHeight;
bgImg.src = "images/bg.png";
letterImg.src = "images/raindrop.gif";
// optional: wait for them to load here
GameLoop();
}
Then drawRain, for example, would look like this:
var DrawRain = function()
{
for (i = 0; i < 10; i++)
{
thisXPos = rain[i][0];
thisYPos = rain[i][1];
context.drawImage(letterImg, thisXPosX, thisYPos); // letterImg was already constructed, no need to make it again
}
};
In complement to Simon Sarris response. I've used a 'double canvas' technique to avoid screen fickering with heavy canvas.
The way it works is always have 2 version of the canvas, one in DOM, one outside, and always draw on the one which is not in DOM. I use it with a redraw queue.
here's a part of a working code
(...)
clear: function() {
//rotating on 2 canvas, one for draw (outside DOM) one for show
var self = this;
if (null == self.canvasbackup) {
var tmpcanvas = self.canvas.clone(true);
self.canvasbackup = self.canvas;
self.canvas=tmpcanvas;
} else {
var tmpcanvas = self.canvasbackup;
self.canvasbackup = self.canvas;
self.canvas=tmpcanvas;
}
self.ctx = self.canvas[0].getContext('2d');
self.ctx.clearRect( 0, 0, self.options.width, self.options.height );
jQuery.each(self.elements,function(idx,elt){
// custom function: my elements need to know which canvas they depends on
elt.reconnectCanvas(self.canvas,self.ctx);
});
},
inDOM: function() {
var self = this;
if(null==self.canvasbackup) {
//1st time need to get all things in DOM
self.canvas.appendTo(self.div);
self.div.appendTo(self.container);
} else {
// remove current shown canvas
self.connectHuman();
self.canvasbackup.remove();
// loosing some events here...
self.canvas.appendTo(self.div);
// div is already in DOM, we are in redraw
}
},
redraw: function() {
var self = this;
self.clear();
jQuery.each(self.elements,function(idx,elt){
elt.draw();
elt.enddraw();
});
self.inDOM();
}
(...)