I'm using Raphael js for the village plan where shapes are cottages on the plan. When I hover cottages they are filled with color. When I click a cottage there is a little window appears to show some info. When I leave my cursor from that window it disappears. Everything works almost like I need it except the fill of the shape. When I'm out of the text window I need the fill of the shape to disappear as well. But it stays. For some reason it works correctly only for the last cottage I've added. Other cottages are filled with color when the window is already hidden.
This is my code:
var canvas = Raphael(canvas_setup.canvas_id, canvas_setup.canvas_width, canvas_setup.canvas_height),
speed_anim_in = 400,
speed_anim_out = 150,
cottage_color_start = '#fff',
cottage_color_end = '#fff',
cottages_array = [];
for (var i = village_area.length - 1; i >= 0; i--) {
canvas.setStart();
var obj = village_area[i];
canvas.image(obj.plan_image, 0, 0, canvas_setup.canvas_width, canvas_setup.canvas_height);
for (var j = 0; j < obj.cottages.length; j++) {
var obj_cottages = obj.cottages[j],
my_path = canvas.path(obj_cottages.coords);
my_path
.attr({stroke: "none", fill: cottage_color_start, "fill-opacity": 0.8, opacity: 0, cursor: "pointer"})
.data('type', obj_cottages.type)
.data('start_color', cottage_color_start)
.data('end_color', cottage_color_end)
.data('clicked', false)
.hover(
function(){
this.attr({fill: this.data('start_color'), opacity: 1}).animate({fill: this.data('end_color')}, speed_anim_in);
},
function(){
if(!this.data('clicked')) {
this.animate({fill: this.data('start_color'), opacity: 0}, speed_anim_out);
}
}
)
.click(function (e) {
this.attr({fill: this.data('start_color'), opacity: 1});
this.data('clicked', true);
$('.cottage_info').html(
'<div>Cottage ' + this.data('type') + '</div>'
).show();
$('.cottage_info').css({'left': e.pageX-44 + 'px', 'top': e.pageY-150 + 'px'});
$('.cottage_info').mouseleave(function() {
$(this).hide();
my_path
.attr({stroke: "none", fill: cottage_color_start, "fill-opacity": 0.8, opacity: 0, cursor: "pointer"})
.data('clicked', false)
this.animate({fill: this.data('start_color'), opacity: 0}, speed_anim_out);
});
return false;
});
};
cottages_array.push(canvas.setFinish());
Could someone help me? I don't know how to make it work right. If I have only one cottage it works perfectly like I needed, but if there are more than one it ruins everything :(
Okay, my co-worker helped me out so I'm writing the solution here for a case someones has the same issue.
We've added eve even for mouseleave with needed action:
eve.on('raphael.event.mouseleave', function(){
this.animate({opacity: 0}, speed_anim_out);
this.data('clicked', false);
});
We check if the object has needed attribute and trigger raphael mouseleave event in a cycle for the array.
$('.cottage_info').mouseleave(function() {
$(this).hide();
for (var x = 0; x < cottages_array.length; x++) {
if (cottages_array[x].data('clicked')) {
eve( 'raphael.event.mouseleave', cottages_array[x] );
break;
};
}
});