JavaScript animation lag after several loops - javascript

I am animating these dotted lines (SVG) for a project using velocity.js.
However, after a few loops, the animation starts to lag a lot.
I have pasted the link to my animation in the codepen below.
http://codepen.io/aofaoin/pen/pbLvAb?editors=0110
for (i = 1; i <= 69; i++) {
$("#gold2 .cls-" + i)
.velocity("fadeOut", {
delay: g2,
duration: 800,
})
.velocity("fadeIn", {
delay: 15,
duration: 800,
})
g2 += 80;
}
I can't use loop:true as i want to orchestrate/choreography the animation.
It would be great if anyone can tell me how can I stop the animation from lagging after a few loops. Thank you!

Looking at your code, I suggest wrapping your velocity manipulation inside of setTimeout(function() { ... }, 0). This will prevent browser from freezes caused by a big number of sync operations you try to do.
for (i = 1; i <= 69; i++) {
setTimeout(function() {
$("#gold2 .cls-" + i)
.velocity("fadeOut", {
delay: g2,
duration: 800,
})
.velocity("fadeIn", {
delay: 15,
duration: 800,
});
g2 += 80;
}, 0);
}
If you need to do your animation with delay, add dedicated delay in setTimeout.

Related

Swiper API - onSetTranslate callback stopped running

I'm using the Swiper API to do a cool carousel at beginning of my project, Swiper Sample
In the project I'm working on, I need to do an animation with some images at the same time I drag the swipe, it is working really great with these setting:
var bgAnim = function () {
var opacity = (100 + (swiper.translate / 8)) / 100,
move = swiper.translate / 4,
tDur = $('.swiper-wrapper').css('transition-duration').slice(0, -1) * 1000; // ## problem to run AUTOPLAY
if (move > 0) { move = 0 }
if (move < -200) { move = -200 }
if (opacity > 1) { opacity = 1 }
if (opacity < 0) { opacity = 0; tDur = tDur / 2 }
$('#girl-bg').animate({ // ## problem to run AUTOPLAY
'left': move,
'opacity': opacity
}, tDur);
$('#logo-bg').animate({ // ## problem to run AUTOPLAY
'opacity': opacity
}, tDur);
}
var swiper = new Swiper('.vision', {
//autoplay: 500,
autoplayDisableOnInteraction: false,
slidesPerView: 3,
spaceBetween: 24,
freeMode: true,
slidesOffsetAfter: 1000,
onSetTranslate: bgAnim
});
The problem is, when I use autoplay it conflicts with the two lines I marked above code snippet, if I take the "animate" and $('.swiper-wrapper').css('transition-duration') off it works well, but I need both to animate the background images...
Can someone help me?
I found the solution, I did an AutoPlay with some methods and callbacks as you can see below and it worked perfectly. (:
var swiperAutoplay = function () {
swiper.setWrapperTranslate(swiper.getWrapperTranslate() - 1);
swiper.update(true);
var autoTime = setTimeout(swiperAutoplay, 3);
$(homeSwiper).children().click(function () {
clearTimeout(autoTime);
});
};
setTimeout(swiperAutoplay, 5000);

How to make animation() endless

I have an element which should be animated all the time.
The animated element has such CSS properties:
#world {
height: 100%;
max-height: 100%;
position: relative;
display: flex;
background :red;
}
I can only move the element to a particular way, like this:
$('#world').animate({right: "2000px", easing: "linear"}, 2000);
But this will just animated for 2000px my element has an endless width.
UPDATE:
ALL 7.5 Sec. #world become bigger.
FIDDLE
You can have a recursive function:
var anim;
anim = function(times) {
$('#world').animate({
right: 2000 * times
}, 2000, 'linear');
return anim(times + 1);
};
anim(1)
This will continue to move #world to the right, 1 pixel per millisecond.
With a step callback:
var anim, my_step_callback;
my_step_callback = function() {
return $('body').append("<p>Hello</p>");
};
anim = function(times) {
$('#world').animate({
right: 2000 * times
}, {
duration: 2000,
easing: 'linear',
step: my_step_callback
});
return anim(times + 1);
};
Good luck!
Why not use right: 100%?
Assuming im reading your question correctly.
You could always do something like this, Where the function calls itself over and over again each time the animation ends.
function moveMe() {
$('#world').animate({width: '+=100px', easing: "linear"}, 2000, moveMe);
}
Why not set the righta value to the width of the element
var width = $('#world').width();
$('#world').animate({right: width, easing: "linear"}, 2000);
You could also increment the value of right as follows
DEMO http://jsfiddle.net/meqk662p/
var counter = 0;
setInterval(function () {
++counter;
}, 100);
$('#world').animate({right: counter+"px", easing: "linear"}, 2000);
The above example would be infinite
try increment the right and call in the callback the same function
var world_right = 2000;
function endlessWorldStep(){
$('#world')
.animate({right: world_right + "px", easing: "linear"}, 2000, endlessWorldStep);
world_right = world_right + 100;
}

