新たなプロジェクト「RECTBEATS(レクトビーツ)」を公開しました。

アプリで作成されたサンプルが、横 4 列、縦 2 行で合計 8 個並んでいる

以前に公開した「RECTGRAPH(レクトグラフ)」と同様に、SVG イメージを生成するウェブアプリです。SVG は 21 個の矩形要素(<rect>)から構成されており、フィボナッチ数列の規則で配置されています。公開時は 8 個のプリセットを用意しています。

生成される矩形要素の配置パターンはランダムなので配色は毎回異なります。また、この矩形要素のカラーやエフェクトを調整して見た目を変更することが可能です。

本アプリは以下の機能で構成されています。

アプリ各機能の名称を示した図。1. PREVIEW、2. TITLE、3. DOWNLOAD、4. SETTINGS、5. BUTTONS のエリアが説明されている。
「SETTINGS」が閉じている状態

イメージのプレビューが表示されます。この SVG 内の矩形要素(<rect>)の配置はランダムなので、毎回異なる配色になります。

タイトルはダウンロード時のファイル名や、ダウンロードしたの SVG の <title> に設定されます。このタイトルは自由に変更できます。

「DOWNLOAD」ボタンを選択すると、プレビュー内容の SVG ファイルがダウンロードできます。

ダウンロードできる SVG ファイルのライセンスは MIT License で、SVG のコードにライセンスに関するコメントを含めています。

「SETTINGS」を選択することで、SVG イメージをカスタマイズできる設定項目が表示されます。ここには、再生時のテンポを変更する「BPM」の項目も含まれます。

各ボタンを選択することで、SVG イメージをアレンジすることができます。

「ROTATE」「MIX」「PLAY」それぞれを選択したときのイメージ
  • 「ROTATE」ボタンを選択すると、SVG イメージが 90° 回転します
  • 「MIX」ボタンを選択すると、プレビュー内の矩形要素の配置がシャッフルされます
  • 「PLAY」ボタンを選択すると、「BPM」のテンポにあわせてプレビュー内の矩形要素の配置がシャッフル(「MIX」)されます

「PLAY」で再生中に、他のタブに移動したりウィンドウを最小化すると一時停止します。


「SETTINGS」を開くと、以下の設定を変更することができます。

アプリ各機能の名称を示した図。6. COLOR、7. LEVEL、8. GUIDE、9. BPM のエリアが説明されている。
「SETTINGS」を開いた状態
「BASE」「STROKE」「OSC.1」「OSC.2」の位置を示した図
  • 「BASE」は、ベースとなる背景カラーです
  • 「STROKE」は、各矩形要素の区切り線や、フィボナッチ・スパイラル(渦を巻いている罫線)などのカラーです
  • 「OSC.1」と「OSC.2」は矩形要素(<rect>)のカラーです

なお、「OSC.1」は 13 個、「OSC.2」は 8 個配置されるので、「OSC.1」のほうが出現する数は多くなります。

OSC は Oscillator(オシレーター、発振器)の略称で、シンセサイザーにおいては音の基本となる波形を発生させるために用いられます。

  • 「STROKE WIDTH」では、罫線のサイズを変更することができます
  • 「OSC.1 LEVEL」と「OSC.2 LEVEL」は、矩形要素それぞれの不透明度(opacity)を変更できます

本アプリで指定できるカラー数は限られていますが、透過率を加えることで立体的な効果を出すことができます。

ガイドは、プレビューエリアでの SVG の見え方を変更する機能です。

「OFF」「SPIRAL」「CIRCLE」それぞれを選択したときのイメージ
  • 「OFF」を選択すると、各正方形の上に重なるガイドが非表示になります
  • 「SPIRAL」を選択すると、各正方形に内接する 1/4 の円弧を結んだ、フィボナッチ・スパイラルが表示されます
  • 「CIRCLE」を選択すると、各正方形内に正円の罫線が表示されます

BPM は「PLAY」ボタンを選択すると、一定の間隔で SVG イメージが変化しますが、そのテンポを指定できます。値は 0 から 240 までの範囲で設定可能です。

現時点では以下の問題を認識しています。

ダウンロードファイル

見出し「ダウンロードファイル」

ダウンロードした SVG ファイルは、一部の環境では開くことができませんのでご了承ください。

本アプリの矩形要素(<rect>)はすべて正方形で、フィボナッチ数列である 1, 1, 2, 3, 5, 8, 13, 21 の比率で配置されます。

