Skip to content

Commit

Permalink
Make Animation frame rate agnostic
Browse files Browse the repository at this point in the history
  • Loading branch information
davidjerleke committed Apr 22, 2023
1 parent 01f95a4 commit 85a3d6d
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const BASE_STYLES = css`
}
.embla__container {
backface-visibility: hidden;
display: flex;
flex-direction: __replace_axis_flex__;
height: __replace_axis_height__;
Expand Down
17 changes: 13 additions & 4 deletions packages/embla-carousel/src/components/Animation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ export type AnimationType = {
proceed: () => void
}

export function Animation(callback: FrameRequestCallback): AnimationType {
export function Animation(callback: CallbackType): AnimationType {
const timeStep = 1000 / 60
const documentVisibleHandler = EventStore()
let lastTimeStamp: number | null = null
let delta = 0
let animationFrame = 0

function init(): void {
Expand All @@ -33,13 +35,20 @@ export function Animation(callback: FrameRequestCallback): AnimationType {
}

function animate(timeStamp: DOMHighResTimeStamp): void {
if (lastTimeStamp === null) {
if (!lastTimeStamp) {
lastTimeStamp = timeStamp
return start()
}

callback(timeStamp - lastTimeStamp)
if (animationFrame) lastTimeStamp = timeStamp
delta += timeStamp - lastTimeStamp
lastTimeStamp = timeStamp

while (delta >= timeStep) {
callback()
delta -= timeStep
}

if (animationFrame) start()
}

function start(): void {
Expand Down
8 changes: 3 additions & 5 deletions packages/embla-carousel/src/components/Engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +129,11 @@ export function Engine(
const slideIndexes = arrayKeys(slides)

// Draw
const update = (frameRate: number): void => {
const update = (): void => {
const pointerDown = engine.dragHandler.pointerDown()
if (!loop) engine.scrollBounds.constrain(pointerDown)

engine.scrollBody
.seek(target, frameRate, !options.loop && pointerDown)
.update()
engine.scrollBody.seek(target).update()
const settled = engine.scrollBody.settle(target)

if (settled && !pointerDown) {
Expand All @@ -151,7 +149,7 @@ export function Engine(
}

engine.translate.to(location)
engine.animation.proceed()
// engine.animation.proceed()
}

let prevTime = new Date()
Expand Down
52 changes: 5 additions & 47 deletions packages/embla-carousel/src/components/ScrollBody.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@ import { Vector1D, Vector1DType } from './Vector1d'

export type ScrollBodyType = {
direction: () => number
seek: (
target: Vector1DType,
frameRate: number,
pointerDown: boolean,
) => ScrollBodyType
seek: (target: Vector1DType) => ScrollBodyType
settle: (target: Vector1DType) => boolean
update: () => void
useBaseMass: () => ScrollBodyType
Expand All @@ -26,9 +22,7 @@ export function ScrollBody(
const velocity = Vector1D(0)
const acceleration = Vector1D(0)
const attraction = Vector1D(0)
const fps60 = (1 / 60) * 1000

let frameRateFactor = 1
let attractionDirection = 0
let speed = baseSpeed
let mass = baseMass
Expand All @@ -40,49 +34,13 @@ export function ScrollBody(
}

function applyForce(force: Vector1DType): void {
// console.log(frameRateFactor, 'frameRateFactor')
// console.log(frameRateFactor, 'frameRateFactor')
// console.log(
// Limit(1 * frameRateFactor, 3 * frameRateFactor).constrain(mass),
// 'mass * frameRateFactor',
// )
// force.divide(Limit(1, 12).constrain(mass * frameRateFactor))
// force.divide(
// Limit(Math.max(1 * frameRateFactor, 1), 3 * frameRateFactor).constrain(
// mass * frameRateFactor,
// ),
// )

const testMass =
mass === 1 || speed === 100 ? mass : mass * frameRateFactor * 0.95
console.log('mass', testMass)
// console.log(testMass, 'testMass')
force.divide(testMass)

// const frameRateMass = mass * frameRateFactor
// force.divide(Limit(1, 10).constrain(frameRateMass))
// console.log(Limit(1, 10).constrain(frameRateMass))

force.divide(mass)
acceleration.add(force)
}

function seek(
target: Vector1DType,
frameRate: number,
pointerDown: boolean,
): ScrollBodyType {
frameRateFactor = roundToTwoDecimals(fps60 / frameRate)
function seek(target: Vector1DType): ScrollBodyType {
attraction.set(target).subtract(location)

const frameRateAttraction = attraction.get() / frameRateFactor
// console.log(frameRateFactor, 'frameRateFactor')
const magnitude = map(
attraction.get(),
0,
100,
0,
pointerDown || speed === 100 ? speed : speed / frameRateFactor,
)
const magnitude = map(attraction.get(), 0, 100, 0, speed)
attractionDirection = mathSign(attraction.get())
attraction.normalize().multiply(magnitude).subtract(velocity)
applyForce(attraction)
Expand Down Expand Up @@ -114,7 +72,7 @@ export function ScrollBody(
}

function useMass(n: number): ScrollBodyType {
mass = Limit(1, 3).constrain(n)
mass = n
return self
}

Expand Down

0 comments on commit 85a3d6d

Please sign in to comment.