Miscellaneous Box
1 min read

Mouse Stalker

アロナが可愛い。

ブルーアーカイブ5周年記念サイトでマウスを追いかけるアロナがあまりにも可愛い――そう思って、このブログにも「マウスストーカー」を導入しました。 ここでは、実際に実装した内容を備忘録としてまとめます。 実装の骨格は 株式会社オーツーさんの解説記事 を参考にさせていただきました。

実装の流れ (Astro版)

  • マウスストーカー用のコンポーネント MouseStalker.astro を作成
  • src/assets の画像を読み込んで最適化
  • View Transitions (SPA遷移) に対応したイベントハンドリングを実装
  • BaseLayout.astro に配置して全ページで有効化

コンポーネントの作成

src/components/MouseStalker.astro を作成します。 Astroの画像最適化機能を使うため、スクリプト内で画像のパスを受け渡すのがポイントです。

---
import { getImage } from "astro:assets";
import stalkerImage from "../assets/Magical_Tech_Chan.png";

// 画像をWebPに最適化してパスを取得
const optimizedImage = await getImage({ src: stalkerImage, format: "webp" });
const imageUrl = optimizedImage.src;
---

<!-- インラインスタイルで背景画像を指定 -->
<div id="stkr" aria-hidden="true" style={`background-image: url(${imageUrl});`}></div>

<style>
  #stkr {
    position: fixed;
    top: 0;
    left: 0;
    width: 80px;
    height: 80px;
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
    pointer-events: none;
    z-index: 9999;
    opacity: 0;
    transition: opacity 0.3s ease;
  }
</style>

<script>
  function initStalker() {
    const stkr = document.getElementById("stkr");
    if (!stkr) return;

    // ... 追従ロジック (省略) ...
    
    // View Transitions対応: ページ遷移時のクリーンアップ
    document.addEventListener("astro:before-swap", () => {
      // イベントリスナーの削除などをここで行う
    }, { once: true });
  }

  // 初回ロード時とページ遷移後に実行
  document.addEventListener('astro:page-load', initStalker);
</script>

View Transitions への対応

このブログでは Astro の View Transitions を使っているため、通常の window.onload やスクリプトの直書きでは、ページ遷移した後に動かなくなってしまいます。 そこで、astro:page-load イベントをフックにして、ページが切り替わるたびにストーカーを再初期化するようにしています。

また、古いイベントリスナーが残らないように astro:before-swap でクリーンアップするのも重要です。

画像の扱い

public フォルダに置くのではなく、src/assets に置いて getImage で最適化することで、サイズを抑えつつ綺麗な表示が可能になります。 CSSの url() に動的なパスを渡すため、Astroのテンプレート構文で style 属性に直接書き込んでいます。

おわりに

アロナが可愛い。 自分も自作のキャラとかを追従させたいと思ったが、画力がないのでダメ… AIに作らせるか、最近のモデルはいい感じに出してくれるみたいだし。