Jump to content
Search Community

Thomas James Thorstensson

Members
  • Posts

    71
  • Joined

  • Last visited

Posts posted by Thomas James Thorstensson

  1. 14 hours ago, GreenSock said:

    You don't have any "repeat" on your timeline, so repeatRefresh: true won't do anything there. In other words, that's not the thing that's repeating - your child tween is what's repeating, so that's where you need to set repeatRefresh: true. 

     

    Also, you can tell the gsap.utils.random() to return a function by passing true as the 3rd parameter so there's no need to wrap it in a function (though that's totally fine). Here's a demo where I increased the random value and made it use x instead of y for ease of visualization:

     

     

     

    Also, it's "circ.out", not "Circ.out". :)

     

    ---

     

    Thanks Jack that fixed that! +1 Barcelona beer owed !

     

    Thomas

    • Like 2
  2. 3 hours ago, mvaneijgen said:

    Use a function based value 

     y: () => gsap.utils.random(-5, 20),
    

    And if it is a timeline that gets invoked multiple times you can call `tL.restart().invalidate()` to invalidate the previous values. 

     

    A minimal demo is always better,  then we can also test our own solutions and show you a working working code. All you need it a single div with the class .exclam, which could not cost more then 5 minutes to setup. But hope it helps and happy tweening! 

     

    Thanks! As that did not change anything I will provide a demo tomorrow morning! But thanks for taking your time with the arrow call!

  3. Hello fellow Green sockers!

     

    Sorry for not providing a CodePen, up against it today.😅

     

    I'm trying to get this to randomize;

    .fromTo(".exclam", { y: 5 }, { duration: .2, y: gsap.utils.random(-5, 20), yoyo: true, repeat: 20}, "<")

    But it is not working! It seems to stop at same value each time. I been away from the green a while and must be missing something obvious.

     

    I've set repeatRefresh to true like so

      const tL = gsap.timeline({ repeatRefresh: true, defaults: { ease: "Circ.out", duration: 1 } });

    Any help and I owe you a beer here in Barcelona, 🍺

     

    Thanks, Thomas

  4. 44 minutes ago, Thomas James Thorstensson said:

    Hello fellow Greensockers!

     

    Here is my little question.

     

    I'm calling an instance method of a Typescript class from my class Banner.ts

    .call(this.imageTiler.doFadeOut,[1], 3);

     

    In ImageTiler class I have

    doFadeOut(imgIndex) {
    this.tileCreatorArr[imgIndex-1].doFadeOut();
    }

     

    Now of course, ''this" in ImageTiler will refer to the Tween I'm calling from in Banner.ts, so the tileCreatorArr is undefined. How do I best bind this up so that I can call doFadeOut and get this to refer to ImageTiler class ?

     

    Thanks in Advance 😎

     

     "S"

     

    Replying to myself here as I found the solution I think. The below works 😎

     

    .call(() => {
    this.imageTiler.doFadeOut(1) //Call the fit function again as action box size is variable and brand area may have been re-sized/hidden
    },[1], 3)
    • Like 1
  5. Hello fellow Greensockers!

     

    Here is my little question.

     

    I'm calling an instance method of a Typescript class from my class Banner.ts

    .call(this.imageTiler.doFadeOut,[1], 3);

     

    In ImageTiler class I have

    doFadeOut(imgIndex) {
    this.tileCreatorArr[imgIndex-1].doFadeOut();
    }

     

    Now of course, ''this" in ImageTiler will refer to the Tween I'm calling from in Banner.ts, so the tileCreatorArr is undefined. How do I best bind this up so that I can call doFadeOut and get this to refer to ImageTiler class ?

     

    Thanks in Advance 😎

     

     "S"

  6. Hi fellow Green Sockers,

     

    A small question. I have

     

    Animation.masterTL = gsap.timeline({ paused: true, repeat: AnimationSettings.loops, repeatDelay: AnimationSettings.loopDelay });
    
    Animation.masterTL.stop();

     

    This throws the error that stop is not a function of the timeline.

     

    Ok so the stop is called further down in the code after that the timeline starts. Is stop not part of GSAP 3+; I cannot see it in the documentation for 3+

     

    This works fine:

     

    Animation.masterTL.paused(true)

     

    Thankful for help, well I guess I sorted it anyhow, so now this is just on "curious" flag level (orange with a tint of green).

     

    Thomas

  7. 2 hours ago, OSUblake said:

     

    That comment is relevant to the example code. And maybe it should be written like this instead.

     

    
    tl.to(...)
      .to(...) //starts immediately after the previous tween's end time (sequenced)
      .to(..., ">-0.5") //overlaps with the previous tween by 0.5 seconds (because the number is negative)

     

    If you don't supply a position parameter, or use a relative one, like"+=1", it will be positioned at the end of the timeline. Using >  positions at the end of the last of the most recently added animation's end time.

     

    Keep in mind that you don't have to position everything sequentially, and can add stuff to a timeline later on. Check how the start time of the scale animation differs in these examples.

     

    The scale animation starts at 2 seconds because that's the end time of the timeline when it gets added.

     

    
    tl.to(".box", { x: 100, duration: 1 }, 1)
      .to(".box", { y: 100, duration: 1 }, 0)
    
      // Starts at 2 seconds
      .to(".box", { scale: 0.5, duration: 1 });

     

    Here, the scale animations starts at 1 second because the y animation is the most recently added animation, and its end time is 1 second.

     

    
    tl.to(".box", { x: 100, duration: 1 }, 1)
      .to(".box", { y: 100, duration: 1 }, 0)
    
      // Starts at 1 seconds
      .to(".box", { scale: 0.5, duration: 1 }, ">");

     

     

    Hello

     

    Thanks. The last two blocks of code made me realise what the difference is! I felt like I was driving down a murky rainy road in Montana in a jaguar, then looked up through the autumn trees and saw the sun, and the road cleared ahead.

     

    Thanks again!

     

    Thomas

    2 hours ago, OSUblake said:

     

     

    • Like 2
  8. Hello Greensockers of Iceland and other green areas of this planet :)

     

    I'm a bit confused about what the difference is between the two below.

     

    From GSAP 3 Release notes :

     

    ">" references the most recently-added animation's END time

     

    .to(..., "") //starts immediately after the previous tween's end time (sequenced)

     

     

    Is not the most recently added animation the same thing as the previous tweens end time so aren't the two above the same?

     

    Thanks

     

    Thomas

  9. 25 minutes ago, GreenSock said:

    Yep, this is all very intentional. The problem is that it's relatively common for people to want to animate the timeScale of other animations, so what would you expect this to do?: 

    
    let animation = gsap.to(...);
    
    // umm...should this tween's timeScale be 0.5 to start or should we animate animation.timeScale() to 0.5???
    gsap.to(animation, {timeScale:0.5, duration:2});

    See the problem? It's inherently ambiguous. 

     

    So to set the initial timeScale of a tween, you can just use the timeScale() method which is quite easy with chaining:

    
    gsap.to(...).timeScale(0.5)

    Does that clear things up? 

     

    Ahaaaa. Thanks for clarifying. Yes I can see the point now and it makes sense to me.

     

    Thanks for taking time!

     

    Thomas, over a cup of coffe!

    • Like 1
  10. Hello, 

     

    It seems to set timeScale I can not set it as creation parameter. Maybe I forgotten something here as I think I've done that before:

     

      this.tl = gsap.timeline({
        repeat: defaultValues.customVariable3,
        repeatDelay: 2,
        
        // THIS DOESNT WORK
        timeScale: defaultValues.customVariable5 || 1   // * this will later be defaultValues.animationSpeed
      });
    
      // THIS WORKS!
      this.tl.timeScale(defaultValues.customVariable5 || 1)

    Not a biggie as the second works but just checking if any fellow GSAP Mphil could advise me on why the first does not.

     

    Stay green, stay alive

     

    Thomas

  11. 24 minutes ago, ZachSaucier said:

    When we ask for a reduced test case we usually mean a complete test case where we see elements on the page and they do things (or don't do them due to an error). Only included the relevant parts as well.

     

    Please recreate a complete minimal demo using our CodePen starter pen as a base when you have the time.

    Sorry, 

     

    It works!

     

    I was over stressed and of course just needed to access it as this.message

     

    see it say it sorted!

     

    Thomas

  12. 3 minutes ago, ZachSaucier said:

    When we ask for a reduced test case we usually mean a complete test case where we see elements on the page and they do things (or don't do them due to an error). Only included the relevant parts as well.

     

    Please recreate a complete minimal demo using our CodePen starter pen as a base when you have the time.

    Okay, roger that, I will do that when I have the time but it will be EOP today I think. I have to push on into the mist as they say in the movies!

     

    Thanks

     

    Thomas, Greensocker

  13. 5 minutes ago, Carl said:

    i'm sure we could find a solution if you take the time to post a reduced test case. Tough working with out-of-context code snippets.

    Ad.prototype.animateThreeFrames = function() {
    
        this.tl.set("#message5, #message4 ", { autoAlpha: 0 });
    
        this.tl.to(".gwd-page-wrapper", { duration: .2, autoAlpha: 1 }, "+=0")
        this.tl.to("#cta", { duration: .2, autoAlpha: 1 }, "+=0")
    
        //1
        .to("#baseImage", { duration: 1, autoAlpha: 1 }, "+=0")
        .from("#message1", {duration: 1,autoAlpha: 0,x: 100})
        .to("#message1", {duration: 1,autoAlpha: 0}, "+=2")
        //2
        .from("#message2", {duration: 1,autoAlpha: 0,x: 100})
        .to("#message2", {duration: 1,autoAlpha: 0}, "+=2")
        //3
        .from("#message3", {duration: 1,autoAlpha: 0,x: 100})
    
        //if legal then show legal
        if (!defaultValues.legal == "") {
          this.tl.to("#message3", {duration: 1,autoAlpha: 0}, "+=2")
          this.animation = this.tl.from("#legal", {duration: 1,autoAlpha: 0, onComplete:this.legalLoopCount, callbackScope:this})
          this.message = this.message3;
        }else {
          this.tl.set("#legal", { autoAlpha: 0 });
        }
    };
    
    Ad.prototype.legalLoopCount = function (el) {
      console.log("value of element is now" + this.animation.message)
      if (this.loopIncr == defaultValues.customVariable3) {
        gsap.to(this.animation.message, {duration: 1,autoAlpha: 0, delay:2})
        gsap.to(this.animation.message, {duration: 1,autoAlpha: 1,delay:2})
      }
      this.loopIncr +=1;
    }
    

    Hi, this is the best I can do at moment as I have to push on with work here in office sorry. I tried the above which is as close to the video example I could get but hmm value is undefined. Thanks

     

     

  14. 6 minutes ago, Thomas James Thorstensson said:

    EDIT

    I spoke to early, sorry,

     

    I tried this line, but it didn't work. I will do a workaround now and pass a label!

     

      this.tl.from("#legal", {duration: 1,autoAlpha: 0, onComplete:this.legalLoopCount.bind(this), callbackScope:this, onCompleteParams:this.message3})
    6 minutes ago, Thomas James Thorstensson said:

     

     

     

     

    Oh great Thanks Carl :)

     

    I thought this was removed in the new flavour of GSAP! I must have misread that part :)

     

    Yes I did here I see the fine comment:

    “scope” values at all (except callbackScope). So no onCompleteScope, onUpdateScope, onStartScope, etc. 

     

    Okay, well this will fix it

     

    Thanks!

     

    Thomas 

     

  15. 2 minutes ago, Carl said:

    I'm guessing you will need to set callbackScope:this (assuming you are using GSAP 3)

     

    watch this video at 6:35

     

     

     

    Oh great Thanks Carl :)

     

    I thought this was removed in the new flavour of GSAP! I must have misread that part :)

     

    Yes I did here I see the fine comment:

    “scope” values at all (except callbackScope). So no onCompleteScope, onUpdateScope, onStartScope, etc. 

     

    Okay, well this will fix it

     

    Thanks!

     

    Thomas 

    • Like 1
  16. Hello again Fellow Socks of Green!

     

    Wondering what the best approach is for this. I cannot bind the onCompleteParams but I cannot figure out how to do it with a string say onCompleteParams:"#message5"

     

    Silly, I shold be able to figure out how to rewrite the gsap bits in legalLoopCount to work with string as argument but can't. Hmm. 

     

    
    this.tl.from("#legal", {duration: 1,autoAlpha: 0, onComplete:this.legalLoopCount.bind(this), onCompleteParams:this.message5})
    
    /**
     * @param {*} elStr The element we are hiding when showing legal
     */
    Ad.prototype.legalLoopCount = function (el) {
      console.log(el)
      if (this.loopIncr == defaultValues.customVariable3) {
        gsap.to(el, {duration: 1,autoAlpha: 0, delay:2})
        gsap.to(el, {duration: 1,autoAlpha: 1,delay:2})
      }
      this.loopIncr +=1;
    }

     

  17. 57 minutes ago, elegantseagulls said:

    Hi @Thomas James Thorstensson,

     

    Where/How are you defining your timeline?

    Hello here is the full code, and this works. As Long as I use an instance of gsap instead of timeline in legalLoopCount(), it works. 

    If I instead use timeline, same timeline, in legalLoopCount, it no longer works. This works:

     

    "use strict";
    
    /**
     * * Is initialized from the GWD default HTML document
     */
    
    function Ad() {
    
      this.loopIncr= 0;
      this.tapArea = document.querySelector("#tapArea");
      document.querySelector("#page1").style.opacity = 0;
    
      // GSAP !
      // repeat: sets number of loops
      this.tl = gsap.timeline({repeat: defaultValues.customVariable3, repeatDelay:2});
    
      this.tl2 = gsap.timeline();
      
      // Init
     // this.setAnimationDefaults();
      this.startAdLib();
      this.callGWDPlayPause();
      setTimeout(this.startAnimation.bind(this), 1000); 
    }
    
    /**
     * !TODO It is not clear if this init is needed since we are using gsap.timline
     * 
     */
    Ad.prototype.setAnimationDefaults = function() {
      this.tl.set("#baseImage", { autoAlpha: 0 });
      this.tl.set("#message1, #message2, #message3, #legal", { autoAlpha: 0 });
      
    }
    
    /**
     * One method for each frame count
     */
    Ad.prototype.animateThreeFrames = function() {
    
        //* See GWD html page where ad is opacity:0 from start
        this.tl.to(".gwd-page-wrapper", { duration: .2, autoAlpha: 1 }, "+=0")
    
        this.tl.to("#cta", { duration: .2, autoAlpha: 1 }, "+=0")
        //1
        .to("#baseImage", { duration: 1, autoAlpha: 1 }, "+=0")
        
        .from("#message1", {duration: 1,autoAlpha: 0,x: 100})
        .to("#message1", {duration: 1,autoAlpha: 0}, "+=2")
        //2
        .from("#message2", {duration: 1,autoAlpha: 0,x: 100})
        .to("#message2", {duration: 1,autoAlpha: 0}, "+=2")
        //3
        .from("#message3", {duration: 1,autoAlpha: 0,x: 100})
    
        //if legal then show legal
        if (!defaultValues.legal == "") {
          this.tl.to("#message3", {duration: 1,autoAlpha: 0}, "+=2")
          this.tl.from("#legal", {duration: 1,autoAlpha: 0, onComplete:this.legalLoopCount.bind(this)})
        }else {
          this.tl.set("#legal", { autoAlpha: 0 });
        }
    };
    
    Ad.prototype.animateFourFrames = function() {
    
    };
    
    Ad.prototype.animateFiveFrames = function() {
    
    };
    
    Ad.prototype.legalLoopCount = function () {
      if (this.loopIncr == defaultValues.customVariable3) {
        gsap.to("#legal", {duration: 1,autoAlpha: 0, delay:2})
        gsap.to("#message3", {duration: 1,autoAlpha: 1,delay:2})
      }
      this.loopIncr +=1;
    }
    
    /**
     * !TODO Needs to change to defaultValues.numberOfFrames later
     * Maybe Ill end up making these methods into regular functions no hoisting can be annoying
     */
    Ad.prototype.startAnimation = function() {
      
        switch (defaultValues.customVariable1) {
            case "3":
              console.log("CASE THREE");
              this.animateThreeFrames();
            break;
          
            case "4":
              console.log("CASE FOUR");
              this.animateFourFrames();
            break;
    
            case "5":
              console.log("CASE FIVE")
              this.animateFiveFrames();
            break;
    
          default:
            console.log("something gone wrong")
            break;
        }
    };
    
    /**
     * Default event handler
     */
    Ad.prototype.handleEvent = function(e) {
      e.preventDefault();
      switch (e.type) {
        case "click":
          break;
        case "webkitTransitionEnd":
          break;
    
        default:
          break;
      }
    };
    
    /**
     * * Ad-Lib
     * Helper methods
     * * Reflection: we should be fine calling them from inside class
     */
    Ad.prototype.startAdLib = function(e) {
      adlibStart();
    };
    
    Ad.prototype.endAdLib = function(e) {
      adlibEnd();
    };
    
    Ad.prototype.callAdlibScreenshot = function() {
      takeScreenshot();
      console.log("screenshot!");
    };
    
    Ad.prototype.stopAdlibScreenshot = function() {
      this.endAdLib();
      console.log("end screenshot!");
    };
    
    /**
     * * GWD
     * Helper methods
     */
    Ad.prototype.callGWDPlayPause = function() {
      gwd.auto_PauseBtnClick = function(event) {
        TweenMax.pauseAll(true, true, true);
        console.log("Pause Timeline");
      };
      gwd.auto_PlayBtnClick = function(event) {
        TweenMax.resumeAll(true, true, true);
        console.log("Play Timeline");
      };
    };
    
    /**
     * Start ad
     */
    function initAd() {
      window.ad = new Ad();
    }

     

    Thanks 

     

  18. I got no clue why but if I replace the legalLoopCount code with this, so I run gsap instead of timeline in legalLoopCount it works

     

    Ad.prototype.legalLoopCount = function () {
      if (this.loopIncr == defaultValues.customVariable3) {
        console.log("END")
        gsap.to("#legal", {duration: 1,autoAlpha: 0})
        gsap.to("#message3", {duration: 1,autoAlpha: 1})
      }
      this.loopIncr +=1;
    }

    Now it works. The other method is unchanged. I must be missing something. But I cant see what. If i put the "tl" back in it no longer works it is as if the timline looses track of the time once I jump into legalLoopCount

  19. 1 hour ago, ZachSaucier said:

    Isn't that because you have 

    
    if (!defaultValues.legal == "") {
      this.tl.to("#message3", {duration: 1,autoAlpha: 0}, "+=2")
      this.tl.from("#legal", {duration: 1,autoAlpha: 0,x: 100, onComplete:this.legalLoopCount.bind(this)})
    }

    running before legalLoopCount runs and then also fade it out in legalLoopCount? Without looking at an example, this is all very abstract but it very much seems related to your animation logic. Can you please try making a minimal demo in a CodePen?

    Sorry for no code pen a bit too busy at work at moment sorry.

     

    Well the reason for that is that if final loop it should fade out legal and show last message again (message3)

     

    But someohow the timing seem to collide at that point. But I mean just because "tl" is in a second method should not mess up the track of the timeline should it. If I take exactly the same two lines from legal loop count and drop them after the on complete in animateThreeFrames it works (if i make legalLoopCount blank and instead put the could right after the onComplete)

     

    Thanks

  20. Hello Feelow Green Socks!

     

    I have the below code. The second bit of gsap code in the method legalLoopCount, behaves oddly but if you put the same animation lines into the top method, it behaves correctly. Instead of ending at the first loop, when you have it in the second method, legalLoopCount, it fades in out and in again. If I lift the same finishing lines into top it works. I put the code in a second method since onComplete is the only way I can execute this action. Maybe I should do the looping manualy instead though and put the logic in one method, that way I can increment the loop counter without waiting for onComplete.

     

    I am sure I'm missing something obvious but it seems to me that somehow when the last bit of code resides in legalLoopCount, that GSAP somehow looses track

    of the timeline. I'm sure I missed something in my Brain.

     

    Code:

     

    Ad.prototype.animateThreeFrames = function() {
    
        //* See GWD html page where ad is opacity:0 from start
        this.tl.to(".gwd-page-wrapper", { duration: .2, autoAlpha: 1 }, "+=0")
    
        this.tl.to("#cta", { duration: .2, autoAlpha: 1 }, "+=0")
        //1
        .to("#baseImage", { duration: 1, autoAlpha: 1 }, "+=0")
        
        .from("#message1", {duration: 1,autoAlpha: 0,x: 100})
        .to("#message1", {duration: 1,autoAlpha: 0}, "+=2")
        //
        .from("#message2", {duration: 1,autoAlpha: 0,x: 100})
        .to("#message2", {duration: 1,autoAlpha: 0}, "+=2")
        //3
        .from("#message3", {duration: 1,autoAlpha: 0,x: 100})
    
        //if legal then show legal
        if (!defaultValues.legal == "") {
          this.tl.to("#message3", {duration: 1,autoAlpha: 0}, "+=2")
          this.tl.from("#legal", {duration: 1,autoAlpha: 0,x: 100, onComplete:this.legalLoopCount.bind(this)})
        }
    };
    
    Ad.prototype.animateFourFrames = function() {
    
    };
    
    Ad.prototype.animateFiveFrames = function() {
    
    };
    
    Ad.prototype.legalLoopCount = function () {
    
      console.log("___THIS LEGAL LOOP COUNT FIRES " + this.loopIncr)
      if (this.loopIncr == 1) {
         this.tl.to("#legal", {duration: 1,autoAlpha: 0}, "+=2")
         this.tl.to("#message3", {duration: 1,autoAlpha: 1})
      }
    
      this.loopIncr +=1;
    }

     

  21. Hi

     

    No errors, 

     

    <script id="js-gsap" src="https://s0.2mdn.net/ads/studio/cached_libs/gsap_3.0.1_min.js"></script>

    I now got the from for x and y to work. Just not for autoAlpha, I think it is GWD doing something odd in its rendered CSS will investigate meself thanks anyhow!

     

    Thomas

  22. Hello

     

    Great job on GSAP 3. I'm working for a client setting something up in Google Web Designer (unfortunately but they like it) with the

    great GSAP 3+

     

    I can get .to to work like usual but .from won't work:

     

    var tl = gsap.timeline();
    tl.from('#baseImage', {duration:1, autoAlpha:0})

     

    Hmm, I wonder why, hmm. Something to do with GWD timeline hmm.

     

    Thankful in advance for any ideas. Meanwhile I will use tl.set to set initial states and then .to since that works.

     

    Thanks

  23. Hello There ,

     

    Swedish London based Rich Media Banner Developer & Designer, with experience of building banners for a vast amount of clients. Canvas or no canvas, no problem. Greensock or Pixie? Can do. Story-boarding needed? I'm your man. Video? You bet! Interactive Javascript or image slider? Consider it done!  Can work over Zeplin or WeTransfer, whatever you prefer.

     

    Some of the companies I worked with:

    WWF, Ogilvy Gamesys, TBWA\Copenhagen, MRM Meteorite, McCann, The Two Marias, NKD Learning, DOOH, York Press, TAG Worldwide, Space66.

     

    Ad banner platforms I work with:

    Google Studio, Google Campaign Manager, Flashtalking, Celtra, Sizmek, AdForm, Admeto, + Yours (Send me the specs!)

     

    Contact me at hello@thomasthorstensson.co.uk for samples of recent work and a discussion of what you need done!

  24. 9 minutes ago, ZachSaucier said:

    Hey Snoop,

     

    It'd be helpful to have a minimal demo of what you're suggesting. Just guessing, I'd guess it's because filter creates a new compositing layer? I'm also guessing that adding a translate3d instead would reproduce the same effect. You can read more about compositing in this Smashing Magazine post (though the ladder half is a bit too long for me). 

     

    Hey, its Snoop,

     

    Thanks for the article link. I was not aware that it too creates a compositing layer like the translate3d fix. Thanks for pointing this out.

     

    I think I'm gonna go and have some coffe now.

     

    Thanks

×
×
  • Create New...