How do I delay the start of a JS animation? - javascript

I was wondering if there is an easy way to delay the start of this anime.timeline animation? I have a pre-loader on my site, so I don't want this animation to trigger until the pre-loader disappears, which is after 2000 ms.
<script>
anime.timeline({loop: true})
.add({
targets: '.ml3 .letter',
opacity: [0,1],
easing: "easeInOutQuad",
duration: 2250,
delay: (el, i) => 150 * (i+1)
}).add({
targets: '.ml3',
opacity: 0,
duration: 1000,
easing: "easeOutExpo",
delay: 10000
});
</script>
I think this is an easy fix, but I'm still new to JS. Thank you!

You can use setTimeout() Method
<script>
setTimeout(function(){
anime.timeline({loop: true})
.add({
targets: '.ml3 .letter',
opacity: [0,1],
easing: "easeInOutQuad",
duration: 2250,
delay: (el, i) => 150 * (i+1)
}).add({
targets: '.ml3',
opacity: 0,
duration: 1000,
easing: "easeOutExpo",
delay: 10000
});
}, 3000);
</script>
This will run your function with a 3 seconds delay.

Have you try to set timeout before animation start?
var animation = function(){
setTimeout(check, 1000);
}
animation();

Related

How to exit a method in Phaser3 only when the played timeline is finished?

I'm quite new in Phaser, but I've already done a bunch of ionic/angular app.
One of my object has a method that will be called by the main scene:
powerOff() {
let easing = 'Cubic'
let overallDuration = 500
let visiblePauseDuration = 100
let flashDuration = overallDuration - visiblePauseDuration / 2
this.scene.tweens.timeline({
tweens: [
{
targets: this,
duration: 0,
tint: 0xff0000,
ease: easing,
},
{
targets: this,
duration: flashDuration,
tint: 0xffffff,
ease: easing,
},
{
targets: this,
duration: visiblePauseDuration,
tint: 0xff0000,
ease: easing,
},
{
targets: this,
duration: flashDuration,
tint: 0xffffff,
ease: easing,
},
{
targets: this,
duration: visiblePauseDuration,
tint: 0xff0000,
ease: easing,
onComplete: () => {
this.scene.sound.play(MainScene.POWER_DOWN)
},
},
{
targets: this,
duration: flashDuration,
tint: 0xf54242,
ease: easing,
},
],
})
this.poweredUp = false
}
The thing is: I need to exit this method only when the timeline has completed.
Is there some await/async support? Or at least promises ?
The scene will call this method on a lot of different objects, and I need that they are not done in parallel but sequentially.
Thanks a lot!!!
var timeline = this.scene.tweens.timeline({
/*TWEENS*/
})
//Timeline complete event listener
timeline.addListener("complete", function(){
//Do something when tweens are complete
}, this);

jQuery to monitor links to see if they are hovered over, if they are go up 3 parents and add css/class

I have lots of links on my page with the HTML format of:
<div class="heading-column">
<div class="heading-container">
<h2 class="heading-item">
<a href="/find/">Find</h2>
</div>
</div>
</div>
Currently we have some animations happening when they hover over the heading-column element, but they should actually only happen when hovering over the a hyperlink.
I'm trying to figure out how to create some jQuery to monitor all hyperlinks, if one with the class of .heading-item a is hovered over for it to update its parent 3 higher (.heading-column) by adding the css of pointer-events: auto; but as soon as the mouse stops hovering, this css rule should be deleted so that the pointer-events: none; stops the .heading-column animation/hover from happening
I'd greatly appreciate some help
Have you tried:
$(".heading-column a").hover(function(){
// In
$(this).closest(".heading-column").css("pointer-events", "none");
}, function(){
// Out
$(this).closest(".heading-column").css("pointer-events", "auto");
});
Reference: https://api.jquery.com/hover/
Might consider adding and removing a Class too.
See if this helps -
https://codepen.io/VweMWoz
const tl = gsap.timeline({paused: true});
tl.from(
".gsap-swipe",
{
y: 20,
x: 20,
rotate: -40,
duration: 3,
transformOrigin: '30% 80%',
ease: Elastic.easeOut.config(1, 0.5),
}, 0
)
.fromTo(
".swipe",
{
xPercent: -100
},
{
duration: 1,
xPercent: 100,
ease: Sine.easeInOut,
stagger: {
each: 0.15
}
}, 0
)
.from(
".maskSwipe",
{
xPercent: -100,
ease: Sine.easeInOut
},
0.4
)
.from(
"#hello",
{
duration: 1.5,
drawSVG: "0%"
},
1
)
.from(
".swoop",
{
duration: 2,
drawSVG: "0%"
},
1
)
.from(
".line",
{
drawSVG: "0%",
duration: 0.5,
stagger: {
each: 0.2
}
},
1
)
.from(
".shape",
{
scale: 0,
duration: 1.3,
transformOrigin: "50% 50%",
rotate: '+=random(-60, 60)',
ease: Elastic.easeOut.config(1, 0.8),
stagger: {
each: 0.2
}
},
0.2
);
// ScrubGSAPTimeline(tl);
let hover = document.querySelector('.js-hover');
hover.addEventListener('mouseover', playTl);
hover.addEventListener('mouseout', resetTl);
function playTl(){
tl.timeScale(1.25).restart();
}
function resetTl(){
tl.progress(0).pause();
}

