how to load bitmap using easeljs? - javascript

I am trying to load bitmap using easeljs but its not working, please help me.
function init() {
canvas = document.getElementById("testCanvas");
context = canvas.getContext("2d");
stage = new createjs.Stage(canvas);
var image = new Image();
image.src = "assets/puli.png";
var container = new createjs.Container();
stage.addChild(container);
bitmap = new createjs.Bitmap(image);
container.addChild(bitmap);
createjs.Ticker.addEventListener("tick", tick);
}
function tick(event) {
if (update) {
update = false; // only update once
stage.update(event);
}
}

You have to load your images using the LoadQueue Class form EaselJs:
take a look at this--> http://www.createjs.com/Docs/PreloadJS/classes/LoadQueue.html
var queue = new createjs.LoadQueue(true);
queue.addEventListener("fileload",onFileLoaded.bind(this));
var manifest = getManifest();
queue.loadManifest(manifest);
onFileLoaded = function(evt)
{
var item = evt.item;
var type = evt.type;
}
getManifest = function()
{
var manifest = [
{src:"/images/yourimage.png", id:"myimage"}
];
return manifest;
}
//create images
var myimage = new createjs.Bitmap(images.myimage);

#CMS is right that preloading the content helps -- the issue you are seeing is likely that the image is not loaded when you update the stage, and it is only updating once.
You can use your approach in the original question, as long as you update the stage once the image is loaded. You can do this simply by waiting for a load event from the image. Something like this:
image.onload = function() {
update = true;
// OR
stage.update();
}
Using PreloadJS is a better approach for a larger app, since it gives you way more control of when assets are loaded, etc -- but its not necessary to get your code working.

I feel your pain.
Try this - I put the addChild and stage update in the onload event.
Works for me.
var stage, rect, img, greenRect;
function init() {
stage = new createjs.Stage("demoCanvas");
rect = new createjs.Shape();
img = new Image();
img.src = 'green.jpg';
img.onload = handleImageLoad;
}
function handleImageLoad(event) {
greenRect = new createjs.Bitmap(img);
stage.addChild(greenRect);
greenRect.x = 100;
greenRect.y = 100;
stage.update();
}

I got this code from YouTube, and it works
<!DOCTYPE html>
<html>
<head>
<script src="easeljs.js"></script> <!==load the EaselJS library==>
<script>
//this sample displays a bitmap file
var stage, img, map; //declare global variables
function init() {
//this function is registered in the html body tag
stage = new createjs.Stage("demoCanvas"); //create a Stage object to work with the canvas element
img = new Image(); //create an Image object, then set its source property
img.src="my_photo.jpg";
img.onload = handleImageLoad //register a handler for the onLoad event
}
function handleImageLoad(event) {
//this function runs when the onload event completes
map = new createjs.Bitmap(img); //create a Bitmap object, then set properties
map.x =50;
map.y =50;
stage.addChild(map); //add the Bitmap object as a child of the stage, then update the stage
stage.update();
}
</script>
</head>
<body onload="init();">
<!==add a canvas tag==>
<canvas id="demoCanvas" width="640" height="480"></canvas>
</body>
</html>

This code works when the PreloadJS library is sourced
<!DOCTYPE html>
<html>
<head>
<script src="EaselJS/lib/easeljs.js"></script> <!==load the EaselJS library==>
<script src="PreloadJS/lib/preloadjs.js"></script> <!==load the PreloadJS library==>
<script>
//this sample displays a bitmap file
var stage; //declare global variables
var img;
var map;
var queue;
function init() {
//this function is registered in the html body tag
stage = new createjs.Stage("canvas"); //create a Stage object to work with the canvas element
img = new Image(); //create an Image object, then set its source property
img.onload = handleImageLoad //register a handler for the onLoad event
queue = new createjs.LoadQueue();
queue.addEventListener('complete', handleImageLoad);
queue.loadManifest([
id="img", img.src="my_photo.jpg"
])
}
function handleImageLoad(event) {
//this function runs when the onload event completes
map = new createjs.Bitmap(img); //create a Bitmap object, then set properties
map.x = 0;
map.y = 0;
stage.addChild(map); //add the Bitmap object as a child of the stage, then update the stage
stage.update();
}
</script>
</head>
<body onload="init();">
<!==add a canvas tag==>
<canvas id="canvas" width="640" height="480"></canvas>
</body>
</html>

