はじめに
最近のWebサイト、どれも同じに見えませんか? 同じUIライブラリ、同じレイアウト、同じ余白。効率化の代償として、Webから「個性」が失われつつあります。一方で、Awwwardsなどで受賞するようなサイトには、ホバーした瞬間に文字が入れ替わったり、画像がカーソルを追いかけたりする、思わず触りたくなる仕掛けが散りばめられています。
「ああいう演出、自分のサイトにも入れたい。でもゼロから実装する時間はない」——そんな悩みに応えてくれるのが、今回紹介する Fancy(Fancy Components)です。アワード級のマイクロインタラクションを、コピペ感覚で自分のプロジェクトに取り込めるReactコンポーネント集です。
Fancyとは
Fancyは、「Webをもう一度楽しくする(make the web fun again)」を掲げるオープンソースのReactコンポーネントライブラリです。React・TypeScript・Tailwind CSS・Motion(旧Framer Motion)で構築されており、テキストアニメーションから物理演算を使った演出まで、遊び心のあるコンポーネントが揃っています。
npmパッケージとして依存に加えるタイプではなく、ソースコードをそのままプロジェクトに取り込むshadcn/uiと同じ思想で設計されているのが特徴です。取り込んだ後は自分のコードなので、デザインに合わせて自由に改変できます。
とはいえ、説明を読むより先に動きを見た方が早いと思います。冒頭で触れた「ホバーすると文字がランダムに入れ替わる」演出を、実際に手元で操作できるサンプルを用意しました。先に挙動を見たい方はこちらからどうぞ。
主な特徴
- アワード級の演出を再現 - 受賞歴のあるサイトで見かける人気のインタラクションを、すぐ使える形で提供しています
- shadcn CLIで導入できる - レジストリを1行追加するだけで、
shadcn addコマンドからコンポーネントを取得できます - コードは自分のもの - ソースコードごと取り込む方式なので、ブラックボックスがなく、カスタマイズも自在です
- モダンな技術スタック - TypeScript・Tailwind CSS・Motionベースで、Next.jsなどの現代的なReact環境にそのまま馴染みます
- 完全オープンソース - 個人・商用を問わず無料で利用できます
インストール
前提条件
Tailwind CSSとMotionがプロジェクトにセットアップされている必要があります。
# npm
npm install tailwindcss@latest motion
# pnpm
pnpm add tailwindcss@latest motion
shadcn CLIでの導入
まだshadcnを初期化していない場合は、先に初期化します。
pnpm dlx shadcn@latest init
次に、プロジェクト直下のcomponents.jsonに@fancyレジストリを追加します。
{
"registries": {
"@fancy": "https://fancycomponents.dev/r/{name}.json"
}
}
これで準備完了です。あとは欲しいコンポーネントを名前で指定するだけです。
pnpm dlx shadcn add @fancy/scramble-hover
なお、コンポーネントが必要とする追加の依存関係はpackage.jsonに追記されるだけで自動インストールはされないため、追加後にnpm install(またはpnpm install)を実行してください。
CLIを使わない場合は、各コンポーネントのドキュメントページからソースコードをコピーして配置する手動インストールも可能です。
Fancyのサンプルを動かす
Fancyのコンポーネントはnpmパッケージとしてインストールするのではなく、shadcn CLIでソースコードをそのままプロジェクトにコピーする配布方式です。そのためimport ScrambleHover from "fancy"のように単体パッケージから直接importすることはできません。そこでこのサンプルでは、ScrambleHoverコンポーネントが持つtext・scrambleSpeed・revealDirectionというAPIと同じ挙動を、React標準のuseStateとsetIntervalだけで再現しています。実際にコピーされるFancyのソースも同じ考え方で書かれているので、動きの仕組みを掴むには十分です。
スクランブル演出の核心は「文字ごとに確定済みかどうかを判定し、未確定の文字だけをランダムな文字に置き換えながら、確定範囲を少しずつ広げていく」という処理です。要点だけを抜き出すと、次のようになります。
const CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
function scrambleStep(text: string, revealed: Set<number>) {
return text
.split("")
.map((ch, i) => {
if (ch === " " || revealed.has(i)) return ch;
return CHARS[Math.floor(Math.random() * CHARS.length)];
})
.join("");
}
下のサンプルは、このscrambleStepをrevealDirection(start / center / end)ごとの確定順序と組み合わせて動くようにしたものです。テキストを書き換えたり、scrambleSpeedのスライダーを動かしたり、revealDirectionを切り替えたりしてから、見出しにマウスを乗せてみてください。
revealDirectionをcenterにすると中央の文字から先に確定し、両端に向かって波が広がるように見えます。startだと左から右へ、endだと右から左へ確定していくので、Fancy公式サイトのScrambleHoverデモと見比べると挙動が一致しているのが分かるはずです。scrambleSpeedを小さくするほど文字の入れ替わりが速くなり、大きくすると1文字ずつじっくり収束していきます。実際のプロジェクトでは、このrevealDirectionとscrambleSpeedをそのまま<ScrambleHover>コンポーネントのpropsとして渡すだけで、同じ調整ができます。
基本的な使い方
まずは定番の「スクランブルテキスト」から試してみましょう。ホバーすると文字がランダムに入れ替わりながら元のテキストに収束していく、SF映画のような演出です。
pnpm dlx shadcn add @fancy/scramble-hover
import ScrambleHover from "@/fancy/components/text/scramble-hover";
export default function Hero() {
return (
<h1 className="text-4xl font-mono">
<ScrambleHover
text="FANCY COMPONENTS"
scrambleSpeed={50}
maxIterations={10}
sequential={true}
revealDirection="start"
/>
</h1>
);
}
たったこれだけで、ホバー時に文字が流れるように解読されていくヘッドラインが完成します。scrambleSpeedで速度、charactersでスクランブルに使う文字セットを変更できるので、日本語サイトならカタカナを混ぜるといった遊びも可能です。
もうひとつ、ナビゲーションと相性抜群の「レタースワップ」も見てみましょう。ホバーすると文字が1文字ずつ縦にスライドして入れ替わります。
pnpm dlx shadcn add @fancy/letter-swap-forward-anim
import LetterSwapForward from "@/fancy/components/text/letter-swap-forward-anim";
export default function NavLink() {
return (
<a href="/works" className="text-xl font-semibold">
<LetterSwapForward
label="Works"
staggerFrom="first"
staggerDuration={0.03}
/>
</a>
);
}
staggerFromを"center"にすると中央から波打つように、staggerDurationを大きくするとゆったりとした動きになります。数値をいじるだけで印象がガラッと変わるので、ぜひ手元で試してみてください。
実践的なユースケース
ポートフォリオのヒーローセクション
Fancyが最も輝くのは、第一印象を決めるヒーローセクションです。スクランブルテキストとレタースワップを組み合わせて、「触って楽しい」トップページを作ってみます。
import ScrambleHover from "@/fancy/components/text/scramble-hover";
import LetterSwapForward from "@/fancy/components/text/letter-swap-forward-anim";
export default function Portfolio() {
const navItems = ["Works", "About", "Contact"];
return (
<main className="flex min-h-screen flex-col justify-between p-10">
<nav className="flex gap-8">
{navItems.map((item) => (
<a key={item} href={`/${item.toLowerCase()}`}>
<LetterSwapForward label={item} staggerDuration={0.02} />
</a>
))}
</nav>
<h1 className="text-6xl font-bold tracking-tight">
<ScrambleHover
text="CREATIVE DEVELOPER"
sequential={true}
revealDirection="center"
/>
</h1>
</main>
);
}
静的なテキストを置いただけのページと比べて、訪問者の滞在時間も記憶への残り方も大きく変わるはずです。
LetterSwapForwardのstaggerFromを動かして確かめる
上のナビゲーションで使ったLetterSwapForwardは、staggerFrom(アニメーションの起点)とstaggerDuration(1文字あたりの遅延)という2つのpropsで動きの印象が大きく変わるコンポーネントです。文字ごとに「上下2段のテキストを重ねておき、ホバー時に上段を上へスライドアウトさせながら下段を繰り上げる」という縦スライドの仕組みを、CSSのtransformとtransitionDelayだけで再現したのが次のサンプルです。
function order(i: number, len: number, staggerFrom: "first" | "last" | "center") {
if (staggerFrom === "first") return i;
if (staggerFrom === "last") return len - 1 - i;
return Math.abs(i - Math.floor(len / 2)); // center
}
// 文字ごとの遅延 = order(i) * staggerDuration
staggerFromとstaggerDurationを切り替えながら、下のリンクにマウスを乗せてみてください。文字が上に流れるように入れ替わるタイミングがどう変わるかを確認できます。
staggerFromをcenterにすると中央の文字から波打つように動き出し、firstだと左から、lastだと右から順に文字がスライドしていきます。staggerDurationを0.01近くまで下げるとほぼ一斉に切り替わり、0.08近くまで上げると1文字ずつ流れるようにゆっくり入れ替わります。ナビゲーションのように短い単語で使う場合はstaggerDurationを小さめに、見出しのように長い文字列では大きめにすると、テンポの良い演出になります。
そのほかのコンポーネント
テキスト系以外にも、Fancyには一癖あるコンポーネントが揃っています。
- Image Trail - カーソルの軌跡に沿って画像が次々と現れる、ギャラリーサイトで人気の演出です
- Gravity - 要素が物理演算で落下・衝突する、遊び心満点のインタラクションです
- Text Highlighter - スクロールに合わせて蛍光ペンで引いたようなハイライトが走ります
- Marquee Along SVG Path - 任意のSVGパスに沿ってテキストや画像が流れるマーキーです
いずれも「これどうやって実装してるんだろう?」と思っていたあの動きが、ソースコード付きで手に入ります。取り込んだコードを読むこと自体が、Motionやアニメーション実装の生きた教材にもなります。
まとめ
Fancyは、標準化されて均一になりがちなWeb UIに、遊び心を取り戻すためのコンポーネント集です。最後にポイントを振り返ります。
- アワード級のマイクロインタラクションをコピペ感覚で導入できます
- shadcn CLIとレジストリ連携でき、導入は
shadcn add @fancy/コンポーネント名だけです - ソースコードごと取り込む方式なので、カスタマイズも学習も自由自在です
- React・TypeScript・Tailwind CSS・Motionというモダンな構成で書かれています
まずはポートフォリオやランディングページのヘッドラインひとつから、Fancyを試してみてください。「動きがあるだけ」で、あなたのサイトは確実に記憶に残るものになります。公式サイト(fancycomponents.dev)のデモを眺めるだけでも、実装のアイデアが次々と湧いてくるはずです。