画面に黒猫を配置するChrome拡張機能を作りました！

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238817/d5406d54-8e93-b92f-40a6-a92b2975e08e.png" width=300>

## どんな拡張機能？

Google Chromeのブラウザの隅に、**黒猫を配置**できるChrome拡張機能です。

動作イメージはこちらのGIF画像をご参照ください。

![Apr-03-2023-18-31-15.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238817/c3935b36-e720-4472-7cc0-8e7b3ecab7b8.gif)

ソースコードはこちらで公開しています。

https://github.com/Tatsurou-Yajima/cat-in-leftmost

## なぜ作ったか？

こちらの記事に触発されました！:pray:

https://qiita.com/nanana08/items/297569fe7d704b5ac1c2

上記の記事では実写の猫を表示していたので、今回は「**イラストのシルエットを固定位置に表示する**」という方向で実装しました。

## どうやって作ったか？

ここからは、どのようにこの拡張機能を作ったかを順に記します。

（ほとんど前述の参考記事と同じです）

### 1. manifest.jsonを準備

拡張機能として機能するために最低限必要な、`manifest.json`を作成します。

```json:manifest.json
{
    "manifest_version": 3,
    "name": "Cat in Leftmost",
    "version": "1.0",
    "description": "ブラウザの左下で猫を飼うことができる拡張機能です",
    "content_scripts": [
        {
            "matches": [
                "https://*/*"
            ],
            "js": [
                "/index.js"
            ],
            "css": [
                "/index.css"
            ]
        }
    ],
    "web_accessible_resources": [
        {
            "resources": [
                "/images/*"
            ],
            "matches": [
                "https://*/*"
            ]
        }
    ]
}
```

ポイントは以下のとおりです。

- `manifest_version`は`3`を指定
  - 以前は`2`がよく使われていたが、現在は非推奨
- `name`, `version`, `description`は好きな文字列でOK
- `content_scripts`で、拡張機能がどのページで動作するか、どのファイルを読み込むかを指定
  - `matches`を`https://*/*`と指定することで、httpsの全サイトで動作するようにする
  - JavaScript, CSSファイルのパスを指定
- `web_accessible_resources` ← 重要！
  - `resources`に、読み込みたい画像のパスを指定
  - 今回は`/images/`以下の全ファイル
  - この指定がないと画像を読み込むことができない
  - `matches`も同様に指定する

### 2. JavaScriptファイルを作成

今回は、下記のような処理を実装します。

- ブラウザの左下に、常に静止画の黒猫を配置
- クリックすると、GIF画像に差し代わる
  - 猫が動く！！（大事）
- 5秒経ったら静止画に戻る
- GIF画像は2種類存在する
  - ランダムでどちらかを表示する

実際のコードはこちらです。

```javascript:index.js
const init = async () => {
    const body = document.body;

    const div = document.createElement("div");
    div.setAttribute("id", "cat-image-wrapper");

    const catImage = document.createElement("img");
    catImage.src = chrome.runtime.getURL("images/black_cat.png");
    catImage.classList.add("cat-image");

    div.appendChild(catImage);
    body.appendChild(div);

    let timerId;

    catImage.addEventListener("click", () => {
        const randomNum = Math.floor(Math.random() * 2);
        const randomImage = randomNum === 0 ? "images/black_cat.gif" : "images/black_cat_stretches.gif";
        catImage.src = chrome.runtime.getURL(randomImage);

        clearTimeout(timerId);
        timerId = setTimeout(function () {
            catImage.src = chrome.runtime.getURL("images/black_cat.png");
        }, 5000);
    });
};

init();
```

下記記事の内容を大いに参考にさせていただきました！

https://qiita.com/nanana08/items/297569fe7d704b5ac1c2

### 3. CSSファイルを作成

今回は以下のような表示を目指します。

- 常に左下に静止画を表示する
  - スクロールしても位置は変わらない
  - クリックできるよ、と伝えるため、ホバー時はポインターにする

実際のコードはこちらです。

```css:index.css
#cat-image-wrapper {
    position: fixed;
    left: 0;
    bottom: 10px;
    z-index: 10000;
}

.cat-image {
    width: 80px;
    height: auto;
}

.cat-image:hover {
    cursor: pointer;
}
```

### 4. 猫の画像を作成