I recomend you AngularJS.
You have to call a function on HTML:
<body ng-init="initCanvas()">
<center>
<canvas id="canvas" width="602" height="447"></canvas>
</center>
</body>
In JavaScript:
var stage, image;
var initCanvas = function() {
stage = new createjs.Stage("canvas");
image = new createjs.Bitmap("img/image.png");
image.x = 0; image.y = 0; image.visible = true;
stage.addChild(image);
stage.update();
};

Related

my images wont load at the first time click [duplicate]

This is my easel js function, it draws a red circle and an image, however the circle is showing but the image isn't.
function Start() {
var stage = new createjs.Stage("DogeCanvas");
var dog = new createjs.Bitmap("doge.jpg");
var circle = new createjs.Shape();
circle.graphics.beginFill("red").drawCircle(0, 0, 50);
circle.x = 100;
circle.y = 100;
dog.x=100;
dog.y=100;
stage.addChild(circle, dog);
stage.update();
}
And this is the html file
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<script src="http://code.createjs.com/easeljs-0.7.0.min.js"></script>
<script src="Doge.js"></script>
</head>
<body bgcolor="#C7C7C7" onload="Start();">
<canvas id="DogeCanvas" width="480" height="320"></canvas>
</body>
</html>
Why? help please, seems like in everyones else code this works but why this isn't working for me?
The image is likely not loaded yet.
You can add a Ticker to the stage to constantly update it (which most applications do, since there is other things changing over time)
Example:
createjs.Ticker.on("tick", stage);
// OR
createjs.Ticker.addEventListener("tick", stage);
// OR
createjs.Ticker.on("tick", tick);
function tick(event) {
// Other stuff
stage.update(event);
}
Listen for the onload of the image, and update the stage again
Example:
var bmp = new createjs.Bitmap("path/to/image.jpg");
bmp.image.onload = function() {
stage.update();
}
Preload the image with something like PreloadJS before you draw it to the stage. This is a better solution for a larger app with more assets.
Example:
var queue = new createjs.LoadQueue();
queue.on("complete", function(event) {
var image = queue.getResult("image");
var bmp = new createjs.Bitmap(image);
// Do stuff with bitmap
});
queue.loadFile({src:"path/to/img.jpg", id:"image"});

HTML5/Javascript Image loading method & passing to variable

