From 3f067397c0358ba2092309a29525cc572b7e0e76 Mon Sep 17 00:00:00 2001 From: David Jerleke Date: Sun, 30 Jun 2024 21:01:47 +0200 Subject: [PATCH] Implement #925. --- .../EmblaCarouselInfiniteScroll.js | 7 +-- .../EmblaCarouselInfiniteScroll.ts | 1 - .../EmblaCarouselInfiniteScroll.ts | 1 - .../src/__tests__/loop-ltr.test.ts | 1 - .../src/__tests__/scrollBounds-ltr.test.ts | 5 +- .../src/__tests__/scrollBounds-rtl.test.ts | 5 +- .../__tests__/scrollBounds-vertical.test.ts | 5 +- .../src/components/Animations.ts | 22 ++----- .../embla-carousel/src/components/Engine.ts | 62 +++++-------------- .../src/components/ScrollBody.ts | 3 +- .../src/components/ScrollBounds.ts | 10 +-- .../src/components/ScrollLooper.ts | 6 +- .../embla-carousel/src/components/ScrollTo.ts | 12 +--- .../src/components/SlideLooper.ts | 4 +- 14 files changed, 39 insertions(+), 105 deletions(-) diff --git a/packages/embla-carousel-docs/src/components/Sandbox/Vanilla/SandboxFilesDist/InfiniteScroll/EmblaCarouselInfiniteScroll.js b/packages/embla-carousel-docs/src/components/Sandbox/Vanilla/SandboxFilesDist/InfiniteScroll/EmblaCarouselInfiniteScroll.js index e290d4079..0e065e799 100644 --- a/packages/embla-carousel-docs/src/components/Sandbox/Vanilla/SandboxFilesDist/InfiniteScroll/EmblaCarouselInfiniteScroll.js +++ b/packages/embla-carousel-docs/src/components/Sandbox/Vanilla/SandboxFilesDist/InfiniteScroll/EmblaCarouselInfiniteScroll.js @@ -47,12 +47,7 @@ export const setupInfiniteScroll = (emblaApi, loadMoreCallback) => { emblaApi.reInit() const newEngine = emblaApi.internalEngine() - const copyEngineModules = [ - 'scrollBody', - 'location', - 'offsetLocation', - 'target' - ] + const copyEngineModules = ['scrollBody', 'location', 'target'] copyEngineModules.forEach((engineModule) => Object.assign(newEngine[engineModule], oldEngine[engineModule]) ) diff --git a/packages/embla-carousel-docs/src/components/Sandbox/Vanilla/SandboxFilesDist/InfiniteScroll/EmblaCarouselInfiniteScroll.ts b/packages/embla-carousel-docs/src/components/Sandbox/Vanilla/SandboxFilesDist/InfiniteScroll/EmblaCarouselInfiniteScroll.ts index 3605eb05a..eb0718c4c 100644 --- a/packages/embla-carousel-docs/src/components/Sandbox/Vanilla/SandboxFilesDist/InfiniteScroll/EmblaCarouselInfiniteScroll.ts +++ b/packages/embla-carousel-docs/src/components/Sandbox/Vanilla/SandboxFilesDist/InfiniteScroll/EmblaCarouselInfiniteScroll.ts @@ -66,7 +66,6 @@ export const setupInfiniteScroll = ( const copyEngineModules: (keyof EngineType)[] = [ 'scrollBody', 'location', - 'offsetLocation', 'target' ] copyEngineModules.forEach((engineModule) => diff --git a/packages/embla-carousel-docs/src/components/Sandbox/Vanilla/SandboxFilesSrc/InfiniteScroll/EmblaCarouselInfiniteScroll.ts b/packages/embla-carousel-docs/src/components/Sandbox/Vanilla/SandboxFilesSrc/InfiniteScroll/EmblaCarouselInfiniteScroll.ts index 3605eb05a..eb0718c4c 100644 --- a/packages/embla-carousel-docs/src/components/Sandbox/Vanilla/SandboxFilesSrc/InfiniteScroll/EmblaCarouselInfiniteScroll.ts +++ b/packages/embla-carousel-docs/src/components/Sandbox/Vanilla/SandboxFilesSrc/InfiniteScroll/EmblaCarouselInfiniteScroll.ts @@ -66,7 +66,6 @@ export const setupInfiniteScroll = ( const copyEngineModules: (keyof EngineType)[] = [ 'scrollBody', 'location', - 'offsetLocation', 'target' ] copyEngineModules.forEach((engineModule) => diff --git a/packages/embla-carousel/src/__tests__/loop-ltr.test.ts b/packages/embla-carousel/src/__tests__/loop-ltr.test.ts index 1e90d4777..4f9cfcd67 100644 --- a/packages/embla-carousel/src/__tests__/loop-ltr.test.ts +++ b/packages/embla-carousel/src/__tests__/loop-ltr.test.ts @@ -13,7 +13,6 @@ export const scrollToLocationInstant = ( engine.target.set(location) engine.scrollBody.useDuration(0) engine.animation.update() - engine.animation.render(1) } describe('➡️ Loop - Horizontal LTR', () => { diff --git a/packages/embla-carousel/src/__tests__/scrollBounds-ltr.test.ts b/packages/embla-carousel/src/__tests__/scrollBounds-ltr.test.ts index 10ee47c09..18d3cd4e5 100644 --- a/packages/embla-carousel/src/__tests__/scrollBounds-ltr.test.ts +++ b/packages/embla-carousel/src/__tests__/scrollBounds-ltr.test.ts @@ -7,7 +7,6 @@ export const setLocationOutOfBounds = ( engine: EngineType, outOfBoundsLocation: number ): void => { - engine.offsetLocation.set(outOfBoundsLocation) engine.location.set(outOfBoundsLocation) engine.target.set(outOfBoundsLocation) } @@ -22,7 +21,7 @@ describe('➡️ ScrollBounds - Horizontal LTR', () => { emblaApi.on('settle', settleCallback) setLocationOutOfBounds(engine, engine.limit.max + 1) - engine.animation.render(1) + engine.animation.update() expect(settleCallback).toHaveBeenCalledTimes(0) }) @@ -47,7 +46,7 @@ describe('➡️ ScrollBounds - Horizontal LTR', () => { emblaApi.on('settle', settleCallback) setLocationOutOfBounds(engine, engine.limit.min - 1) - engine.animation.render(1) + engine.animation.update() expect(settleCallback).toHaveBeenCalledTimes(0) }) diff --git a/packages/embla-carousel/src/__tests__/scrollBounds-rtl.test.ts b/packages/embla-carousel/src/__tests__/scrollBounds-rtl.test.ts index f268c77eb..4dcdd1b0b 100644 --- a/packages/embla-carousel/src/__tests__/scrollBounds-rtl.test.ts +++ b/packages/embla-carousel/src/__tests__/scrollBounds-rtl.test.ts @@ -7,7 +7,6 @@ export const setLocationOutOfBounds = ( engine: EngineType, outOfBoundsLocation: number ): void => { - engine.offsetLocation.set(outOfBoundsLocation) engine.location.set(outOfBoundsLocation) engine.target.set(outOfBoundsLocation) } @@ -24,7 +23,7 @@ describe('➡️ ScrollBounds - Horizontal RTL', () => { emblaApi.on('settle', settleCallback) setLocationOutOfBounds(engine, engine.limit.max + 1) - engine.animation.render(1) + engine.animation.update() expect(settleCallback).toHaveBeenCalledTimes(0) }) @@ -53,7 +52,7 @@ describe('➡️ ScrollBounds - Horizontal RTL', () => { emblaApi.on('settle', settleCallback) setLocationOutOfBounds(engine, engine.limit.min - 1) - engine.animation.render(1) + engine.animation.update() expect(settleCallback).toHaveBeenCalledTimes(0) }) diff --git a/packages/embla-carousel/src/__tests__/scrollBounds-vertical.test.ts b/packages/embla-carousel/src/__tests__/scrollBounds-vertical.test.ts index 1daddfaa0..05ac692d1 100644 --- a/packages/embla-carousel/src/__tests__/scrollBounds-vertical.test.ts +++ b/packages/embla-carousel/src/__tests__/scrollBounds-vertical.test.ts @@ -7,7 +7,6 @@ export const setLocationOutOfBounds = ( engine: EngineType, outOfBoundsLocation: number ): void => { - engine.offsetLocation.set(outOfBoundsLocation) engine.location.set(outOfBoundsLocation) engine.target.set(outOfBoundsLocation) } @@ -24,7 +23,7 @@ describe('➡️ ScrollBounds - Vertical', () => { emblaApi.on('settle', settleCallback) setLocationOutOfBounds(engine, engine.limit.max + 1) - engine.animation.render(1) + engine.animation.update() expect(settleCallback).toHaveBeenCalledTimes(0) }) @@ -53,7 +52,7 @@ describe('➡️ ScrollBounds - Vertical', () => { emblaApi.on('settle', settleCallback) setLocationOutOfBounds(engine, engine.limit.min - 1) - engine.animation.render(1) + engine.animation.update() expect(settleCallback).toHaveBeenCalledTimes(0) }) diff --git a/packages/embla-carousel/src/components/Animations.ts b/packages/embla-carousel/src/components/Animations.ts index e7c4f9d28..5097f7c54 100644 --- a/packages/embla-carousel/src/components/Animations.ts +++ b/packages/embla-carousel/src/components/Animations.ts @@ -1,12 +1,8 @@ import { EngineType } from './Engine' import { EventStore } from './EventStore' -import { mathAbs, WindowType } from './utils' +import { WindowType } from './utils' export type AnimationsUpdateType = (engine: EngineType) => void -export type AnimationsRenderType = ( - engine: EngineType, - lagOffset: number -) => void export type AnimationsType = { init: () => void @@ -14,20 +10,18 @@ export type AnimationsType = { start: () => void stop: () => void update: () => void - render: (lagOffset: number) => void } export function Animations( ownerDocument: Document, ownerWindow: WindowType, - update: AnimationsType['update'], - render: AnimationsType['render'] + update: AnimationsType['update'] ): AnimationsType { const documentVisibleHandler = EventStore() const timeStep = 1000 / 60 let lastTimeStamp: number | null = null - let lag = 0 let animationFrame = 0 + let lag = 0 function init(): void { documentVisibleHandler.add(ownerDocument, 'visibilitychange', () => { @@ -44,18 +38,15 @@ export function Animations( if (!animationFrame) return if (!lastTimeStamp) lastTimeStamp = timeStamp - const elapsed = timeStamp - lastTimeStamp + const timeElapsed = timeStamp - lastTimeStamp lastTimeStamp = timeStamp - lag += elapsed + lag += timeElapsed while (lag >= timeStep) { update() lag -= timeStep } - const lagOffset = mathAbs(lag / timeStep) - render(lagOffset) - if (animationFrame) ownerWindow.requestAnimationFrame(animate) } @@ -82,8 +73,7 @@ export function Animations( destroy, start, stop, - update, - render + update } return self } diff --git a/packages/embla-carousel/src/components/Engine.ts b/packages/embla-carousel/src/components/Engine.ts index be6c99a74..aeff9c682 100644 --- a/packages/embla-carousel/src/components/Engine.ts +++ b/packages/embla-carousel/src/components/Engine.ts @@ -1,10 +1,5 @@ import { Alignment } from './Alignment' -import { - Animations, - AnimationsType, - AnimationsUpdateType, - AnimationsRenderType -} from './Animations' +import { Animations, AnimationsType, AnimationsUpdateType } from './Animations' import { Axis, AxisType } from './Axis' import { Counter, CounterType } from './Counter' import { DragHandler, DragHandlerType } from './DragHandler' @@ -49,7 +44,6 @@ export type EngineType = { indexPrevious: CounterType limit: LimitType location: Vector1DType - offsetLocation: Vector1DType options: OptionsType percentOfView: PercentOfViewType scrollBody: ScrollBodyType @@ -157,31 +151,19 @@ export function Engine( // Animation const update: AnimationsUpdateType = ({ dragHandler, + eventHandler, scrollBody, scrollBounds, + scrollLooper, + slideLooper, + translate, + location, + animation, options: { loop } }) => { if (!loop) scrollBounds.constrain(dragHandler.pointerDown()) scrollBody.seek() - } - const render: AnimationsRenderType = ( - { - scrollBody, - translate, - location, - offsetLocation, - scrollLooper, - slideLooper, - dragHandler, - animation, - eventHandler, - scrollBounds, - options: { loop } - }, - lagOffset - ) => { - const velocity = scrollBody.velocity() const shouldSettle = scrollBody.settled() const withinBounds = !scrollBounds.shouldConstrain() const hasSettled = loop ? shouldSettle : shouldSettle && withinBounds @@ -192,35 +174,22 @@ export function Engine( } if (!hasSettled) eventHandler.emit('scroll') - offsetLocation.set(location.get() - velocity + velocity * lagOffset) - if (loop) { scrollLooper.loop(scrollBody.direction()) slideLooper.loop() } - translate.to(offsetLocation.get()) + translate.to(location.get()) } - const animation = Animations( - ownerDocument, - ownerWindow, - () => update(engine), - (lagOffset: number) => render(engine, lagOffset) - ) + + const animation = Animations(ownerDocument, ownerWindow, () => update(engine)) // Shared const friction = 0.68 const startLocation = scrollSnaps[index.get()] const location = Vector1D(startLocation) - const offsetLocation = Vector1D(startLocation) const target = Vector1D(startLocation) - const scrollBody = ScrollBody( - location, - offsetLocation, - target, - duration, - friction - ) + const scrollBody = ScrollBody(location, target, duration, friction) const scrollTarget = ScrollTarget( loop, scrollSnaps, @@ -232,7 +201,6 @@ export function Engine( animation, index, indexPrevious, - scrollBody, scrollTarget, target, eventHandler @@ -299,7 +267,6 @@ export function Engine( indexPrevious, limit, location, - offsetLocation, options, resizeHandler: ResizeHandler( container, @@ -313,14 +280,13 @@ export function Engine( scrollBody, scrollBounds: ScrollBounds( limit, - offsetLocation, + location, target, scrollBody, percentOfView ), - scrollLooper: ScrollLooper(contentSize, limit, offsetLocation, [ + scrollLooper: ScrollLooper(contentSize, limit, location, [ location, - offsetLocation, target ]), scrollProgress, @@ -336,7 +302,7 @@ export function Engine( slideSizesWithGaps, snaps, scrollSnaps, - offsetLocation, + location, slides ), slideFocus, diff --git a/packages/embla-carousel/src/components/ScrollBody.ts b/packages/embla-carousel/src/components/ScrollBody.ts index 466929bec..d14d23a5b 100644 --- a/packages/embla-carousel/src/components/ScrollBody.ts +++ b/packages/embla-carousel/src/components/ScrollBody.ts @@ -15,7 +15,6 @@ export type ScrollBodyType = { export function ScrollBody( location: Vector1DType, - offsetLocation: Vector1DType, target: Vector1DType, baseDuration: number, baseFriction: number @@ -52,7 +51,7 @@ export function ScrollBody( } function settled(): boolean { - const diff = target.get() - offsetLocation.get() + const diff = target.get() - location.get() return mathAbs(diff) < 0.001 } diff --git a/packages/embla-carousel/src/components/ScrollBounds.ts b/packages/embla-carousel/src/components/ScrollBounds.ts index 0c888daac..b2034f2c4 100644 --- a/packages/embla-carousel/src/components/ScrollBounds.ts +++ b/packages/embla-carousel/src/components/ScrollBounds.ts @@ -12,7 +12,7 @@ export type ScrollBoundsType = { export function ScrollBounds( limit: LimitType, - offsetLocation: Vector1DType, + location: Vector1DType, target: Vector1DType, scrollBody: ScrollBodyType, percentOfView: PercentOfViewType @@ -25,15 +25,15 @@ export function ScrollBounds( function shouldConstrain(): boolean { if (disabled) return false if (!limit.reachedAny(target.get())) return false - if (!limit.reachedAny(offsetLocation.get())) return false + if (!limit.reachedAny(location.get())) return false return true } function constrain(pointerDown: boolean): void { if (!shouldConstrain()) return - const edge = limit.reachedMin(offsetLocation.get()) ? 'min' : 'max' - const diffToEdge = mathAbs(limit[edge] - offsetLocation.get()) - const diffToTarget = target.get() - offsetLocation.get() + const edge = limit.reachedMin(location.get()) ? 'min' : 'max' + const diffToEdge = mathAbs(limit[edge] - location.get()) + const diffToTarget = target.get() - location.get() const friction = frictionLimit.constrain(diffToEdge / edgeOffsetTolerance) target.subtract(diffToTarget * friction) diff --git a/packages/embla-carousel/src/components/ScrollLooper.ts b/packages/embla-carousel/src/components/ScrollLooper.ts index 47d99583a..5e0f96740 100644 --- a/packages/embla-carousel/src/components/ScrollLooper.ts +++ b/packages/embla-carousel/src/components/ScrollLooper.ts @@ -8,7 +8,7 @@ export type ScrollLooperType = { export function ScrollLooper( contentSize: number, limit: LimitType, - offsetLocation: Vector1DType, + location: Vector1DType, vectors: Vector1DType[] ): ScrollLooperType { const jointSafety = 0.1 @@ -17,8 +17,8 @@ export function ScrollLooper( const { reachedMin, reachedMax } = Limit(min, max) function shouldLoop(direction: number): boolean { - if (direction === 1) return reachedMax(offsetLocation.get()) - if (direction === -1) return reachedMin(offsetLocation.get()) + if (direction === 1) return reachedMax(location.get()) + if (direction === -1) return reachedMin(location.get()) return false } diff --git a/packages/embla-carousel/src/components/ScrollTo.ts b/packages/embla-carousel/src/components/ScrollTo.ts index bdd6e406e..0f03e801d 100644 --- a/packages/embla-carousel/src/components/ScrollTo.ts +++ b/packages/embla-carousel/src/components/ScrollTo.ts @@ -1,7 +1,6 @@ import { AnimationsType } from './Animations' import { CounterType } from './Counter' import { EventHandlerType } from './EventHandler' -import { ScrollBodyType } from './ScrollBody' import { ScrollTargetType, TargetType } from './ScrollTarget' import { Vector1DType } from './Vector1d' @@ -14,7 +13,6 @@ export function ScrollTo( animation: AnimationsType, indexCurrent: CounterType, indexPrevious: CounterType, - scrollBody: ScrollBodyType, scrollTarget: ScrollTargetType, targetVector: Vector1DType, eventHandler: EventHandlerType @@ -25,15 +23,7 @@ export function ScrollTo( targetVector.add(distanceDiff) - if (distanceDiff) { - if (scrollBody.duration()) { - animation.start() - } else { - animation.update() - animation.render(1) - animation.update() - } - } + if (distanceDiff) animation.start() if (indexDiff) { indexPrevious.set(indexCurrent.get()) diff --git a/packages/embla-carousel/src/components/SlideLooper.ts b/packages/embla-carousel/src/components/SlideLooper.ts index 86bbe9697..2fc5edf87 100644 --- a/packages/embla-carousel/src/components/SlideLooper.ts +++ b/packages/embla-carousel/src/components/SlideLooper.ts @@ -31,7 +31,7 @@ export function SlideLooper( slideSizesWithGaps: number[], snaps: number[], scrollSnaps: number[], - offsetLocation: Vector1DType, + location: Vector1DType, slides: HTMLElement[] ): SlideLooperType { const roundingSafety = 0.5 @@ -77,7 +77,7 @@ export function SlideLooper( loopPoint, slideLocation: Vector1D(-1), translate: Translate(axis, slides[index]), - target: () => (offsetLocation.get() > loopPoint ? initial : altered) + target: () => (location.get() > loopPoint ? initial : altered) } }) }