Jump to content
Search Community

darkus

Members
  • Posts

    36
  • Joined

  • Last visited

Posts posted by darkus

  1. 4 hours ago, Rodrigo said:

    Hi,

     

    I don't see anything that comes out as bad or potentially problematic in your code.

     

    Just an FYI, I tried this and seems to work fine on an iPad and android phone:

    let smoother = ScrollSmoother.create({
      wrapper: "#smooth-wrapper",
      content: "#page",
      effects: true,
      normalizeScroll: true,
      smoothTouch: 0.1
    });
    
    let brokenPin = gsap.timeline({
      scrollTrigger: {
        trigger: ".pinme",
        pin: true,
        start: "top top",
        scrub: 1,
        end: "+=" + pinAmount
      }
    });

    Here is a fork of your codepen:

     

     

     

    Here you can see the debug version (no iframes):

    https://cdpn.io/pen/debug/oNQevgB

     

    Now if the current version you have is working as expected, then keep it. Just sharing some insight about it in case it's helpful.

     

    Happy Tweening!

    Yup, with normalizeScroll it does work, but you lose the ability to pull down to refresh on iphone/ipad so it looses the true native feel of a webpage

  2. 5 hours ago, kanguyen-vn said:

    I think I figured it out after wrestling with it for a few hours. Basically I had to make new ScrollTriggers that pin every group of n cards on top of the screen, alongside those that pin the cards in each group at their respective y coordinates. The math got kind of confusing but luckily I worked my way through it. If anybody asks me to explain the code though,... 🏃‍♂️🏃‍♂️

     

    I also made it dynamic so that the number of cards shown at once can be replaced just via the cardCount variable. I don't know if this is the cleanest code (maybe there is a way to make it even more compact), but this does exactly what I want it to do. Thank you @darkus again for the nudge in the right direction 😀 Would still love to see if anybody has a cleaner solution to this problem!

     

     

     

    Nice work, the end result is very cool and reading through your code, what you are doing makes alot of sense.  👍

    • Like 1
  3. @GreenSock

    So as a follow-up.  I just discovered pinReparent.  Setting that to true, completely fixed my problem.  It seems to work on my actual page, and in the codepen example

     

    Hope I'm not doinganything terribly wrong by using it, but it seems to do the trick....

     

     

    Heres a fork using pinReparent

    See the Pen YzRQvQe by darkuss (@darkuss) on CodePen

  4. 9 minutes ago, GreenSock said:

    This has nothing to do with GSAP - if you set position: fixed on an element that's INSIDE another element that has a transform applied (which is what smooth scrolling does), that position: fixed will be relative to the container with the transform applied, NOT the viewport. You can try it on your own without any GSAP/ScrollTrigger. It creates a new stacking context or something like that. 

     

    Why did you set pinType: "fixed"? The default behavior automatically figures it out for you and uses pinType: "transform" which is the appropriate one in this context. You mentioned some kind of "bouncing" effect - what do you mean? Is it just on mobile? If so, there are several solutions you can choose from (because on mobile, ScrollSmoother disables smoothing): 

    1. Try setting ScrollTrigger.normalizeScroll(true)
    2. Set pinType: ScrollTrigger.isTouch ? "fixed" : "transform" 
    3. Set a small smoothing amount on mobile, like smoothTouch: 0.1

    You only need to choose ONE of the above options. 

    So to get a little more detailed on the issue,

     

    On desktop everything is working great out of the box (with scrollsmoother).  When loading the same exact page on iOS/mobile, the page has studdered scroll and pull to refresh dont work, so I decided to make an if/else statement and when we are on mobile, we dont load scrollsmoother

     

    if (isMobile == true)
        {
    
            gsap.registerPlugin(ScrollTrigger,MotionPathPlugin, Flip);
        }
    else
        {
    
            gsap.registerPlugin(ScrollTrigger, ScrollSmoother, MotionPathPlugin, Flip);
            
            
            smoother = ScrollSmoother.create({
                wrapper: "#smooth-wrapper",
                content: "#page",
                effects:true,
                    smooth:1.2,
            });    
    
        }   

     

     

    With this the page 'feels' great on both Desktop and iOS/mobile, but then the next problem was the pin dissapears as mentioned in the OP.

     

    I was assuming the pinType was being automatically being set to 'transform' while on desktop (because of scrollsmoother) and then now fixed for mobile.   So I went ahead and forced 'transform' on the mobile version as well.   That didnt work, so then I told it to pin it to the scroll-smoother outer html container  pin:(isMobile == true) ? "#smooth-wrapper" : true. 

     

    Well that did solve the problem of the pin dissapearing, and it now shows up during scroll.  But then a new problem arose, that all the triggers for animations after that pin were completly misaligned and firing to early. 

     

    So now back to putting scrollSmoother back on for mobile and then turning normalizeScroll off.  By turning it off, the page now acts and 'feels' native on iOS, but then I get the weird jelly bouncing of the elements inside the pin.  I feel like im in a catch22 no matter what I do

     

    Specifially to your suggestions:

    1. Setting normalize scroll to true, makes iOS feel non native.  Pull to refresh doesnt work well, and flicking to scroll fast is a bit jerky and feels uncharacteristically non slick by GSAP standards.  Making smoothtouch a low number has helped with this, but still not great.

    2. That is fine, and is my original plan, but is being stymied by the above things.

     

    As I mentioned, I feel like there is probably a simple solution here but anywway I got at it, I hit some kind of wall.  I figured solving why an area dissapears with a pin is the best method of attack.    Now reading up I can see this strange thing about transform not being relative.  So strange!

  5. I have the following codepen which shows the example.  In this example, there is a scrolltrigger (brokenPin) that pins an element, but all its content dissapears during the pin and then comes back after the pin is complete.   I've explicitly set the pinType to be 'fixed', as this is what I belive to be the default behavior and works better in most cases.  The transform pin has a weird bouncing effect that isnt that nice, so I'd rather have it as fixed.  On my real page, if I change it to transform type, then the pinspacing doesnt work for whatever reason and the scrolltriggers following the pinnned area come in immediatly.  This latter part I cant reproduce on codepen yet.  So my main question is the first part, why is everything disappearing, and is there any way around it besides switching to a transform pintype?

     

     

     

    See the Pen XWygYjX by darkuss (@darkuss) on CodePen

  6. So cribbing other peoples work and using an "unofficial" GSAP classname plugin, i've made an accordion menu where the name of the item will highlight when the mouse goes over the area, and should stay highlighted when the accordion is clicked/opened

     

    My problem is that when a user clicks another menu item, id like any highlighted accordion title to unhighlight and the other menus should collapse.  THe other menus do properly collapse, but I cant get the name to properly unhighlight.

     

    I tried simply mass unhighlighting using JQuery remove class and that kills the animation for any subsequent tries.   I'm not tied to using the add classname method, but thats all I could come up with because I couldnt figure out how to reverse a the animation if I just directly animate the classname change (text color change)

     

    Any ideas?

     

    See the Pen rNQjvpL by darkuss (@darkuss) on CodePen

  7. 3 hours ago, GreenSock said:

    It's pretty tough to troubleshoot blind, but are you using the latest version of ScrollSmoother/ScrollTrigger? I can't imagine how killing a ScrollTrigger (that was pinned) could possibly "wipe out" a bunch of page content. All it does is remove the pinSpacer and swap the original element back into where it started. My best guess is that you've got some sort of CSS/layout issue with how you built things that causes things to collapse if the pinSpacer element isn't there. Or maybe you're actually inserting a bunch of stuff INSIDE the pinSpacer which you definitely shouldn't do. If you can provide a minimal demo illustrating the problem, I'm sure we'd be able to identify the problem. 

    Agree with you, never seen anything able to just erase huge blocks of content like that before, especially from just killing a pin. 

     

    Not sure what is going on since I cant reproduce it on the sample codepen.   

     

    I'm going to keep playing with that pen to see if I can reproduce the problem (and will update you) or just delve deeper into how I coded my page.  Its become a gargantuan mess :) but I can say that pin/pinspacer is super clean with only 2 elements animating inside the pin, but has nothing to do with the parts that are getting just deleted off the screen

  8. 2 hours ago, GreenSock said:

    Yeah, this is a tricky scenario because you're removing a pin while the smoother is trying to "catch up" to the normal scroll position and you're changing the entire height of the page which would impact how ScrollSmoother is doing its smoothing distance-wise. 

     

    How about this?:

     

     

     

    Is that working the way you hoped? It's using the smoother's positioning rather than the native page's, and it's forcing a refresh() of the smoother's ScrollTrigger so that it gets based on the NEW page height. 

     

    Oh wow, seems to work really well on the codepen. 

     

    However, when I transpose it to my development site it doesnt work.  In my case, it jumps to the bottom of my page (creates some new blank whitespace, it semes like it wants to jump even below the bottom).  And as far as I can tell, it actually wipes out all my page content above where the pin was (ALOT of page content).  Its hard to explain, I've never seen anything like that.  I'm trying to replicate the effect on codepen but I cant.  

     

    Heres to a longshot that my description rings any bells?

  9. Sorry ahead of time for the ultranoob question

     

    I've read the timeline part of the GSAP docs over and over and I think I understand most of what it says   I'm also getting most of my timelines to work well, probably our of sheer luck (goes to show how well GSAP is written I guess :)

     

    But I have a fundamental question that I dont understand and need help with as my animations are getting more complex:

    How do you translate pixel length into time for timeline duration/delay/etc?

     

    Right now, if I setup a timeline with a scrolltrigger, say to trigger at the start and end of a certain div


     

    let mytimeline = gsap.timeline({
         scrollTrigger: {
             trigger: ".myDiv",
              start:'top bottom',
              end:"bottom top",
              scrub: true,
              markers:true,
    
            }
        });

     

    1. The actual scroll length of the mytimeline timeline is determined by the length of the div, how does that translate to the 'seconds' length of a GSAP timeline?  Is whatever the length of my div by default equal to 1 second, 10 seconds, etc..  for example?

     

    2. If I start adding things to my timeline, then the timeline will lengthen since they are added to the end of the timeline, but by how much length is the timeline lengthened if no duration is explicitly given?

     

                                          mytimeline.to(
                                              ".mySecondDiv", {
                                                  opacity: 0, 
                                                      }, 0);

     

    3. In my above example, say I gave my .to a duration of 1 second, does that mean 1 second = 1000pixles (the height of .myDIv), for example?

     

    Thank you!

  10. 10 hours ago, Rodrigo said:

    Hi,

     

    I'm not saying that is inherent to ScrollSmoother. The solution being applied here is based on ScrollTrigger and maybe there's a better one that's eluding me, that's all.

     

    Finally out of curiosity, the demo in my previous post is working in the way you intend or not?

     

    Happy Tweening!

    No unfortunatly it doesnt work :(

  11. 3 hours ago, Rodrigo said:

    Hi,

     

    I think this could be related to the way ScrollSmoother works actually. The solution you're trying does actually work in a scenario with just ScrollTrigger as you probably saw in the other threads where this was implemented, like here:

    The best solution I can come up with is to pause the ScrollSmoother instance for a bit and then use a timeout to un-pause it and instead of using the ScrollTrigger instance that is pinning the section, better use the ScrollTrigger instance associated with ScrollSmoother. Here is a fork of your codepen:

     

     

     

    Still the setTimeout option doesn't make me very happy, so I'll check with the top floor offices and see if there is a better way.

     

    Hopefully this helps.

    Happy Tweening!

    Well its certainly good to hear i'm not totally crazy and this could be inherent to the way scrollsmoother is designed.  If a solution does come from up above, that would be outstanding.  Thanks for championing this!

  12. 1 hour ago, Rodrigo said:

    Hi,

     

    I think the biggest issue is on this part:

    let t0 = gsap.timeline({
      scrollTrigger: {
        trigger: ".MediaArea",
        start: "center center",
        end: "bottom 20%",
        duration: 10,
        pin: true,
        scrub: true,
        //markers:true,
        onLeave: anim,
        onLeaveBack: anim
      }
    });

    You're creating an animation with a ScrollTrigger instance in it, everytime you pass certain points in t0 ScrollTrigger instance. That spells trouble to me. On top of that I'm having a bit of a hard time following the order of events in your code and finding out what does what exactly.

     

    Keep in mind that the golden rule for ScrollTrigger is to create your ScrollTrigger instances in the order they happen, right now you're creating the animation with the scrubbed Flip instance after all your ScrollTrigger instances have been created. Strictly speaking that should happen after the pin of the first section but before the letters staggered animation. On top of that I set the everytime above in bold for a reason, there is absolutely no need to create that instance on every pass, just on resize, as the example I linked in the other thread does:

    let flipCtx;
    function anim() {
      flipCtx && flipCtx.revert();
      const p1 = document.querySelector(".p-1");
      const p2 = document.querySelector(".p-2");
      const bg = document.querySelector(".p-bg");
      p1.appendChild(bg);
      bg.style.cssText = ""; // clear out the inline styles (shouldn't be necessary beyond 3.11.5)
      
      flipCtx = gsap.context(() => {
        const state = Flip.getState(bg, {props: "transform"});
        p2.appendChild(bg);
        const flip = Flip.from(state, { absolute: true });
    
        ScrollTrigger.create({/*...*/});
      });
    }
    
    anim();
    
    window.addEventListener("resize", anim);

     

     

     

    Unfortunately your example has a lot of moving parts and we don't have the time resources to solve complex issues for our users. I can give you some advice on how I would tackle this:

    • Make the black element and the image container children of the same element, that is also a child of the element with the MediaArea class. Right now the starting positions are a bit odd since you're pinning just the black element. With this approach you can pin the parent of the black box and the image without any issues.
    • Focus on creating the Flip animation first and toggle it with a button. Forget about ScrollTrigger for now.
    • Once the Flip animation works as expected add ScrollTrigger just for that animation and pinning that section, forget about the letters.
    • Once the Flip animation works with ScrollTrigger add the letters back to the mix.

    Hopefully this helps.

    Happy Tweening!

     

    Thanks for the detailed reply, I went through what you said with a fine toothed comb :)

     

    Just somenotes/follow-up questions if I can pick your brain

    1. The black box (.blackbox) and the image container (.MediaAreaImage) are both contained/parented by .MediaArea and it is .MediaArea that is getting pinned

    2. The flip animation without the scrollTrigger does work very well, but because of the attempt to make it scrub, I decided to go ahead and integrate it with scrolltrigger per your prior suggestion and its so close now

    3. The reason I have anim() starting with each scrolltrigger at the onLeave point is because if I just run it at page load, it immediately removes the target .MediaAreaImage from the .MediaAream and does not respect the pinning of its container (.MediaArea)

     

    You can see that in the following variant CodePen where the image scrolls in under the black box

     

    In actuallity, the black box and the image are absolutly positioned div and are supposed to be on top of each other, with the black box fading away to show the image under that is at the same time going to Flip to the final target

     

    See the Pen BaGQGrx by darkuss (@darkuss) on CodePen

  13. I have a fairly large pin area with alot of complex animations inside of it.  I want this pin to run only one time. 

     

    Using once:true isnt good because it leave alot of whitespace

     

    So I've read about killing the trigger onLeave

     

    I know there have been several posts about this, and I read through all of them and tried to implement all the permutations but still cant get this to work properly.

     

    My problem is that there is still a bit of a kick as the page jumps as the whitespace is being removed and the scroll location is jumping to where it was 'supposed' to be

     

    1. You notice the effect, if you scroll through the pin at a decent speed, sometimes its percieved as a pause, othertimes its seen as a glitchy short jump if you have this pen on full screen (short jump meaning its jumping to the wrong place)

    2. On my development page the incorrect jump distance is much larger. I cant replicate this on codepen, likely because my real page is much much larger and more complex

     

    See the Pen MWzbPor by darkuss (@darkuss) on CodePen

  14. Pinspacing basically creates a blank space (a fakeout) which is the length of the pin, so in your second panel, it creates a blank space thats the length of your x translation, which is defined by the start and end positions you gave the scrolltrigger.

     

    Because of that blank space the last panel stays down while you scroll through the images (the last panel is REALLY far down).

     

    If you turn pinspacing off, then that blank space is not created-and the third panel is just below the second panel, as would be the case if you didnt use GSAP at all, thats why its covering the second panel so fast.

     

    In your case, I'm thinking putting all of it in a timeline and then sequencing the specific times when you want things to show might be the most accurate way to do it, but admittedly i'm not an expert so i'll let them weigh in

  15. This is a continuation of a prior thread 

     

    In essence, I am trying to move a div that has an image inside of it, to the space of another div, in the meantime transforming the div/image into a circle and resizsing it to the target div size.

     

    In this case, the sequence of events is:

    1. Black box div should appear

    2. Black box div should get pinned while the user scrolls

    3. Black box div should fade away revealing an image underneath

    4. Image will then transform into a circle and resize a little so that its truly circular (black box is actually a rectangle)

    5. Using Flip, the image will then move from its pinned location to a final target as the pin is released

     

    This is all working for the most part

     

    My problem occurs if a user decides to scroll up during this set of events, where everything gets reversed with scrub.

     

    1. If you try to scroll up, what you will notice happen is that the circular image will go back to the source div using Flip, but then if the user decides to scroll forward again, the image stops moving with the black box, and then the user can see it actually scroll up behind the black box as the black box is pinned.  Its as if the absolute posiitioning is not being undone somehow?

    2. The image is not being properly resizes anymore, so that when you do scroll back forward again and the flip occrs a second time, the image is now larger then the target green box

    3. This third problem is much less important, for some reason the resized image doesnt exactly lineup with the green box.  Not exactly sure why, because in my actual size it does line up perfectly.  I messed something up in the translation to codepen.  I can probbaly figure this one out.

     

     

    Any ideas?

     

     

    See the Pen mdQOjPW by darkuss (@darkuss) on CodePen

  16. gsap.getProperty has been a lifesaver, but it seems to give the calculated value.  For example if I have height:calc(100% - 50px); in my CSS value, gsap.getProperty will return 550px instead ofcalc(100% - 50px) (as it should).  But is there an option or flag to allow me to get it to give me calc(100% - 50px)?  And as a follow-up, can I actually gsap.to with a value such as calc(100% - 50px)

  17. 30 minutes ago, Rodrigo said:

    Hi,

     

    Maybe you're looking for something like this:

     

     

     

    Hopefully this helps.

    Happy Tweening!

     

     

    In your modification the other boxes are not shrinking, so the overall width of the container will expand off the screen

     

    I'm wondering if this is a limitation with use of grids with 'auto' width, and I need to do some more complex code to explicitly set the width for each box

  18. I've setup a grid of 3 content boxes that should expand when hovered over and then shrink again.   When one of the boxes expands, the others will have a compensatory shrink thanks to CSS grids

     

    Currently, the expansion and shrink effect works perfectly if you enter or leave any single box from outside the grid area.

     

    However, a problem arises when you try to move from one hovered box to another hovered box, lets say "Box content 1" directly to "Box content 2".  In this case, then the box you are leaving correctly shrinks, but the box that expands, has a little 'hiccup' or a pause and then snaps slightly then continues to grow as normal.

     

    I've put an image as a background into the 3 boxes, to really highlight the jarring effect, but you can just delete the image and will see red boxes and also be able to see the problem in its purest form.

     

    I'm imaging the animations between enter and leave are "fighting" one another and thats why thats happening, but thats just a simplistic explanation.

     

    Anyone have ideas on how to smooth this transition out?

     

     

    Of course, a codepen is better then my description:

     

    See the Pen LYXZxXd by darkuss (@darkuss) on CodePen

  19. To me, this looks like you are almost pinned that area twice?  I changed it to set the pin only one time for the main area, as it looks like you are animating the content in.  With this change I dont see the jump effect anymore

     

    I added some area top and bottom for aesthetics to see how it could look in real life, see what you think
     

     

     

    See the Pen vYVqovo by darkuss (@darkuss) on CodePen

     

    • Like 1
×
×
  • Create New...