A function that execute once when scrollY is higher than 100vh

I want call my function once when the statement if (scrollY > 100vh), but on every scroll when I get more than 100vh is calling func. I understand the reason why is that, but don't know how to fix that.
Perhaps it is simple but I can't do that.
I want a simple animation on scrolling.
code :
import anime from 'animejs';
var txt = document.querySelector('.textanimation');
txt.innerHTML = txt.textContent.replace(
/\S/g,
"<span class='letter'>$&</span>"
);
window.addEventListener('scroll', () => {
const vh = window.innerHeight;
const scrolled = window.scrollTop;
if (scrolled > vh) {
const scrollTextAnimation = anime.timeline();
scrollTextAnimation
.add({
targets: '.textanimation .letter',
translateY: [-100, 0],
easing: 'easeOutExpo',
duration: 1400,
delay: (el, i) => 30 * i
})
.add({
targets: '.textanimation',
duration: 1000,
easing: 'easeOutExpo',
delay: 1000
});
}
});
just add once option to the event listener to execute it one time.
window.addEventListener('scroll', () => {
const vh = window.innerHeight;
const scrolled = window.scrollTop;
if (scrolled > vh) {
const scrollTextAnimation = anime.timeline();
scrollTextAnimation
.add({
targets: '.textanimation .letter',
translateY: [-100, 0],
easing: 'easeOutExpo',
duration: 1400,
delay: (el, i) => 30 * i
})
.add({
targets: '.textanimation',
duration: 1000,
easing: 'easeOutExpo',
delay: 1000
});
}
}, {once: true});
I just added a bool that change the statement to false when I make a scrollY more than innerHeight/2. "Once" option in addEventListener was not working, don't know why. Is there a better solution how to fix that?
The code below is working:
let myBool = true;
window.addEventListener('scroll', () => {
if (window.scrollY > window.innerHeight / 2 && myBool) {
anime.timeline()
.add({
targets: '.textanimation .letter',
translateY: [-100, 0],
easing: 'easeOutExpo',
duration: 1400,
delay: (el, i) => 30 * i
})
.add({
targets: '.textanimation',
duration: 1000,
easing: 'easeOutExpo',
delay: 1000
});
myBool = false;
}
});
You can remove the event listener after your logic executes in order to stop it from ever firing again. You can do this in two ways:
1) Use the once option as defined in the parameters for addEventListener here. This option automatically removes the event listener after the event happens once. The OP has already stated this isn't working for them (possibly because the scroll needs to reach a certain height before the logic works so it is being removed too early).
2) Call removeEventListener after the logic executes:
import anime from 'animejs';
var txt = document.querySelector('.textanimation');
txt.innerHTML = txt.textContent.replace(
/\S/g,
"<span class='letter'>$&</span>"
);
var animateOnce = function() {
const vh = window.innerHeight;
const scrolled = window.scrollTop;
if (scrolled > vh) {
const scrollTextAnimation = anime.timeline();
scrollTextAnimation
.add({
targets: '.textanimation .letter',
translateY: [-100, 0],
easing: 'easeOutExpo',
duration: 1400,
delay: (el, i) => 30 * i
})
.add({
targets: '.textanimation',
duration: 1000,
easing: 'easeOutExpo',
delay: 1000
});
// remove the event listener after the animation happens on the first time
window.removeEventListener('scroll', animateOnce);
}
}
window.addEventListener('scroll', animateOnce);
3) Here are a couple of other solutions in a post on sitepoint.

