-
-
Notifications
You must be signed in to change notification settings - Fork 193
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feat]: Continuously running carousel (ticker, marquee, ..) #114
Comments
Hello Robin (@openscript), Thank you for your question. Let me know if I understod you correctly and it did help. Best, |
Hello David (@davidjerleke) 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 |
Hi again Robin (@openscript), Yes, I think the 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, |
Hi again @davidjerleke 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 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, |
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.
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?
Feel free to provide an example of what you want to achieve (share a link to a website or similar). Thanks in advance, |
Hello David (@davidjerleke) 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: 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, |
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, |
Hi David (@davidjerleke) 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 |
Hello, this solution isn't working since version 4.4.0. Loop does not working properly. Is here any solution for 4.5.3 please? To reproduce it you can only swap version in your CodeSandobox or my modified version with 4.5.3 and faster scroll. |
Hi @filiptvarek, Thanks for noticing this. It stopped working because I refactored some internal methods in later versions. I've updated the original CodeSandbox in this comment and it should work as expected now. Cheers, |
It works. Thank you very much |
@ameliagroen @samdhoffman As for VanillaJS, I am fiddling around with this myself. Adapting the sandbox above, this seems to be working for me. let rafId = 0;
const animate = () => {
const engine = embla.dangerouslyGetEngine();
engine.location.add(-0.025); // controls the speed
engine.target.set(engine.location);
engine.scrollLooper.loop(-1);
engine.slideLooper.loop();
engine.translate.to(engine.location);
rafId = requestAnimationFrame(animate)
}
const startAutoScroll = () => {
rafId = requestAnimationFrame(animate)
}
const stopAutoScroll = () => {
rafId = cancelAnimationFrame(rafId) || 0;
}
embla.on("settle", startAutoScroll);
embla.on("pointerDown", stopAutoScroll);
startAutoScroll(); Hope this helps :) |
It is a pity that there is no official example that would be supported when the next update version is released. |
Hi @7iomka, I don't doubt that you mean well, but I don't think it's helping. I'm the sole maintainer of this project and always have an insane backlog. This is what's been done for the upcoming v8. If devs really want me to add more features/plugins, and if I'm to spend even more of my unpaid spare time than I already do, I have to be motivated by something. I want this comment to be constructive so here are ways to not just say I want this an that, but also ways to actually support this project:
More support means better chances for me to add more examples, more features and plugins. Best, |
@Poylar, @dash-james, @AmeerSapadmi, @7iomka, @pedrobernardina, @abdulrauf11, @ameliagroen, @ruie, @samdhoffman: There is a plugin being developed for this purpose that will be named |
hi, i would prefer react + js |
@Poylar and @mdrahiem thank you for considering testing this plugin. CodeSandboxes here: React + JavaScriptReact + TypeScript
Please feel free to test it anyway you want. For example, you can read what the different options do below and test and see if they behave as expected. I will temporarily just dump the documentation page for the |
Hello @davidjerleke I did test options and methods and below are the results. Options: Methods: Events: ✅ - Success ❓- Not sure how to test ❌ - Not working (I think) For <div>
status:{' '}
{emblaApi?.plugins().autoScroll?.isPlaying()
? 'playing'
: 'not playing'}
</div> For const stopPlay = useCallback(
(index) => {
if (!emblaApi) return
emblaApi.plugins().autoScroll?.stop()
emblaApi.scrollTo(index)
},
[emblaApi]
)
const resumePlay = useCallback(
(index) => {
if (!emblaApi) return
emblaApi.plugins().autoScroll?.play()
emblaApi.scrollTo(index)
},
[emblaApi]
)
const resetPlay = useCallback(
(index) => {
if (!emblaApi) return
emblaApi.plugins().autoScroll?.reset()
emblaApi.scrollTo(index)
},
[emblaApi]
)
<button onClick={stopPlay}>Stop</button>
<button onClick={resumePlay}>Resume</button>
<button onClick={resetPlay}>Reset</button> Please correct me if my above implementation is wrong for |
Thanks a lot for testing @mdrahiem! I will update the CodeSandbox with the playing state, events and demonstrate how to do it. Stay tuned 👍. |
Also an update on browsers. ✅ - Chromium Engine Version 120 |
@mdrahiem please check the CodeSandbox again, I've added the features you weren't sure about so you can see how it's intended to work. Best, |
Thanks for updating the code @davidjerleke Below is the update on testing. Methods: Events: ❌ reset - I was expecting the slider to be reset (start from slide 1) but what I see is, it stops for a while (because of ❓ rootNode - I still couldn't find any implementation for this. I see the implementation in javascript version though. 😄 |
@mdrahiem thank you for testing again 🙂!
I think I need to update the description of what this does. That's valuable input, thanks 👍. The
It's useful when you're using previous/next buttons and want the carousel to continue after the user has navigated with the buttons and the carousel has settled. See here and here. ❓ rootNode - I still couldn't find any implementation for this. I see the implementation in javascript version though. 😄 This allows you to select a custom element that should listen for Did these explanations make sense? Best, |
Thank you so much for taking time and explaining these. They makes sense now 🙂 |
@mdrahiem thanks for testing ⭐! The plugin will be released soon. |
Glad I could be of some help. Please feel free to tell me if I can contribute more in anyway. 🙂 |
Thanks that's very kind of you @mdrahiem. @mdrahiem and anyone else reading this for that matter: If you want to make contributions you can browse discussions with the label After your pull request have been merged, you will automatically be added as a contributor here and here. Best, |
[Feat]: Continuously running carousel (ticker, marquee, ..)
Update 2024-01-30 🎉
Update 2024-01-29The person in question unpublished their package but the NPM registry threw errors when I tried to publish Update 2024-01-26Sorry guys, was just about to publish this package ( |
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?
The text was updated successfully, but these errors were encountered: