Week 12026年1月4日

新しい個人ウェブサイト

Cache-ControlFOUCSanity CMSFlipnote Studio

概要

個人ウェブサイト兼ブログを作りました。色々技術的な部分とかビジュアルスタイルについて書きます。

技術的詳細

Sanity CMSでのコンテンツ管理

3つのドメインで異なる役割を持たせています:

- kynantokoro.com: 公開済みコンテンツのみを表示
- draft.kynantokoro.com: 下書きを含む全てのコンテンツを表示(Sanity CDNを無効化し、ほぼ即時でプレビュー可能にしています)
- cms.kynantokoro.com: Sanity Studio(コンテンツ編集画面)

draft版とcms版はCloudflare Accessでアクセス管理を行っています。

FOUCのないテーマ切り替え

ダークモード/ライトモードの切り替えでよくある問題が、FOUC(Flash of Unstyled Content)です。Cookieを使ってSSRでテーマを適用する方法もありますが、ブログのようにユーザーによらず同じコンテンツを提供するサイトでは、HTTP Cache-Controlとの相性が悪くなります。

一度Cookieベースのアプローチを試した上で、最終的にはクライアントサイドでのテーマ切り替えを採用しました。`<head>`タグ内でCSSの描画が始まる前に、同期的にテーマのattributeやclassをセットすることで、FOUCを完全に防ぎながら、HTMLレスポンスは全て同じ内容になり、HTTP Cache-Controlヘッダーを使った積極的なキャッシングが可能になります。

AI翻訳機能

CMS内に独自のAI翻訳機能を実装しました。日本語で記事を書いた後、ワンクリックで英語に翻訳できます(逆も然り)。翻訳エンジンにはClaude(Anthropic)を使用しています。

記事はSanityのPortable Text形式(JSONベースの構造化されたリッチテキスト)で管理されており、埋め込み画像、カスタムブロック(ゲーム埋め込み、オーディオプレイヤーなど)、テキストのスタイリング、文書構造などを保ったまま翻訳できます。

ビジュアルスタイル

サイトのビジュアル面では、ニンテンドーDSの「うごくメモ帳(うごメモ)」で作成したアニメーションを活用しています。

トップページのGIF

プロフィール画像には、DSの画面いっぱいに描いた10フレームほどのアニメーションをGIF化したものを使用しています。SSRやHTTP Cacheの挙動を視覚的に確認できるよう、サーバー側で彩度をランダムに生成しています。ページをリロードすると色味が変わるのは、実はキャッシュの動作確認のためでもあります。

ブログエントリーのキーイメージ

各ブログエントリーには、seed値に基づいて決定的に生成されるキーイメージが表示されます。以下のパラメータがseedから決まります:

- GIFのフレームindex(どのフレームを使うか)
- Zoom倍率
- 傾き
- 色相(hue)

実際に画像を生成しているわけではなく、CSSのプロパティを変更しているだけです。軽量かつ柔軟にビジュアルバリエーションを生み出せます。

完全にランダムだと面白くないので、「志向性」を持たせています。例えば、傾きは基本的に90度単位で、たまに斜めの角度が出るようにしています。このような制約により、ランダムでありながら統一感のあるビジュアルになっています。

毎週何か作る

このブログを始めた理由の一つに、「Game a Week Challenge」や、Creative Coding系のクリエイターのブログに影響を受けたことがあります。定期的に何かを作って公開するという習慣に何か執着があるのかもしれないです。(自分の関わっている音楽のプロジェクトも大体そういう制約を無理やり作って生まれたものが多いです。)

本当は「毎週ゲームを作る」というのをやりたかったのですが、自分の関心がコロコロ変わることはわかっているので、もう少しゆるいルールにしました。

「1週間に1つ、何か面白いものができたらアップする」

それがゲームでも、音楽でも、ツールでも、実験的なコードでも何でも良し!ただし仕事と生活優先で 😅