import { Meta } from '@storybook/addon-docs/blocks'

<Meta title='@dxtmisha/en/functional-basic/Functions/frame - Cyclic requestAnimationFrame'/>

# `frame`

A utility that cyclically calls `requestAnimationFrame` to perform frame-by-frame animation in the browser.

It's useful for creating smooth animations because the browser automatically optimizes the frame rate (typically 60 FPS) and pauses the animation when the tab is inactive.

**SSR Behavior:**
In non-DOM environments (such as SSR), `requestAnimationFrame` is not used. The function executes the `callback` once synchronously and immediately calls `end` (the loop via `next` is not started) to prevent stack overflow and thread blocking on the server.

**Parameters:**
- `callback: () => void` — The function to call to update your animation.
- `next?: () => boolean` — A condition function. If it returns `true` (only in browser), the animation loop continues.
- `end?: () => void` — A callback function that is executed once the animation loop ends.

**Returns:**
`void`

```typescript
import { frame } from '@dxtmisha/functional-basic'

const element = document.getElementById('box')
let position = 0

// Animation: slide the box 1px per frame until position reaches 100
frame(
  // callback (update frame)
  () => {
    position += 1
    if (element) {
      element.style.transform = `translateX(${position}px)`
    }
  },
  // next (should we continue?)
  () => position < 100,
  // end (when finished)
  () => console.log('Animation complete!')
)
```