I have some code for loading images.
var assets = {
total:0,
success:0,
error:0
};
var stillLoading = true;
var img = {};
function LoadImage(name, path){
var toLoad = new Image();
toLoad.src = path;
assets.total++;
toLoad.addEventListener("load", function(){
assets.success++;
console.log(name + " loaded.");
img[name] = toLoad;
}, false);
toLoad.addEventListener("error", function(){
assets.error++;
}, false);
};
function Loading(){
if (assets.success == assets.total){
if (stillLoading){
console.log("All assets loaded. Starting game.");
};
stillLoading = false;
return false;
}else{
stillLoading = true;
return true;
};
};
May still be inefficient, and ugly since I'm new to practicing javascript, open to suggestions. It loads the image and tells the main program when all the assets have finished loading through the function Loading(), and then adds the image to the object img.
I've been using this for a while now for my images, and it works.
For example, if I did.
LoadImage("Car", "imageOfCar.png");
ctx.drawImage(img.Car, 0, 0);
this would draw the image just fine to the canvas.
However, when I assign another variable the image, which for various reasons I want to do, such as assigning images to objects. e.g.
var secondCar = img.Car
then try to draw it.
ctx.drawImage(secondCar, 0, 0);
I get this error.
Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(HTMLImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap)'
If it works for the initial variable, it should act the same way towards another variable that has just been assigned the exact same thing. So why is it am I getting this error?
If I was to load the image the typical way that doesn't check if it's finished loading.
img.Car = new Image();
img.Car.src = "imageOfCar.png";
secondCar = img.Car;
ctx.drawImage(secondCar);
This would work.
The behaviour here is a bit confusing, could someone explain to me what is happening, and perhaps suggest a way to fix it?
EDIT: Just to clarify.
This is the html file, called index.html.
<!DOCTYPE html>
<head>
<title>HTML5 Game Base</title>
<link rel = "stylesheet" type = "text/css" href = "styles.css">
</head>
<body>
<canvas id="screen" width="270" height="480" style="border:1px solid #000000;"></canvas>
<script src = "script.js"></script>
</body>
</html>
The canvas is set up as screen. All the javascript code I've displayed above takes place within script.js which is called in index.html.
This is how screen is called within the script.js.
var canvas = document.getElementById("screen");
var ctx = canvas.getContext("2d");
This is what ctx.drawImage() is referencing.
I realize this won't be the most helpful answer, but I tinkered around with your code a little. This is what I used:
<!DOCTYPE html>
<head>
<title>HTML5 Game Base</title>
</head>
<body>
<canvas id="screen" width="270" height="480" style="border:1px solid #000000;"></canvas>
<script>
var stillLoading = true;
var img = {};
var canvas = document.getElementById("screen");
var ctx = canvas.getContext("2d");
assets = {};
assets.total = 0;
function LoadImage(name, path){
var toLoad = new Image();
toLoad.src = path;
assets.total++;
toLoad.addEventListener("load", function(){
//assets.success++;
console.log(name + " loaded.");
img[name] = toLoad;
}, false);
toLoad.addEventListener("error", function(){
assets.error++;
}, false);
}
</script>
</body>
</html>
Then in Chrome's console I typed
LoadImage("Car", "map.png");
LoadImage("un", "Untitled.png");
ctx.drawImage(img.Car, 0, 0);
ctx.drawImage(img.un, 0, 0);
and get the expected result of images loading in the canvas. Even when assigning one of the img images to a new variable, this works as expected.
var second = img.Car
ctx.drawImage(second, 0, 0)
It appears everything is working fine when run manually, so my guess would be timing. When are you running these commands? Are they in the js file or from the console?
It would appear your LoadImage function is fine. Sorry this is not super helpful, but hopefully will help you rule out where not to look for the problem.
One approach could be to utilize Promise , as load event of new Image is asynchronous secondCar could be undefined when used as parameter within setInterval, e.g., load event of img may not be complete when var secondCar = img.Car applied after call to LoadImage; also added variable reference for setInterval for ability to call clearInterval() if needed
var canvas = document.getElementById("screen");
var ctx = canvas.getContext("2d");
var interval = null;
var assets = {
total: 0,
success: 0,
error: 0
};
var stillLoading = true;
var img = {};
function LoadImage(name, path) {
return new Promise(function(resolve, reject) {
var toLoad = new Image();
assets.total++;
toLoad.addEventListener("load", function() {
assets.success++;
console.log(name + " loaded.");
img[name] = toLoad;
// resolve `img` , `assets` object
resolve([img, assets])
}, false);
toLoad.addEventListener("error", function() {
assets.error++;
reject(assets)
}, false);
toLoad.src = path;
})
};
function Loading() {
if (assets.success == assets.total) {
if (stillLoading) {
console.log("All assets loaded. Starting game.");
};
stillLoading = false;
return false;
} else {
stillLoading = true;
return true;
};
};
var promise = LoadImage("Car", "http://pngimg.com/upload/audi_PNG1736.png");
promise.then(function(data) {
// `data` : array containing `img` , `assets` objects
console.log(data);
var secondCar = data[0].Car;
interval = setInterval(function() {
if (!(Loading())) {
ctx.drawImage(secondCar, 0, 0);
};
}, 1000 / 60);
});
<canvas id="screen" width="1000" height="700" style="border:1px solid #000000;"></canvas>
Solved. Turns out it was a timing issue. In the example I gave, when secondCar is assigned img.Car, img.Car had not yet loaded.
Instead I created a new function called Initialise(), and called it from within Loading(). So from now on I would just have to initialise all my variables that may require images from within Initialise(). This way, variables can only be assigned images after they've loaded.
New Code:
var canvas = document.getElementById("screen");
var ctx = canvas.getContext("2d");
var assets = {
total:0,
success:0,
error:0
};
var stillLoading = true;
var img = {};
function LoadImage(name, path){
var toLoad = new Image();
toLoad.src = path;
assets.total++;
toLoad.addEventListener("load", function(){
assets.success++;
console.log(name + " loaded.");
img[name] = toLoad;
}, false);
toLoad.addEventListener("error", function(){
assets.error++;
}, false);
};
function Loading(){
if (assets.success == assets.total){
if (stillLoading){
console.log("All assets loaded. Starting game.");
Initialise();
};
stillLoading = false;
return false;
}else{
stillLoading = true;
return true;
};
};
LoadImage("Car", "http://pngimg.com/upload/audi_PNG1736.png");
function Initialise(){
window.secondCar = img.Car;
};
setInterval(function(){
if (!(Loading())) ctx.drawImage(secondCar, 0, 0);
}, 1000/60);
Works now, thanks for the help although I ended up solving it myself. I would still appreciate any tips on how to improve it. Or knowing that I'm new to javascript, any nitpicks to help me conform to javascript conventions.