各矩形要素の比率がフィボナッチ数列であることを表す図

フィボナッチ数列は、先行する 2 つの数の和から構成される数列ですが、n = 0 と n = 1 の場合はそのまま 0 と 1 が入ります。

F0=0 F1=1

n = 2 以降は次の式で定義されます。

Fn=Fn-1+Fn-2

また、隣接する 2 つの数の比(大きい数から小さい数を割った比率)は、次第に黄金比である 1.618... に近似していくという特徴があります。

n = 0 から n = 8 までと、n = 13 のフィボナッチ数列、隣接する 2 つの数の比を表した図

このフィボナッチ数列は、ミツバチの系統図や植物の葉序パターン(茎のまわりの葉の配列)、ハリケーンの雲などの自然界の現象に加え、株式市場のパターンや音楽、絵画、建築など、身の回りのいたるところに宿っています。

ウェブデザインにおいては、スペーシングのスケールに用いられたり 1、ロゴマークのデザインがフィボナッチ数列から成り立っていることがあります。

フィボナッチ数列や黄金比については、以下の書籍やウェブページを参考にしました。

ここからは、具体的な実装内容を説明していきます。

当初実装したときの課題として、SVG の罫線(stroke)を要素の内側に引く方法が見当たりませんでした(通常は中央に位置します)。

このため、設定した stroke が SVG イメージの領域に収まらない問題が起こりますが、CSS の scale()translate() を駆使して内側に収まるように調整しています。

before: stroke を内側に引けないため、罫線の半分が収まらない。after: CSS で罫線の分だけサイズを縮小し位置を調整する

具体的には以下のような CSS を指定しています。

stroke-width が 10 のときの CSS の例
g {
  --strokeWidth: 10;
  --adjust: calc((var(--strokeWidth) / 2) * 1px);

  translate: var(--adjust) calc(64px + var(--adjust));
  scale: calc((340 - var(--strokeWidth)) / 340);
}

再生の制御(Page Visiblity API)

見出し「再生の制御(Page Visiblity API)」

「PLAY」ボタンを選択すると、設定したテンポ(BPM)でプレビュー内の矩形要素の配置が定期的にシャッフルされますが、これは setInterval() で繰り返し処理を実行しています。

この再生を停止する方法として、再び「PLAY」ボタンを押す方法に加え、Page Visiblity API でも制御しています。具体的には、他のタブに移動したりウィンドウを最小化すると一時停止します。

最近のブラウザでは、他のタブに切り替えれば一時的に setInterval() の処理が停止するのでパフォーマンス上の効果は見込めないかもしれませんが、ページを移動してから戻ってきても再生が継続している必要性は低いので、この制御を適用しました。

「ダウンロード」ボタン選択時には、以下の処理を実行しています。

  • ファイル名の作成
  • SVG コードの整理
    • スタイル指定の調整
    • 不要な属性の削除
    • 使用していないガイドの削除
  • ライセンスコメントの追加
  • ファイル圧縮(空白や改行の削除)
  • ファイルのダウンロード
    • Blob オブジェクトの作成
    • ダウンロード用に <a> 要素を生成して click() イベントを実行
  • 後処理

前項の「ガイドモード」で説明した、scale()translate()、そして「ROTATE」ボタンを選択したときの rotate() は CSS で指定していますが、デザインツール(Adobe Illustator や Figma)で開くとうまく反映されません。

この問題を解消するために、ダウンロードファイル作成時に各要素を囲う <g> 要素を追加して、そちらに transform 属性として直接指定することで対処しています。

ダウンロードした SVG ファイルの例
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 340 340" role="img">
  <!-- ... -->
  <g transform="rotate(90, 170, 170) translate(2.5 67.5) scale(0.9853)">
    <!-- ... -->
  </g>
</svg>

本アプリはプレビューを大きく見せたかったので、すべてのレイアウトで 1 カラム構成としていますが、「SETTINGS」を開いた状態だとスペースを取ってしまい、スクリーンサイズによっては調整しながらプレビューを確認するのが難しいのが悩みどころです。

ほかにも、シーケンサーのような機能や、すべての SVG イメージの再生・停止や BPM を同期させるアイデアもあったのですが、処理が複雑になったり、UI のバランス調整がしっくりいかなかったりと、わかりづらくなりそうでしたので実装は見合わせました。

このように課題を残すアプリですが、今後も折を見て調整していきます。

脚注

  1. 音楽、数学、タイポグラフィ | シフトブレイン/スタンダードデザインユニット