An open API service indexing awesome lists of open source software.

https://github.com/darkroomengineering/tempus

Use only one requestAnimationFrame for your whole app
https://github.com/darkroomengineering/tempus

clock raf ticker time

Last synced: 5 months ago
JSON representation

Use only one requestAnimationFrame for your whole app

Awesome Lists containing this project

README

          

# Tempus

[![TEMPUS](https://assets.darkroom.engineering/tempus/banner.gif)](https://github.com/darkroomengineering/tempus)

## Introduction

`tempus` means time in Latin, this package is a lightweight, high-performance animation frame manager for JavaScript applications.

## Packages

- [tempus](./README.md)
- [tempus/react](./packages/react/README.md)

## Features

- 🚀 Merge multiple requestAnimationFrame loops for better performance
- ðŸŽŊ Control execution priority of different animations
- ⚡ Support for custom frame rates (FPS)
- 🔄 Compatible with popular animation libraries
- ðŸŠķ Zero dependencies
- ðŸ“Ķ ~1KB gzipped

## Installation

using package manager

```bash
npm install tempus
```

```js
import Tempus from 'tempus'
```

using script tag

```html

```

## Basic Usage

```javascript
import Tempus from "tempus"

// Simple animation at maximum FPS
function animate(time, deltaTime) {
console.log('frame', time, deltaTime)
}

Tempus.add(animate)
```

### Cleanup
```javascript
const unsubscribe = Tempus.add(animate)

unsubscribe()
```

### React

See [tempus/react](./packages/react/README.md)

## Advanced Usage

### Custom Frame Rates

```javascript
Tempus.add(animate, {
fps: 30 // Will run at 30 FPS
})

Tempus.add(animate, {
fps: '50%' // Will run at 50% of the system's FPS
})
```

### Priority System

`——[-Infinity]——[0]——[Infinity]——> execution order`

#### Input
```javascript
// Default priority: 0 (runs second)
Tempus.add(() => console.log('animate'))

// Priority: 1 (runs third)
Tempus.add(() => console.log('render'), { priority: 1 })

// Priority: -1 (runs first)
Tempus.add(() => console.log('scroll'), { priority: -1 })
```
#### Output

```
scroll
animate
render
```

### Global RAF Patching

```javascript
// Patch native requestAnimationFrame across all your app
Tempus.patch()
// Now any requestAnimationFrame recursive calls will use Tempus
```

### Ping Pong Technique

```javascript
let framesCount = 0

// ping and pong will run at 50% of the system's FPS,
// but never during the same frame
Tempus.add(() => {
if (framesCount === 0) {
console.log('ping')
} else {
console.log('pong')
}

framesCount++
framesCount %= 2
})
```

## Integration Examples

### With Lenis Smooth Scroll
```javascript
Tempus.add(lenis.raf)
```

### With GSAP
```javascript
// Remove GSAP's internal RAF
gsap.ticker.remove(gsap.updateRoot)

// Add to Tempus
Tempus.add((time) => {
gsap.updateRoot(time / 1000)
})
```

### With Three.js
```javascript
Tempus.add(() => {
renderer.render(scene, camera)
}, { priority: 1 })
// the render will happen after other rafs
// so it can be synched with lenis for instance
```

## API Reference

### Tempus.add(callback, options)

Adds an animation callback to the loop.

- **callback**: `(time: number, deltaTime: number) => void`
- **options**:
- `priority`: `number` (default: 0) - Lower numbers run first
- `fps`: `number` (default: Infinity) - Target frame rate
- **Returns**: `() => void` - Unsubscribe function

### Tempus.patch()

Patches the native `requestAnimationFrame` to use Tempus.

### Tempus.unpatch()

Unpatches the native `requestAnimationFrame` to use the original one.

## Best Practices

- Use priorities wisely: critical animations (like scroll) should have higher priority
- Clean up animations when they're no longer needed
- Consider using specific FPS for non-critical animations to improve performance (e.g: collisions)
- Use Ping Pong technique for heavy computations running concurrently.

## License

MIT ÂĐ [darkroom.engineering](https://github.com/darkroomengineering)

# Shoutout

Thank you to [Keith Cirkel](https://github.com/keithamus) for having transfered us the npm package name 🙏.