Reputation: 83
I'm trying to make some kind of interactive map with KineticJS, where hovered places make other images to load. But i can't make mouse events work properly. Thing is, everything works fine but only with first mouseover attempt, and when i hover second time, mouseout trigger don't work :(
i.e. When i do "mouseout" second time, i want map part to be light blue again (n_amer image), but it remeins dark blue (n_amer_sel image).
Here is the link where you can see this bug: http://kinlibtst.elitno.net/
I would be very grateful for the help!
Code:
function loadImages(sources, callback) {
var assetDir = 'PROJECT/';
var images = {};
var loadedImages = 0;
var numImages = 0;
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 = assetDir + sources[src];
}
}
function initStage(images) {
var stage = new Kinetic.Stage({
container: 'container',
width: 900,
height: 452
});
var imagesLayer = new Kinetic.Layer();
// img vars
var n_amer = new Kinetic.Image({
image: images.n_amer,
x: 0,
y: 0
});
var n_amer_sel = new Kinetic.Image({
image: images.n_amer_sel,
x: 0,
y: 0
});
// mouse events
n_amer.on('mouseover', function() {
imagesLayer.add(n_amer_sel)
stage.draw();
});
n_amer_sel.on('mouseout', function() {
imagesLayer.remove(n_amer_sel);
stage.draw();
});
// imageBuffer for transparent pixels
n_amer.createImageBuffer(function() {
imagesLayer.drawBuffer();
});
n_amer_sel.createImageBuffer(function() {
imagesLayer.drawBuffer();
});
// add to stage
imagesLayer.add(n_amer);
stage.add(imagesLayer);
}
window.onload = function() {
var sources = {
n_amer: 'N-Amer.png',
n_amer_sel: 'N-Amer_sel.png'
};
loadImages(sources, initStage);
};
Upvotes: 4
Views: 1956
Reputation: 156
Instead of using a new image object, change the image on the existing object:
function loadImages(sources, callback) {
var assetDir = 'http://kinlibtst.elitno.net/PROJECT/';
var images = {};
var loadedImages = 0;
var numImages = 0;
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 = assetDir + sources[src];
}
}
function initStage(images) {
var stage = new Kinetic.Stage({
container: 'container',
width: 900,
height: 1000
});
var imagesLayer = new Kinetic.Layer();
// img vars
var n_amer = new Kinetic.Image({
image: images.n_amer,
x: 0,
y: 0
});
// mouse events
n_amer.on('mouseover', function() {
this.setImage(images.n_amer_sel);
stage.draw();
});
n_amer.on('mouseout', function() {
this.setImage(images.n_amer);
stage.draw();
});
// imageBuffer for transparent pixels
n_amer.createImageBuffer(function() {
imagesLayer.drawBuffer();
});
// add to stage
imagesLayer.add(n_amer);
stage.add(imagesLayer);
}
window.onload = function() {
var sources = {
n_amer: 'N-Amer.png',
n_amer_sel: 'N-Amer_sel.png'
};
loadImages(sources, initStage);
};
Upvotes: 2
Reputation: 3502
That is a really strange behaviour... maybe something to do with the imagebuffers... you may try to redraw the buffers inside the listeners.
In any case, I'd suggest to add both images and use show()
and hide()
. This operations are usually faster than adding/removing childs.
var n_amer_sel = new Kinetic.Image({ image: images.n_amer_sel, x: 0, y: 0, visible: false });
n_amer.on('mouseover', function() {
n_amer_sel.show();
stage.draw();
});
n_amer_sel.on('mouseout', function() {
n_amer_sel.hide();
stage.draw();
});
// add to stage
imagesLayer.add(n_amer);
imagesLayer.add(n_amer_sel);
stage.add(imagesLayer);
You can see it working (aside from the tainted canvas issue) in this fiddle
Upvotes: 1
Reputation: 296
Try adding both handlers on the unselected image, for example:
n_amer.on('mouseover', function() {
imagesLayer.add(n_amer_sel)
stage.draw();
});
n_amer.on('mouseout', function() {
imagesLayer.remove(n_amer_sel);
stage.draw();
});
Upvotes: 1