nuclearpeace
nuclearpeace

Reputation: 83

KineticJS mouse event issue

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

Answers (3)

Stripps
Stripps

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

jbalsas
jbalsas

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

mdellanoce
mdellanoce

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

Related Questions