How to remove bitmap image on click from canvas - javascript

I am using createjs as my framework. I've placed a Bitmap on the canvas and I created a function to try and remove it but I keep getting an error message in the console that image is not defined. This is what my code looks like:
// onload=init() called in html doc
function init(){
var canvas = new createjs.Stage("canvas");
// Add image to canvas
image = new createjs.Bitmap("image.png");
image.x = 200;
image.y = 180;
image.scaleX = 0.35;
image.scaleY = 0.35;
canvas.addChild(image);
image.addEventListener('click', pop);
canvas.update();
}
//remove image from canvas
function pop() {
console.log('pop');
canvas.removeChild(image);
}
When I click on it, I get the console message "pop" followed by the error I mentioned above. I've tried moving the function inside init but I appear to get the same problem.

Make image as global variable, so that it can be accessed by all the functions in your case function pop.
var image;// defining 'image' variable as global
function init(){
var canvas = new createjs.Stage("canvas");
// Add image to canvas
image = new createjs.Bitmap("image.png");
image.x = 200;
image.y = 180;
image.scaleX = 0.35;
image.scaleY = 0.35;
canvas.addChild(image);
image.addEventListener('click', pop);
canvas.update();
}
//remove image from canvas
function pop() {
console.log('pop');
canvas.removeChild(image);
}

This is a scope issue. You defined image inside your init function, so it is not accessible on the pop method.
There are two easy fixes. Either move the var image outside of the init function, or use the click target instead.
var image;
function init() {
init = new createjs.Bitmap();
// etc
}
// OR
function pop(event) {
stage.removeChild(event.target);
}
Scope is really important to understand when building JavaScript applications, so I suggest getting to know it a little better :)
Cheers,

Related

Bitmap image not showing up in canvas

