Chaining two functions in an event - mootools

I have this code, I'd like to make all a's .ita, .eng, .rus visible on hovering the .all. After mouseleave, I'd like to fade out the a's, and shrink back .languages to the size of just .all.
<nav class="languages">
L
ITA
ENG
RUS
</nav>
In the mouseleave event in the code below I would like to first tween the languages element, then bring the width of the container to 60px. Since it happens async, I cannot manage to see the fadeout of the element.
$$('nav.languages').addEvents({
'mouseenter': ->
this.setStyle('width', "400px")
languages.tween('opacity', 0, 1)
, 'mouseleave': ->
languages.tween('opacity', 1, 0)
this.setStyle('width', "60px")
})
I am reading about the chain method but it refers to a class, not an event, as I have understood.
Thanks

you can set link: chain to the instance of Fx.Tween
as for the rest, its more complex but something like this will work.
http://jsfiddle.net/d201npL2/1/
(function(){
var languages = document.getElement('nav.languages span');
languages.set('tween', {
link: 'chain'
});
var nav = document.getElement('nav.languages').addEvents({
'mouseenter:relay(a.all)': function(){
nav.setStyle('width', 400);
languages.fade(0, 1);
},
'mouseleave': function(){
languages.fade(1, 0);
this.setStyle('width', 60)
}
});
}());
you can do all this in pure CSS3, you know that, right?

Related

Best way to use svg animating library vivus with intersection observer

I use vivus.js to animate SVGs. I wonder what is the best way to use it in combination with intersection observer, concerning performance.
On my page are several sections, including inline svgs. These svgs should be animated when scrolling down the page, stop when leaving the viewport und start again when the container is observed again.
It works but i am not sure if this is the best way to build vivus objects und play them again and again in this way.
These solution seems to crash firefox performance..
I welcome all comments, suggestions and proposed improvements.
$( document ).ready(function() {
//Define observed Items
var myItems = document.querySelectorAll(".observed-item");
//Define observer Options
var observeroptions = {
root: null,
rootMargin: "-35% 0% -35% 0%",
threshold: 0,
};
//Create new Observer Object
var observer = new IntersectionObserver(function(entries, observer){
entries.forEach(function(entry){
//Define Index Variable
var myIndex = $(entry.target).index();
var myvivus = new Vivus("item-svg" + myIndex, {
duration: 150,
start: 'manual'
},
function () {
$(entry.target).addClass('callback-item-animation');
}
)
if (entry.intersectionRatio > 0) {
//Add class to Entry Target
$(entry.target).addClass("item-animate");
myvivus.reset().play();
} else {
//Remove animated Class from observed Item
$(entry.target).removeClass("item-animate");
myvivus.stop().reset();
}
});
},observeroptions);
myItems.forEach(function(myItem) {
observer.observe(myItem);
});
});
I created a pen:
https://codepen.io/Milenoi/pen/JBxgOG
Please Note: without Polyfill works in Chrome + Firefox
As you can see, the animation doesn't work as expected, the svg animation should stop when leaving observer and start again wenn element is intersected again..
Your hoisting observer and clashing it in the function. Add var or let before observer =, then change the name of observer in that function to something unique. Also qualify everything with window. Or context. That should improve the performance marginally

Fx.Reveal event when done (complete)

