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

<Meta title='@dxtmisha/vi/functional-basic/Functions/frame - Vòng lặp requestAnimationFrame'/>

# `frame`

Tiện ích này sẽ gọi vòng lặp `requestAnimationFrame` để thực hiện hoạt ảnh theo từng khung hình (frame-by-frame) trong trình duyệt.

Trình duyệt tự động tối ưu hóa tốc độ khung hình (thường là 60 FPS) và dừng hoạt ảnh khi tab không hoạt động, giúp hiển thị mượt mà.

**Hành vi trong SSR:**
Trong các môi trường không có DOM (chẳng hạn như SSR), `requestAnimationFrame` sẽ không được sử dụng. Hàm thực thi `callback` một lần đồng bộ và gọi ngay lập tức hàm `end` (vòng lặp qua `next` không được bắt đầu) để ngăn chặn tràn ngăn xếp (stack overflow) và chặn luồng trên máy chủ (server thread blocking).

**Tham số:**
- `callback: () => void` — Hàm được gọi để cập nhật hoạt ảnh.
- `next?: () => boolean` — Hàm điều kiện. Nếu trả về `true` (chỉ trong trình duyệt), vòng lặp hoạt ảnh tiếp tục.
- `end?: () => void` — Hàm được thực thi một lần khi vòng lặp hoạt ảnh kết thúc.

**Trả về:**
`void`

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

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

// Hoạt ảnh: di chuyển khối 1px mỗi khung hình cho đến khi đến vị trí 100
frame(
  // callback (cập nhật khung hình)
  () => {
    position += 1
    if (element) {
      element.style.transform = `translateX(${position}px)`
    }
  },
  // next (tiếp tục?)
  () => position < 100,
  // end (kết thúc)
  () => console.log('Hoạt ảnh đã hoàn thành!')
)
```
