Countdown using javascript - 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++;
}
}

Related

JavaScript animation lag after several loops

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.

jQuery - end setinterval after X rund

I have a little slider im working on which is almost there im jsut having some trouble with me jQuery.
So first off:
I want my slider to reset after the interval has run x amount of times.
It was my understanding that the following would work but it doesn't seem to take. 6000, slides, function() { homesliderend();
so lets say slides = 2 set interval should call homesliderend(); but it doesn't the interval just keeps running.
Second Issue: I'm also trying to get it to add 100% to lengther every 6 seconds. But instead of adding 100 each time its just setting it to 100 its not multiplying.
jQuery(document).ready(function($) {
"use strict";
function homesliderend() {
$(".lengther").animate({
left: "0%"
}, 500);
}
function homeslider() {
var slides = $(".slide.t-align").length,
lwidth = slides * 100,
n = 0;
$(".lengther").css("width", lwidth + "%");
setInterval(function() {
var tn = n + 100;
$(".lengther").animate({
left: "-" + tn + "%"
}, 500);
}, 6000, slides, function() {
homesliderend();
});
}
homeslider();
});
The setInterval will not stop automatically, you need to clear the interval to stop it.
Also you need to increase the value of n to increase the left param
jQuery(document).ready(function ($) {
"use strict";
function homesliderend() {
$(".lengther").animate({
left: "0%"
}, 500);
}
function homeslider() {
var slides = $(".slide.t-align").length,
lwidth = slides * 100,
n = 0;
$(".lengther").css("width", lwidth + "%");
var interval = setInterval(function () {
var tn = ++n * 100;
$(".lengther").animate({
left: "-" + n + "%"
}, 500);
//if the last item is slided then stop the animation and run homesliderend
if (n == slides) {
clearInterval(interval);
homesliderend();
}
}, 6000);
}
homeslider();
});

Create Random Falling Object in Jquery

I trying to make the div fall from top to bottom.
Here is the code that i tried but it doesn't satisfy my needs .I want to generate the 20 div once ready then how to make that 20 div falling continuously from top to bottom consistently. Is it possible to do that in jquery.
http://jsfiddle.net/MzVFA/
Here is the code
function fallingSnow() {
var snowflake = $('<div class="snowflakes"></div>');
$('#snowZone').prepend(snowflake);
snowX = Math.floor(Math.random() * $('#site').width());
snowSpd = Math.floor(Math.random() + 5000);
snowflake.css({'left':snowX+'px'});
snowflake.animate({
top: "500px",
opacity : "0",
}, snowSpd, function(){
$(this).remove();
fallingSnow();
});
}
var timer = Math.floor(Math.random() +1000);
window.setInterval(function(){
fallingSnow();
}, timer);
Much Appreciate your Help.
Thanks
Not sure if this is what you want.
I am animating 20 snowflakes, wait until animation finishes for all of them, then restart all over again.
jsfiddle
function fallingSnow() {
var $snowflakes = $(), qt = 20;
for (var i = 0; i < qt; ++i) {
var $snowflake = $('<div class="snowflakes"></div>');
$snowflake.css({
'left': (Math.random() * $('#site').width()) + 'px',
'top': (- Math.random() * $('#site').height()) + 'px'
});
// add this snowflake to the set of snowflakes
$snowflakes = $snowflakes.add($snowflake);
}
$('#snowZone').prepend($snowflakes);
$snowflakes.animate({
top: "500px",
opacity : "0",
}, Math.random() + 5000, function(){
$(this).remove();
// run again when all 20 snowflakes hit the floor
if (--qt < 1) {
fallingSnow();
}
});
}
fallingSnow();
Update
This version creates 20 divs only once, and animate them again and again.
jsFiddle
function fallingSnow() {
var $snowflakes = $(),
createSnowflakes = function () {
var qt = 20;
for (var i = 0; i < qt; ++i) {
var $snowflake = $('<div class="snowflakes"></div>');
$snowflake.css({
'left': (Math.random() * $('#site').width()) + 'px',
'top': (- Math.random() * $('#site').height()) + 'px'
});
// add this snowflake to the set of snowflakes
$snowflakes = $snowflakes.add($snowflake);
}
$('#snowZone').prepend($snowflakes);
},
runSnowStorm = function() {
$snowflakes.each(function() {
var singleAnimation = function($flake) {
$flake.animate({
top: "500px",
opacity : "0",
}, Math.random() + 5000, function(){
// this particular snow flake has finished, restart again
$flake.css({
'top': (- Math.random() * $('#site').height()) + 'px',
'opacity': 1
});
singleAnimation($flake);
});
};
singleAnimation($(this));
});
};
createSnowflakes();
runSnowStorm();
}
fallingSnow();
Update2
This one that initializes the left once the animation is done for each snowflake, looks more natural in my opinion.
Also changed the delay from
Math.random() + 5000
to
Math.random()*-2500 + 5000
demo
This is simple.
Your design of function must be this.
function snowflake()
{
if($(".snowflakes").length <= 20)
{
generate_random_snowflake();
}
else
{
call_random_snowflake();
}
}
check this out, pretty simple i just added a function that triggers jquerysnow() and then calls itself again wit random time
updated code now it will just create 20 snow flakes
snowCount = 0;
function snowFlakes(){
console.log(snowCount);
if(snowCount > 20){
return false
}else{
var randomTime = Math.floor(Math.random() * (500) * 2);
setTimeout(function(){
snowCount = snowCount +1;
jquerysnow();
snowFlakes();
},randomTime);
}
}
function jquerysnow() {
var snow = $('<div class="snow"></div>');
$('#snowflakes').prepend(snow);
snowX = Math.floor(Math.random() * $('#snowflakes').width());
snowSpd = Math.floor(Math.random() * (500) * 20);
snow.css({'left':snowX+'px'});
snow.html('*');
snow.animate({
top: "500px",
opacity : "0",
}, 2000, function(){
$(this).remove();
//jquerysnow();
});
}
snowFlakes()
http://jsfiddle.net/v7LWx/22/

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...