Slide Up Linear Easing First Step Does Nothing

I'm developing an accordion plugin, and it's mostly done except for one bug where for the first few steps of the slideUp/slideDown, the accordion is 1px taller than it's meant to be, causing a visual bug. I've narrowed it down to the fact that the first step in the slideUp animation doesn't do anything, and I can't figure out why. Here's an example:
console.log('Start');
var diff = 0;
var upNow = 100;
var downNow = 0;
$.fx.interval = 1000;
var duration = $.fx.interval * 100;
$("#div1").slideUp({
easing: 'linear',
duration: duration,
step: function(now) {
if (now != 0 && now > 90) {
console.log("Slide Up: " + now);
upNow = now;
}
}
});
$("#div2").slideDown({
easing: 'linear',
duration: duration,
step: function(now) {
if (now != 0 && now < 10) {
downNow = now;
diff = 100 - (upNow + downNow);
console.log("Slide Down: " + now);
console.log("Slide Difference:" + diff);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div style='height: 100px; background-color: red;' id='div1'>
</div>
<div style='height: 100px; background-color: blue; display: none;' id='div2'>
</div>
http://jsfiddle.net/hbh6U/
The problem is that I need these to be in sync, and I can't figure out why they're not, or how to get them in sync. One idea I've had is to skip the first step of the slideDown animation, but I'm not sure how to do that either. Has anyone got any ideas, or faced this bug before?
The problem comes down to this line in jQuery's internal defaultPrefilter method:
tween.start = prop === "width" || prop === "height" ? 1 : 0;
This causes the animation for the second div (from 1px to 100px) to be shorter than that of the first div (from 0 to 100px).
To solve this modify your step function like this:
function linearStep(now, animation){
var animationStart = animation.start;
if (animationStart === 1){
animationStart = 0;
}
animation.now = (animation.end - animationStart ) * animation.pos + animationStart;
}
It overwrites the calculated now value by doing the same calculation with a fixed animationStart, which is 0 instead of 1.
This will break if the animation actually starts at 1, but there'd be other ways to handle it then.
Side-by-side Fiddle: http://jsfiddle.net/Nd3w2/3/
i don't exactly know where is this issue coming from... Sunday morning... not too much time to investigate... But i found two possible solution based on your fiddle...
First one was to wrap these two DIVs in another DIV with overflow:hidden.
Second one... probably more appropriate is to call "slide" function only on one of the divs and then update the size of second one in callback, something like that:
console.log('Start');
var diff = 0;
var upNow = 100;
var downNow = 0;
$.fx.interval = 1000;
var duration = $.fx.interval * 100;
$("#div1").slideUp({ easing: 'linear', duration: duration, step: function(now)
{
if(now != 0 && now > 90)
{
console.log("Slide Up: " + now);
upNow = now;
}
$("#div2").height(100- $("#div1").height());
}});
Also remove "disply:none" form div2 styles...
It fixes the issue and is a bit more elegant solution in my opinion... Calling two separate animation functions can lead to possible sync problems... Hope that helps...

Countdown using javascript

I'm trying to create a countdown for a quiz I created. The quiz will create a percentage and I am trying to create a JavaScript function that will count down from 100% to the users quiz score percentage.
Also is it possible to change the color of the percentage while it's counting down?
Example 100% Green and it starts to fade to red when it hits 59% and below?
What I am working with now:
<div id="counter">
</div>
var stop = 6;
for(i=1; i <= 100; i++) {
$('#counter').append('<p>' + i + '%');
}
$('#counter').cycle({
delay: 600,
fx: 'none',
backwards: true,
speed: 300,
timeout: 60,
autostop: 1,
autostopCount: stop,
});
Link:http://jsfiddle.net/joshsmith/WE3UA/4/
Thank You
This will make it change from pure green at 100% to pure red at 50%. I'm not sure if you wanted it to stay green all the way down to 60%. If you want that, then just put a ternary statement into the green function like this "return i > 60 ? 255 : Math.round(256*(i+40)/50-256)"
var stop = 60;
function green(i) { return Math.round(256*i/50-256); }
function red(i) { return 256-green(i); }
function toHex(c) { var h = c.toString(16); return h.length > 1 ? h : '0'+h; }
function color(i) { return i <= 50 ? 'f00' : toHex(red(i)) + toHex(green(i)) + '00'; }
for(i=1; i <= 100; i++) {
$('#counter').append('<p style="color: #' + color(i-1) + '">' + i + '%');
}
$('#counter').cycle({
delay: 600,
fx: 'none',
backwards: true,
speed: 300,
timeout: 60,
autostop: 1,
autostopCount: stop,
});
Looks like you'e already doing a pretty good job on the countdown itself.
You can easily animate colors using something like this jQuery color plugin:
https://github.com/jquery/jquery-color
Since your cycle plugin just iterates through a lot of elements that have already been created, you can simply set the paragraphs for valeus below 59 to whatever value you want.
You get a after event which gets fired after every tick. You could use that to change the color of your text.
var stop = 6;
for(i=1; i <= 100; i++) {
$('#counter').append('<p>' + i + '%');
}
var nCounter = 0;
$('#counter').cycle({
delay: 600,
fx: 'none',
backwards: true,
speed: 300,
timeout: 60,
autostop: 1,
autostopCount: stop,
after: function(currSlideElement, nextSlideElement, options, forwardFlag)
{
nCounter++
var percent = nCounter /stop * 100;
if(percent < 10)
{
$('#counter').css("color", "red");
}
}
});
U Just Need to Make Increment In RGB Values According to User Progress.
Try it out :)
var c1=c2=c3=0;
for(i=1; i <= 100; i++)
{
document.getElementById("#counter").style.color=rgb(c1,c2,c3);
if(i>30 && i<60)
{
c2++;
}
}

Trail effect with jQuery?

Can this be done ? Basically I want to animate an absolute-positioned image with right:xxxPX, let's say. Well, when the animation is in progress, can I add a "trail" effect to it?
Thanks,
Adrian
This should work:
var box = $('#box'),
// Create some clones (these make up the trail)
clones = $.map(Array(10), function(item, i){
return box.clone().css('opacity', 1 / (i + 1)).hide().insertAfter(box);
});
box.animate({
top: 100,
left: 200
}, {
duration: 1000,
step: function(now, fx) {
// On each step, set a timeout for each clone,
// making it move to the required position.
var prop = fx.prop;
$.each(clones, function(i, clone){
clone = $(clone).show();
setTimeout(function(){
clone.css(prop, now);
}, 50 * i);
});
}
});
Demo: http://jsbin.com/ifobe3

Categories