グラデーション作成 Web サービス 🎨 を公開したので使ってみてほしい

## TL;DR

![グラデーション日和.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317946/f6ca2b91-c33b-2649-ea25-ba66fe92bef0.gif)


こんな感じで、かんたんにグラデーションを生成できる Web サービスをつくってみました :yum:

:link: [グラデーション日和](https://fav-gradation.yumyumcolor.com/)



個人的に推している `Svelte` （ `Sapper` ）で開発をして公開までこぎつけたのですが、マイナーフレームワークならではの苦労などありました。
比較対象としてあげられる `Vue` （ `Nuxt` ）と比べながら、つまずきポイントや、 Web サービスを公開するために利用した技術などを紹介していきます ❗



## なぜグラデーション生成サービス ❓

もともと作る予定はなかったんです……。

[こちらの記事](https://qiita.com/azukisiromochi/private/c2b0f1d30485764210ee) でも書いたのですが、グラデーションを作るツールでランダムに生成するものが意外とないんですよね。
ぽちぽちとクリックするだけでランダムなもの（配色であったりグラデーションであったり）が僕は好きなので、作ることにしました。



## どんなサービスなの ❓

### 使い方

#### ベースカラーを選ぶ

まず、 **色を選びます** 。
![img1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317946/edf5aba5-1fd8-ca37-e756-da91a1e5c07b.png)
選んだ色がグラデーションのベースカラーになるわけですが、色相環（色を環状に並べたもの）を `30°` づつに分割した 12 色を用意しました。
赤（ `0°` ）であればその `±15°` の範囲の色をベースにグラデーションを作っていく感じです。

#### とりあえずクリックする

ベースカラーを選んだら、あとは **お気に入りのグラデーションができるまでクリック** します。
![img2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317946/8f9d4afe-1de9-9eff-255d-07dfadea8044.gif)
※ gif の色数の関係で画質が悪いです

クリックを繰り返しているうちに、勢い余ってお気に入りのグラデーションを通り過ぎてしまわないように、画面の下の方にヒストリーを表示するためのボタンを付けました。

お気に入りのグラデーションが表示されている状態で、ヘッダーのコピーボタンをクリックすれば `linear-gradient(50deg,hsl(14,94%,44%),hsl(268,90%,38%))` のような CSS のスタイルがクリップボードにコピーされます。



#### シェアする

お気に入りのグラデーションが表示されている状態で、ヘッダーの Twitter ボタンをクリックすれば、グラデーションの情報をパラメーターに持つ URL をシェアすることができます。
お気に入りのグラデーションを発見した時に利用してみてください！



### それだけ ❗

ポチっ、ポチっ、ポチっとすればグラデーションが作成できる、そんなシンプルなサービスにしました。
使い手は選びますが、気に入った人がいたら使ってもらえると嬉しいです :yum:



## 使った技術の紹介

### [Svelte](https://svelte.dev/) （ [Sapper](https://sapper.svelte.dev/) ）

いちばん慣れている `Vue` （ `Nuxt` ）を使えばもっとスムーズだったと思うのですが、せっかくなので、最近よく Qiita にも投稿している `Svelte` （ `Sapper` ）を使ってみることにしました。

`Svelte` にして **よかった点** 、 **わるかった点** 、それぞれを `Vue` との比較を交えて紹介します。
（たくさん紹介したいですが、抜粋して 3 つずつ）



#### よかった点

##### ビルドが早い！とにかく早い！

`Svelte` はビルドのスピードが早いです。
`Vue` を使い始めた頃は早いなーと感心したものですが（当時僕はサーバーサイドメインでしたし）、 `Vue` を遅く感じるくらいには早いです。



##### クラスのバインドが便利

今回のコードを抜粋して紹介します。

```vue
<script>
  // クラス名を動的に用意
  export let hue;
  const paletteColorClass = hue ? 'is-hsl-' + hue : '';
</script>

<!-- class 属性にそのままセットできる -->
<div class="palette {paletteColorClass}">
</div>
```

`<script>` タグ内で変数 `paletteColorClass` にクラス名を定義していますが、テンプレート側ではそれを `class="palette {paletteColorClass}"` の形でそのままセットできます。
クラス名が変動するケースでは、 `Vue` の場合 `v-bind:class="classObject"` のようにクラスオブジェクトを用意して、そこにセットする必要がありますが、 `Svelte` はそのひと手間が不要です。

また、次のような書き方も出来ます。

```vue
<script>
  let open;
  let close;

  export const openPalette = () => {
    open = true;
    close = false;
  };
  const closePalette = () => {
    open = false;
    close = true;
  };
</script>

<div class="palette--container" class:open class:close>
</div>

<style lang="scss">
  .open {
    // any...
  }
  .close {
    // any...
  }
</style>
```

`open` という名前のクラスを動的にセットしたい場合に `class:open` と指定することで、変数 `open` の bool 値が `true` の場合のみにクラスをセットしてくれます。
また、一度に複数を指定することもできます。



##### コンポーネントの親子間のやりとりが簡単

この内容を詳しく書くとそれだけで記事が 1 本書けてしまいますので、子コンポーネントの関数を親コンポーネントから実行するケースを紹介します。

まずは子コンポーネント `Palette.svelte` で親に実行してもらう関数 `openPalette` を用意します。

```javascript
export const openPalette = () => {
  open = true;
  close = false;
};
```

その際に `export` 句を付けることで親コンポーネントからアクセスができるようになります。

続いて親コンポーネント。

```vue
<script>
  import Palette from '../components/Palette.svelte';

  let palette;
  onMount(() => {
    palette.openPalette()
    }
  });
</script>

<Palette bind:this="{palette}" />
```

子コンポーネントをインポートし、 `<script>` タグで扱えるように `bind:this="{palette}"` のように変数 `palette` と紐付けています。
子コンポーネントの関数は描画されてないと実行できないため `onMount` を使っていて、あとは `palette.openPalette()` とコールするだけで OK です。



#### わるかった点

##### ググっても情報が少ない

`Svelte` は `Vue` と比べても DX が高いと思っているのですが、それを体感するまでのハードルが高いです。
npm パッケージの導入ひとつをとっても、うまくいかなかった時にググってもほとんど情報がないことが多々あります。

また、あったとしてもそのほとんどが英語の記事になります。
人気フレームワークの `Vue` であればそんなことはなく、大抵のことはググれば出てきますよね。





##### 環境設定が難儀

フロントエンド開発に欠かせない Lint ですが、 `Svelte` の場合はその設定も `Vue` に比べて難しいです。
そもそも **『これだ』というテンプレがない** というのもありますが、手探りで環境設定をしないと行けないのはモチベーションを下げる要素になりかねません。

また、エディターにおいても（プラグインによって改善してきているものの） `Svelte` に対応しきれているとは言い難く、エラーの波線を見ながらコーディングするのは精神衛生上よくないですよね……。



##### CSS フレームワークが充実していない

これに関しては詳しく後述しますが、 `Svelte` で利用できる CSS フレームワークは多くなく、有名どころを利用しても `Vue` のようにスムーズに導入出来ませんでした。
使えるフレームワークは [こちらの記事](https://qiita.com/oekazuma/items/06a8a351c55d548fca91) でまとめられていますが、どのフレームワークも `Vue` のものの縮小版といった感じですし、情報の収集が難しいのも相まってハードルが高く感じられました。



### [Smelte](https://smeltejs.com/)

Smelte とは `Svelte` 用につくられた CSS フレームワークで、 `Vue` でいうところの [Vuetify](https://vuetifyjs.com/ja/) にあたります。
Vuetify といえば多彩なテンプレートが用意されており、機能も充実。 Vue 開発のド定番なフレームワークです。

いっぽう Smelte はというと、
> The project was initially inspired by Vuetify, but comes at much lower price. The website you're viewing is only a fraction of both JS (670 vs 40 Kb) and CSS (110 vs 10 Kb) payloads of even the most basic Vuetify example layout) , and of course has dark mode.

と公式サイトにあるように、リッチさよりも軽量化に力を入れているようです。



##### 実際に使ってみた感覚は

Vuetify を使っているような感覚はなく、 [Tailwind CSS](https://tailwindcss.com/) を直接使っている気分になりました。
とはいえ、 `Svelte` コンポーネントが用意されているので使いたいものとマッチすれば便利なんじゃないかな、と思います。
（あとは情報ももう少しあれば……）



##### 自動生成される `global.css` 

Smelte を Sapper で利用するさいに用意されているテンプレートでは、画面で利用する `global.css` が自動生成されます。
（正確には `server.js` 起動時に Smelte や Tailwind のスタイルをインポートして `global.css` を書き換えている）

これ自体は便利なんですが、 `global.css` の容量が大きくなってしまい、 Lighthouse さんにも怒られてしまうほどです……。
![img3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317946/88bba541-a9cb-7f10-a578-c3970fbe2f8d.png)
~~利用しているのになぜか削除しろといわれる `global.css` さんかわいそう~~

これについては、 `rollup.config.js` から `Smelte` のプラグインを実行する部分を削除して、ミニファイしたファイルを読み込むようにすることを検討しています。
（よい方法を知っている方がいれば、教えて下さい）



##### とはいえ

悪いところばかりあげていますが、軽量なフレームワークは価値があります。
リッチな CSS フレームワークを導入すると、その縛りに囚われてしまったり、容量が肥大してしまったり、よいことばかりではないですしね。

まだまだ発展途上な感がありますので、引き続き追いかけていこうと思います！



### [Netlify](https://www.netlify.com/)

[以前、配色 Web サービスを公開したとき](https://qiita.com/azukisiromochi/items/4d07e1b247baed01f11b#comments) にもお世話になった Netlify を今回も利用しました。

Netlify は `Svelte` が台頭し始めた頃に、 `Sapper` の静的サイトジェネレーターによるビルドにいち早く対応したことが話題になりました。
（ `Svelte` 追っかけてる僕以外は知らないか……）

また、 `Sapper` 側の [公式サイトにもホスティングサービスとして Netlify を載せる](https://sapper.svelte.dev/docs#Exporting) など親和性が高いことが Netlify を選んだ理由です。
あとは、普段使っていて慣れていましたしね。



##### Sapper プロジェクトのホスティング方法

`Sapper` は `npm run export` コマンドで静的サイトジェネレーターの役割を果たします。
Netlify ではこのコマンドを利用してビルドを行うことで、ホスティングすることができます。

![img4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317946/8b6de932-7711-6086-cdcf-cd03b275f965.png)

| 設定項目           | 入力値              |
| ------------------ | ------------------- |
| Build command:     | `npm run export`    |
| Publich directory: | `__sapper__/export` |



### Google アナリティクス

個人開発を行う場合、リリースしたサイトへのアクセスを可視化することが大切です。
大抵のサイトが Google アナリティクスを導入していると思いますが、 `Sapper` においてもかんたんに利用するためのパッケージが用意されています。

#### [sapper-google-analytics](https://www.npmjs.com/package/sapper-google-analytics)

`sapper-google-analytics` パッケージを利用すれば、 `Sapper` で開発された Web サイトに Google アナリティクスを導入することができます。

##### インストール

```shell
npm i sapper-google-analytics
```

##### 使い方

```vue
<GoogleAnalytics {stores} id={ga_measurment_id}/>
 
<script>
  import GoogleAnalytics from "sapper-google-analytics/GoogleAnalytics.svelte"
  import { stores } from "@sapper/app"
 
  let ga_measurment_id = "UA-SOMETHING"  // your analytics id
</script> 
```





### PWA

`Sapper` は標準で PWA （ Progressive Web Apps ）に対応しています。
PWA  自体は `Nuxt` でも利用できますし、変わりはないのですが、以前に比べて進化したなぁと感じたので紹介します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317946/c5f51122-56bf-081d-27ff-a2b4fb6066e8.gif" width=40% />


起動時にスプラッシュまで表示されて、ネイティブさながらな動作をします。
Google Play ストアでの公開が可能になることも話題になりましたが、静的な Web サービスはどんどん PWA を導入してもよいかもしれませんね :yum:



## まとめ

6 月くらいに思い立って作り始めましたが、以前に比べスムーズに公開できたと思います。
![img6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317946/149c4b05-a259-a3e6-c5d5-8343c92f79cc.png)
配色 Web サービスの記事にも書きましたが、 **モチベーションの維持** をいかに行うかが個人開発を行う上でのポイントだと思います。

僕自身としては「 **好きなものを作ると楽しい！** 」だとか、「 **おぉ！　動いたッ！　やべぇ！！** 」とか、そんな **気持ちの上がりがあるのなら総じて『個人開発 = 楽しい』になるのではないかな** と考えています。



#### [グラデーション日和](https://fav-gradation.yumyumcolor.com/)

まだ公開したてのサービスで、安定してないかもしれません。
そもそもグラデーションを作ること自体がニッチなのかもしれません。

それでも「自分がほしい」と思って作ったサービスには愛着があり、まだまだ良くしていきたいなと思っています。
感想や意見を Qiita コメントでも、 Twitter でもいいので頂けたら嬉しいです！励みになります！



#### Thanks ❗

こんな長い記事を最後まで読んでいただき、ありがとうございました ❗❗

Web サービスの方も「 **今日の気分は何色？** 」な感じで使ってもらえると嬉しいです！