Javascript - image displaying over text

The code runs with no bugs, but a problem I am having is because the ".onLoad" function makes it display after the text has already been displayed on the screen. The problem I am facing is that I would like if the text (Loading graphics and loading variables) displayed over the image.
The code is here:
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml1-transitional.dtd">
<html>
<body>
<canvas id="ctx" width="800" height="500" style="border:1px solid #d3d3d3;"></canvas>
<script>
var ctx = document.getElementById("ctx").getContext("2d");
var canvas = document.getElementById('ctx');
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function(){
context.drawImage(imageObj,0,0);
};
imageObj.src = 'img/startscreen.jpg';
ctx.fillText('Loading variables.',50,50);
character=new Object();
character.hp=1;
character.name=null;
ctx.fillText('Loading graphics..',50,100);
</script>
</body>
</html>
I would layer the background image on its own canvas positioned behind the text layer. Then you can clear and update the text layer without having to re-draw the background image.
#background,#overlay {
position: absolute;
}
<canvas id="background"></canvas>
<canvas id="overlay"></canvas>
var can = document.getElementById('overlay'),
bg_can = document.getElementById('background'),
height = can.height = bg_can.height = 500,
width = can.width = bg_can.width = 500,
ctx = can.getContext('2d'),
bctx = bg_can.getContext('2d');
var img = new Image();
img.src = ' ... ';
img.onload = init;
function init() {
// draw the background
bctx.drawImage(this, 0, 0);
// draw your initial text
updateText('hello world');
// other stuff that is going to take time
updateText('done');
}
function updateText(msg) {
ctx.clearRect(0, 0, width, height);
ctx.fillText(msg, 50, 100);
}
This isn't very well thought out (my code example) for re-use purposes.. but I don't know much about your other needs :) hope this helps.
If you want to overlay String on image, why don you use image as backGround imange and place text over it??
Css
try in css
#ctx{
background-image:url('img/startscreen.jpg');}
remove image source in script or insert css in script itself
Css in scripts
ctx.style.backgroundImage=url('img/startscreen.jpg');
I called the function for the text to be displayed after the background has:
imageObj.src = 'img/startscreen.jpg';
imageObj.onload = function(){
context.drawImage(imageObj,0,0);
init()
};
function init(){
ctx.fillText('Loading variables.',50,50);
character=new Object();
character.hp=1;
character.name=null;
ctx.fillText('Loading graphics..',50,100);
}

How to detect onload event of image which was loaded in custom object

I am creating a sample program to display an image on canvas but would like to enclose actual drawing process into a custom object.
The following code won't show the image as pictFrame.img.onload can't catch onload event of image file. Chrome console says "TypeError: Cannot set property 'onload' of undefined" with the expression although it can correctly evaluate pictFrame.img.src or pictFrame.img.height.
How should I detect image loading which is being initiated when the object is created?
<html>
<head>
<script type="text/javascript">
function pictFrame(context, imgsrc, pos_x, pos_y, size_x, size_y)
{
this.context = context;
this.img = new Image();
this.img.src = imgsrc;
this.pos_x = pos_x;
this.pos_y = pos_y;
this.size_x = size_x;
this.size_y = size_y;
this.draw = function() {
this.context.drawImage(this.img, this.pos_x, this.pos_y, this.size_x, this.size_y);
};
}
// These variables must live while the page is being displayed.
// Therefore, they can't be defined within window.onload function.
var canvas;
var context;
var pictFrame;
window.onload = function()
{
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
pictFrame = new pictFrame(context, "darwin.jpg", 10, 10, 200, 200);
};
pictFrame.img.onload = function() // Can't catch onload event
{
pictFrame.draw();
}
</script>
</head>
<body>
<canvas id="canvas" width="500" height="300"></canvas>
</body>
</html>
Its because you are calling before pictFrame gets instantiated. You get this in chrome,
Uncaught TypeError: Cannot set property 'onload' of undefined
do like below instead,
window.onload = function()
{
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
pictFrame = new pictFrame(context, "images/bahu.png", 10, 10, 200, 200);
console.log("called");
pictFrame.img.onload = function()
{
console.log(" onload called");
pictFrame.draw();
}
};
I mean, do onload call after window.onload has finished instead of calling it before.

