昔mixiアプリでネココレースというアプリを作ったのですが、その素材が放置状態でもったいない事に気づいたので、ネココさんを着替えさせて喋らせてTwitter上に投稿できる簡易なWebアプリを作ってみました。
ログインなど不要ですぐ使えます。
構成
Google App Engine
この手のWebサービスにはあまり意味がないのですが、SSR(サーバーサイドレンダリング)で一応全部ページクロールできるようにして多少SEO的な効果も期待し、静的ホスティングサービスではなくGoogle App Engineにしてみました。
Nuxt.js
最近は簡単なアプリケーションはNuxt.jsだととにかく簡単に色々作れるのでよく使っています。前述と同様、SSR目的でもあります。
Firebase
今回はデータを登録して表示するだけというシンプルなデータ構成のため、わざわざサーバーを用意しなくてもよいFirebaseを使ったサーバーレス構成にしました。
データの保存にFirestore、画像の保存にStorageを使っています。
Buefy
Bulmaというやわらかい感じのデザインを実装できるフレームワークを使っています。ただ、Bulma自体はほんとにCSSだけで、動きなどは自分で付けなければなりませんので、動き部分も実装されているBuefyを使っています。これを入れるだけでBulma自体のCSSもそのまま使うことができ汎用的で非常に便利です。
仕組み
プロジェクトの作成
プロジェクトはcreate-nuxt-appを使って作成し、TypeScriptを追加しました。以前下記でまとめていた方法になります。
Nuxt.js+ExpressのプロジェクトをTypeScript化する
Storeの利用
動物や着せ替えの選択は、選択したコンポーネントだけでなく、画像のダウンロードやシェアする画像を作成する等、他の場所でも使うためにStoreのStateとして保持しておきます。
StoreはNuxt.jsのマニュアルを見ると非常に理解しやすく、下記の記事でも以前まとめています。
VuexのStoreはNuxt.jsのマニュアルを見るとすぐ理解できる
画像の作成
画像は html2canvas で作成しました。今回はサーバーが無いためこれを使ってブラウザ上で画像を作成する形です。left: -2000px
とかにしたdiv上にあれこれ配置し、それをhtml2canvasで変換しているだけです。
一点注意点として、デフォルトの挙動では端末のサイズによってcanvasのスケールが変わってしまうようですので、下記のように等倍で作成します。
const canvas = await html2canvas(this.$refs.canvas, { scale: 1 })
Blobに変換する方法は下記等、色々情報があります。
Canvasで描画した画像を送信してサーバに保存する - Qiita
canvas.toBlob もあるみたいですね。早く全てのブラウザで実装されてほしいものです。
あとはStorageへの登録はマニュアル通りです。ファイル名は登録したメッセージデータのID名にしています。
const ref = firebase.storage().ref()
const imageRef = ref.child(`images/${messageId}.png`)
const imageSnapshot = await imageRef.put(blob)
画像のURLも取っておきます。調べた情報によると、上記のimageRefでなく、再度Storage側から取ってきたものを使わないとダメなようです。
const ref = firebase.storage().ref()
const imageRef = ref.child(`images/${messageId}.png`)
const url = imageRef.getDownloadURL()
このURLもメッセージデータに保存しておけば完成です。
あとは表示画面で入力されたメッセージや画像のURLをメタタグに入れておけば、その詳細ページのURLをシェアしてもらうことでツイートでシェアすることができます。
Nuxt.jsの場合メタタグの設定はページコンポーネント内で下記のように行います。
head() {
const title = this.getTitle() + ' - ネココさんトーク'
const description = `${this.categoryExplanation}:${this.message.message}`
return {
title,
meta: [
{
name: 'description',
content: description
},
{ name: 'og:title', content: title },
{
property: 'og:image',
content: this.message.imageUrl
},
{
property: 'og:description',
content: description
},
{
name: 'twitter:card',
content: 'summary_large_image'
},
{
name: 'twitter:image',
content: this.message.imageUrl
}
]
}
}
SSRのためデータはasyncDataで取っておきましょう。
async asyncData({ params }) {
const messageRef = messagesCollection.doc(params.id)
const message = await messageRef.get()
const messageData: any = message.data()
messageData.id = message.id
return {
message: messageData
}
}
シェアする画面へのURLの作成は下記のような感じです。
tweetUrl() {
const url = encodeURIComponent(
process.env.URL + `/messages/${this.message.id}`
)
const text = encodeURIComponent(this.categoryExplanation)
const hashtags = encodeURIComponent('ネココさんトーク')
return `https://twitter.com/share?url=${url}&text=${text}&hashtags=${hashtags}`
}
デプロイ
Google App Engineへのデプロイは下記で以前解説しています。
ZeitのNowでも良いと思います。GAEはFirebaseのプランが変わってしまう(無料枠は利用可能です)、Zeitは無料でのデプロイ回数制限がある、という違いがあるので適宜良い方を選択してください。
おまけでGA
Google Analyticsの導入は下記をインストールして設定するだけでした。めちゃくちゃ簡単。
nuxt-community/analytics-module: Google Analytics Module
まとめ
大雑把になりますが作り方をざっと紹介しました。興味のある方は是非試してなにか作ってみてください!
不明点があればTwitter等で聞いてもらえれば可能な範囲で答えます。
Top comments (0)