Jump to content
GreenSock

tomektomczuk

Counter controlled by ScrollTrigger (Uncaught TypeError: func is not a function)

Go to solution Solved by Carl,

Recommended Posts

I have a counter controlled by ScrollTrigger 

timeline() {
   const counters = document.querySelectorAll( 'span.counter' );
   const tl = gsap.timeline( { paused: true } );
   counters.forEach( ( counter ) => {
      tl.from( counter, {
         textContent: 0,
         duration: counter.parentElement.getAttribute(
            'data-counter-duration'
         ),
         ease: 'power1.in',
         snap: { textContent: 1 },
         scrollTrigger: {
            trigger: counter,
            markers: true,
            onEnter: tl.play(),
         },
      } );
   })

}

and whenever element reach the scroller-start I get Uncaught TypeError: func is not a function

 

_callback = function _callback(self, func) {
  if (self.enabled) {
    var result = func(self);
    result && result.totalTime && (self.callbackAnimation = result);
  }

 

Link to comment
Share on other sites

@tomektomczuk  I've moved your question to its own topic, please create your own topic when asking future questions.

 

Can you provide a minimal demo if your issue. What you are showing now is 1/3 of the needed to get any change of debugging. Where is the HTML and CSS? If you could provide this in a Codepen, someone will be sure to help you out. 

 

Personally I never create a ScrollTrigger in a tween,  I always add it to the timeline it self, but its hard to debug without a minimal demo 

const tl = gsap.timeline( 
  { paused: true },
	scrollTrigger: {
		trigger: counter,
		markers: true,
		onEnter: tl.play(),
    },
);

 

Link to comment
Share on other sites

Hi I have created little demo for this 

See the Pen JjZKyqJ by tomektomczuk (@tomektomczuk) on CodePen

 

and you can see the same result on the console. I would also like the counter to be recalculated on the scroll back

Link to comment
Share on other sites

I've moved your tl to be created for each counter and move the ScrollTrigger logic to the timeline. I've removed your onEnter and onLeave and set scrub: true, this will make it that the animation is connected to the users scroll, so if you scroll down the counter will count up and if you scroll back the counter will count down.

 

See the Pen dyKXVMe?editors=0010 by mvaneijgen (@mvaneijgen) on CodePen

 

I can't see any of the errors you mentioned. And I don't know what you mean by the following 

19 minutes ago, tomektomczuk said:

I would also like the counter to be recalculated on the scroll back

 

I would advise you to take a look at the docs https://greensock.com/docs/v3/Plugins/ScrollTrigger and study its content, the videos are also great on there! Everything you want to know is in there.

 

Hope it helps and happy tweening! 

  • Like 1
Link to comment
Share on other sites

Sorry I have used incorrect attribute.

 

import { gsap, ScrollTrigger } from 'gsap/all.js';
gsap.registerPlugin( ScrollTrigger );

export default class Counter {
   constructor() {
      this.timeline();
   }
   timeline() {
      const counters = document.querySelectorAll( 'span.counter' );
      counters.forEach( ( counter ) => {
         if (
            counter.parentElement.getAttribute( 'data-counter-duration' )
         ) {
            const scroll = counter.parentElement.getAttribute(
               'data-counter-scroll'
            );
            const comma = counter.parentElement.getAttribute(
               'data-counter-comma'
            );
            const tl = gsap.timeline( {
               paused: true,
               scrollTrigger: {
                  trigger: counter,
                  toggleActions:
                     scroll === 'true'
                        ? 'restart none none none'
                        : 'play none none none',
               },
            } );

            tl.from( counter, {
               textContent: 0,
               duration: counter.parentElement.getAttribute(
                  'data-counter-duration'
               ),
               ease: 'power1.in',
               snap: { textContent: 1 },
            } );
         }
      } );
   }

   numberWithCommas( number ) {
      return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
   }
}

 

How can I apply numberWithCommas so it will work like in the following example ?

See the Pen b2c2c56064274fd14620faa9d5537e40 by akapowl (@akapowl) on CodePen

 

Link to comment
Share on other sites

With these kind of questions we love to see what you've already tried in a minimal demo,  so we can better understand what you ar struggling with. For this its just adding the the function to your code and add the onUpdate logic to the tween, almost exactly like the example you've provided. 

 

See the Pen ZEROrrK?editors=1011 by mvaneijgen (@mvaneijgen) on CodePen

  • Like 2
Link to comment
Share on other sites

  • Solution

Excellent job as always @mvaneijgen

 

I just recently learned about toLocaleString()

const num = 123455.34
console.log(num.toLocaleString())

//output 123,455.34

 

Great for currency too!

 

 

docs

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString

 

See the Pen jOKrZJy?editors=0010 by snorkltv (@snorkltv) on CodePen

  • Like 3
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×