Skip to content

Commit cbf0e66

Browse files
authored
Merge pull request #1057 from davidjerleke/feature/#1056
[Feat]: Give animation variables more descriptive names and round rendered position
2 parents e714441 + 9ce1023 commit cbf0e66

File tree

8 files changed

+95
-69
lines changed

8 files changed

+95
-69
lines changed

packages/embla-carousel/src/__tests__/loop-ltr.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ describe('➡️ Loop - Horizontal LTR', () => {
5050
)
5151

5252
expect(emblaApi.containerNode().style.transform).toBe(
53-
'translate3d(0.09000000000000001px,0px,0px)'
53+
'translate3d(0.09px,0px,0px)'
5454
)
5555
})
5656
})
@@ -274,7 +274,7 @@ describe('➡️ Loop - Horizontal LTR', () => {
274274
)
275275

276276
expect(emblaApi.containerNode().style.transform).toBe(
277-
'translate3d(-1209.8899999999999px,0px,0px)'
277+
'translate3d(-1209.89px,0px,0px)'
278278
)
279279
})
280280

@@ -285,7 +285,7 @@ describe('➡️ Loop - Horizontal LTR', () => {
285285
)
286286

287287
expect(emblaApi.containerNode().style.transform).toBe(
288-
'translate3d(450.09000000000003px,0px,0px)'
288+
'translate3d(450.09px,0px,0px)'
289289
)
290290
})
291291
})
@@ -940,7 +940,7 @@ describe('➡️ Loop - Horizontal LTR', () => {
940940
)
941941

942942
expect(emblaApi.containerNode().style.transform).toBe(
943-
'translate3d(-1419.8899999999999px,0px,0px)'
943+
'translate3d(-1419.89px,0px,0px)'
944944
)
945945
})
946946

@@ -951,7 +951,7 @@ describe('➡️ Loop - Horizontal LTR', () => {
951951
)
952952

953953
expect(emblaApi.containerNode().style.transform).toBe(
954-
'translate3d(440.09000000000003px,0px,0px)'
954+
'translate3d(440.09px,0px,0px)'
955955
)
956956
})
957957
})

packages/embla-carousel/src/__tests__/loop-rtl.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ describe('➡️ Loop - Horizontal RTL', () => {
4141
)
4242

4343
expect(emblaApi.containerNode().style.transform).toBe(
44-
'translate3d(-0.09000000000000001px,0px,0px)'
44+
'translate3d(-0.09px,0px,0px)'
4545
)
4646
})
4747
})
@@ -267,7 +267,7 @@ describe('➡️ Loop - Horizontal RTL', () => {
267267
)
268268

269269
expect(emblaApi.containerNode().style.transform).toBe(
270-
'translate3d(1209.8899999999999px,0px,0px)'
270+
'translate3d(1209.89px,0px,0px)'
271271
)
272272
})
273273

@@ -278,7 +278,7 @@ describe('➡️ Loop - Horizontal RTL', () => {
278278
)
279279

280280
expect(emblaApi.containerNode().style.transform).toBe(
281-
'translate3d(-450.09000000000003px,0px,0px)'
281+
'translate3d(-450.09px,0px,0px)'
282282
)
283283
})
284284
})
@@ -939,7 +939,7 @@ describe('➡️ Loop - Horizontal RTL', () => {
939939
)
940940

941941
expect(emblaApi.containerNode().style.transform).toBe(
942-
'translate3d(1419.8899999999999px,0px,0px)'
942+
'translate3d(1419.89px,0px,0px)'
943943
)
944944
})
945945

@@ -950,7 +950,7 @@ describe('➡️ Loop - Horizontal RTL', () => {
950950
)
951951

952952
expect(emblaApi.containerNode().style.transform).toBe(
953-
'translate3d(-440.09000000000003px,0px,0px)'
953+
'translate3d(-440.09px,0px,0px)'
954954
)
955955
})
956956
})

packages/embla-carousel/src/__tests__/loop-vertical.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ describe('➡️ Loop - Vertical', () => {
4141
)
4242

4343
expect(emblaApi.containerNode().style.transform).toBe(
44-
'translate3d(0px,0.09000000000000001px,0px)'
44+
'translate3d(0px,0.09px,0px)'
4545
)
4646
})
4747
})
@@ -267,7 +267,7 @@ describe('➡️ Loop - Vertical', () => {
267267
)
268268

269269
expect(emblaApi.containerNode().style.transform).toBe(
270-
'translate3d(0px,-1209.8899999999999px,0px)'
270+
'translate3d(0px,-1209.89px,0px)'
271271
)
272272
})
273273

