Skip to content

Commit

Permalink
feat: remove utils, add throttling option to startAnimationFrame
Browse files Browse the repository at this point in the history
  • Loading branch information
verekia committed Apr 4, 2024
1 parent 23bdb14 commit 169d911
Show file tree
Hide file tree
Showing 13 changed files with 98 additions and 178 deletions.
26 changes: 14 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,14 @@ The library consists of:
- [**Animation loops**](#animation-loops)
- [**Headless virtual joysticks**](#virtual-joysticks)
- [**Browser API helpers**](#browser-api-helpers)
- [**General math and gamedev utilities**](#utilities)
- [**Tailwind media queries**](#tailwind)
- [**Extra hooks for React Three Fiber**](#react-three-fiber)

**Important**: Until we hit 1.0.0, expect breaking changes in minor versions.

## Demos

Check out the [**React**](https://manapotion.org/), [**Vue**](https://vue.manapotion.org/), [**Svelte**](https://svelte.manapotion.org/), and <a href="https://vanilla.manapotion.org/" target="_blank"><b>vanilla JS</b></a> demos.
Check out the [**React**](https://manapotion.org/), [**Vue**](https://vue.manapotion.org/), [**Svelte**](https://svelte.manapotion.org/), and [**vanilla JS**](https://vanilla.manapotion.org/) demos.

## Installation

Expand Down Expand Up @@ -339,6 +338,19 @@ const unsub = startAnimationFrame(({ delta, elapsed }) => {
// call unsub() to stop the animation loop
```

### Throttling

You can throttle the animation loop by passing a `throttle` option to `useAnimationFrame`/`startAnimationFrame`:

```jsx
useAnimationFrame(
({ delta, elapsed }) => {
// Your animation loop
},
{ throttle: 1000 } // ms
)
```

## Virtual joysticks

⚠️ React-only for now ⚠️
Expand Down Expand Up @@ -432,16 +444,6 @@ const FullscreenButton = () => {

**Note**: Locking keys is a [Chrome experimental feature](https://developer.chrome.com/blog/better-full-screen-mode) to maintain fullscreen when players press Esc (they have to hold it instead). It lets games show in-game dialogs that players can close with Esc without leaving fullscreen.

# Utilities

Mana Potion provides a few utility functions that are useful for JS gamedev and animations in general.

- [`lerp`](https://tsdocs.dev/docs/@manapotion/core/functions/lerp.html): Linear interpolation.
- [`clamp`](https://tsdocs.dev/docs/@manapotion/core/functions/clamp.html): Clamps a number between a minimum and a maximum value.
- [`throttle`](https://tsdocs.dev/docs/@manapotion/core/functions/throttle.html): Throttles a function by a given time in ms.
- [`debounce`](https://tsdocs.dev/docs/@manapotion/core/functions/debounce.html): Debounces a function by a given time in ms.
- [`throttleDebounce`](https://tsdocs.dev/docs/@manapotion/core/functions/throttleDebounce.html): Throttles a function by a given time in ms, but also makes a final call to it after the throttle time has passed.

# Tailwind

Mana Potion provides a Tailwind theme containing the following `screens` breakpoints:
Expand Down
15 changes: 3 additions & 12 deletions examples/react/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import { ForwardedRef, forwardRef, RefObject, useImperativeHandle, useRef, useState } from 'react'

import {
debounce,
Listeners,
lockKeys,
lockOrientation,
resetKeyboard,
resetMouse,
throttle,
throttleDebounce,
unlockKeys,
unlockOrientation,
useAnimationFrame,
Expand Down Expand Up @@ -39,13 +36,6 @@ import {
import TwitterIcon from './components/TwitterIcon'
import MobileJoystick from './MobileJoystick'

export const throttledHello = throttle((...args) => console.log('throttledHello', ...args), 1000)
export const debouncedHello = debounce((...args) => console.log('debouncedHello', ...args), 1000)
export const throttledDebouncedHello = throttleDebounce(
(...args) => console.log('throttledDebouncedHello', ...args),
1000,
)

interface EventNotificationActions {
setMessage: (message: string) => void
}
Expand Down Expand Up @@ -120,9 +110,10 @@ const UI = ({
})

useAnimationFrame(
throttle(({ elapsed }) => {
({ elapsed }) => {
animationFrameThrottledRef.current!.textContent = String(elapsed)
}, 100),
},
{ throttle: 100 },
)

return (
Expand Down
6 changes: 3 additions & 3 deletions examples/svelte/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
Listeners,
lockKeys,
lockOrientation,
throttle,
unlockKeys,
unlockOrientation,
useAnimationFrame,
Expand Down Expand Up @@ -47,9 +46,10 @@
})
useAnimationFrame(
throttle(({ elapsed }) => {
({ elapsed }) => {
animationFrameThrottledEl.textContent = String(elapsed)
}, 100),
},
{ throttle: 100 },
)
</script>

Expand Down
6 changes: 3 additions & 3 deletions examples/vanilla/src/App.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import {
RightMouseButtonUpPayload,
ScreenOrientationChangePayload,
startAnimationFrame,
throttle,
unlockKeys,
unlockOrientation,
unlockPointer,
Expand Down Expand Up @@ -189,10 +188,11 @@ document.addEventListener('DOMContentLoaded', () => {
})

startAnimationFrame(
throttle(({ elapsed }) => {
({ elapsed }) => {
const el = document.getElementById('animationFrameThrottled')!
el.textContent = String(elapsed)
}),
},
{ throttle: 100 },
)
})

Expand Down
6 changes: 3 additions & 3 deletions examples/vue/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
Listeners,
lockKeys,
lockOrientation,
throttle,
unlockKeys,
unlockOrientation,
useAnimationFrame,
Expand Down Expand Up @@ -42,9 +41,10 @@ useAnimationFrame(({ elapsed }) => {
})
useAnimationFrame(
throttle(({ elapsed }) => {
({ elapsed }) => {
animationFrameThrottledEl.value!.textContent = String(elapsed)
}, 100),
},
{ throttle: 100 },
)
</script>

Expand Down
22 changes: 22 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@
"publint": "publint"
},
"dependencies": {
"lodash.throttle": "^4.1.1",
"zustand": "^4.5.1"
},
"devDependencies": {
"@ianvs/prettier-plugin-sort-imports": "^4.2.1",
"@types/lodash.throttle": "^4.1.9",
"@typescript-eslint/eslint-plugin": "^7.4.0",
"@typescript-eslint/parser": "^7.4.0",
"eslint": "^8.57.0",
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ export * from './stores/mouseStore'
export * from './stores/joysticksStore'
export * from './loops'
export * from './browser'
export * from './util'
export * from './tailwind'

export * from './listeners/devicetype'
Expand Down
25 changes: 22 additions & 3 deletions packages/core/src/loops.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,33 @@
export type FrameCallback = ({ delta, elapsed }: { delta: number; elapsed: number }) => void
import throttle from 'lodash.throttle'

export const startAnimationFrame = (callback: FrameCallback) => {
export type AnimationFrameCallback = ({
delta,
elapsed,
}: {
delta: number
elapsed: number
}) => void
export type AnimationFrameOptions = {
throttle?: number
}

export const startAnimationFrame = (
callback: AnimationFrameCallback,
options?: AnimationFrameOptions,
) => {
let request: number | undefined
let previousTime = performance.now()
const state = { delta: 0, elapsed: 0 }
let throttledCallback = callback

if (options?.throttle) {
throttledCallback = throttle(callback, options?.throttle)
}

const animate = (time: number) => {
state.delta = time - previousTime
state.elapsed += state.delta
callback(state)
throttledCallback(state)
previousTime = time
request = requestAnimationFrame(animate)
}
Expand Down
132 changes: 0 additions & 132 deletions packages/core/src/util.ts

This file was deleted.

Loading

0 comments on commit 169d911

Please sign in to comment.