Mootools wait with Fx.Morph start - javascript

I am trying to get var effect = new Fx.Morph(testMorph, { to wait/delay 2 seconds before starting.
(fiddle here)
But when I try .wait(2000) or .delay(2000), or even .wait(2000, effect) I get Uncaught TypeError: Object [object Object] has no method 'delay'
Any ideas how to get this working?
Code I'm using:
var testMorph = document.id('testMorph');
var effect = new Fx.Morph(testMorph, {
transition: 'back:out',
duration: 900,
link: 'chain'
}).start({
'top': 20,
'opacity': 1
}).start({
'border-color': '#A80025',
'color': '#A80025'
});
effect.delay(2000);

You can use a combination of chain() and delay() to achieve the desired effect.
new Fx.Morph(testMorph, {
transition: 'back:out',
duration: 900,
link: 'chain'
}).start().chain(function(){
this.start.delay(2000,effect,{
//first
});
}).chain(function(){
this.start({
//second
});
});
The chain() adds another effect at the end of the current one.
The first effect is simply start() with an empty effect, to provide context to our chain of events.
It is then chained to the delayed event, using the start.delay() method (delay() is a property of Function).
This, in turn, is chained to your other effect.
See here.

Related

How to replace margin-left animation with transform in Jquery animate() to fix laggy multislider

I'll preface this by saying my initial problem is difficult to reproduce.
Brief explanation of my problem following, question is at the bottom.
So I am using the Jquery multislider for a project.
Here is a link to it: Multislider
Now my issue is that the animation of the moving elements seems to lag... Sometimes.
It jumps instead of moving smoothly.
The way the element works is by applying the animate() method to the first item and applies an inline margin-left property to the first .item
With some research I have found that CSS animations often cause problems when margins are used for the animation(among some other properties like top/bottom/left/right, as well as height/width) and that using transform is preferable.
So far so good.
This is the snippet in the javascript that creates the animation:
function singleLeft(){
isItAnimating(function(){
reTargetSlides();
$imgFirst.animate(
{
marginLeft: -animateDistance /* This is the part that causes me problems */
}, {
duration: animateDuration,
easing: "swing",
complete: function(){
$imgFirst.detach().removeAttr('style').appendTo($msContent);
doneAnimating();
}
}
);
});
}
function singleRight(){
isItAnimating(function(){
reTargetSlides();
$imgLast.css('margin-left',-animateDistance).prependTo($msContent);
$imgLast.animate(
{
marginLeft: 0
}, {
duration: animateDuration,
easing: "swing",
complete: function(){
$imgLast.removeAttr("style");
doneAnimating();
}
}
);
});
}
Now if I understand it correctly, I have to replace the marginLeft: -animateDistance portion with a transformX property, is that correct?
But I am failing to make it work.
So my question is, how can I replace the marginLeft: -animateDistance portion with transform: translateX() and add the animateDistance variable between the parentheses?
I have tried something like transform: "translateX(-$(animateDistance))", but that just disables the animation entirely.
Am I missing something?
I'm open for other suggestions to solve the issue of the laggy animation as well, this just is the conclusion I came to.
You can use animate with $(this) and .css() if you use step()
let test = "100";
$('div h2').animate({ pxNumber: test }, {
step: function(pxNumber) {
$(this).css('transform','translateX(-' + pxNumber + 'px )');
},
duration:'slow',
easing: "swing",
complete: function(){
console.log('Animation done');
// doneAnimating();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div><h2>Move it</h2></div>

How to manage multiple elements in a mouseenter function in Mootools?

Hi! I really try to find a topic related to my issue here, but I had no luck...
Some simple code: I have two divs, placed in the same position -
<div id="fader1" style="display:inline-block;position:absolute;background-image:url(images/fader1.png);opacity:1;width:296px;height:435px;margin:-215px 50px -20px"></div>
<div id="fader2" style="display:inline-block;position:absolute;background-image:url(images/fader2.png);opacity:0;width:296px;height:425px;margin:-215px 50px -20px"></div>
The idea is when the mouse passes over the div "fader1", the opacity changes to 0, and the opacity of fader2 changes to 1. And turn back like the beginning if I put the cursor out of the div.
I've tried to achieve this with mootools but I'm now in a dead-end.
Mootools Demos have the example of Fx.Morph like this:
$('myElement').set('opacity', 0.5).addEvents({
mouseenter: function(){
// This morphes the opacity and backgroundColor
this.morph({
'opacity': 0.6,
'background-color': '#E79D35'
});
},
mouseleave: function(){
// Morphes back to the original style
this.morph({
opacity: 0.5,
backgroundColor: color
});
}
});
As you can see, I can only manage ONE element (this.morph). I try to put other element like: "('fader1').morph" with no results... But I think that I'm doing it wrong.
I really appreciate any help you can give me to achieve this in mootools. Regards!
you should read the manual and not copy/paste from examples.
$('myElement').set('opacity', 0.5).addEvents({
mouseenter: function(){
// This morphes the opacity and backgroundColor
this.morph({
'opacity': 0.6,
'background-color': '#E79D35'
});
}
});
in the above function, the scope this refers to myElement. if you need to reference a different element, then simply do so.
(function(){
var other = $('myOtherElement').set('moprh', {
link: 'cancel'
}); // save a reference and set link to cancel existing morphing
$('myElement').set('opacity', 0.5).addEvents({
mouseenter: function(){
// This morphes the opacity and backgroundColor
other.morph({
'opacity': 0.6,
'background-color': '#E79D35'
});
},
mouseleave: function(){
// Morphes back to the original style
other.morph({
opacity: 0.5,
backgroundColor: color
});
}
});
}());
read up on what $ (documentid) returns (an element), saving an element into a variable and referencing it later - this is standard javascript.

Why does this not pauseFx before morph-ing?

This morphs just fine but I need it to pause first then morph.
var animate = (function(){
var div = document.getElement('div.es-transition');
if (div){
div.set('morph', {duration: 800, transition: 'quad:out'});
div.pauseFx(1000, 'morph');
div.addClass('hidden');
div.setStyles({'visibility': 'hidden', 'opacity': 0});
div.removeClass('hidden').fade('in');
}
});
window.addEvent('load', animate);
Banging head.
TIA
don't know about pauseFx? this is not standard mootools-core api. it has http://mootools.net/docs/core/Fx/Fx#Fx:pause - which needs to be applied to the instance.
in your case, it makes no sense anyway as you pause before you even run it. which means, use setTimeout or delay. pause is to stop and resume a morph/tween midway. please clarify what you are trying to achieve
also. .set('morph') does not work with .fade() - fade is based on tween options, not morph. the difference between tween and morph is single property vs multiple properties.
if I understand this correctly, you need to rewrite as:
var animate = (function(){
var div = document.getElement('div.es-transition');
if (div){
div.set('tween', {duration: 800, transition: 'quad:out'});
div.addClass('hidden');
div.setStyles({'visibility': 'hidden', 'opacity': 0});
(function(){
div.removeClass('hidden').fade(0, 1);
}).delay(1000);
}
});
window.addEvent('load', animate);

how to remove a method with a callback or otherwise

I have the following code that animates an object with a delay of 800 ms:
$('#navMenu').mousemove(function (e) {
thisX = e.pageX
if (thisX >= 1625) {
$('#prbBtnHolder').animate({ left: '-=150' }, 300).delay(800);
}
});
If the #prbBtnHolder has a certain css left property i want to be able to remove the delay()method and stop the animation. How do i do this? This is what I've tried so far:
//...
$('#prbBtnHolder').animate({ left: '-=150' }, 300).delay(800);
if ($('#prbBtnHolder').css('left') < -100) {
$(this).animate({left: '-=0px'});
}
But this does not remove the delay method nor does it achieve the desired effect. Any other ideas?
In order to clear the effects queue, you'll need to use the step callback to see if your condition is met.
http://api.jquery.com/animate/
$('#prbBtnHolder').animate({
left: '-=150'
},
{
duration: 300,
step: function(now, fx) {
if (now < -100) {
// uncomment and you'll see the next animation
$(fx.elem).clearQueue().stop();
}
}
}).delay(800).animate({ width: '200px', height: '200px' }, 300);
Here is a jsbin example:
http://jsbin.com/utejew/3
$(this).clearQueue();
jQuery Docs for clearQueue
Removes all elements in the effect Queue for the given Element. Otherwise you could use js native setTimeoutfunction to animate which can easily be cleared with clearTimeout.
Before you Animate $('#prbBtnHolder') you can calculate how far the Button is away from -100 and animate it only that far.

Why i am unable to set z-index of div using jquery?

I have created a sample
http://jsbin.com/eqiti3
here we have three divs. Now, what i want to do is: on clicking of any div it should come on the top of other div then fade and then back to its original position. This is what i am using:
$(".box").click( function () {
var zindex = $(this).css('z-index');
/* this too is not working
$(this).css('z-index',14);
$(this).fadeTo ( 'slow', 0.5 ).fadeTo('slow', 1 )
$(this).css('z-index',zindex);
*/
$(this).css('z-index',14).fadeTo ( 'slow', 0.5 ).fadeTo('slow', 1 ).css('z-index',zindex);
} );
provided $(this).css('z-index',14) this alone is capable of making the div to come over other divs.
Use the callback
$(this).css('z-index',14)
.fadeTo('slow', 0.5 )
.fadeTo('slow', 1, function(){
$(this).css('z-index',zindex);
});
The 3rd parameter is a callback function, it will run when the animation ends.
Revision #3 on jsBin.
change your code to this:
$(".box").click( function () {
var zindex = $(this).css('z-index');
$(this).css('z-index',14).fadeTo ( 'slow', 0.5 ).fadeTo('slow', 1, function(){
$(this).css('z-index',zindex);
});
});
You can't chain the .css() method after fadeTo(), because those fx functions run asyncronously and therefore, .css() was executing immediately.
That's why all fx methods do offer callbacks which fire when finished.
See this in action: http://jsbin.com/eqiti3/2/edit
Set background:'white'; it is solved for me

Categories