Good morning all,
I have an animated number counter that counts up from 0 to the specified number. However if I enter a decimal number (i.e. 99.99%) it rounds up to 100%. Is there a way to make it count up to the number that is given?
Please let me know if you need more information.
Thanks in advance!
numbersAnimate(_Panel) {
if (!_Panel) {
return;
}
// Get document language
const _Document = document.documentElement;
let lang = _Document.getAttribute('lang');
// Grab all panel amount nodes
const _PanelAmounts = _Panel.querySelectorAll('.panel__amount');
if (!_PanelAmounts) {
return;
}
//Loop over all the panel amounts
for (const _PanelAmount of _PanelAmounts) {
//Convert to jQuery object
const $PanelAmount = $(_PanelAmount);
//Panel amount stored in value
const value = $PanelAmount.data('amount');
//If there is no value return
if (!value || value.length < 1) {
return;
}
// If not a number return
if (isNaN(value)) {
return;
}
//Animation....
$PanelAmount.prop('Counter', 0).animate({
Counter: value
}, {
duration: 1000,
easing: 'linear',
step: function(now) {
$PanelAmount.text(this.Counter.toFixed());
}
});
}
//Add animated class because scroll event checks if it's there, if it isn't then add it.
_Panel.classList.add('animated');
//JSON Structure
"statistic": {
"amount": "99.99",
"symbol": "%"
},
<span className="panel__amount panel-text-style-c" data-amount={jsonData.statistic.amount}>0</span>
You are using Math.ceil(now) which will round to the nearest integer. Have you tried removing it?
$PanelAmount.text(now).toLocaleString(lang);
Old:
//Panel amount is the animated number
$PanelAmount.prop('Counter', 0).animate({
Counter: value
}, {
duration: 1000,
easing: 'linear',
step: function(now) {
$PanelAmount.text(Math.ceil(now)).toLocaleString(lang);
}
});
New:
function startCounter(){
$('.PanelAmount').each(function (index) {
var size = $(this).text().split(".")[1] ? $(this).text().split(".")[1].length : 0;
$(this).prop('Counter',0).animate({
Counter: $(this).text()
}, {
duration: 2000,
easing: 'swing',
step: function (now) {
$(this).text(parseFloat(now).toFixed(size));
}
});
});
}
startCounter();
.PanelAmount {
font-size: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="counter">99.99</div>
New JQuery works to the exact decimal point
Related
I've used the jQuery prop-method with the counter-property to create an animation that counts from 0 to the value from the .count-string through an each-loop.
This works as intended, but I would like to increase this value by 3, 2 and 1 respectively, set by the variables cowsIncrement, sheepIncrement and pigsIncrement. Each increment has to happen in 3, 2 and 1-second intervals as well (similiar to the increment value), and it has to run infinitely with the same animation. How would I go about doing this?
Can somebody provide solution from jQuery/Vanilla Js?
// #count1
let cowsIncrement = 3;
// #count2
let sheepIncrement = 2;
// #count3
let pigsIncrement = 1;
$('.count').each(function() {
$(this).prop('Counter', 0).animate({
Counter: $(this).text()
}, {
duration: 1500,
easing: 'swing',
step: function(now) {
$(this).text(Math.ceil(now).toLocaleString('de-DE'));
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="count" id="count1">3000</div><span>cows</span>
<div class="count" id="count2">2000</div><span>sheep</span>
<div class="count" id="count3">1000</div><span>pigs</span>
Use an object that maps element IDs to the corresponding increments. Then use a complete: function that starts repeated animations with 3-second durations and the appropriate increment.
The key to getting the animations to repeat at the end is to use a named function, so it can call itself in the complete: option.
// #count1
let cowsIncrement = 3;
// #count2
let sheepIncrement = 2;
// #count3
let pigsIncrement = 1;
const increments = {
count1: cowsIncrement,
count2: sheepIncrement,
count3: pigsIncrement
};
$('.count').each(function() {
$(this).prop('Counter', 0).animate({
Counter: $(this).text()
}, {
duration: 1500,
easing: 'swing',
step: function(now) {
$(this).text(Math.ceil(now).toLocaleString('de-DE'));
},
complete: repeatAnimation
});
});
function repeatAnimation() {
let increment = increments[this.id];
let current = Number($(this).prop('Counter'));
console.log(this.id, current, increment);
$(this).animate({
Counter: current + increment
}, {
duration: 3000,
easing: 'swing',
step: function(now) {
$(this).text(Math.ceil(now).toLocaleString('de-DE'));
},
complete: repeatAnimation
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="count" id="count1">3000</div><span>cows</span>
<div class="count" id="count2">2000</div><span>sheep</span>
<div class="count" id="count3">1000</div><span>pigs</span>
I am working on an animation to show this kind of effect using animejs, I have been able to show push the text after 1000ms each and change the opercity to 0.5. But its not in sync like the one in this gif what can I do to add make the effect effective for delay and duration.
My html code with the text all the text, which is shown base on the loop.
<div class="onboarding-content">
<div [class]="bottomStyle">
<div class="onboardtxt one">
<p [class]="firstAnimation">Hello, Meet Mat</p>
</div>
<div class="onboardtxt two">
<p [class]="secondAnimation">Some text</p>
</div>
<div class="onboardtxt three">
<p [class]="thirdAnimation">Some text two </p>
</div>
<div class="onboardtxt four">
<p [class]="forthAnimation">Some text three</p>
</div>
</div>
</div>
My js file
// Animation
count: number;
display: string = "display";
firstAnimation: string = "first";
secondAnimation: string = "second";
thirdAnimation: string = "third";
forthAnimation: string = "forth"
truthy: any;
bottomStyle: string = "bottom"
constructor(public navCtrl: NavController) {
var messages = ['1','2','3','4','5']
var count = 0;
var that = this
var timer = function () {
if (count === 1) {
that.firstAnimation = "first-para-animation";
} else if (count === 2) {
that.firstAnimation = "first-second-fire-animation";
that.secondAnimation = "second-para-animation";
} else if (count === 3) {
that.secondAnimation = "second-second-fire-animation";
that.thirdAnimation = "third-para-animation";
} else if (count === 4) {
that.thirdAnimation = "third-second-fire-animation";
that.forthAnimation = "forth-para-animation";
} else if (count === 5) {
that.truthy = true;
// that.bottomStyle = "no-margin"
}
// check the length of count before pushing
if (count < messages.length) {
count += 1
} else {
clearInterval(interval)
}
}
// // setting the interval after how long it should call the timer function
var interval = setInterval(timer, 1000)
}
ionViewDidLoad() {
console.log('ionViewDidLoad home page');
anime.timeline({ loop: false })
.add({
targets: 'div.bottomStyle',
translateY: [
{ value: 10, delay: 0 },
// { value: 0, duration: 400 },
],
easing: "easeOutQuart",
duration: 0,
// delay: function (el, i, l) {
// return 1000 * i;
// },
// delay: function(el, i) {
// return 800 * i;
// },
color: '#fff'
})
anime.timeline({ loop: false })
.add({
targets: ['.onboardtxt.one',],
duration:100,
// delay:1200,
opacity: 0.5
})
anime.timeline({ loop: false })
.add({
targets: ['.onboardtxt.two',],
// delay:1300,
delay:4400,
opacity: 0.5,
// opacity: 0.5,
})
anime.timeline({ loop: false })
.add({
targets: ['.onboardtxt.three',],
delay:5500,
opacity: 0.5,
// delay:500
});
}
Have you looked at the documentation since then? It's quite good: https://animejs.com/documentation/#timelineBasics
Based on your code, you need to add to only ONE timeline, so that they are synced (the pushed texts happen sequentially).
Example derived from "Timeline Basics":
// Create a timeline with default parameters
var tl = anime.timeline({
easing: 'easeOutExpo',
duration: 750
});
// Add children
tl
.add({
targets: '.onboardtxt.one',
translateX: 250,
})
.add({
targets: '.onboardtxt.two',
translateX: 250,
})
.add({
targets: '.onboardtxt.three',
translateX: 250,
});
I've got the following code:
var tot = 0;
var prices = {
"Price1:": 37152.32,
"Price2:": 54023,
"Price3:": 37261.75
};
var animationDuration = 2000; // Must be lower than carousel rotation
function animatePrices() {
var dur = animationDuration / Object.keys(prices).length;
for (var key in prices) {
tot += prices[key];
$({
p: 0
}).animate({
p: tot
}, {
duration: dur,
easing: 'linear',
step: function(now) {
document.getElementById("total").textContent = now.toFixed(2);
document.getElementById("what-for").textContent = key + " $" + prices[key];
}
});
}
}
window.onload = function() {
animatePrices();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
$<span id="total"></span>
<br>
<span id="what-for"></span>
But as you can see, in the what-for span it shows Price3. But I want it to loop through the prices as the price goes up.
Ex:
When now is 37100 then what-for is Price1.
When now is 40000 then what-for is Price2.
When now is 100000 then what-for Price3.
What am I doing wrong?
The problem in you code is that it was calling animate inside a loop. That is messing up your the variable logic. You can use something like the following. I am using recursive call on animation end here.
var tot = 0;
var prices = {
"Price1:": 37152.32,
"Price2:": 54023,
"Price3:": 37261.75
};
var pricesArray = Object.keys(prices);
var animationDuration = 20000; // Must be lower than carousel rotation
var dur = animationDuration / pricesArray.length;
function animatePrices() {
key = pricesArray.shift();
start = tot;
tot += prices[key];
if(!key)
return false;
$({
p: start
}).animate({
p: tot
}, {
duration: dur,
easing: 'linear',
step: function(now) {
$("#total").text(now.toFixed(2));
$("#what-for").text(key + " $" + prices[key]);
},
done: animatePrices
});
}
window.onload = animatePrices;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
$<span id="total"></span>
<br>
<span id="what-for"></span>
If you like, added a ratio for each animation in Rejith R Krishnan code.
I changed the object associated array though, to :
var prices = [
37152.32,
54023,
37261.75
];
and the ratios :
var ratios=[];
for(var i = 0; i < prices.length; i++){
ratios[i]=prices[i]/total;
}
https://jsfiddle.net/a6k9w9k7/
hi i have some problem on jquery code . this code fade up on scroll i use number counter values in this code
countswing = 0;
tiles = $("div .newstats").fadeTo(0, 0);
$(window).scroll(function(d,h) {
tiles.each(function(i) {
a = $(this).offset().top + $(this).height();
b = $(window).scrollTop() + $(window).height();
if (a < b)
{
$(this).fadeTo(2000,1);
if(countswing<1)
{
jQuery({someValue: 0}).animate({someValue: 700}, {
duration: 1000,
easing:'swing', // can be anything
step: function() { // called on every step
// Update the element's text with rounded-up value:
$('#stats1').text(Math.ceil(this.someValue) + "+");
}
});
jQuery({someValue: 0}).animate({someValue: 500}, {
duration: 1000,
easing:'swing', // can be anything
step: function() { // called on every step
// Update the element's text with rounded-up value:
$('#stats2').text(Math.ceil(this.someValue) + "+");
}
});
jQuery({someValue: 0}).animate({someValue: 1000}, {
duration: 1000,
easing:'swing', // can be anything
step: function() { // called on every step
// Update the element's text with rounded-up value:
$('#stats3').text(Math.ceil(this.someValue) + "+");
}
});
countswing++;
}
}
});
});
but my problem is when i scroll download or scroll up number count not stop its number count again and again i want when i scroll download browser its fade up show then number count only one time when its number count complete then not its count again and again
i also use countswing variable of value 0 for stop counter . like you see in code but its not work it its show same problem .
please tell me how to do only count one time?
Here's a sample image of what i'm trying to accomplish
Say I click from 150 value the handle should only move to 50 and not jump to 150. I click again it move from 50 to 100.
The other way around, say the handle is on value 150 then i click on value 5, it should not jump directly to 5 it should move from 150 to 100.
How can I do that?
Here's my code:
var valMap = [5, 10, 20, 50, 100, 150];
value = 0;
var slider = $("#slider").slider({
disabled: false,
animate: true,
min: 0,
max: valMap.length - 1,
slide: function (event, ui) {
slider.slider("option", "animate", "slow");
},
change: function () {
var Slideval = $(this).slider('value');
console.log(Slideval, value)
if(value < Slideval) {
console.log("incremented")
} else if(value > Slideval) {
console.log("decremented")
}
value = Slideval;
}
});
Here's a sample jsfiddle: http://jsfiddle.net/endl3ss/jNwww/21/
I don't know the slider too much, but here is a working solution based on your specification:
http://jsfiddle.net/5xMMz/11/
and here is the full code for reference
var valMap = [5, 10, 20, 50, 100, 150,500,1000,5000];
value= 0;
var lastSlideValue = 0;
var internalSlideCalling = false;
var slider = $("#slider").slider({
disabled : false,
animate : true,
min : 0,
max : valMap.length - 1,
slide : function(event, ui) {
slider.slider("option", "animate", "slow");
},
change: function(){
var Slideval = $(this).slider('value');
if (!internalSlideCalling)
{
if (Slideval>lastSlideValue && lastSlideValue < $(this).slider('option','max'))
{
Slideval = lastSlideValue+1;
}
else if (lastSlideValue > $(this).slider('option','min'))
{
Slideval = lastSlideValue-1;
}
lastSlideValue = Slideval;
}
console.log(Slideval, value)
if(value < Slideval) {
console.log("incremented")
} else if(value > Slideval){
console.log("decremented")
}
value = Slideval;
if (!internalSlideCalling){
internalSlideCalling = true;
$(this).slider('value',Slideval);
}
else
internalSlideCalling = false;
}
});
$("#slider").slider('values',valMap);
Then you can use event which will raise when we move slider and then set the value for slider.We can manually set the slider value.
This is event code
slide: function( event, ui ) {
// code
},
$('#id').slider("value",value); //using this we can set the slider value
Use
$("#slider").slider({
step: 50
})
Here is the link for more information - http://jqueryui.com/slider/#steps