Closed openscript closed 7 months ago
Hello Robin (@openscript),
Thank you for your question. Is the CodeSandbox in this conversation what youβre looking for?
Let me know if I understod you correctly and it did help.
Best, David
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 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 @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 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?
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 (@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, 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 (@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, David
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. But tbh I am not very familiar with the requestAnimationFrame API. So I don't know if this might lead to any drawbacks.
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, David
@Poylar, @dash-james, @AmeerSapadmi, @7iomka, @pedrobernardina, @abdulrauf11, @ameliagroen, @ruie, @samdhoffman:
There is a plugin being developed for this purpose that will be named embla-carousel-auto-scroll
which at the time of writing is 80% complete. I'm hoping to be able to finish it soon:
Hi @Poylar, @dash-james, @AmeerSapadmi, @7iomka, @pedrobernardina, @abdulrauf11, @ameliagroen, @ruie, @samdhoffman,Β @easydrops, @filiptvarek, @MHase, @ashtonlance, @dan-wu-open, @geenious, @ridwanrsk, @mdrahiem:
I'm very close to wrapping up this plugin. If anyone would like to help out and test it before the release, I would very much appreciate that. Maybe we can catch one or two bugs before the release and speed up the process.
If you're interested, I'm going to create CodeSandboxes that I will share with you here so let me know what setup you would prefer:
Thanks in advance!
Hey @davidjerleke I would prefer React + Typescript. Also may I know what test scenarios you want me to cover? I have never done this before π but I would love to do it π¬ . Please guide me. TIA.
hi, i would prefer react + js
@Poylar and @mdrahiem thank you for considering testing this plugin. CodeSandboxes here:
Also may I know what test scenarios you want me to cover?
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 AutoScroll
plugin below:
Hello @davidjerleke I did test options and methods and below are the results.
Options: β speed β startDelay β direction β playOnInit β stopOnInteraction β stopOnMouseEnter β stopOnFocusIn β rootNode
Methods: β play β stop β reset β isPlaying
Events: βautoScroll:play βautoScroll:stop
β - Success β- Not sure how to test β - Not working (I think)
For isPlaying
I tried the below code.
<div>
status:{' '}
{emblaApi?.plugins().autoScroll?.isPlaying()
? 'playing'
: 'not playing'}
</div>
For play
, reset
I tried with below code.
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 play, reset, isPlaying
and I would be glad to test Events
if I find some example. Thanks!
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 β - Firefox 121.0 β - Safari Version 17.2.1
@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, David
Thanks for updating the code @davidjerleke Below is the update on testing.
Methods: β play β stop β isPlaying
Events: β autoScroll:play β autoScroll:stop
β 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 startDelay
) and then it plays from the same position. Please correct if my expectation is wrong.
β rootNode - I still couldn't find any implementation for this. I see the implementation in javascript version though. π
@mdrahiem thank you for testing again π!
β 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
startDelay
) and then it plays from the same position. Please correct if my expectation is wrong.
I think I need to update the description of what this does. That's valuable input, thanks π. The reset
method does the following:
startDelay
option value.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 mouseenter
and mouseleave
, if you don't want the default Embla root node (which is the element you attach emblaRef
to). It's used when stopOnMouseEnter
is true
.
Did these explanations make sense?
Best, David
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 help wanted
. We are happy to accept contributions from our users. For more details see the contributing guidelines.
After your pull request have been merged, you will automatically be added as a contributor here and here.
Best, David
embla-carousel-auto-scroll
has been released to the NPM registry!
The person in question unpublished their package but the NPM registry threw errors when I tried to publish embla-carousel-auto-scroll
. I've contacted NPM support and they said that the package wasn't properly unpublished so they did that for me. Unfortunately, NPM say that I have to wait 24h before I can try publishing embla-carousel-auto-scroll
again.
Sorry guys, was just about to publish this package (embla-carousel-auto-scroll
), but someone has taken a too similar name so I've asked them to unpublish their package before I can release the official 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?