Embla-carousel: Continuously running carousel (ticker, marquee, ..)

Created on 31 Oct 2020  路  9Comments  路  Source: davidcetinkaya/embla-carousel

Hello everybody

I'm using Embla already in a project and it's great. Thank you for the amazing work!

Now I have the use case to build a carousel which runs continuously like a "stock market" ticker. So no speed up and slow down. Do you think it's easy to build something like that with Embla? Where would be a good starting point?

demonstration resolved

Most helpful comment

Hi David (@davidcetinkaya)

Thank you so much! This is exactly what I wanted to achieve. It's pretty amazing that embla allows to configure this from outside.

Have a great day

Robin

All 9 comments

Hello Robin (@openscript),

Thank you for your question.
Is the CodeSandbox in this conversation what you鈥檙e looking for?

Let me know if I understod you correctly and it did help.

Best,
David

Hello David (@davidcetinkaya)

Thank you for the very quick response.

The CodeSandbox shows exactly what I want, except that it doesn't start running after it has been dragged, but I think it's not to hard to implement this for the settle hook? :)

Hi again Robin (@openscript),

Yes, I think the settle hook is appropriate for what you want to achieve. So something along these lines:

embla.on('settle', () => {
  /*
    Run the same code that scrolls the carousel slowly.
    You probably want to extract it into a reusable function.
  */
})

Please let me know if you have additional requirements or questions 馃檪.

Kindly,
David

Hi again @davidcetinkaya

Thank you for taking the time and helping me out.

I've tried to implement it for a while, but I get very strange side-effects. I thought a video of the screen would be the easiest to show it:

https://drive.google.com/file/d/1rBKMEgZJFVjHT49NW9YL5_2PpxtwU3BJ/view

My code looks like this:

import styled from '@emotion/styled';
import { useEmblaCarousel } from 'embla-carousel/react';
import { EmblaCarousel } from 'embla-carousel/vanilla';
import { Engine } from 'embla-carousel/vanilla/components/engine';
import React, { useEffect } from 'react';

const Viewport = styled.section`
  overflow: hidden;
`;

const Container = styled.div`
  display: flex;
`;

const Slide = styled.div`
  position: relative;
  min-width: 100%;
`;

export type TickerProps = {};

export function Ticker() {
  const [tickerRef, ticker] = useEmblaCarousel({ loop: true, dragFree: true, containScroll: 'trimSnaps' });

  const startScrolling = (engine: Engine, ticker: EmblaCarousel) => {
    engine.scrollBody.useSpeed(0.01);
    engine.scrollTo.index((ticker.scrollSnapList().length || 0) - 1, -10);
  };

  useEffect(() => {
    const engine = ticker?.dangerouslyGetEngine();

    if (engine && ticker) {
      ticker?.on('settle', () => startScrolling(engine, ticker));

      startScrolling(engine, ticker);
    }
  }, [ticker]);

  return (
    <Viewport ref={tickerRef}>
      <Container>
        <Slide>111111111111</Slide>
        <Slide>222222222222</Slide>
        <Slide>333333333333</Slide>
      </Container>
    </Viewport>
  );
}

The direction parameter I set to -10 at engine.scrollTo.index I've chosen because with -1 the 'error' is barely visible. An observation I have made is, that the last slide (3) is getting slower and slower the closer it comes to the left end.

It is reproducible with this. It seems like the original has the same problem without my modifications. If you wait until it comes to the end, it is also getting slower and slower.

Greetings to the north,
Robin

Hello Robin (@openscript),

Side note: I took the liberty to modify your latest comment, only to add syntax highlight to your code. I hope that was ok?

Thank you for the additional information. Seems like I might be misunderstanding you.

It seems like the original has the same problem without my modifications. If you wait until it comes to the end, it is also getting slower and slower.

The requirements mentioned in issue #105 was to show users that the content is scrollable. So the idea was to start scrolling automatically from the beginning and stop scrolling at the end of the content. The easing at the beginning and the end was not an issue there.

Let's go through your use case and requirements again. Is this what you're looking for?

  • The content should scroll automatically without any easing whatsoever as long as the carousel isn't dragged.
  • It should scroll and loop endlessly.
  • It should stop when the user drags the carousel, and start over when the carousel has settled.

Feel free to provide an example of what you want to achieve (share a link to a website or similar).

Thanks in advance,
David

Hello David (@davidcetinkaya)

It made me happy to see your kind reply. Thank you!

Yes, I think we are talking about the same use cases. Easing is not required, but it would maybe be nice for the speed up at the beginning and after dragging. Easing at the end doesn't make sense to me, if it's an endless loop.

I want to achieve something like on the Gatsby website, but with dragging:
image

Have a great day,

Robin

Hi Robin (@openscript),

Thanks for the example link. That helps 馃檪. I'll see if I can create a CodeSandbox for you, and I'll let you know how it goes when I've had the chance to do so.

Best,
David

Hello again Robin (@openscript),

I've created a CodeSandbox for you. This sandbox basically re-creates the internal Embla animation loop without the easing. I haven't had the time to test this thoroughly so I'm going to leave that up to you. I hope that's ok.

Please let me know if it's working as expected.

Kindly,
David

Hi David (@davidcetinkaya)

Thank you so much! This is exactly what I wanted to achieve. It's pretty amazing that embla allows to configure this from outside.

Have a great day

Robin

Was this page helpful?
0 / 5 - 0 ratings