Skip to content

Commit

Permalink
useFramerate
Browse files Browse the repository at this point in the history
  • Loading branch information
clementroche committed Nov 14, 2024
1 parent 94c601c commit 1bb628b
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 16 deletions.
26 changes: 25 additions & 1 deletion docs/App.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useRef } from 'react'
import React, { useEffect, useRef, useState } from 'react'
import { useIntersectionObserver } from '../src/hooks/use-intersection-observer'
import { useResizeObserver } from '../src/hooks/use-resize-observer'
import {
Expand All @@ -10,13 +10,37 @@ import {
useRect,
useMediaQuery,
useWindowSize,
useLazyState,
useFramerate,
} from '../src/index'

if (typeof window !== 'undefined') {
window.useRect = useRect
}

function App() {
const [counter, setCounter] = useState(0)

useEffect(() => {
const interval = setInterval(() => {
// setCounter((prev) => prev + 1)
}, 1000)

return () => clearInterval(interval)
}, [])

const [get, set] = useLazyState(
0,
(value, prevValue) => {
console.log('set', value, prevValue)
},
[counter],
)

useFramerate(1, (time, deltaTime) => {
console.log('time', time, 'deltaTime', deltaTime)
})

const [setRectRef, rect, setRectWrapperRef] = useRect({})
const [setResizeObserverRef, entry] = useResizeObserver({})

Expand Down
7 changes: 6 additions & 1 deletion src/hooks/use-frame/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@ This hook allows you to run a callback every frame based on [@darkroom.engineeri
## Example

```jsx
import { useFrame } from '@darkroom.engineering/hamo'
import { useFrame, useFramerate } from '@darkroom.engineering/hamo'

function MyComponent() {
useFrame((time, deltaTime) => {
console.log(`time elapsed: ${time}`, `time elapsed since last frame: ${deltaTime}`)
})

useFramerate(30, (time, deltaTime) => {
// 30 fps
console.log(`time elapsed: ${time}`, `time elapsed since last frame: ${deltaTime}`)
})
}
```
23 changes: 22 additions & 1 deletion src/hooks/use-frame/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

import Tempus from '@darkroom.engineering/tempus'
import { useEffect } from 'react'
import { useEffect, useRef } from 'react'

export function useFrame(callback, priority = 0) {
useEffect(() => {
Expand All @@ -16,3 +16,24 @@ export function useFrame(callback, priority = 0) {
}
}, [callback, priority])
}

export function useFramerate(fps, callback, priority = 0) {
const timeRef = useRef(0)
const lastTickDateRef = useRef()

const executionTime = 1000 / fps

useFrame((time, delaTime) => {
timeRef.current += delaTime

if (!lastTickDateRef.current) lastTickDateRef.current = time

if (timeRef.current >= executionTime) {
timeRef.current = timeRef.current % executionTime
const delaTime = time - lastTickDateRef.current
lastTickDateRef.current = time

callback?.(time, delaTime)
}
}, priority)
}
10 changes: 8 additions & 2 deletions src/hooks/use-lazy-state/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { useCallback, useEffect, useRef } from 'react'

export function useLazyState(initialValue, callback) {
export function useLazyState(initialValue, callback, deps = []) {
const stateRef = useRef(initialValue)
const prevStateRef = useRef(undefined)

useEffect(() => {
callback(initialValue, initialValue)
callback(initialValue, undefined)
}, [initialValue])

function set(value) {
Expand All @@ -17,11 +18,16 @@ export function useLazyState(initialValue, callback) {

if (value !== stateRef.current) {
callback(value, stateRef.current)
prevStateRef.current = stateRef.current
stateRef.current = value
}
}

const get = useCallback(() => stateRef.current, [])

useEffect(() => {
callback(stateRef.current, prevStateRef.current)
}, [...deps])

return [get, set]
}
11 changes: 2 additions & 9 deletions src/hooks/use-object-fit/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
import { useMemo } from 'react'

export function useObjectFit(
parentWidth = 1,
parentHeight = 1,
childWidth = 1,
childHeight = 1,
objectFit = 'cover',
deps = [],
) {
export function useObjectFit(parentWidth = 1, parentHeight = 1, childWidth = 1, childHeight = 1, objectFit = 'cover') {
const [width, height] = useMemo(() => {
if (!parentWidth || !parentHeight || !childWidth || !childHeight) return [1, 1]
const parentRatio = parentWidth / parentHeight
Expand All @@ -22,7 +15,7 @@ export function useObjectFit(
}
const height = width / childRatio
return [parentWidth / width, parentHeight / height]
}, [parentWidth, parentHeight, childHeight, childWidth, objectFit, ...deps])
}, [parentWidth, parentHeight, childHeight, childWidth, objectFit])

return [1 / width, 1 / height]
}
2 changes: 1 addition & 1 deletion src/hooks/use-timeout/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect } from 'react'

export function useTimeout(callback, delay, ...deps) {
export function useTimeout(callback, delay, deps = []) {
useEffect(() => {
const timeout = setTimeout(callback, delay)

Expand Down
2 changes: 1 addition & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
export { useOutsideClickEvent } from './hooks/use-click-outside-event.js'
export { useDebug } from './hooks/use-debug.js'
export { useDocumentReadyState } from './hooks/use-document-ready-state.js'
export { useFrame } from './hooks/use-frame/index.js'
export { useFrame, useFramerate } from './hooks/use-frame/index.js'
export { useIntersectionObserver } from './hooks/use-intersection-observer.js'
export { useInterval } from './hooks/use-interval.js'
export { useIsClient } from './hooks/use-is-client.js'
Expand Down

0 comments on commit 1bb628b

Please sign in to comment.