vueuse-motion-skilld について
@vueuse/motion は Popmotion を基盤とする Vue 3 用の宣言的アニメーションライブラリで、ディレクティブ、コンポーネント、コンポーザブルから利用できます。Nuxt 連携、プリセット、視覚効果を減らす設定への対応も備えています。
主な機能
- 01ディレクティブ・コンポーネント・コンポーザブルの各インターフェース
- 02組み込みプリセットとカスタムバリアント
- 03ジェスチャー・ビューポート・状態に応じたアニメーション
- 04Nuxt 連携と SSR の初期スタイル
- 05視覚効果を減らす設定の検出
活用シーン
- 01テンプレート要素への入場・ビューポートアニメーション追加
- 02Markdown コンテンツ向けの SSR 対応アニメーション設定
- 03コンポーザブルによるジェスチャーやプログラム制御
- 04視覚効果を減らす設定に応じたアニメーション調整
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ skilld-dev/ vue-ecosystem-skills --skill vueuse-motion-skilldインストール後、Claude Code で/vueuse-motion-skilldを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/api.mdmigration.mdnuxt-ssr.mdvariants-transitions.md詳細
@vueuse/motion 3.0.3
Popmotion(WAAPI ではありません)を基盤とする、宣言的なアニメーションのための Vue 3 コンポーザブルです。互換性のある 3 つの利用方法があります。v-motion ディレクティブ、<Motion>/<MotionGroup> コンポーネント、useMotion() コンポーザブルです。
環境の制限
- Vue 3 のみ対応(peer は
vue >=3.0.0、package.json:79-81)。 - v3.0.0 以降は ESM のみです。CommonJS ビルドはありません(
"type": "module"、.mjsのエクスポートのみ、package.json:2,31-35;https://github.com/vueuse/motion/pull/254)。`require()` は使えません。CJS プロジェクトでは ESM または動的なimport()への移行が必要です。 @vueuse/core/@vueuse/sharedv13 とpopmotion11 に依存します(package.json:82-89)。- Nuxt との連携には
@nuxt/kit>=3.13 が必要です(オプションの依存関係、package.json:90-92)。 - アニメーションは
window上で実行されます。SSR ではinitialバリアントのみをインラインスタイルとしてレンダリングします(Nuxt と SSR を参照)。
セットアップ
Vue アプリのエントリポイント(README.md:32-44):
import { createApp } from 'vue'
import { MotionPlugin } from '@vueuse/motion'
import App from './App.vue'
createApp(App).use(MotionPlugin).mount('#app')
MotionPlugin は v-motion ディレクティブ、30 個のプリセットディレクティブ(v-motion-fade など)、グローバルな Motion/MotionGroup コンポーネント、オプションで指定したカスタムディレクティブを登録します(dist/index.mjs:1712-1736)。
app.use(MotionPlugin, {
directives: { 'pop-bottom': { initial: { scale: 0, y: 100 }, visible: { scale: 1, y: 0 } } },
excludePresets: true, // skip the 30 built-in preset directives
})
Nuxt:'@vueuse/motion/nuxt' を modules に追加します。プラグイン、コンポーネント、コンポーザブルの自動インポートがインストールされます(dist/nuxt/module.mjs:13-24)。Nuxt と SSR を参照してください。
よくあるタスク
ディレクティブ(最も一般的)
<template>
<div
v-motion
:initial="{ opacity: 0, y: 100 }"
:enter="{ opacity: 1, y: 0 }"
/>
<div v-motion-slide-visible-left />
</template>
バリアントのプロパティ:initial、enter、leave、visible、visibleOnce(ケバブケースの visible-once も使用できます。dist/index.mjs:1054-1057)、hovered、tapped、focused、およびカスタムキー用の :variants。省略形の :delay/:duration(ミリ秒)は、enter/visible/visibleOnce のトランジションに適用されます(dist/index.mjs:1043-1051)。
コンポーネント(SSR/MDC との互換性がより高い)
<Motion is="p" preset="slideVisibleLeft" :duration="600">Text in Motion!</Motion>
preset には、プラグインの directives に含まれる名前も含め、キャメルケースのプリセット名を指定します(dist/index.mjs:1551-1562)。<MotionGroup> はすべての子要素に 1 つの設定を適用します。:is を指定しない場合は、要素をレンダリングしません。
コンポーザブル(プログラムによる制御)
<script setup lang="ts">
import { ref } from 'vue'
import { useMotion } from '@vueuse/motion'
const target = ref<HTMLElement>()
const { variant, apply, stop } = useMotion(target, {
initial: { opacity: 0, y: 100 },
enter: { opacity: 1, y: 0 },
custom2: { scale: 1.2 },
})
// switch variant (triggers transition): variant.value = 'custom2'
// temporary animation, then revert: await apply({ scale: 2 }); await apply('enter')
</script>
インスタンスメンバー:target、variant、variants、state、motionProperties、apply、set、stop、leave、isAnimating(dist/index.d.mts:535-576)。全 API についてはAPI リファレンスを参照してください。
スクリプトからテンプレートのモーションにアクセスする
ディレクティブに文字列値を指定し、useMotions() から読み取ります。
<div v-motion="'hero'" :initial="{ opacity: 0 }" :enter="{ opacity: 1 }" />
const motions = useMotions()
const play = () => { motions.hero?.variant.value = 'custom' }
バグを防ぐルール
- 期間、遅延、
repeatDelayの単位はミリ秒です(delay: 1000= 1 秒)。dist/index.d.mtsの JSDoc には「秒」とあります(Framer Motion の型からコピーされたもの)が、値はそのままミリ秒単位で Popmotion に渡されます。公式ドキュメントと実行時のデフォルト値(300/800)もミリ秒です(dist/index.mjs:266-281,431-441;https://motion.vueuse.org/features/transition-properties.html)。 - 後からアニメーションさせるすべてのキーを、必ず
initialにも宣言してください。これにより要素の初期状態が定まり、leave/visibleの反転時に戻る基準ができます(https://motion.vueuse.org/features/variants.html)。 visibleは要素がビューポートから離れるとinitialを再適用しますが、visibleOnceは一度だけ実行されます(dist/index.mjs:696-707)。- セットアップのトップレベルで
useMotions()を分割代入しないでください。 インスタンスはセットアップの実行後に登録されるため、オブジェクトを保持し、遅延してインデックスを参照してください(motions.hero?.apply('x'))。登録はグローバルで行われ、v-motionに渡された文字列値がキーになります(dist/index.mjs:9,1065;https://github.com/vueuse/motion/issues/109)。 apply('unknown-key')はThe variant unknown-key does not exist.をスローします。 その場限りの状態には、オブジェクト形式のapply({ ... })を使用してください(dist/index.mjs:534-537)。leave(done)はleaveバリアントを想定し、存在しない場合はinitialにフォールバックします。<transition @leave="(el, done) => leave(done)">に割り当ててください(dist/index.mjs:568-582)。- デフォルトのトランジションはプロパティごとに選択されます。
x/y/z/rotate*/scale*にはスプリング、opacity/color/backgroundColorには 300 ミリ秒の線形トゥイーン、配列ターゲットには 800 ミリ秒のキーフレームが使われます(dist/index.mjs:266-290,443-446)。バリアントのtransitionで上書きできます(https://motion.vueuse.org/features/transition-properties.html)。 - イベントバリアント(
hovered/tapped/focused)は、現在のバリアントに優先順位(hovered < focused < tapped)に従って重ねて適用されます。リスナーは宣言済みのバリアントに対してのみ登録されます(dist/index.mjs:597-657;https://motion.vueuse.org/features/variants.html)。 v-motionのプリセットディレクティブ名はスラッグ形式です。例:v-motion-fade-visible-once、v-motion-roll-left、v-motion-slide-topなど(camelCase キー ->slugify、dist/index.mjs:1459-1464,1718)。30 種類すべてのプリセットはバリアントとトランジションに記載されています。
用途に応じた使い分け
- テンプレートのみの表示アニメーション:ディレクティブ、またはプリセットディレクティブ。
- SSR の比重が大きいコンテンツや Markdown でレンダリングされるコンテンツ(MDC):
<Motion>/<MotionGroup>。ディレクティブよりも確実にinitialスタイルを挿入します(dist/index.mjs:1662-1667;https://motion.vueuse.org/features/components.html)。 - ジェスチャー、シーケンス処理、またはテンプレート外で駆動される値:
useMotion()。バリアントシステムを使わず、Popmotion レベルのスプリングを直接扱う場合はuseSpring()+useMotionProperties()を使用します(dist/index.mjs:1747-1772)。 - ユーザー設定を尊重する:
const reduced = useReducedMotion()を使い、値が true の場合はアニメーションを省略するか短縮してください(dist/index.mjs:1774-1777)。
参考資料
- API リファレンス:すべてのエクスポート、コンポーザブルのシグネチャ、
MotionInstance/SpringControlsのメンバー、低レベルのコンポーザブル。 - バリアントとトランジション:バリアントの仕様、アニメーション可能なモーションプロパティ、トランジションオプション、プリセット一覧。
- Nuxt と SSR:モジュールの設定、ランタイム設定ディレクティブ、SSR の動作と注意点。
- 移行とバージョン:v2 -> v3 の変更点、ナイトリーチャンネル、パッケージ情報。