Tech カテゴリのイメージ

締切のプレッシャーを炭酸にして飛ばすアプリ「シュワーっとストレス解消くん」を作った

締切が近いとき、頭の中で同じ言葉がずっと鳴っている。「あと3日」「まだ結果が出ていない」。その反芻を止めたくて、プレッシャーを炭酸の泡に変えて飛ばすアプリを作った。

シュワーっとストレス解消くんを開く

書いた文字が、そのまま泡になる

テキスト欄にいま効いているプレッシャーを書いて「シュワーっとする」を押すと、グラスに炭酸が注がれ、書いた文字が一文字ずつ泡に入って上がってくる。「論文の締切」と書けば、論・文・の・締・切が泡になってのぼっていく。自分が書いた言葉が物理的に浮いて消えるのが、このアプリの全部だ。

プリセットのボタンも置いた。論文の締切、査読コメント、学会発表、進捗報告、実験が終わらない、メール返してない。押すと入力欄に足される。書くのすら面倒な日のためのもので、実際そういう日ほど必要になる。

書いた内容はどこにも送信も保存もされない。通信のない静的ページなので、そもそも外に出しようがない。

眺めるだけにしない

流すだけのアプリだと、押したあとにやることがなくなる。そこで泡はタップで割れるようにした。放っておいても水面まで上がって勝手にはじけるが、自分で割ると音が少し大きく、最後に「自分で割った N コ」と出る。8割以上を自力で割ると、締めのメッセージにひとこと足される。

「のこりプレッシャー」のゲージが減っていくのも、進捗が目に見えて気持ちがいい。炭酸の強さは微炭酸・ふつう・強炭酸から選べて、強くすると泡の数が増えて上昇も速くなる。連打したい日は強炭酸がいい。

音は合成、絵はCSS

例によって外部ファイルなしの単一HTMLで作っている。

・グラスと炭酸水、ストローはすべてCSS。水面のふくらみは楕円のborder-radiusで作った ・注いだ瞬間の「シュワー」はWeb Audioのホワイトノイズをハイパスフィルタに通したもの。音声ファイルは使っていない ・泡がはじける音はサイン波を8ミリ秒で立ち上げて130ミリ秒で落とすだけ。周波数を毎回ランダムに散らすと、連打しても単調にならない

検証でハマったこと

ここが今回いちばんの学びだった。作ったあと自動で動作確認していて、泡がまったく上昇しないように見えた。位置を測ると5秒経っても1ピクセルも動いていない。CSSの bottom-40px から 104% へ動かしていたので、pxとパーセントの補間に失敗したのだと考えて、transform: translateY() 方式に書き直した。

それでも動かなかった。おかしいと思ってアニメーションの内部状態を見たら、原因はまったく別のところにあった。

document.hidden // true
document.timeline.currentTime // 0 のまま進まない
requestAnimationFrame の発火数 // 0

検証に使っていたブラウザのタブが非表示状態で、ブラウザがCSSアニメーションと requestAnimationFrame を丸ごと凍結していた。アプリのバグではなく、確認環境が時間を止めていただけだった。setTimeout は動くので泡は生成される、けれど一切上昇しない。この組み合わせが「アニメーションのバグ」に見えて、私はしばらく無実のコードを直していたことになる。

回避策として、Web Animations APIで時間を手で送って軌道を確かめた。

const a = bubble.getAnimations()[0];
const dur = a.effect.getTiming().duration;
a.currentTime = dur * 0.5; // 進行度50%へ手動で送る
bubble.getBoundingClientRect(); // その時点の位置を測る

これでグラスの下から入り、内部を通過し、上へ抜けることを数値で確認できた。時間が止まった環境でも、進行度を指定すれば位置は正しく計算される。動きを含むUIを自動で検証するとき、この方法は覚えておくと役に立つ。

なお transform への書き直しは、元の bottom でも動いた可能性が高い。ただ transform のほうが合成処理に乗って軽いので、そのまま残した。誤診から入った変更だが、結果としては悪くない場所に着地した。

まとめ

・書いたプレッシャーの文字が炭酸の泡になって抜けていくアプリを作った ・泡はタップで割れる。自分で割った数が最後に出る ・内容はどこにも送信・保存されない。通信のない単一HTML ・絵はCSS、音はWeb Audioで合成。素材ファイルはゼロ ・非表示タブではCSSアニメーションもrAFも完全に止まる。動くUIの自動検証はWeb Animations APIで手動送りするのが確実 ・シュワーっとストレス解消くんから。締切が重い日にどうぞ