@@ -278,7 +278,7 @@ describe('➡️ Loop - Vertical', () => {
278278
)
279279

280280
expect(emblaApi.containerNode().style.transform).toBe(
281-
'translate3d(0px,450.09000000000003px,0px)'
281+
'translate3d(0px,450.09px,0px)'
282282
)
283283
})
284284
})
@@ -939,7 +939,7 @@ describe('➡️ Loop - Vertical', () => {
939939
)
940940

941941
expect(emblaApi.containerNode().style.transform).toBe(
942-
'translate3d(0px,-1419.8899999999999px,0px)'
942+
'translate3d(0px,-1419.89px,0px)'
943943
)
944944
})
945945

@@ -950,7 +950,7 @@ describe('➡️ Loop - Vertical', () => {
950950
)
951951

952952
expect(emblaApi.containerNode().style.transform).toBe(
953-
'translate3d(0px,440.09000000000003px,0px)'
953+
'translate3d(0px,440.09px,0px)'
954954
)
955955
})
956956
})

packages/embla-carousel/src/components/Animations.ts

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ import { EngineType } from './Engine'
22
import { EventStore } from './EventStore'
33
import { WindowType } from './utils'
44

5-
export type AnimationsUpdateType = (
6-
engine: EngineType,
7-
timeStep: number
8-
) => void
5+
export type AnimationsUpdateType = (engine: EngineType) => void
96
export type AnimationsRenderType = (
107
engine: EngineType,
118
lagOffset: number
@@ -23,14 +20,14 @@ export type AnimationsType = {
2320
export function Animations(
2421
ownerDocument: Document,
2522
ownerWindow: WindowType,
26-
update: (timeStep: number) => void,
23+
update: () => void,
2724
render: (lagOffset: number) => void
2825
): AnimationsType {
2926
const documentVisibleHandler = EventStore()
30-
const timeStep = 1000 / 60
27+
const fixedTimeStep = 1000 / 60
3128
let lastTimeStamp: number | null = null
32-
let lag = 0
33-
let animationFrame = 0
29+
let accumulatedTime = 0
30+
let animationId = 0
3431

3532
function init(): void {
3633
documentVisibleHandler.add(ownerDocument, 'visibilitychange', () => {
@@ -43,49 +40,65 @@ export function Animations(
4340
documentVisibleHandler.clear()
4441
}
4542

46-
function animate(timeStamp: DOMHighResTimeStamp): void {
47-
if (!animationFrame) return
48-
if (!lastTimeStamp) lastTimeStamp = timeStamp
43+
function shouldUpdate(): boolean {
44+
return accumulatedTime >= fixedTimeStep
45+
}
4946

50-
const elapsed = timeStamp - lastTimeStamp
51-
lastTimeStamp = timeStamp
52-
lag += elapsed
47+
function updateAndRemoveAccumulatedTime(): void {
48+
update()
49+
accumulatedTime -= fixedTimeStep
50+
if (shouldUpdate()) updateAndRemoveAccumulatedTime()
51+
}
52+
53+
function renderWithAlpha(): void {
54+
const alpha = accumulatedTime / fixedTimeStep
55+
render(alpha)
56+
}
57+
58+
function animate(timeStamp: DOMHighResTimeStamp): void {
59+
if (!animationId) return
5360

54-
while (lag >= timeStep) {
55-
update(timeStep)
56-
lag -= timeStep
61+
if (!lastTimeStamp) {
62+
lastTimeStamp = timeStamp
63+
update()
64+
renderWithAlpha()
5765
}
5866

59-
const lagOffset = lag / timeStep
60-
render(lagOffset)
67+
const timeElapsed = timeStamp - lastTimeStamp
68+
lastTimeStamp = timeStamp
69+
accumulatedTime += timeElapsed
6170

62-
if (animationFrame) ownerWindow.requestAnimationFrame(animate)
71+
if (shouldUpdate()) updateAndRemoveAccumulatedTime()
72+
renderWithAlpha()
73+
74+
if (animationId) {
75+
animationId = ownerWindow.requestAnimationFrame(animate)
76+
}
6377
}
6478

6579
function start(): void {
66-
if (animationFrame) return
67-
68-
animationFrame = ownerWindow.requestAnimationFrame(animate)
80+
if (animationId) return
81+
animationId = ownerWindow.requestAnimationFrame(animate)
6982
}
7083

7184
function stop(): void {
72-
ownerWindow.cancelAnimationFrame(animationFrame)
85+
ownerWindow.cancelAnimationFrame(animationId)
7386
lastTimeStamp = null
74-
lag = 0
75-
animationFrame = 0
87+
accumulatedTime = 0
88+
animationId = 0
7689
}
7790

7891
function reset(): void {
7992
lastTimeStamp = null
80-
lag = 0
93+
accumulatedTime = 0
8194
}
8295

8396
const self: AnimationsType = {
8497
init,
8598
destroy,
8699
start,
87100
stop,
88-
update: () => update(timeStep),
101+
update,
89102
render
90103
}
91104
return self

packages/embla-carousel/src/components/Engine.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,14 @@ export function Engine(
157157
const slideIndexes = arrayKeys(slides)
158158

159159
// Animation
160-
const update: AnimationsUpdateType = (
161-
{ dragHandler, scrollBody, scrollBounds, options: { loop } },
162-
timeStep
163-
) => {
160+
const update: AnimationsUpdateType = ({
161+
dragHandler,
162+
scrollBody,
163+
scrollBounds,
164+
options: { loop }
165+
}) => {
164166
if (!loop) scrollBounds.constrain(dragHandler.pointerDown())
165-
scrollBody.seek(timeStep)
167+
scrollBody.seek()
166168
}
167169

168170
const render: AnimationsRenderType = (
@@ -171,6 +173,7 @@ export function Engine(
171173
translate,
172174
location,
173175
offsetLocation,
176+
previousLocation,
174177
scrollLooper,
175178
slideLooper,
176179
dragHandler,
@@ -179,7 +182,7 @@ export function Engine(
179182
scrollBounds,
180183
options: { loop }
181184
},
182-
lagOffset
185+
alpha
183186
) => {
184187
const shouldSettle = scrollBody.settled()
185188
const withinBounds = !scrollBounds.shouldConstrain()
@@ -192,7 +195,7 @@ export function Engine(
192195
if (!hasSettled) eventHandler.emit('scroll')
193196

194197
const interpolatedLocation =
195-
location.get() * lagOffset + previousLocation.get() * (1 - lagOffset)
198+
location.get() * alpha + previousLocation.get() * (1 - alpha)
196199

197200
offsetLocation.set(interpolatedLocation)
198201

@@ -203,11 +206,12 @@ export function Engine(
203206

204207
translate.to(offsetLocation.get())
205208
}
209+
206210
const animation = Animations(
207211
ownerDocument,
208212
ownerWindow,
209-
(timeStep) => update(engine, timeStep),
210-
(lagOffset: number) => render(engine, lagOffset)
213+
() => update(engine),
214+
(alpha: number) => render(engine, alpha)
211215
)
212216

213217
// Shared

packages/embla-carousel/src/components/ScrollBody.ts

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export type ScrollBodyType = {
55
direction: () => number
66
duration: () => number
77
velocity: () => number
8-
seek: (timeStep: number) => ScrollBodyType
8+
seek: () => ScrollBodyType
99
settled: () => boolean
1010
useBaseFriction: () => ScrollBodyType
1111
useBaseDuration: () => ScrollBodyType
@@ -21,38 +21,36 @@ export function ScrollBody(
2121
baseDuration: number,
2222
baseFriction: number
2323
): ScrollBodyType {
24-
let bodyVelocity = 0
24+
let scrollVelocity = 0
2525
let scrollDirection = 0
2626
let scrollDuration = baseDuration
2727
let scrollFriction = baseFriction
2828
let rawLocation = location.get()
2929
let rawLocationPrevious = 0
3030

31-
function seek(timeStep: number): ScrollBodyType {
32-
const fixedDeltaTimeSeconds = timeStep / 1000
33-
const duration = scrollDuration * fixedDeltaTimeSeconds
34-
const diff = target.get() - location.get()
31+
function seek(): ScrollBodyType {
32+
const displacement = target.get() - location.get()
3533
const isInstant = !scrollDuration
36-
let directionDiff = 0
34+
let scrollDistance = 0
3735

3836
if (isInstant) {
39-
bodyVelocity = 0
37+
scrollVelocity = 0
4038
previousLocation.set(target)
4139
location.set(target)
4240

43-
directionDiff = diff
41+
scrollDistance = displacement
4442
} else {
4543
previousLocation.set(location)
4644

47-
bodyVelocity += diff / duration
48-
bodyVelocity *= scrollFriction
49-
rawLocation += bodyVelocity
50-
location.add(bodyVelocity * fixedDeltaTimeSeconds)
45+
scrollVelocity += displacement / scrollDuration
46+
scrollVelocity *= scrollFriction
47+
rawLocation += scrollVelocity
48+
location.add(scrollVelocity)
5149

52-
directionDiff = rawLocation - rawLocationPrevious
50+
scrollDistance = rawLocation - rawLocationPrevious
5351
}
5452

55-
scrollDirection = mathSign(directionDiff)
53+
scrollDirection = mathSign(scrollDistance)
5654
rawLocationPrevious = rawLocation
5755
return self
5856
}
@@ -71,7 +69,7 @@ export function ScrollBody(
7169
}
7270

7371
function velocity(): number {
74-
return bodyVelocity
72+
return scrollVelocity
7573
}
7674

7775
function useBaseDuration(): ScrollBodyType {

0 commit comments

Comments
 (0)