useRaf 🎬
はじめに
アニメーションをスムーズにしたいですか?ブラウザの再描画タイミングで正確にコードを実行したいですか?useRaf があなたの最適なパートナーです!🎯
この Hook は、便利な requestAnimationFrame の呼び出しとキャンセル機能を提供し、アニメーションのリズムを簡単に制御でき、カクツキの悩みから解放されます!
コードデモ
基本的な使い方 ⚡
次のブラウザ再描画の前にコードを実行し、ブラウザのレンダリングリズムと完全に一致させます:
js
import { useRaf } from '@vant/use';
export default {
setup() {
let count = 0;
// 次のフレームで実行、1回だけ実行
useRaf(() => {
console.log(`第 ${++count} 回実行`); // 1回だけ実行
console.log('🎬 アニメーション開始!');
});
},
};ループアニメーション 🔄
ループモードを有効にして、連続したアニメーション効果を作成します:
js
import { useRaf } from '@vant/use';
export default {
setup() {
let count = 0;
const cancelRaf = useRaf(
() => {
console.log(`🎭 第 ${++count} フレーム`);
// 5回実行したら停止
if (count === 5) {
console.log('🎬 アニメーション終了!');
cancelRaf();
}
},
{
isLoop: true, // 开启循环模式
interval: 100, // 每 100ms 执行一次
},
);
},
};元素动画控制 🎨
DOM 操作と組み合わせて滑らかな要素アニメーションを作成:
js
import { ref } from 'vue';
import { useRaf } from '@vant/use';
export default {
setup() {
const elementRef = ref();
let position = 0;
const startAnimation = () => {
const cancelRaf = useRaf(
() => {
position += 2;
if (elementRef.value) {
elementRef.value.style.transform = `translateX(${position}px)`;
}
// 移动到 200px 时停止
if (position >= 200) {
console.log('🎯 动画完成!');
cancelRaf();
}
},
{
isLoop: true,
},
);
};
return {
elementRef,
startAnimation,
};
},
};性能监控 📊
利用 RAF 监控页面性能:
js
import { useRaf } from '@vant/use';
export default {
setup() {
let frameCount = 0;
let lastTime = performance.now();
const cancelRaf = useRaf(
() => {
frameCount++;
const currentTime = performance.now();
// 每秒计算一次 FPS
if (currentTime - lastTime >= 1000) {
const fps = Math.round((frameCount * 1000) / (currentTime - lastTime));
console.log(`📊 当前 FPS: ${fps}`);
frameCount = 0;
lastTime = currentTime;
}
},
{
isLoop: true,
},
);
// 10 秒后停止监控
setTimeout(() => {
cancelRaf();
console.log('📊 性能监控结束');
}, 10000);
},
};响应式动画 📱
根据设备性能调整动画频率:
js
import { useRaf } from '@vant/use';
export default {
setup() {
// 检测设备性能
const isLowPerformance = navigator.hardwareConcurrency <= 2;
const animationInterval = isLowPerformance ? 32 : 16; // 低性能设备降低帧率
let rotation = 0;
const elementRef = ref();
const startRotation = () => {
const cancelRaf = useRaf(
() => {
rotation += isLowPerformance ? 2 : 4; // 低性能设备减慢动画
if (elementRef.value) {
elementRef.value.style.transform = `rotate(${rotation}deg)`;
}
if (rotation >= 360) {
rotation = 0;
}
},
{
isLoop: true,
interval: animationInterval,
},
);
return cancelRaf;
};
return {
elementRef,
startRotation,
};
},
};API 参考
型定義
ts
function useRaf(
callback: () => void,
options?: {
interval?: number;
isLoop?: boolean;
},
): () => void;パラメータ
| パラメータ | 説明 | 型 | デフォルト値 |
|---|---|---|---|
| callback | 実行するコールバック関数 | () => void | - |
| options | 設定オプション | RafOptions | {} |
RafOptions
| 属性 | 説明 | 型 | デフォルト値 |
|---|---|---|---|
| interval | 実行間隔(ミリ秒)、ループモードでのみ有効 | number | 0 |
| isLoop | ループモードを有効にするかどうか | boolean | false |
戻り値
| 型 | 説明 |
|---|---|
() => void | アニメーションループを停止するキャンセル関数 |
实际应用场景
🎮 游戏开发
- 游戏循环渲染
- 角色移动动画
- 粒子效果系统
🎨 UI 动画
- 页面过渡效果
- 加载动画
- 滚动视差效果
📊 数据可视化
- 图表动画更新
- 实时数据展示
- 进度条动画
🔧 性能优化
- 批量 DOM 更新
- 防抖动画处理
- 性能监控工具
最佳实践
✅ 推荐做法
js
// 1. 及时清理动画
const cancelRaf = useRaf(callback, { isLoop: true });
onUnmounted(() => {
cancelRaf();
});
// 2. 根据设备性能调整
const interval = navigator.hardwareConcurrency <= 2 ? 32 : 16;
// 3. 避免在回调中进行复杂计算
useRaf(() => {
// 简单的 DOM 操作
element.style.transform = `translateX(${position}px)`;
});❌ 避免做法
js
// 1. 忘记清理循环动画
useRaf(callback, { isLoop: true }); // 可能导致内存泄漏
// 2. 在回调中进行复杂计算
useRaf(() => {
// 複雑な計算は避ける(性能に影響)
const result = heavyCalculation();
});
// 3. 过度使用循环模式
useRaf(callback, { isLoop: true, interval: 1 }); // 過度に高い頻度调试技巧
🔍 性能分析
js
// 监控动画性能
let frameTime = 0;
const cancelRaf = useRaf(() => {
const start = performance.now();
// 你的动画代码
animateElement();
frameTime = performance.now() - start;
if (frameTime > 16) {
console.warn(`⚠️ 动画帧耗时过长: ${frameTime.toFixed(2)}ms`);
}
}, { isLoop: true });🐛 调试工具
js
// 添加调试信息
const debugRaf = (callback, options) => {
console.log('🎬 RAF 动画开始', options);
return useRaf(() => {
console.log('📽️ 执行动画帧');
callback();
}, options);
};ブラウザ互換性
| ブラウザ | サポートバージョン |
|---|---|
| Chrome | ✅ 10+ |
| Firefox | ✅ 4+ |
| Safari | ✅ 6+ |
| Edge | ✅ 12+ |
| IE | ❌ サポートなし |
関連ドキュメント
🎯 コア機能
- useEventListener - イベントリスナー管理 - イベント処理の最適な相棒
- usePageVisibility - ページ可視性 - アニメーションの再生と一時停止を制御
- useWindowSize - ウィンドウサイズ - レスポンシブアニメーションに不可欠
🎨 スタイル関連
- テーマカスタマイズ - Theme - 個性的なアニメーションテーマを作成
- Watermark - 透かしコンポーネント - 動的な透かし効果
🔧 開発ツール
- Vant Use 紹介 - より多くのコンポジション API を理解する
- useToggle - 状態切り替え - アニメーション状態管理
📱 モバイル最適化
- useRect - 要素位置 - 正確なアニメーション位置決め
- useScrollParent - スクロールコンテナ - スクロールアニメーションの最適化
🎪 高度な使い方
- useRelation - コンポーネント関係 - 複雑なアニメーション編成
- useCustomFieldValue - カスタムフィールド - アニメーションデータバインディング