svelteでparticles.jsを動かす

[svelte](https://svelte.dev/)で[particle.js](https://vincentgarreau.com/particles.js/)を使いたかったのですが、軽い気持ちでやろうとしたらライブラリも情報も見つからなかったので備忘録として。

できあがるとこんな感じに表示されます。
![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210824/2e8a35e3-8d58-abe3-51b7-af56c66b4615.png)

なお、動作環境や設定の前提として、svelteは、公式で紹介されている方法でインストールしたそのままを使っているものとします。

sapperはよくわかりません。


# 手順

## １、ライブラリをインストール

```sh
npm install particles.js
```

## ２、`rollup.config.js` でoutputに `strict: false` を設定する

```js
export default {
  ...
  output: {
    ...
    strict: false,  
  },
  ...
}
```

rollupを動かしっぱなしでやっている場合は、一度止めて再実行の必要があります。（多分）

これをやらなかった場合、あとで`Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them`というエラーにひっかかることになります。

以下ページに詳しい情報が載っています。
https://github.com/VincentGarreau/particles.js/issues/123

## ３、実行用コンポーネントを作成

```js
<script>
  import { onMount } from "svelte";
  import "particles.js";

  const config = {
    particles: {
      number: {
        value: 80,
        density: {
          enable: true,
          value_area: 800,
        },
      },
      color: {
        value: "#ffffff",
      },
      shape: {
        type: "circle",
        stroke: {
          width: 0,
          color: "#000000",
        },
        polygon: {
          nb_sides: 5,
        },
        image: {
          src: "img/github.svg",
          width: 100,
          height: 100,
        },
      },
      opacity: {
        value: 0.5,
        random: false,
        anim: {
          enable: false,
          speed: 1,
          opacity_min: 0.1,
          sync: false,
        },
      },
      size: {
        value: 10,
        random: true,
        anim: {
          enable: false,
          speed: 80,
          size_min: 0.1,
          sync: false,
        },
      },
      line_linked: {
        enable: true,
        distance: 300,
        color: "#ffffff",
        opacity: 0.4,
        width: 2,
      },
      move: {
        enable: true,
        speed: 12,
        direction: "none",
        random: false,
        straight: false,
        out_mode: "out",
        bounce: false,
        attract: {
          enable: false,
          rotateX: 600,
          rotateY: 1200,
        },
      },
    },
    interactivity: {
      detect_on: "canvas",
      events: {
        onhover: {
          enable: false,
          mode: "repulse",
        },
        onclick: {
          enable: true,
          mode: "push",
        },
        resize: true,
      },
      modes: {
        grab: {
          distance: 800,
          line_linked: {
            opacity: 1,
          },
        },
        bubble: {
          distance: 800,
          size: 80,
          duration: 2,
          opacity: 0.8,
          speed: 3,
        },
        repulse: {
          distance: 400,
          duration: 0.4,
        },
        push: {
          particles_nb: 4,
        },
        remove: {
          particles_nb: 2,
        },
      },
    },
    retina_detect: true,
  };

  onMount(() => {
    particlesJS("particles-js", config);
  });
</script>

<style>
  #particles-js {
    background: black;
  }
</style>

<div id="particles-js" />
```

ちなみに[vue-particlesjs](https://github.com/adedayojs/vue-particlejs)のコードを参考にさせていただきましたm(_ _)m


## 完成

以上の設定を終えたら、３で作成したコンポーネントを適当に読み込めば動くはずです。


# ハマりどころ

動いてみれば簡単な話だったのですが、いくつかハマりどころがあったので書き残しておきます。

## １、インストールするライブラリ間違えた

出だしにして最大のハマりどころだったのですが、npm上に `particles.js` とは別に `particlejs` というライブラリがあり、当初よく確認せずにそちらをインストールしてしまって、公式のサンプルコードがまったく動かず（あたりまえ）、相当な時間を溶かす羽目になりました。
なんとなくそれっぽい名前で〜みたいな無駄なトライしないで、ちゃんと公式のドキュメントを読みながらやりましょう。

##  ２、`particlesJS.load` はjsonの読み込みにしか対応していない

設定をsvelteのコード内で変えたかったので最終的に上記のように`particlesJS`から実行する方法をとったのですが、公式のREADMEやサンプルコードだと`particlesJS.load`というのがよく使われています。
`particlesJS`だと生成するパーティクルの設定をそのまま渡せますが、`particlesJS.load`は設定の記述されたjsonファイルを読み込んで実行するための関数なので、設定をそのまま渡そうとしても**絶対**動きません。
これも「なんとなくこれもいけるのでは」と無駄なトライをして時間を無駄にしたやつです。
最終的にはコードを読んで、これは絶対無理なやつ、と納得しました。

## ３、 `strict: false` にする必要がある

手順の２ですでに説明済みですが、エラーが出たときには原因がわからなくてしばらくあちこちいじくりまわしました。
なおエラー文言で検索すると一番上に上記でリンクを貼った解決方法が書かれたページが出てきます。（泣ける）

## ４、表示エリアの背景を黒にしておく

黒でなくてもいいのですが…

さて、エラーはすべて解消した…のに、なぜか表示されません。
色々調べた結果判明したのは、**描画されているオブジェクトがすべて白かったために白背景だと見えなかった**ということでした。背景を黒くしたら見えました＾＾
※なお、パーティクルの設定は公式のREADMEに書かれていたものを使っています。



以上、お役に立ちましたら幸いです。