【FGO】「村正ぁーーー!」するためのネタサイト作成記録


はじめに

こちらのサイトの作成備忘録です。インフラ等の全体像は別途記事にしたいと思います。

Fate/Grand Orderというスマートフォン向けゲームのコラージュ画像を生成するお遊びサイトです😇

(C) TYPE-MOON

方針検討

やりたいことは 「既存の画像に、セリフだけ好きに挿入する」 という簡単なものです。なんとなくフロントだけでもできそうですが、ある程度フォントを原作に近づけたいと考えたので、特定のフォントを気兼ねなく使えるかな?と思い、バックエンドも構築することにしました。

またお遊びサイトでお金のことを気にしたくなかったので、ホスティングはGithub pagesで行うことにしました。

以上を加味した上で、ぱぱっと作りたいので、自分の既存の技術スタックで取り組むことに決めました。具体的にはフロントエンドNuxt.js(TypeScript不使用)+Vuetify.js、バックエンドLambda+API Gateway(Python)。

図にすると下記のイメージです。生成する画像は再利用不要かつそこまでサイズも大きくないので、base64エンコードして直にクライアントに返すようにします。(S3に一時保存などしない)

フロントエンド

コードは下記にあります。
https://github.com/tenkoh/fgo-scenes

プロジェクト生成

SSGを狙って下記の通り設定する。

npx create-nuxt-app fgo-scenes

create-nuxt-app v3.7.1
✨  Generating Nuxt.js project in fgo-scenes
? Project name: fgo-scenes
? Programming language: JavaScript
? Package manager: Npm
? UI framework: Vuetify.js
? Nuxt.js modules: Axios - Promise based HTTP client
? Linting tools: ESLint, Prettier
? Testing framework: None
? Rendering mode: Universal (SSR / SSG)
? Deployment target: Static (Static/Jamstack hosting)
? Development tools: jsconfig.json (Recommended for VS Code if you're not using typescript)
? Continuous integration: None
? Version control system: Git

Github pagesに対応するための準備

github pagesにdeployすると公開URLは<username>.github.io/<repositry name>になる。Nuxtはデフォルトではルートディレクトリ以下にindex.html/static以下のファイルを配置するため、上記URL形式に対応するために次の変更が必要。

nuxt.config.js
const basePath = '/fgo-scenes/'
export default{
  // Global page headers: https://go.nuxtjs.dev/config-head
  head: {
    link: [
      { rel: 'icon', type: 'image/x-icon', href: basePath + 'favicon.ico' }
    ]
  },
  generate: {
    dir: 'docs'
  },
  router: {
    base: basePath
  }
}

1

面倒なのは/static以下のファイルへのリンク。ファイルパスを動的に変更するために処置が必要。2
ベストプラクティスがよくわからないが、下記手順で対応してみる。

  1. プラグインを活用して、グローバル変数としてbaseパスを定義する。
  2. .vueファイル中で、ファイル名を動的に設定する。
~/plugins/globals.js
export default ({ app }, inject) => {
  inject('basePath', ()=>{
    return '/fgo-scenes/'
  })
}
~/components/VuetifyLogo.vue
<template>
  <img
    alt="Vuetify Logo"
    :src="logo"
  >
</template>

<script>
export default {
  data(){
    return{
      logo: this.$basePath() + 'vuetify-logo.svg'
    }
  }
}
</script>

実装

以降は基本的なNuxtプロジェクトの流れに乗って開発するだけ。

  • 表示速度が極端に遅くならないように、下記の処置は実施しました。

  • PWAは今回非対応にしています。

バックエンド

AWS Serverless Application Model(SAM)を使って構築していきます。任意のフォントを使って画像に文字を埋め込む、という点について参考文献が多く見つかったため、言語はPythonを選択しました。3

コードは下記に保存してあります。
https://github.com/tenkoh/fgo-scenes-api

フォントは原作では「スキップ」という書体が使われていますが、有料フォントのため、無料で公開されているフォントの中でイメージが近いものを使用させて頂きました。こんなフォントを無料公開されているとは…!感謝!
https://okoneya.jp/font/genei-latin.html

そのままではファイルサイズが大きいので、常用漢字等に限ったサブセットを作成し、使用させて頂きました。

おわりに

さくさくっと作ることができました。いろいろな仕組みに感謝ですね…!

最後に、現在開催中のネロ祭復刻イベントに対して…

※個人の見解です


  1. Github pagesがファイルを読み取るには、rootまたは/docsディレクトリ以下に必要なファイルを置く必要がある。 

  2. https://nuxtjs.org/docs/2.x/directory-structure/static 

  3. 出来栄えを確認したところ、起動速度などパフォーマンス面が気になったので、他のコンパイル型言語とかでも良かったかもしれません。