React/Next.jsに入門したからスクリーンショットを良い感じに加工するWebサービスを作ってみた

普段はVue.js、NuxtJSを使って個人開発をしています。エンジニアの[K(@k_urtica)](https://twitter.com/k_urtica)といいます。

今回、Next.jsを初めて学んでみたので、Next.jsでWebサービスを作ってみました（入門した理由は[後述](#なぜReact/Next.jsに入門したか)）
ちなみに私のReactの知識はGatsbyでブログを作っているぐらいのものです。といっても、Reactの機能をバリバリ使って構築しているようなものではないので、ゼロに近い知識です（Next.jsにいたっては完全にゼロ）

入門するにあたってひとまずざっと以下の事をやりました。

- [Next.jsのドキュメント](https://nextjs.org/docs)を一通り読む
- [Next.jsの公式チュートリアル](https://nextjs.org/learn/basics/create-nextjs-app)を実施
- [Reactのドキュメント](https://ja.reactjs.org/docs/getting-started.html)を一通り読む
- Qiita/Zenn等でReactのhooks、パフォーマンス周りの記事を読む

## 作ったもの

https://superbshot.dev/

[**Superb Shot**](https://superbshot.dev/)という、スクリーンショット（または単に何かしらの画像）を、**目を引くような良い感じ**のスクリーンショットへ加工することができるWebサービスです。

具体的には、スクリーンショット画像に**様々な魅力的なグラデーション背景やパディング、シャドウを付けたり、インスタグラム風味のフィルター加工**を簡単に施すことができます。
加工した画像はクリップボードにコピーするか、画像ファイルとしてダウンロードすることができます。

本サービスの想定される使われ方
⇒ SNSで画像をシェアする前に目に留まる画像へ加工する、などなど。

**加工した画像①（背景/パディング/角丸/シャドウ/フィルター付与）**
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271387/7142aef7-2947-24d1-4207-479f30c1d9db.png)
**加工した画像②（背景/パディング/シャドウ/フィルター付与）**
![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271387/8af84ed3-cde1-ca13-f56a-27db1dda9acd.png)
**加工した画像③（背景/パディング/角丸/シャドウ）**
![image3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271387/ff07e4fe-e295-17bc-154d-552ab460685b.png)

## Superb Shotの使い方

Superb Shotの使い方をご紹介します。比較的シンプルな機能でかつ、直感的に操作できるようなインタフェースにしたので、実際に見ていただいた方が早いかもしれません。

（登録不要でブラウザ上で処理が完結するため、簡単そしてセキュアに使えます）

:::note warn
深い理由は無いですが、今回は英語サイトとして作成しています。
気が向いたらi18nで日本語やその他翻訳を追加する予定です。
:::

### 画像を選択する

トップページのヒーローヘッダーで加工したい画像を選択できます。以下の3つの方法があります。

- **ドラッグ&ドロップゾーンへ画像をドロップする**
- ***Brouse file*から画像ファイルを選択する**
- ***Paste file*からクリップボードの画像を使用する**
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271387/24eb3794-7025-97ee-b558-e7dc0ead4b44.png)
または、3つのデモ画像を使用することもできます（ちなみにデモの1枚目、2枚目は私が撮影したものです）

### 画像を編集する

トップページで画像を選択すると編集ページへ遷移します。
編集ページ右側のサイドバーに一通りの設定があり、何かしらの設定値を変えるとリアルタイムでプレビュー画像へ反映されます。

**↓多様で魅力的なバックグランドカラー**
![多様で魅力的なバックグランドカラー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271387/9377d368-6ff3-fce5-9933-ba0955091e5a.gif)
**↓パディング、角丸(border-radius)、シャドウ**
![パディング、角丸(border-radius)、シャドウ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271387/02801abd-3f1c-3bae-997c-bd62bc4de251.gif)
**↓インスタ風味の画像フィルター**
![インスタ風味の画像フィルター](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271387/3d107dc4-3478-5439-9c10-909eac706dae.gif)

### 画像を保存する

編集ページのサイドバー下部にある**COPY**、**DOWNLOAD**ボタンからそれぞれクリップボードへコピー、画像ファイルとしてダウンロードできます。

:::note warn
現状ダウンロードできる画像形式は`png`のみですが、そのうち`jpeg`をサポートするかもしれません。
:::

### 既知のバグ

~~腹立たしいことに~~Safariで一部レイアウトがおかしくなる箇所があることを確認しています。気が向いたら修正します。Chromeを使ってね。

## 技術的なこと

Superb Shotで使用している主な技術について。

- [Next.js (v12)](https://nextjs.org/)
- [React (v18)](https://ja.reactjs.org/)
- [Recoil](https://recoiljs.org/)
- [TailwindCSS (v3)](https://tailwindcss.com/)
- [daisyUI](https://daisyui.com/)
- [instagram.css](https://github.com/picturepan2/instagram.css)

記事タイトルおよび冒頭にも書いていますが、Next.jsで構築し静的サイトとしてVercelにデプロイしています。
フロントエンドオンリーのお手軽構成となっています。
StoreはRecoilを使用（Reduxは本サービスにおいては明らかに過剰な代物だったので却下）

UIはCSSフレームワークとしてTailwindCSSとdaisyUIを使っています。daisyUIはデザインが好きだったのでいつか使ってみたかったと思い入れてみました。
自分でゼロからコンポーネントを実装したり、何かしらのUIフレームワークと組み合わせるまでもない時にdaisyUIはすぐに使えて便利です。

`instagram.css`はインスタ風味のCSSフィルターです。一部のフィルターは少し調整して使っています。
CSSフィルターでこんなに色々できるってことを初めて知りました。

### 気に入ってるところ

全然メインの機能ではないのですが、、画像選択ボックスの**グラデーショナルなアニメーションボーダー**が個人的に気に入ってるポイントです。
![chrome-capture-2022-8-18 (6).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271387/7e1678ae-120e-67ae-e7a7-90b84aab8e30.gif)

これはたまたま見つけた↓の動画からインスピレーションを得ました！

<iframe width="560" height="315" src="https://www.youtube.com/embed/1EAtn4B-76g" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

↓ソースコード

https://codepen.io/ahmad_hania/pen/rRPKbZ

### 勘違いしていたこと

当初Next.jsのSSG≒NuxtJSのSSGと思っていましたが完全に勘違いしていました。
NuxtJSのSSGはS3やGitHubPages、Netlify等々、静的サイトとしてどこにでもデプロイできますが、Next.jsのそれは基本的にはVercelが必要みたいですね。。
Next.jsで完全に静的サイトとするには**Static HTML Export**を利用する必要がありますが、色々と機能に制限があるので使っていません。

https://nextjs.org/docs/advanced-features/static-html-export#unsupported-features

※途中まで作って、もしかしてGatsbyを使った方が適当だったかなぁと結構悩みましたがNext.jsで作り切りました。

## かかった時間

毎日手を動かしていたわけではないですが、期間としてはReact/Next.jsの学習時間含めて1～2週間ほどです。
私はよく頭の中でデザインを考えながら実装するというやり方をとるのでデザインで悩み、実装も手戻りしながらなので（無駄に）時間がかかりました。。

## 運営費、そしてマネタイズ

バックエンドもない普通の静的サイトなので現状サイトの運営費はドメイン代以外かかっていません。
また、マネタイズはしていません。やるとしたら今後需要がありPVが安定した数値になったら広告を貼るかもしれないです。

日々運営費が掛かっていたらマネタイズを真剣に考える必要がありますが、掛かっていなければ何も考えず公開し続けても問題は無いのです。**個人開発においてはいかに低コスト（完全無料にこだわるぐらいでも良い）で運営できるかを最優先に考えます。**

## なぜReact/Next.jsに入門したか

Nuxt3の開発状況を見て、です。
私は普段Nuxtをよく使いますが、Nuxtのv3リリースが遅れており2022年9月時点でv3の安定版がリリースされていません。RCが順次リリースされていますがまだまだ大きなバグや変更点が多く私自身の中ではまだ使えないと判断しています。
また、Nuxt3がリリースされたとしてもよく使う関連ライブラリ（特にi18nやPWA、sitemap、Vuetify等々）の対応も待つ必要があり中々厳しいものがありました。

今更Nuxt2で新規プロジェクトを作る気にはなれず、それならばとReact/Next.jsに入門した次第です。
あとは、少し前までは日本ではReactよりVueのが流行っていた感がありましたが、今はReactが圧倒的に使われている状況も理由のひとつです。

## おわりに (&宣伝)

初めてReact/NextでWebサービスを作ってみましたが、React良いなぁと思いました。
パフォーマンス周りはVueよりも注意して実装する必要がある感じがしましたが、**ライブラリが豊富、環境構築周りで悩むこと無し、情報量多い、需要が高い**等々今後もReact/Next.jsで開発していこうかなぁと思っています（少なくともNuxt3が安定するまでは）

**Superb Shot**使ってみてね😉

https://superbshot.dev/

（宣伝）**Web ToolBox**というブラウザ上で使える、様々な便利なツール集を公開しているWebサービスを開発しています。こちらもよろしくお願いします！

https://web-toolbox.dev/