How to increase spin speed in velocity.js?

I am using velocity.js for spinner and let user spin multiple times.
Currently my code spins the wheel for only few seconds but i want it to spin about more than a minute.
I couldn't find any solution for this so is there any solution?
$(".fancybox").parent("li").velocity({
opacity: 1
}, {
duration: 100,
complete: function () {
$(".wheel").velocity({
rotateZ: "-" + _deg + "deg",
},
{
duration: 1500,
direction: 'clockwise',
speed: 9000,
easing: "swing",
tween: [0, 100],
complete: function (elements)
{}
});
}
});
This is working jsfiddle demo i am attaching.

jQuery animation in order delay

Hey all I am trying to call out animations in order. Currently the code below seems to call them all out at the same time even with the delay function (which doesn't seem to be working at all...)
$(".overlayChoice1").delay(500).animate({
top: '-15px' }, { duration: 1700, easing: 'easeOutElastic' })
$(".overlayChoice2").delay(500).animate({
top: '-45px' }, { duration: 1700, easing: 'easeOutElastic' })
$(".overlayChoice3").delay(500).animate({
top: '-75px' }, { duration: 1700, easing: 'easeOutElastic' })
$(".overlayChoice4").delay(500).animate({
top: '-105px' }, { duration: 1700, easing: 'easeOutElastic' })
What all would I need to do in order to have the execute one at a time?
If you want the animations to happen sequentially you should nest each animation in the complete callback of the prior:
$(".overlayChoice1").delay(500).animate({
top: '-15px' }, { duration: 1700, easing: 'easeOutElastic' }, function(){
$(".overlayChoice2").delay(500).animate({
top: '-45px' }, { duration: 1700, easing: 'easeOutElastic' }, function(){
$(".overlayChoice3").delay(500).animate({
top: '-75px' }, { duration: 1700, easing: 'easeOutElastic' }, function(){
$(".overlayChoice4").delay(500).animate({
top: '-105px' }, { duration: 1700, easing: 'easeOutElastic' });
})
})
})
.animate reference: http://api.jquery.com/animate/
You either need to send the next one as a callback, or use incremental delays.
Callbacks:
$(".overlayChoice1").delay(500).animate({
top: '-15px' }, { duration: 1700, easing: 'easeOutElastic' }, function(){
$(".overlayChoice2").delay(500).animate({
top: '-45px' }, { duration: 1700, easing: 'easeOutElastic' }, function(){
$(".overlayChoice3").delay(500).animate({
top: '-75px' }, { duration: 1700, easing: 'easeOutElastic' }, function(){
$(".overlayChoice4").delay(500).animate({
top: '-105px' }, { duration: 1700, easing: 'easeOutElastic' }, function(){
});
});
});
});
Incremental delays:
$(".overlayChoice1").delay(500).animate({
top: '-15px' }, { duration: 1700, easing: 'easeOutElastic' })
$(".overlayChoice2").delay(2700).animate({
top: '-45px' }, { duration: 1700, easing: 'easeOutElastic' })
$(".overlayChoice3").delay(4900).animate({
top: '-75px' }, { duration: 1700, easing: 'easeOutElastic' })
$(".overlayChoice4").delay(7100).animate({
top: '-105px' }, { duration: 1700, easing: 'easeOutElastic' })
$(".overlayChoice1").animate({ top: '-15px' }, 1700, "easeOutElastic", function() {
// Animation overlayChoice1 complete.
$(".overlayChoice2").animate({ top: '-45px' }, 1700, "easeOutElastic", function() {
// Animation overlayChoice2 complete.
.....
} })
});
Personally, I'd use a much more DRY implementation that doesn't repeat so much code and triggers the next animation based on the completion callback of the previous one:
function runAnimations() {
var cntr = 1, top = -15;
function next() {
if (cntr <= 4) {
$(".overlayChoice" + cntr).delay(500)
.animate({top:top+'px'}, {duration:1700, easing:'easeOutElastic'}, next);
++cntr;
top -= 30;
}
}
next();
}

Categories

Resources