I need some direction here as I'm not clear on what I'm doing wrong. All I'm trying to do is a load a bitmap in the center of the canvas but it's not showing up. My file path is correct and I don't see what I might have coded incorrectly, where am I going wrong?
var canvas, stage, centerX, centerY;
function init() {
'use strict';
canvas = document.getElementById("easel");
stage = new createjs.Stage(canvas);
centerX = canvas.width / 2;
centerY = canvas.height / 2;
var ship = new createjs.Bitmap("../images/millenium.png"),
shipCenterX = ship.width / 2,
shipCenterY = ship.height / 2;
ship.x = centerX;
ship.y = centerY;
ship.regX = shipCenterX;
ship.regY = shipCenterY;
stage.addChild(ship);
stage.update();
}
The way this library appears to handle drawing to the canvas is by calling stage.update() which they recommend attaching to their "tick" event (e.g. http://www.createjs.com/docs/easeljs/classes/Stage.html)
Basically, we need to keep continually redrawing the canvas, and createjs gives us a method to do that, like so:
createjs.Ticker.addEventListener("tick", handleTick);
function handleTick(event) {
stage.update();
}
However, since you haven't made your stage globally accessible, I tweaked your init function slightly so that we can access stage by returning it at the end of the function. Thus you can set stage in the global scope to the result of the function:
var stage = init();
And handleTick will use that stage by default. However if you're thinking of reusing your objects outside of your init() function, you may want to consider passing them to the init function or keeping their initial data structure outside of the init function to make them easier to access.
https://jsfiddle.net/jpgw1oka/
And make sure you are loading the CreateJS library: https://code.createjs.com/createjs-2015.11.26.min.js.
Remove the 'use strict'.
And make sure you are declaring your variables and function calls inside a window.onload event listener.
E.g.
var canvas, stage;
function init() {
canvas = document.getElementById("easel");
stage = new createjs.Stage(canvas);
var ship = new createjs.Bitmap("../images/millenium.png");
ship.x = Math.floor(stage.canvas.width * 0.5);
ship.y = Math.florr(stage.canvas.height * 0.5);
ship.regX = Math.floor(ship.image.width * 0.5);
ship.regY = Math.floor(ship.image.height * 0.5);
stage.addChild(ship);
stage.update();
}

removeChild() not working using easeljs

I am using easeljs to create a stage and then i am putting tiles on the stage on random locations. When the user clicks on a tile, the tile must be removed from the stage.
There are two problems that i am facing. First was that the mouse event was not working. The code "tile.onPress = (tileOnPress).bind(this);" so i used the addEventListener method instead. Now although the function is being called as i am getting the output on the console, the tile is not being removed from the stage.
Here is the code:
c99.Game = (function(){
function Count99Game() {
console.log("Count 99 game starts");
this.canvas = document.getElementById('game-canvas');
this.stage = new createjs.Stage(this.canvas);
var totalTiles = 10;
var tileOnPress = function(event) {
console.log("Pressed");
this.stage.removeChild(event.target);
this.stage.update();
};
for (var i = totalTiles; i > 0; i--) {
var tile = new c99.Tile(i);
this.stage.addChild(tile);
tile.x = Math.random()*(this.canvas.width - tile.width);
tile.y = Math.random()*(this.canvas.height - tile.height);
//tile.onPress = (tileOnPress).bind(this);
tile.addEventListener("click", tileOnPress.bind(this));
}
this.stage.update();
}
return Count99Game;
})();
I would appreciate if someone could tell me why "tile.onPress = (tileOnPress).bind(this);" isn't working and also what changes need to be done in the tileOnPress function so that the tile that is pressed can be removed from the stage.
The complete code can be found at https://github.com/ZANTGames/count99/blob/master/js/count99-game.js
Try this
this.stage.removeChild(event.target.parent)
This is because event.target is shape and its parent is tile and basically you want to remove the tile so this is working
For your future reference I have found it from this documentation
http://www.createjs.com/docs/easeljs/classes/Stage.html

Html5 canvas not drawing

I have a problem with an object not drawing it's image. I've set the onload property of the image to the draw function..
//ctor
function Sprite(someargs,pContext)
this.setContext(pContext); //This could be the problem?
this.setX(px);
this.setY(py);
this.setTexture(pImagePath);
//I run this in the constructor
Sprite.prototype.setTexture = function(pImagePath){
this.texture = new Image();
this.texture.onload = this.draw();
this.texture.src = pImagePath;
};
Sprite.prototype.draw = function(){
this.getContext().drawImage(this.texture,this.getX(),this.getY(),100,100);
};
Sprite.prototype.setContext = function(pContext){
this.mContext = pContext;
};
No errors at runtime, image not drawn onto canvas though.
I'v put alerts in all the above methods, all of which are being executed.
Anyone got any ideas as to why it's not drawing?
Cheers
this.texture.onload = this.draw();
you are not setting onload to the draw function but to the result of draw function
this.texture.onload = this.draw;
also wouldn't be good because you will lose your context of this in here.
this inside of draw function will point to texture instead of Sprite
you need to bind the function draw to this (which is the Sprite at the moment) and pass it to onload
this.texture.onload = this.draw.bind(this);
or:
var that = this;
this.texture.onload = function() { that.draw(); }

Load stage with all elements in kineticjs

I try load my simple stage from json file, I load images but it's all in one layer, and image is not in group, so resize not working, i don't know how i should to load all elements with layers and group;
This is my function to load(it's only image for now)
function load(loadStage) {
counter = 2;
activeStage = stage;
stage = Kinetic.Node.create(loadStage,'right');
var background = stage.get('.background');
var backgroundImage = stage.get('.backgroundImage');
var clipartsImage = stage.get('.image');
var text = stage.get('.text');
console.log(stage.getChildren());
for(i=0;i<clipartsImage.length;i++){
counter++;
(function() {
var image = clipartsImage[i];
groups[counter] = image.parent.get;
//console.log(image);
var imageObj = new Image();
imageObj.onload = function() {
imageObj.src = image.attrs.src;
console.log(image);
image.setImage(imageObj);
image.on('mouseover', function() {
document.body.style.cursor = 'pointer';
});
image.on('mouseout', function() {
document.body.style.cursor = 'default';
});
image.on('click', function(evt) {
this.children[0].children[3].show();
var shape = evt.targetNode;
this.moveToTop();
active = layers[shape.getId()];
objectId = shape.getId();
});
image.getLayer().draw;
};
imageObj.src = image.attrs.src;
})();
stage.draw();
}
stage.draw();
}
And this is my json file, http://wklej.org/id/1105520/ this is middle stage. I'll keep trying, but if someone has had a similar problem and solved it, I would be grateful for your help :)
1)
What is going on with your JSON file? the base64 string has blown up into a million lines...
For starters, KineticJS.Layer cannot have a layer as a child. References:
https://github.com/ericdrowell/KineticJS/wiki/Change-Log#455-july-28-2013
new add() validation. An error is thrown if invalid children are added to a parent, for example, when adding a layer to another layer.
https://github.com/ericdrowell/KineticJS/wiki
KineticJS event not fired for child of a grouped layer
Inside your JSON file, you have tons of layers layered within each other, this is definitely going to cause a problem. Actually it looks like you have a layer for EACH group that you have! This is completely wrong KineticJS structure.
You should do some research on how and when to use layers and groups, here are some references:
What are the differences between group and layer in KineticJs
https://github.com/ericdrowell/KineticJS/wiki (again, the data structure hierarchy for KineticJS)
2)
No need to call stage.draw() twice.
3)
JSON is a data format, it only stores object attributes. This means it does not store any references to events attached to objects.
What this means is that when you load your JSON string, you'll have to rebind the updateAnchor function to all your anchors again. (Similar to how you are rebinding click function to your images onload)
You'll have to do something like this inside your load function, after you create the stage with your JSON file:
var children = layer.getChildren(); //Use the layer that has all your groups with images/anchors. *REMEMBER you can't layers within layers!
for (var i=0; i<children.length; i++) {
//If name starts with 'anchor'
if (children.getName().indexOf('anchor') !== -1) {
children[i].on('dragmove', function(evt) {
updateAnchor(this);
layer.draw();
});
}
}

HTML5 Canvas: Create a Image.onload() function via Image.prototype

So, my goal is to have a simple function that allows me to just type something like:
var map = new Image();
map.onloadDraw();
map.src = "images/" + worldmapCanvasShapeImage;
which will automatically refresh the canvas when loaded.
This is what I already came up with:
Image.prototype.onloadDraw = function(){
this.onload() = function() {
drawMap();
drawMarkers();
drawArticles();
}
}
It doesn't seem to work, it's probably a small error but I can't find a lot of information about it.
Image.prototype.onloadDraw = function(){
this.onload = function() {
drawMap();
drawMarkers();
drawArticles();
}
}
Skip the pair of parens after onload. You are defining it, not invoking it. :)

Categories