How to make an animated number counter?

I want to add an animated number counter-up, I found this code online but I’m having a hard time changing the number, I want it to start from 0 to 10000. and want it to slow down a little, It runs to fast for my needs.

100
body { font-family:Helvetica; font-size:40px; color: [#fcdb17](https://www.wix.com/velo/forum/search/~num~fcdb17) ;

}

1 Like

Try this code, just remember to create a Text Element with #text string as its id.

$w.onReady(() => {
  let count = 0 //start time
  const endTime = 10000 // end time
  const interval = 100 // interval between counts ms
  const counter = setInterval(() => {
    $w('#text').text = String(count) // update text
    count === endTime && clearInterval(counter) // clears the interval when count is equal to endTime
    count++ // increment count
  }, interval)
})


How to make not load with page but load with scroll to it?

Just add an element to be your anchor and use a method called . onViewportEnter() to call this same code I created.

To clean the code a little bit, let’s put all this code inside a function called startCounter() and then we call it.

const startCounter = () => {
  let count = 0 //start time
  const endTime = 10000 // end time
  const interval = 100 // interval between counts ms
  const counter = setInterval(() => {
    $w('#text').text = String(count).toLocaleString('en-US') // update text
    count === endTime && clearInterval(counter) // clears the interval when count is equal to endTime
    count++ // increment count
  }, interval)
}

$w.onReady(() => {
  $w('#element').onViewportEnter(startCounter)
})

Thank you so much.
one more question, How to add a comma separator in the numbers like 10,000 instead of 10000, and is there a way where we can add β€œ+” at the end like 10,000+.
Thank you

@midosaid88 just add this method to the string: . toLocaleString ()
The parameter inside the method can be empty (so the user locale is going to be used) or you can set it to the locale you want, like: β€˜en-US’

@bwprado like that? It does not add the comma

const startCounter = () => {
let count = 0 //start time
const endTime = 10000 // end time
const interval = 1 // interval between counts ms
const counter = setInterval (() => {
$w ( β€˜#text37’ ). text = String ( count ). toLocaleString () // update text
count === endTime && clearInterval ( counter ) // clears the interval when count is equal to endTime
count ++ // increment count
}, interval )
}

$w . onReady (() => {
$w ( β€˜#text37’ ). onViewportEnter ( startCounter )
})

@midosaid88

$w.onReady(()=>{
    $w('#text37').onViewportEnter(()=>{
    let count = 0 //start time
  const endTime = 10000 // end time
  const interval = 100 // interval between counts ms
  const counter = setInterval(() => {
    $w('#text').text = String(count) // update text
    count === endTime && clearInterval(counter) // clears the interval when count is equal to endTime
    count++ // increment count
  }, interval)
    })
})
1 Like

@midosaid88 because it is already a string, sorry for not being specific.

Try this:

$w('#text37').text = count.toLocaleString()

@bwprado Thanks

@bwprado When I add two counter, Non of them works

const startCounter = () => {
let count = 9550 //start time
const endTime = 10000 // end time
const interval = .005 // interval between counts ms
const counter = setInterval(() => {
$w(β€˜#text57’).text = count.toLocaleString() // update text
count === endTime && clearInterval(counter) // clears the interval when count is equal to endTime
count++ // increment count
}, interval)
}

$w.onReady(() => {
$w(β€˜#text57’).onViewportEnter(startCounter)
})

const startCounter = () => {
let count = 1900 //start time
const endTime = 200000 // end time
const interval = .005 // interval between counts ms
const counter = setInterval(() => {
$w(β€˜#text59’).text = count.toLocaleString() // update text
count === endTime && clearInterval(counter) // clears the interval when count is equal to endTime
count++ // increment count
}, interval)
}

$w.onReady(() => {
$w(β€˜#text59’).onViewportEnter(startCounter)
})

@midosaid88 that is not how you add two counters, and .005 is not a valid microseconds interval, if I am not wrong. To create two counters, you are going to need a different function and start them on the same .onReady() method.

@bwprado I’m not good at coding at all and trying to learn as I go.

and I actually need 3 counters

@midosaid88 this is the function you need. I hope you can understand, because it is a curried function.

const createTimer = (element, interval) => (startTime, endTime) => {
  let count = startTime
  const counter = setInterval(() => {
    element.text = count.toString()
    count++
    count === endTime && clearInterval(counter)
  }, interval)
  return counter
}

const timer1 = createTimer($w('#text1'), 1000) // element and interval
const timer2 = createTimer($w('#text2'), 500) // element and interval
timer1(1, 10) // startTime and endTime
timer2(1, 10) // startTime and endTime


1 Like

@bwprado Thank you so much.
When I add $w . onReady (() => { $w ( β€˜#element’ ). onViewportEnter ( startCounter )}) to make the counter start on View Port Enter, it dosen’t work. What I’m doing wrong?

@midosaid88 did you create an element with the ID #element? My example was just for illustration. You need to have an element that is going to trigger this method.

@bwprado Still doesn’t work, here is the full code
const createTimer = ( element , interval ) => ( startTime , endTime ) => {
let count = startTime
const counter = setInterval (() => {
element . text = count . toLocaleString () // update text
count ++
count === endTime && clearInterval ( counter )
}, interval )
return counter
}

const timer1 = createTimer ( $w ( β€˜#text57’ ), 1 ) // element and interval
const timer2 = createTimer ( $w ( β€˜#text59’ ), 1 ) // element and interval
const timer3 = createTimer ( $w ( β€˜#text58’ ), 100 ) // element and interval
timer1 ( 9456 , 10001 ) // startTime and endTime
timer2 ( 198650 , 200001 ) // startTime and endTime
timer3 ( 1 , 101 ) // startTime and endTime

$w . onReady (()=>{ $w ( β€˜#text57’ ). onViewportEnter ( startCounter )})
$w . onReady (()=>{ $w ( β€˜#text59’ ). onViewportEnter ( startCounter )})
$w . onReady (()=>{ $w ( β€˜#text58’ ). onViewportEnter ( startCounter )})

@midosaid88 you can only have one onReady() method per page. It is the method executed when the elements on the page are rendered.

Refactor your code with one onReady with all the elements onViewportEnter() method inside.

@bwprado like this?

const createTimer = ( element , interval ) => ( startTime , endTime ) => {
let count = startTime
const counter = setInterval (() => {
element . text = count . toLocaleString () // update text
count ++
count === endTime && clearInterval ( counter )
}, interval )
return counter
}
$w . onReady (() => {
$w ( β€˜#text57’ ). onViewportEnter ( startCounter )
$w ( β€˜#text58’ ). onViewportEnter ( startCounter )
$w ( β€˜#text59’ ). onViewportEnter ( startCounter )
})

const timer1 = createTimer ( $w ( β€˜#text57’ ), 1 ) // element and interval
const timer2 = createTimer ( $w ( β€˜#text59’ ), 1 ) // element and interval
const timer3 = createTimer ( $w ( β€˜#text58’ ), 100 ) // element and interval
timer1 ( 9456 , 10001 ) // startTime and endTime
timer2 ( 198650 , 200001 ) // startTime and endTime
timer3 ( 1 , 101 ) // startTime and endTime

@midosaid88 no, I just realized there are a lot of mistakes in your code. When I get on the PC I’ll send you the solution.