Search code examples
javascriptjqueryraphael

Hover function not working on Rapael.js objects from an array


Using Raphael.js 2.1.0 I am trying to create circle objects on the Canvas from an array of coordinates by using this code:

var map = Raphael('canvas', 500, 500);
var coords = [ [150,50], [20,85], [350,95] ];
var circle;
for(var i = 0; i < coords.length; i++){
  circle = map.circle(coords[i][0], coords[i][1], 20);
  circle.toFront();
  circle.attr({
      fill: '#98ED00',
      translation: "4,4",
      stroke: '#FFF',
      'stroke-width': 4,
      opacity: 1,
  });
}

  circle.hover(
  function () {
      circle.animate({
          fill: 'red',
          opacity: 1,
          map: 30,
              'stroke-width': 4
      }, 300);
  }, function () {
      circle.animate({
           fill: '#98ED00',
          opacity: 1,
              'stroke-width': 4,
          map: 20
      }, 300);

  });

but the hover function ONLY functioning on the LAST created object! How can I fix this issue?


Solution

  • The problem is which circle are you referencing when you call 'circle.glow()', as you have 3 ?

    The circle var gets overwritten each time, so the handler just gets attached to the last one.

    To get around this, there's a few different ways. You could create an array for the circles and add a hover handler to each one. Or you could create a closure which is the example below. It depends if you need to do anything with it later that may affect the solution...

    var map = Raphael('canvas', 500, 500);
    var coords = [ [150,50], [20,85], [350,95] ];
    
    for(var i = 0; i < coords.length; i++){
        (function() {
          var circle;
          circle = map.circle(coords[i][0], coords[i][1], 20);
          circle.toFront();
          circle.attr({
             fill: '#98ED00',
              translation: "4,4",
              stroke: '#FFF',
             'stroke-width': 4,
             opacity: 1,
         });
         circle.hover(
           function () {
             circle.animate({
                  fill: 'red',
                  opacity: 1,
                  map: 30,
                  'stroke-width': 4
              }, 300)
             }, function () {
               circle.animate({
                   fill: '#98ED00',
                   opacity: 1,
                  'stroke-width': 4,
                  map: 20
              }, 300)
             }    );
        })();
    };
    

    http://jsfiddle.net/HVh9E/2/