hi sorry completely new to mootools used to jquery, have a container (saved to variable itemContent) which reveals,
after this a function galleryScroll is call which scrolls the element to the container saved to var itemScroll,
want to make sure itemContent is revealed before scroll function is called whats the best way to do this?
thanks
itemContent.reveal({
'height' : '100%',
duration: 1600,
}).addClass('open-content');
// should this fire this in a callback function so it fires once the container is revealed
galleryScroll.toElement(itemScroll);
Fx.Reveal extends Fx and as such, inherits all of it's events.
try via the element setter:
itemCount.set('reveal', {
onComplete: function(){
galleryScroll.toElement(this.element);
}
}.reveal({... });
you can also get the reveal instance:
var fxReveal = itemCount.get('reveal');
this will return the instance and you can set whatever you like to it like usual.
You can enable chaining with the link option.
itemContent.reveal({
'height': '100%',
duration: 1600,
link: 'chain'
}).addClass('open-content');
This example will hide, reveal and then alert. Please note that I need to get the reveal instance as the standard Element in mootools does not implement the Chain class.
document.id('first').set('reveal', {
duration: 'long',
transition: 'bounce:out',
link: 'chain'
}).dissolve().reveal().get('reveal').chain(function(){alert('message');});
To see it in action: http://jsfiddle.net/LKSN8/1/

Open div on element click , close on body OR element click Mootools

I made this fiddle
http://jsfiddle.net/nAb6N/10/
As you can see I have 2 animators , a element and body class,
I am adding class to body after the first click on a element but once I click on body is not closing it. If I define animators as
var animators = $$('#opendiv,body');
it works ok except that I do not want the div to open on body click. I need it to close on body click.
Any help is appreciated.
Thank you!
Right. Seems as if you really require an outerClick pattern to close. Here's the one that is most notably used within mootools devs, allowing you to create a custom event, based on click:
Element.Events.outerClick = {
base : 'click',
condition : function(event){
event.stopPropagation();
return false;
},
onAdd : function(fn){
this.getDocument().addEvent('click', fn);
},
onRemove : function(fn){
this.getDocument().removeEvent('click', fn);
}
};
The way it works is: it is based on a normal click. upon adding, it adds the callback as a click event on the document. when a click happens within the element itself,it stops bubbling via event.stopPropagation();, else, it will bubble and the callback will run.
here's how it ties together after the above:
http://jsfiddle.net/dimitar/nAb6N/13/
(function() {
var opener = $('opendiv');
var boxtoopen = $('box');
boxtoopen.set('morph', {
duration: 700,
transition: 'bounce:out'
});
boxtoopen.addEvent('outerClick', function(event) {
boxtoopen.morph(".openOff");
opener.removeClass("hide");
});
opener.addEvent('click', function(e) {
e.stop();
boxtoopen.morph(".openOn");
this.addClass("hide");
});
})();
I have also 'outsourced' the morph properties to the CSS as it makes more sense, semantically.
P.S. note that you need mootools 1.4.3 or 1.4.5, but not 1.4.4 as there's a morph bug to do with units in that release. the jsfiddle above uses 1.4.6 (mootools edge).

How do I convert this snippet to Mootools

I have a Prototype snippet here that I really want to see converted into Mootools.
document.observe('click', function(e, el) {
if ( ! e.target.descendantOf('calendar')) {
Effect.toggle('calendar', 'appear', {duration: 0.4});
}
});
The snippet catches clicks and if it clicks outside the container $('calendar') should toggle.
Are you trying to catch clicks anywhere in the document? Maybe you could try...
var calendar = $('calendar');
$$('body')[0].addEvent('click', function(e) {
if (!$(e.target).getParent('#calendar')) {
var myFx = new Fx.Tween(calendar, {duration: 400});
myFx.set('display', 'block');
}
}
I'm not sure how you are toggling visibility but the way Fx.Tween.set works allows you to change any CSS property. You may want to look at http://mootools.net/docs/core/Fx/Fx.Tween for other possibilities.
Also, notice that I wrapped e.target using a $. This is specifically for IE. I wrote a post about this here under the sub-heading "Mootools Events Targets".
Lastly, I factored out $('calendar') so that you are not searching the DOM every time.

Onload set divs opacity to 50%

Okay, so I have a site running Joomla and it is using the mootools 1.11 framework. I've fudged together a working version of this using examples from the mootools 1.2 framework but cannot get the two to co-exist even with the compatibility layer, without breaking other modules in the Joomla site.
Question
I have a couple of divs with a class of ".box_panel" and I have it so that they on mouseover they go from 50% opacity and back to 100% opacity on mouseleave. The problem I'm having is what is the code to set them to 50% onload?
In mootools 1.2 I used:
<body onload="$$('div.box_panel').fade(0.5);">
The code I'm using for the mouseover/mouseleave effects is:
window.addEvent('domready',function() {
//first, apply a class to each of your menu element
//$$('.links') puts every element wearing the .links class into an array
//$$('.links').each is to browse the array an apply a function to... each of them
$$('.box_panel').each(function(el, i) {
//there comes exactly your former fx statement except for
var ExampleFx = new Fx.Style(el, 'opacity', { //the fact i apply the effect on el
wait: false, //and wait: false which make the effect not waiting (very useful on the mouseout or mouseleave function...
opacity: 0.5,
duration: 500,
transition: Fx.Transitions.Quart.easeInOut
});
//and there i apply (always on el) the effect on mouseenter (similar in this case but often better than mouseover)
//and mouseleave (same for mouseenter but concerning mouesout)
el.addEvent('mouseleave', function() { ExampleFx.start(1, 0.5); });
el.addEvent('mouseenter', function() { ExampleFx.start(0.5, 1); });
});
});
Can you not just add ExampleFx.start(1, 0.5); before the last brackets (after the $$('.box_panel')... statement)?
Simple:
$$('.box_panel').effect('opacity', 0.5);
// run this right after your window.addEvent('domready', function() {
Edit: I were a bit wrong here. Mladen Mihajlovic answered completly correct. Also, here are some links for you:
MooTools 1.11 Documentation
MooTools 1.11 Demos