Shake a login form on error

I have successfully built a login form using ajax and want to add a shake effect to the form when the user enters incorrect details. I have the function in place that will fire but just need to build the jquery effect (note I know of jquery UI but don't want to use it! I don't want to use ANY plugins for this)
So far I have:
function shakeForm() {
var p = new Array(15, 30, 15, 0, -15, -30, -15, 0);
p = p.concat(p.concat(p));
$('form').css('left',p);
}
From what I understand I need to loop the array of values but how do I do that? Note that the element form has a position of relative already. So it's just a case of running those values as the left value in a random sequence?
Thanks
Why bother?
Animations are queued.
More - instead a left attribute you can use margin-left what prevents to adding position attribute :)
function shakeForm() {
var l = 20;
for( var i = 0; i <= 10; i++ ) {
$( 'form' ).animate( {
'margin-left': '+=' + ( l = -l ) + 'px',
'margin-right': '-=' + l + 'px'
}, 50);
}
}
Its better to use CSS to this instead of JS. CSS uses less resources(is faster) and its simpler.
You can find good (and 'ready to use') examples here: https://daneden.me/animate/
I have made a plugin for this .. check it http://static.mbiosinformatica.com.br/jQuery/
Is it working in IE ( 7 , 8 , 9 ) , Chrome and Firefox.
And, you can apply a callback function, to show error message .. or anything else.
$('#div').shake({
positions : { 'L' : 50 , 'R' : 50 } , // shake only left and right (U,L,R,D)
rotate : false , // rotate div on shake .. true/false
parent : false // shake parent div .. true/false
}, function(){ /* do something */ });
In the positions, you can send array too, just: positions: [ [ 'L', 50 ... ] ]
This value '50' its the shake distance from original position ..
To change timeout ( delay ) and effect duration, you have to set timeout: [you timeout .. / delay ] and the effect times .. interval: ...
mmm why use native js if jquery animate() is available... you try recurring like this:
var p = new Array(15, 30, 15, 0, -15, -30, -15, 0);
function shakeForm(index) {
if(typeof index === "undefined") index = 0;
if(typeof p[index] === "undefined") return false;
$("form").animate({
"left": p[index]
}, function() {
shakeForm(index + 1);
});
}
For those of you who are stubborn (like me) and hate libraries...
var e = document.getElementById('dividname');
e.style.marginLeft='8px';
setTimeout(function(){e.style.marginLeft='0px';},100);
setTimeout(function(){e.style.marginLeft='8px';},200);
setTimeout(function(){e.style.marginLeft='0px';},300);
then in your css:
.shakeClass{
transition: margin 100ms;
}
loop throw the array using jQuery.each: http://jsfiddle.net/N8F7Z/1/
function shakeForm() {
var p = "15 30 15 0 -15 -30 -15 0".split(" ");
$.each(p, function(key, value) {
var delay = 100;
setTimeout(function() {
$("form").css("left", value + "px");
}, delay*key);
});
}
A simple way to make an array is splitting a string with every space:
var p = "15 30 15 0 -15 -30 -15 0".split(" ");
The delay between each step:
var delay = 100;
Using setTimeout(function() {...}, theTimeBeforeFiring )
theTimeBeforeFiring = delay * key
key is the key the value has in the array:
key = 0, 1, 2, 3
jquery animations are queued by default, so you just need to call animate for each element of the array:
function shakeForm() {
var p = [15, 30, 15, 0, -15, -30, -15, 0];
var x = $('form').offset().left;
var speed = 40;
$.each(p, function() {
$('form').animate({'left': x + this}, speed);
});
}
Example: http://jsfiddle.net/3qdFL/
The examples above change the original position of the element.
function shakeForm() {
var margin = 15;
var speed = 50;
var times = 5;
for( var i = 0; i < times; i++ ){
$( "form" ).animate( { 'margin-left': "+=" + ( margin = -margin ) + 'px' }, speed);
$( "form" ).animate( { 'margin-right': "+=" + ( margin = -margin ) + 'px' }, speed);
$( "form" ).animate( { 'margin-right': "+=" + ( margin = -margin ) + 'px' }, speed);
$( "form" ).animate( { 'margin-left': "+=" + ( margin = -margin ) + 'px' }, speed);
}
}
demo here http://jsfiddle.net/UW6tN/1/
why not use css3 animations? less over head in my opinion. There so many plugins that exist because so many reinvent the wheel... I searched for the same thing and got 20 results of forums, and jquery plugins(yet another script to add)..but I found this and it works of coarse.
not my answer but it pure css3!
CSS animation similar to Mac OS X 10.8 invalid password "shake"?

Categories