I have a set that only contains a rectangle.
var hoverTrigger = this.paper.set();
var outline = this.paper.rect();
outline.attr({
...
hoverTrigger.push(outline)
this.sprite.push(hoverTrigger);
Upon hover, the rectangle is supposed to expand, and some links are added to it, and upon mouse off, the links disappear and the rectangle becomes small again.
hoverTrigger.hover(function () {
var link = this.paper.text();
hoverTrigger.push(link);
outline.animate({
...
}, function() {
link.remove();
outline.animate({
...
});
However, it seems like the hover function is being applied to each item in the set individually, and not the whole set, because when you go to mouse over a link, the hover off function fires and the link disappears. Sometimes the box gets hover on and hover off events in quick succession and spazzes.
Is there a way to apply a hover to a set of things, so that mousing between two things in the set doesn't trigger hover off?
Having faced this limitation myself recently, I decided to write a small extension to Raphael called hoverInBounds
that resolves it.
Simply, once the mouse enters the element we keep track of when it actually moves outside its bounds - executing the hover out function then, not before.
Demo: http://jsfiddle.net/amustill/Bh276/1
Raphael.el.hoverInBounds = function(inFunc, outFunc) {
var inBounds = false;
// Mouseover function. Only execute if `inBounds` is false.
this.mouseover(function() {
if (!inBounds) {
inBounds = true;
inFunc.call(this);
}
});
// Mouseout function
this.mouseout(function(e) {
var x = e.offsetX || e.clientX,
y = e.offsetY || e.clientY;
// Return `false` if we're still inside the element's bounds
if (this.isPointInside(x, y)) return false;
inBounds = false;
outFunc.call(this);
});
return this;
}
Place the above block of code before you create your Raphael paper object.
I hit on this problem before. I found 2 solutions.
Create a rectangle over other elements with opacity set to 0
var paper = new Raphael( 0, 0, 100, 100 );
var rect = paper.rect( 0, 0, 100, 100 ).attr({ opacity: 0 });
rect.hover( func_in, func_out );
This only works for elements that have 1 overall action like click.
The other option is to cancel the hover function when hovering over a set of elements
var funcOutTimer;
set.hover( function( ) {
if( funcOutTimer ) { // Hovered into this element in less than 100 milliseconds => cancel
window.clearTimeout( funcOutTimer);
} else {
// do stuff
}
},
function( ) {
funcOutTimer = setTimeout( function( ) {
// do stuff
}, 100 ); // wait for 100 milliseconds before executing hover out function
});
Basically the hover in function is only executed when first entering a set of elements for the first time and the hover out function will only execute once when finally the element you have hovered into is not part of that set.
I found that this works with the following
myCircleElement.hover (
function(e) { myTextElement.animate({opacity:1}, 800); },
function(e) {
var x = e.layerX || e.x,
y = e.layerY || e.y;
// Return `false` if we're still inside the element's bounds
if (this.isPointInside(x, y)) return false;
// otherwise do something here.. eg below
myTextElement.animate({opacity:0}, 800); //
}
);
The method Bruno details have this minor issue:
If you create a rectangle over the other elements, if the other elements are text then those texts can't be selected in the web page. But it works.
By the way the attribute "opacity": 0 is not enough, I had to add the "fill": "white" attribute in my case.
You need to bring the object to the front like this: obj.toFront(); obj is a raphael shape like "rect", etc.
I tested it on a mouseover and mouseout event and it works.
Check my fiddle here: link to fiddle
function withArray(x,y){
var rect = paper.rect(x, y, 100, 60).attr({
fill: "green"
});
rect.text = paper.text(x+(100/2), y + 30, 'rect w/array').attr({
'font-size': 12,
"fill": "white"
});
var rectover = paper.rect(x,y,100,60).attr({
fill: "white",
opacity: 0
});
var myArray = paper.set();
myArray.push(rect, rect.text, rectover);
myArray.mouseover(function() {
var anim = Raphael.animation({
transform: ['S', 1.5, 1.5, (rect.attr("x")), (rect.attr("y"))]
}, 100, "backOut", function() {
});
myArray.animate(anim);
}).mouseout(function() {
var anim = Raphael.animation({
transform: [""]
}, 50, "backOut", function() {
});
myArray.stop().animate(anim);
});
}
©2020 All rights reserved.