Easel.js: Browser compatibility when placing an image within a container and adding mouse interactions

I'm going to start this question off by saying that this is 100% working in Firefox (v21.0). For some reason it's not working in Google Chrome (v27.0.1453.94m). It also doesn't work in IE10.
Here is the JavaScript code I'm having issues with:
function canvasDrawBackground(value){
console.log(value);
stage.removeChild(background);
var temp = new createjs.Bitmap("images/bg_" + value +".jpg");
background = new createjs.Container();
background.x = background.y = 0;
background.addChild(temp);
stage.addChild(background);
background.addEventListener("mousedown", function(evt) {
var offset = {x:evt.target.x-evt.stageX, y:evt.target.y-evt.stageY};
evt.addEventListener("mousemove",function(ev) {
ev.target.x = ev.stageX+offset.x;
ev.target.y = ev.stageY+offset.y;
stage.update();
});
});
stage.update();
}
So, in Firefox the above code works, as in the image is added to the canvas and you can drag it around.
In Chrome / IE10 nothing happens - or more simply nothing appears on the canvas. I think the issue is in regards to when I add the image into the container, as I can place other items into the container and it works.
I am using http://code.createjs.com/easeljs-0.6.1.min.js and this code is based off of the "drag" tutorial. Here's the code from the tutorial:
<!DOCTYPE html>
<html>
<head>
<title>EaselJS demo: Dragging</title>
<link href="../../shared/demo.css" rel="stylesheet" type="text/css">
<script src="http://code.createjs.com/easeljs-0.6.0.min.js"></script>
<script>
var stage, output;
function init() {
stage = new createjs.Stage("demoCanvas");
// this lets our drag continue to track the mouse even when it leaves the canvas:
// play with commenting this out to see the difference.
stage.mouseMoveOutside = true;
var circle = new createjs.Shape();
circle.graphics.beginFill("red").drawCircle(0, 0, 50);
var label = new createjs.Text("drag me", "bold 14px Arial", "#FFFFFF");
label.textAlign = "center";
label.y = -7;
var dragger = new createjs.Container();
dragger.x = dragger.y = 100;
dragger.addChild(circle, label);
stage.addChild(dragger);
dragger.addEventListener("mousedown", function(evt) {
var offset = {x:evt.target.x-evt.stageX, y:evt.target.y-evt.stageY};
// add a handler to the event object's onMouseMove callback
// this will be active until the user releases the mouse button:
evt.addEventListener("mousemove",function(ev) {
ev.target.x = ev.stageX+offset.x;
ev.target.y = ev.stageY+offset.y;
stage.update();
});
});
stage.update();
}
</script>
</head>
<body onLoad="init();">
<canvas id="demoCanvas" width="500" height="200">
alternate content
</canvas>
</body>
</html>
To simulate my issue, change "var circle = new createjs.Shape();" into a bitmap / image, createjs.Bitmap("images/bg_" + value +".jpg");. It then doesn't render.
Any help is greatly appreciated! Hopefully I'm just doing it wrong. :P
This is probably because the image is not loaded. If you only update the stage after creating it, the image may not display. I would recommend adding a callback to the image to update the stage after its loaded.
// Simple approach. May not work depending on the scope of the stage.
var temp = new createjs.Bitmap("images/bg_" + value +".jpg");
temp.image.onload = function() { stage.update(); }
It also may make sense to preload the images you intend to use.

Categories

Resources