はじめに
Vueでサイトを作っていると、「もう少しインパクトが欲しいな」と思うことがあります。
個人的には、Reactで使えるアニメーションライブラリがVueにないことにモヤモヤしていました。特に React Bits という3万スター超えのライブラリを見て「Vueでも同じようなの欲しいな」と思っていたんですよ。
そんな中で見つけたのが Vue Bits です。これ、React Bitsの公式Vue移植版なんですよね。同じDavid Haz氏がメンテナンスしていて、すでにGitHubスターが3,300を超えています。
文章より先に、実際にVue Bitsのアニメーションがどんな動きをするのか見てもらったほうが早いと思います。ブラウザ上で編集・実行できるサンプルを用意したので、先に触ってみたい方はこちらからどうぞ。
Vue Bitsとは
Vue Bitsは、アニメーション付きのVueコンポーネントを90以上収録したオープンソースのライブラリです。MIT + Commons Clauseライセンスで提供されていて、毎週新しいコンポーネントが追加されています。
公式サイト: https://vue-bits.dev
コンポーネントは大きく4つのカテゴリに分かれています。
- テキストアニメーション: タイピングエフェクト、グリッチ効果、スプリットテキストなど
- アニメーション: フェードイン、スライド、パララックスなど
- コンポーネント: インタラクティブなUIパーツ
- 背景: パーティクル、グラデーション、幾何学模様など
特徴・メリット
React Bitsとの互換性
React Bitsで気に入ったコンポーネントがあれば、Vue Bitsでもほぼ同じものが使えます。プロジェクトによってReactとVueを使い分けている人には、これが地味に嬉しいポイントです。
最小限の依存関係
重たいライブラリを入れるとバンドルサイズが膨らんで困ることがあります。Vue Bitsは最小限の依存関係で設計されていて、モダンなVue/Nuxtプロジェクトにシームレスに統合できます。
高いカスタマイズ性
propsを通じてかなり細かくカスタマイズできます。ソースコード自体もコピーして使う形式なので、必要に応じて自分で改造することも可能です。
毎週アップデート
これ、意外と重要なんですよね。90以上のコンポーネントが収録されていますが、毎週新しいコンポーネントが追加されています。コミュニティも活発で、コントリビューターは20人以上います。
インストール方法
Vue Bitsは jsrepo というCLIツールを使ってインストールします。npmから直接入れる形式ではないのがちょっと独特ですね。
jsrepoを使ったインストール
まず、jsrepoをインストールします。
npm install -g jsrepo
次に、使いたいコンポーネントを追加します。
npx jsrepo add github/DavidHDev/vue-bits/TextAnimations/SplitText
コンポーネントごとにコマンドを実行する形式です。使いたいものだけ入れられるので、バンドルサイズを抑えられます。
詳細なセットアップ手順は、各コンポーネントのドキュメントページに記載されています。
Vue Bitsのサンプルを動かす
Vue Bitsはjsrepoでソースをコピーして使う配布形式なので、import一発で読み込める配布パッケージはありません。そこで、Vue Bitsの代表コンポーネントであるSplitTextが内部で使っているアニメーションエンジンGSAP(gsap.fromToによるスタッガーアニメーション)を使って、同じ仕組みの最小構成を再現しました。テキストを1文字ずつ<span>に分割し、staggerオプションで少しずつ時間差をつけて表示するのが核になる考え方です。
要点だけを抜き出すと、次のようになります。
const chars = text.split('')
// 各文字をspanに分割してから、時間差(stagger)をつけてフェードイン
gsap.fromTo(
chars,
{ opacity: 0, y: 40 },
{ opacity: 1, y: 0, duration: 0.6, ease: 'power3.out', stagger: 0.04 }
)
実際に動かせるサンプルが下です。上のテキスト入力を書き換えてから「アニメーション再生」ボタンを押すと、その場で文字が新しい内容に切り替わってアニメーションします。
実際のVue BitsのSplitTextコンポーネントには、この他にもdelay(文字ごとの時間差)、duration(1文字分のアニメーション時間)、ease(イージング関数)、from/to(開始・終了時のスタイル)、splitType(chars / words / linesの切り替え)といったpropsが用意されています。上のサンプルでstagger: 0.04を0.15にすると文字がゆっくり順番に現れるようになりますし、y: 40を-40にすれば上から降ってくる動きに変わります。数値を変えて挙動の違いを確認してみてください。
基本的な使い方
インストールしたコンポーネントは、通常のVueコンポーネントとして使えます。
テキストアニメーションの例
<template>
<div class="hero-section">
<SplitText
text="Welcome to my portfolio"
:delay="50"
:animation-from="{ opacity: 0, y: 40 }"
:animation-to="{ opacity: 1, y: 0 }"
/>
</div>
</template>
<script setup lang="ts">
import SplitText from '@/components/ui/SplitText.vue';
</script>
背景エフェクトの例
<template>
<div class="relative min-h-screen">
<Particles
class="absolute inset-0"
:quantity="100"
color="#ffffff"
/>
<div class="relative z-10">
<!-- コンテンツ -->
</div>
</div>
</template>
<script setup lang="ts">
import Particles from '@/components/ui/Particles.vue';
</script>
propsで細かく調整できるので、サイトのトンマナに合わせやすいです。
実践的なユースケース
ポートフォリオサイト
個人的には、ポートフォリオサイトとの相性が抜群だと思います。ヒーローセクションにテキストアニメーション、背景にパーティクルエフェクトを入れるだけで、かなり見栄えが良くなります。
Vueで個人サイトを作っている人には、まさにうってつけのライブラリですね。
Vue Bitsの「コンポーネント」カテゴリには、MagicBentoやTiltedCard、ElasticSliderのようにマウスの動きに追従して反応するUIパーツが揃っています。これらは共通して、GSAPのgsap.quickTo()(対象のプロパティを高速に何度も更新するための専用トゥイーン関数)でポインタ位置を追いかける実装になっています。CTAボタンにこの動きを付けると、ポートフォリオのお問い合わせボタンなどが一気に「触りたくなる」見た目になります。
const xTo = gsap.quickTo(button, 'x', { duration: 0.3, ease: 'power3' })
const yTo = gsap.quickTo(button, 'y', { duration: 0.3, ease: 'power3' })
button.addEventListener('mousemove', (e) => {
const rect = button.getBoundingClientRect()
xTo((e.clientX - rect.left - rect.width / 2) * 0.4)
yTo((e.clientY - rect.top - rect.height / 2) * 0.4)
})
下のボタンにマウスを乗せて動かしてみてください。ボタンがカーソルにわずかに吸い寄せられるように追従します。
* 0.4の係数を大きくするほどボタンが大胆に追従するようになり、duration: 0.3を短くするとより機敏な動きになります。実際のVue Bitsコンポーネントも、こうした数値パラメータをpropsとして公開しているものが多いです。
ランディングページ
LPでユーザーの目を引きたいセクションに使うのも効果的です。ただし、やりすぎると逆効果なので、ポイントを絞って使うのがコツですね。
Vue Bitsの「背景」カテゴリにあるParticlesコンポーネントは、実際にはWebGLライブラリのoglを使ってGPU上でパーティクルを描画しています。ここでは仕組みをつかみやすいように、同じ「ランダムに揺らぎながら漂うパーティクル」という演出を、GSAPで各要素をアニメーションさせるだけのシンプルな実装で再現しました。
// 各パーティクルにランダムな移動量と周期を与えて、無限にゆらゆら揺らす
dots.forEach((dot) => {
gsap.to(dot, {
x: gsap.utils.random(-40, 40),
y: gsap.utils.random(-40, 40),
duration: gsap.utils.random(2, 4),
repeat: -1,
yoyo: true,
ease: 'sine.inOut'
})
})
スライダーでパーティクルの数を変えられます。数を増やすと背景がより賑やかになる代わりに、実際のプロジェクトではその分描画負荷も上がる点に注意してください(だからこそVue BitsはWebGLでの描画を選んでいます)。
Nuxtプロジェクト
Vue Bitsは最新のVue/Nuxtプロジェクトに対応しています。Nuxt 3でSSGやSSRを使っている場合も、適切に動作します。
注意点
いくつか気になる点もあります。
- ライセンス: MIT + Commons Clauseなので、商用利用する場合は条項を確認しておいたほうがいいです
- SSR対応: Nuxtで使う場合、一部のコンポーネントはクライアントサイドでのみ動作するものがあります
- パフォーマンス: 背景エフェクト系は処理が重いものもあるので、モバイルでの動作確認は必須です
- まだ若いプロジェクト: React Bitsと比べるとまだ5ヶ月程度の歴史なので、コンポーネント数はこれから増えていく段階です
まとめ
Vue Bitsは、手軽にリッチなアニメーションを導入できる便利なライブラリです。
- 90以上のコンポーネントを収録(毎週追加)
- React Bitsの公式Vue移植版
- 最小限の依存関係
- jsrepoで簡単インストール
- Nuxtにも対応
30代になって思うのは、「良いものは技術スタックを超えて広まる」という話なんですよね。React Bitsの成功を見て、Vue版を望む声は多かったはずです。それが公式で提供されているのは素直に嬉しいです。
VueやNuxtでポートフォリオやLPを作る機会があれば、ぜひ試してみてください。
参考リンク