Wablo
Wabloは、友だちに30秒の落書きを送るための iOS アプリです。テキストなし、写真なし、スタンプなし。指で描いたぐにゃぐにゃの線が、そのままカードになって友だちの机の上に積まれます。会社の仕事とは別に、個人プロジェクトとしてひとりで作っています1。
なんで落書きなのか
メッセージアプリを開くと、まず「なにを書くか」を考えることになります。写真を送るなら「どれを選ぶか」。どちらも、ちょっとだけ腰が重い。用事がないと送れない空気があります。
でも、仲のいい友だちに伝えたいことの大半は、用事ではありません。いま思い出した。授業がひま。へんな犬を見た。そういうものは文章にすると大げさになるし、送ったあとの既読の重さにも耐えられません。
だから Wablo は、線だけにしました。指でぐにゃっと描いた線には、上手も下手もありません。うまく伝える義務から自由です。むしろ、へたな絵ほどよく届きます。
30秒しかありません
Wablo のキャンバスには30秒のタイマーがついています。時間切れになったら、その時点の絵がそのまま送信されます。描き直しはできません。
ひどい仕様に聞こえるかもしれません。でもこれは罰ではなくて、考えすぎる前に送るための仕掛けです。30秒あれば犬は描けます。上手な犬は描けません。それでいいんです2。
ちなみに、まっしろのまま送ろうとすると、さすがに止められます。なにか一本は描いてください。
画面遷移を捨てて、机にしました
ここからが本題です。UXの話を、すこし長めにさせてください。なにしろ、いちばん頑張ったところなので。
Wablo には画面遷移がありません。ナビゲーションスタックも、タブビューも、モーダルもありません。かわりに、横幅が画面6枚ぶんある大きな机がひとつだけあります。
友だちの落書きが積まれる「らくがき」。自分の場所である「じぶん」。友だちいちらんの「ともだち」。これらは切り替わる画面ではなく、最初からぜんぶ机の上に並んでいます。左にらくがき、まんなかにじぶん、右にともだち。アプリの構造が、そのまま空間の記憶になります。「あの機能はどの画面だっけ」ではなく「あれは右のほうに置いてあった」と覚えてもらう設計です。
そして、ユーザーに「画面が変わった」と感じさせる手段を2つだけに絞りました。カメラが動くか、机の上の物が動くか。この2つの語彙だけで、アプリ全体のナビゲーションを組み立てています。
カメラだけが動く
タブを切り替えても、Wablo では画面がスライドしません。かわりに、カメラがふわっと浮き上がります。
まず机全体が見える高さまで離陸して、空中を移動し、目的の場所へ降りて着席する。3幕構成で、ぜんぶで約1秒。離陸の瞬間、滞空の頂点、着地で、それぞれ違う振動が指に刻まれます。俯瞰中のカメラにはマイナス1.8度だけロールをかけてあって、これは子どもが身を乗り出して机の反対側を覗き込むときの、頭の傾きのつもりです。
この間、机の上の物は1ピクセルも動きません。動くのはカメラだけ。だから俯瞰したとき、隣のエリアが「本当にそこにある」のが見えます。しかも各エリアは机の上に少しずつ傾けて置いてあって、上から見ると散らかった紙の束のようです。着席するとカメラが逆方向にロールして傾きを打ち消すので、手元の画面はまっすぐ。散らかりは俯瞰でだけ見える、という小さな贅沢です。
ひとつだけカメラについてくるものがあります。右下に貼ってあるタブのステッカーです。カメラが飛んでも、あれだけは画面の同じ場所に居続けます。机の上の物ではなく、手に持っている物だからです。
カメラの移動は酔いやすい人には酔うので、Reduce Motion をオンにするとカメラは一切飛ばず、0.11秒の短いクロスフェードに切り替わります。世界観よりも、気持ち悪くならないことが先です。
描くときは、机を片付ける
では描くときはどうするか。ここでもカメラは動きません。机を片付けます。
返信ボタンを押すと、上のバーは左上へ15度傾きながら、カードの束は右へ11度傾きながら、返信ボタン自身は右下へ18度傾きながら、それぞれ固有の方向へ紙切れのように飛んでいきます。残るのは方眼紙だけ。そこへ、まっさらな紙が下からすっと上がってきます。
描き終えて戻るときは、同じパーツが同じ方向から同じ角度で帰ってきます。行きと帰りが対称だから、「片付けた物を元の場所に戻した」ように見えます。画面が切り替わったのではなく、机の状態が変わっただけ。描画中もあなたは同じ机の前に座っています。
ルールもひとつ決めました。カメラが飛んでいる間は机を片付けない。机が片付いている間はカメラを飛ばさない。両方が同時に起きると、俯瞰で小さく縮んだ紙が斜めに飛んでいく「壊れた物理」が見えてしまいます。この世界の説得力は、そういう一瞬で崩れるので。
紙には重さがある
送信した落書きの動きは、いちばん振り付けに時間をかけたところです。
描き上げた紙がすこし持ち上がって、画面の外へ飛んでいく。しばらくして、画面の外から戻ってきて、束の一番上にぽとっと着地します。ここからが本番で、着地の衝撃は6段階に分けてあります。束がわずかに沈み、跳ね返り、揺れながら収まっていく。この揺れは下のカードほど小さく伝わるようにしてあって、1枚下は86%、2枚下は50%の振幅です。紙の束に紙が落ちたときの、あの伝わり方。ぜんぶで約1.2秒です。
更新ボタンを押すと、束はいったんばらばらに散らばって、画面の外から1枚ずつ飛び込んで積み直されます。1枚ごとに小さな振動が刻まれるので、何枚届いているか、指先でなんとなくわかります。
なにもしていないときも、束は数秒おきにごくかすかに揺れています。机の上の紙は、完全には静止しないものなので。
くるくるは机に存在しません
ローディングにも同じ理屈を通しました。方針は単純です。回転する円弧は、この机の上に存在しない。だからスピナーは使いません。
300ミリ秒以内に終わる待ちには、なにも出しません。一瞬だけ現れて消えるインジケータは点滅として知覚されて、「なんか遅い」という記憶だけを残すからです。それより長い待ちには、これから届く紙とまったく同じ寸法の白い紙を、先に机へ置いておきます。データが届いた瞬間、紙の中身が入れ替わるだけで、レイアウトは1ピクセルも動きません。
読み込みに失敗したときは、墜落した紙飛行機の絵が出ます。取りに行った紙飛行機が落ちた、それだけの話なので、拾ってもう一度飛ばせばいい。エラーまで含めて、ぜんぶ机の上の名詞で語ることにしています。
方眼紙、クレヨン、ラムネ色
見た目の合言葉は「方眼紙」「クレヨン」「ラムネ色」「ぷにっと押せる」「ぽとっと落ちる」の5つです。
白いカードと淡い色で、主役はあくまで描かれた線。角は大きく丸く、線は太く、ボタンは押すと少し沈んで戻ります。ミニマルで洗練されたSNSではなく、机の上の紙と、子どものころのおもちゃ箱。ガラスや金属のようなプレミアムな質感は、意図的に避けています。
やらないことリスト
作る機能を決めるより、作らない機能を決めるほうに時間を使いました。
フィードはありません。いいねの数も、ランキングも、公開プロフィールもありません。フォロワーという概念自体がないので、増やすものも減らすものもありません。リアクションは、カードをダブルタップして置ける小さなマークだけ。しかも5個で打ち止めです。
SNSが作りたかったわけではないからです。作りたかったのは、放課後の教室で、となりの机に落書きした紙を投げる、あの感じです。
中身の話をすこしだけ
iOS は Swift 6 + SwiftUI + The Composable Architecture。机とカメラの物理はぜんぶ自前で、カメラの移動は Core Animation に直接駆動させているので、本体の処理が一瞬詰まってもカメラは止まりません。サーバーは Cloudflare Workers + Hono、データベースは Neon、画像は R2 という構成です。ロック画面には WidgetKit のウィジェットで、友だちの最新の落書きがそのまま出ます。アプリを開くより先に、犬(もしくはアシカ)が目に入る設計です。
インフラが苦手な人間3がひとりでサーバーまで面倒を見られているのは、ぜんぶエッジのプラットフォームがえらいおかげです。
さいごに
画面遷移をひとつも作らずにアプリをひとつ作る、というのは、正直に言えば遠回りでした。でも「アプリを操作している」ではなく「机の上の紙を触っている」と感じてもらえる瞬間が一度でもあるなら、遠回りのぶんは回収できたと思っています。
Wablo はまだ小さなアプリです。でも、友だちのロック画面にへんな犬が届いて、3秒だけ笑ってもらえたら、このアプリは仕事をしたことになります。会話がそこから始まってもいいし、始まらなくてもいい。
伝えたいことが特にない日にこそ開いてもらえるアプリに、なれたらと思っています。結論は、みなさんの指で描いてください。