I was wondering if there is a way to slowly auto scroll the content of a carousel with the dragFree option? In order to sort of show to users that there is more content in a nice way.
Kind of something like that, but automatically:

Hello F茅lix (@flayks),
Thank you for your question. How about this CodeSandbox? Does it meet your requirements?
Best,
David
@davidcetinkaya, you are a code angel! It absolutely does what I had in mind. Thank you 馃檶
Great news @flayks! I'm closing this as resolved then. Enjoy 馃檪.
Alright @davidcetinkaya, I spoke too soon.
I'm facing some issues with this feature, I'm using Next. Related to the code you made as well for the breakpoint checking, this throws me back a 500 error. Not much detail tho, unfortunately :/
If you have any idea? Have I done something wrong in my component logic or code?
import React, { useState, useEffect, useCallback } from 'react'
import { useEmblaCarousel } from 'embla-carousel/react'
import { debounce } from '../../utils/functions'
const Scroller = ({ children, screenThreshold = 549, settingsProps = {} }) => {
const [isActive, setIsActive] = useState(false)
const [scrollProgress, setScrollProgress] = useState(0)
const [scroller, embla] = useEmblaCarousel({
// Settings
containScroll: 'trimSnaps',
dragFree: true,
...settingsProps
})
// Check
const checkEmbla = useCallback(() => {
// Enable only on a small screen
const smallScreen = document.documentElement.clientWidth < screenThreshold
setIsActive(smallScreen)
if (isActive) {
// Scroll event
onScroll()
embla.on('scroll', onScroll)
// Auto scroll slowly
const engine = embla.dangerouslyGetEngine()
engine.scrollBody.useSpeed(0.01)
engine.scrollTo.index(embla.scrollSnapList().length - 1)
}
}, [embla, setIsActive])
// On scroll
const onScroll = useCallback(() => {
if (!embla) return
// Update scrollbar when scrolling
setScrollProgress(Math.max(0, Math.min(1, embla.scrollProgress())) * 100)
}, [embla, setScrollProgress])
// Init
useEffect(() => {
// Check for carousel
checkEmbla()
// Resize
window.addEventListener('resize', debounce(checkEmbla, 150))
}, [checkEmbla])
return isActive ? (
<div className="scroller">
<div className="scroller__container grid" ref={isActive ? scroller : null}>
<div className="scroller__pan">
{children.map((child, index) => (
<div className="scroller__item" key={index}>
{child}
</div>
))}
</div>
</div>
<div className="scroller__progress">
<div style={{ transform: `translateX(${scrollProgress}%)` }} />
</div>
</div>
) : children
}
export default Scroller
I suspect that the problem is coming from this line:
engine.scrollBody.useSpeed(0.01)
Commenting it indeed takes the Scroller component to the last item with no dramas, but as soon as I set the scrollBody.useSpeed method, I get the error. Mysterious 馃
Hi @flayks,
Just guessing but maybe you should perform a check if the window object exists? It won鈥檛 be there on the server right?
Best,
David
@davidcetinkaya that is true. Does engine.scrollBody.useSpeed() uses window or document?
@flayks, I鈥檓 not sure because I don鈥檛 have access to my computer right now. Try document?
I guess Embla will try to scroll a container which should be an HTML element, but doesn鈥檛 exist on the server.
But to be honest I鈥檓 not sure if that鈥檚 what鈥檚 causing this.
@flayks I noticed that your checkEmbla function doesn鈥檛 check for the existence of the embla variable before executing the scrolling? It only checks for isActive?
@davidcetinkaya I'll give it a try.
I tried to add it at the first place, but as soon as I do that:
const checkEmbla = useCallback(() => {
if (!embla) return
...
It stops any kind of code after and breaks the detection with the breakpoint.
@flayks the if statement should probably be inside isActive and wrap the auto scrolling code.
But also guessing at this point.
@davidcetinkaya right. It works in the isActive indeed, thanks!
Although, no luck for checking for window or document for engine.scrollBody.useSpeed().
@flayks Maybe the window you use for the resize handler and the document for clientWidth need checks if they exist so they don鈥檛 cause 500 on the server side (unrelated to Embla)?
If this doesn鈥檛 solve the issue, I need a more detailed error log in order to debug this. Because I鈥檓 not sure Embla is causing the issue.
@davidcetinkaya I think it's alright as the whole code is ran in an useEffect method which is not rendered by Next. It runs pretty smoothly except for the useSpeed function
@flayks I see. Is the issue present on the browser or server? Sorry but I still don鈥檛 have much useful information and a good understanding of the issue.
@davidcetinkaya ok, I've done some investigating and with a fresh NextJS app and only the Scroller component with some divs inside, and it works. It must be from somewhere else in my app, can't tell where but I'll have a deeper look. The code works tho! 馃憣
Okay @davidcetinkaya, I've got some news, and it's (I suppose), not Embla, but Preact. I configured my NextJS project using Preact instead of React, and there is something in the useSpeed that it doesn't like. What exactly is the question because even with the debugger/profiler I have close to 0 log, but that's the reason behind this confusion!
Thanks for the update @flayks. So do you intend to use Embla with React or Preact? Or was the Preact setup a mistake?
Sounds strange, but I only have experience with React, not Preact, so I can鈥檛 even start guessing why this is happening. Especially without an error log.
@davidcetinkaya I started the project using Next with React but I tried to use Preact in order to reduce the bundle size, but I feel that it's causing more issues than giving a lightweight code haha
I created a repo replicating my setup: https://github.com/flayks/embla-next-preact
As I mentioned, hardly any errors or logging, it only works without the line 35 of the Scroller.jsx file.
Not a huge deal IMO, but that's a bit odd.
Thanks for clarifying F茅lix (@flayks). That sounds a bit odd yeah. With no intention of being rude, at the time of writing Embla Carousel works with Vanilla-JS and React. I haven't tested Embla with Preact at all. I might decide to add support in the future and in that case the repo you shared may be helpful for debugging purposes 馃憤.
I'm glad it works with React though 馃檪.
Best,
David
@davidcetinkaya no worries. I just found that weird. As I don't know much about Preact either I just wanted to give it a go, but no big deal really, I switched back to React instead. That would be good for the peeps using it tho, as it's a super good lightweight alternative to React. Thanks for your help anyway!
Most helpful comment
@davidcetinkaya, you are a code angel! It absolutely does what I had in mind. Thank you 馃檶