Infinite scrolling carousel with hover effects using Framer Motion

Поделиться
HTML-код
  • Опубликовано: 15 ноя 2024

Комментарии • 62

  • @Akios281
    @Akios281 8 месяцев назад +5

    I had been trying to do this for weeks with Framer Motion using a different approach, but I wasn’t as satisfied. Thank you for this great tutorial. I’m learning a lot by following you. I prefer this video format focused on a replicable component that can easily adapt to various situations over the lengthy clone videos.

    • @builtwithcode
      @builtwithcode  8 месяцев назад +1

      Glad to hear you’re finding value from the videos! And thanks for the feedback on the video lengths, I’ll continue to focus on more narrow tutorials but may experiment with a longer build in the future.

  • @jasiekhalczuk4974
    @jasiekhalczuk4974 Месяц назад

    best framer-motion carousel tutorial, blessing

  • @NotWasim
    @NotWasim Месяц назад

    This is class. Made it super simple to understand what everything is!

  • @spillttea3195
    @spillttea3195 5 месяцев назад +1

    Bro I was trying to do this for so long but you were the only one who explained it properly! thanks so much for the video !

  • @aleaus
    @aleaus 6 месяцев назад +7

    To eliminate the jump give the motion.div a width: max-content

    • @kosti2647
      @kosti2647 6 месяцев назад +1

      exactly! otherwise it might have width capped by the end of the viewport

    • @meirbek241
      @meirbek241 5 месяцев назад +1

      thank you

  • @alexandrebtn
    @alexandrebtn Месяц назад

    Thanks a lot for this video !

  • @faisalrehman3868
    @faisalrehman3868 5 месяцев назад +1

    after 25 sec of duration it give a jerk and restart from the 1st image that looks wired if you decrease duration to less i.e 5. is there any fix for this thing ?

  • @raimondszakis8337
    @raimondszakis8337 3 месяца назад +1

    I used this as example for my infinite vertical carousel, I am having issue where complete callback is never called despite animation running in loops, this in turn causes issue when onDrag Y pos is updated, I end up creating control version where Y pos is not different after animation has finished looping once :D quite funny, I'll try to sort that on my own
    ----update
    Fun fact, onRepeat callback is not implemented, it only exists as part of .d.ts file as interface value.
    I fixed my issue by manually detecting when I am close to finishing single iteration via onUpdate callback, and seting mustFinish(false)

  • @bhagyeshpatel6472
    @bhagyeshpatel6472 5 месяцев назад

    Great 🎉 very helpful , Just one question can we change animation direction from left to right.?

  • @DazzyDude00
    @DazzyDude00 4 месяца назад +1

    Didn't really need to use a 3rd party package to get the size of the div container, could've used `scrollWidth` to get that value

  • @ChampuStrike
    @ChampuStrike Месяц назад

    I been trying to replicate the same but i get snaps back to the begining instead of it reseting in the background, what am i doing wrong?

  • @cx20012002
    @cx20012002 5 месяцев назад

    great video, just 1 quick question, what is that rerender state for? I can't see anywhere using this state apart from setting it true or false, I removed it and everything is still working fine, is it just for triggering useEffect to rerender the component? I think mustFinish state is enough to trigger, please let me know if i am wrong.
    also duration * (1 - xTranslation.get() / finalPosition) seems to be unnecessary, just use duration and can't tell the difference

    • @builtwithcode
      @builtwithcode  5 месяцев назад

      Yep the rerender variable wasn't really necessary :)
      On the duration piece - you need the custom version when mustFinish is true, because the default duration lengths correspond to the time it takes to scroll the entire row. By definition if mustFinish is true, we have already progressed part way through the row of cards, so we need to scale the duration to get the correct intended speed.

  • @8bitWatermelon
    @8bitWatermelon 9 месяцев назад

    back with a banger ⚡🧪💯

  • @scrumptious1177
    @scrumptious1177 8 месяцев назад

    You just saved my day! Thank you!

  • @ashn_427
    @ashn_427 4 месяца назад

    Can the slowdown on hover effect be done using only javascript? If so can someone please reply with a link to any video explaining how it's done?

  • @alejita.jaramillo
    @alejita.jaramillo 2 месяца назад

    nice guide... but if mouseover the picture how can set paused and after mouseout retake the animation keeps on the moving from the same point without restart the animation... I would really appreciate it if you could help me

    • @useMadness
      @useMadness Месяц назад

      I used a trick by setting the FAST_DURATION variable to a really big number (100,000) to make it seem like it’s paused. It still moves, but super slowly, so it looks like it’s on pause. If you come up with a better way to do this, that would be great

  • @harshitpant07
    @harshitpant07 4 месяца назад

    loved the approach i was trying to do the same but I am stuck on a problem if the content increases let's say card's data from a API the speed increases how do we decrease speed proportionally to content

    • @builtwithcode
      @builtwithcode  4 месяца назад

      Instead of using a fixed value for the duration, you can make it dynamic based on the length of the response array. E.g., something like duration = arrayLength * 10 (the 10 will control the speed which you can play around with)

  • @elenbrodt3880
    @elenbrodt3880 23 дня назад

    when it gets in the end of the second array, it its with a black spot, how can i fix it?

  • @aymenbachiri-yh2hd
    @aymenbachiri-yh2hd 3 месяца назад

    Thank you so much

  • @mikescriven
    @mikescriven 5 месяцев назад +1

    Great video!
    This causes a horizontal scrollbar to show up on my website, can anyone help me remove it?
    Any help would be greatly appreciated.

    • @builtwithcode
      @builtwithcode  5 месяцев назад

      In CSS, you can use the ::-webkit-scrollbar:horizontal selector and set the width/height to 0 & background to transparent. If you want an example, I do this for a vertical scrollbar towards the end of my custom scrollbar video.

    • @ThomasAndreLubin
      @ThomasAndreLubin 10 дней назад

      Is there other way to solve that ? ::-webkit-scrollbar is non standard and not recommended in production

  • @mankaransingh1029
    @mankaransingh1029 5 месяцев назад

    Great Video! Just want to ask can I reverse the direction? Can anyone help me with the code

  • @doskooza
    @doskooza 4 месяца назад

    Awesome! Thanks

  • @andrewii23
    @andrewii23 9 месяцев назад +3

    Gem hidden here

  • @laurensmesure
    @laurensmesure 7 месяцев назад

    Great video, thanks! Not entirely sure about the last part. I have refactored it with an `isSlow` state value and the useEffect like this:
    ```
    useEffect(() => {
    if (!width) return;
    const finalPosition = -width / 2 - 16;
    const controls = animate(xTranslation, [xTranslation.get(), finalPosition], {
    ease: "linear",
    duration: (isSlow ? 120 : 60) * (1 - xTranslation.get() / finalPosition),
    repeat: Infinity,
    repeatType: "loop",
    repeatDelay: 0,
    });
    return () => {
    controls.stop();
    };
    }, [width, xTranslation, isSlow]);
    ```
    Was there a bug that made you implement the useEffect with `mustFinish` & `rerender`?

    • @builtwithcode
      @builtwithcode  7 месяцев назад

      I probably didn't need `rerender` :). But I needed `mustFinish` to know whether to set the xTranslation animation to start at 0 (reshift everything back to the starting point) or to xTranslation.get() (handle changes in speed). Looking at your code, I don't see a place to reset the value of xTranslation to 0, so not sure if this would work. But let me know if I'm missing something.

    • @laurensmesure
      @laurensmesure 7 месяцев назад +3

      @@builtwithcode Yes you're right, good catch. I refactored it and set the `speed` attribute.
      ```
      const control = useRef(null!);
      useEffect(() => {
      if (!width) return;
      const finalPosition = -width / 2 - 16;
      control.current = animate(xTranslation, [0, finalPosition], {
      ease: "linear",
      duration: 60,
      repeat: Infinity,
      repeatType: "loop",
      repeatDelay: 0,
      });
      return () => {
      control.current.stop();
      };
      }, [width, xTranslation]);
      ...
      onPointerDown={() => control.current.speed = 0.5}
      ```

  • @salmaahmed7789
    @salmaahmed7789 5 месяцев назад

    it waits for the last item to reach the end and then reset and start the loop which leaves a lot of space, I don't understand why

    • @builtwithcode
      @builtwithcode  5 месяцев назад

      Did you map over two copies of the card array?

    • @zh1094
      @zh1094 2 месяца назад

      it's because the formula he used, won't work for you as it is.

  • @OutrospectiveOfficial
    @OutrospectiveOfficial 8 месяцев назад +1

    There's still a slight occasional jump in the scrolling behaviour when the reset of the scrolling items happens.
    Did you figure out what's causing this by any chance?

    • @n59k.
      @n59k. 7 месяцев назад

      same problem(

    • @meirbek241
      @meirbek241 5 месяцев назад

      same issue, please tag me if you find an answer

    • @n59kk
      @n59kk 5 месяцев назад

      @@meirbek241i just solved it by creating a similar animation with tailwind without frame motion

    • @meirbek241
      @meirbek241 5 месяцев назад

      @@n59kk interesting, do you mind sharing link to repo how you solved it?

  • @8bitWatermelon
    @8bitWatermelon 9 месяцев назад

    [QUESTION]: Why the use of the pages directory? Is there a particular reason or just preference.

    • @builtwithcode
      @builtwithcode  9 месяцев назад +2

      I'm sticking with the Pages Router for now because Framer Motion has issues with the App Router, particularly around and page transitions. But I think this specific project *should* work fine in the App Router.

    • @Dexquest3d
      @Dexquest3d 9 месяцев назад

      I'll try this on the app router

    • @kuizigames1872
      @kuizigames1872 7 месяцев назад

      @@Dexquest3d Did you manage to try this on routed? I am unable to get the infinite scrolling to start.

  • @zh1094
    @zh1094 2 месяца назад

    I am a bit disappointed that the formula wasn't explained properly at all because the exact final position formula will not work for everyone.

    • @builtwithcode
      @builtwithcode  2 месяца назад

      Sorry to hear that, is there anything I can clarify?

    • @Hellothere-by4ye
      @Hellothere-by4ye Месяц назад

      remove left and right padding if their is any on scroll container

  • @ricardocnn
    @ricardocnn 4 месяца назад

    Wow! Super Top!

  • @SubhamayPaul
    @SubhamayPaul 8 месяцев назад

    Can you provide the entire code?

    • @builtwithcode
      @builtwithcode  8 месяцев назад

      GitHub repo link is in the description, the main branch has the final code

  • @n59k.
    @n59k. 7 месяцев назад +1

    thx 4 vid!
    i have the problem with undefined reading resolver in controls.stop, so i used this method to handle the problem.
    👇
    const stopAnimation = () => {
    if (controls) {
    controls.stop();
    }
    };
    return stopAnimation;

    • @luiscosta2385
      @luiscosta2385 7 месяцев назад

      Where did you put this one?

    • @n59k.
      @n59k. 7 месяцев назад

      @@luiscosta2385 to the same place where he writes return controls.stop

    • @safiye430
      @safiye430 7 месяцев назад

      perfect! you saved my day, thanks

  • @Forsvinne77
    @Forsvinne77 7 месяцев назад

    Thanks ❤

  • @alexandertarariko1572
    @alexandertarariko1572 6 месяцев назад

    Awesome, ty

  • @shoumyadeepnarayan1739
    @shoumyadeepnarayan1739 7 месяцев назад

    where is the logic for resetting the image container content ??

    • @builtwithcode
      @builtwithcode  6 месяцев назад

      This works through the "infinite" animation and smartly selecting the endpoint for the xTranslation to line up the second copy of the cards with the original starting position.