今回は`/images`フォルダにすべての画像を配置します。

用意するのは以下の画像です。

#### ① 静止画(PNG)

背景を投下させたいので、PNG画像を用意します。

![screenshot-2023-04-03-185723.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238817/e48176a2-e32e-867f-57ef-e6dbd67a9c84.png)


（切り抜きが甘いのがバレてしまう……）

#### ② 動画(GIF)

今回の実装で一番時間がかかったのがこのステップです。

先に成果物をお見せすると、こちらです。

##### 1つ目

![black_cat (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238817/a15ba5e0-53e9-fc54-1c1a-73c481e7a0e2.gif)


##### 2つ目

![black_cat_stretches (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238817/4cee09e4-5f0d-1bf8-6224-0792b8b89ae5.gif)

今回は`Google Web Designer`というアプリでGIFを作成しました。

https://webdesigner.withgoogle.com/intl/ja_jp

始めて触るアプリということもあり、思うようにアニメーションを動かすことができなくて苦労しました。

試行錯誤の末できあがったのが上記の2ファイル、というわけです。

（3時間くらいかかりました:v:）

また、作成したGIFの背景を透過させたかったので、下記のサービスを使用しました。

https://www.unscreen.com/

登録不要で、GIFをアップロードするだけで背景を透過してくれます。

**これですべての準備ができました！**

## 動作確認

ここまででディレクトリ構造は以下のようになっています。

```log
.
├── images
│   ├── black_cat.gif
│   ├── black_cat.png
│   └── black_cat_stretches.gif
├── index.css
├── index.js
└── manifest.json
```

ここからは、実際にGoogle Chrome上で動かしてみましょう。

### 1. chrome://extensions/へアクセス

Google Chromeを起動し、アドレスバーに下記アドレスを入力します。

`chrome://extensions/`

すると下記のような画面になります。

![screen-shot2023-04-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238817/7296a5c2-66c3-daa0-6109-0030757f07c4.png)

### 2. デベロッパー モードをONにする

![2023-04-03-19.15.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238817/1de21181-9e23-09cf-0c15-e9ac419a2882.png)

### 3. 「パッケージ化されていない拡張機能を読み込む」クリック

![2023-04-03-19.18.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238817/8512439c-1e2f-a539-1f33-a8f8805d4581.png)

### 4. フォルダ指定

作成したコードのルートディレクトリを指定し、「選択」ボタンをクリックします。

![2023-04-03-19.20.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238817/cdb07828-0e04-2530-46b8-d4cf5488f998.png)

### 5. 拡張機能が表示される

拡張機能一覧画面に、`Cat in Leftmost`拡張機能が表示されます。

![2023-04-03-19.22.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238817/1d0b5d3e-f8c3-11c7-2162-46a094013f40.png)

（コードを編集した際は、リフレッシュアイコンをクリックすると反映されます）

### 6. 使ってみる！

では、いよいよ実際に使ってみましょう！

お好きなWebサイト（SSL化されたページ）を開き、拡張機能をクリックします。

![2023-04-03-19.26.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238817/675e8087-9e9b-485f-6563-3cd8333d09f5.png)

**動きました！**:tada::tada::tada:

![Apr-03-2023-18-31-15 (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238817/9cd34f46-3230-2461-6679-30148e066e95.gif)

## おわりに

以上、拡張機能を作って動かしてみました。

ソースコードはこちらで公開しています。

https://github.com/Tatsurou-Yajima/cat-in-leftmost

拡張機能を作るのは初めてだったのですが、思ったよりも簡単に作れました！

`manifest.json`の書き方で少し悩んだりしましたが、すぐに解決することができました。

ちゃんとパッケージ化して配布するにはもう少しきちんとドキュメントを読んだりしないといけないと思いますが、とっかかりとしては今回のシンプルな成果物で満足しています！

今後は、気が向いたらGIFのパターンを追加したり、画質を上げたりしていきたいと思います。

（とはいえ、どちらかといえばデザイナーの領域になるので、別の人にお願いするかも……）

以上です。

改めて、今回拡張機能を作るきっかけをくれたこちらの記事（@nanana08さま）に感謝します！

https://qiita.com/nanana08/items/297569fe7d704b5ac1c2

最後まで見ていただきありがとうございました！:cat::cat::cat: