感動するUIの作り方 3連発
こんばんは
daiizdaiiz.iconです
Notaでの開発
Scrapboxチーム 2年
Helpfeelチーム 2年
趣味での活動
GUI勉強会に参加
https://gyazo.com/8769fb28b4381b0c148ed1d38972c14f https://scrapbox.io/daiiz/%E5%85%A5%E9%96%80GUI
本日の3本
履歴を遡るスライダー
タッチデバイスでの文字選択
表作成ツール
履歴を遡るスライダー
https://gyazo.com/c97d5cb327f234e899541c453bf44719
一定期間が経っている状態で編集されるとスナップショットが撮られる
行単位での編集差分を確認できる
履歴をパラパラ見ていくための操作パーツを作りたい
真っ先に思いつくUIの例
https://gyazo.com/19f2f7db9c823e881c1a255e02a17afe
履歴が多くなったときに選びづらくなる
スナップショットの総数がひと目で分からない
課題
スナップショットが撮られた瞬間と、そのバージョンが継続していた期間の両方を示したい
素早く前後のバージョンを比較したい
本文に集中してほしいので細かい設定をいじったりするのは無し
こんな感じでどうだろう
等間隔な目盛りを表示する
https://gyazo.com/ecb80325822451a636bff491b42c8551
1目盛りずつ移動するためのPrev/Nextボタンも置いてみる
https://gyazo.com/1a0acb9f020dbfd723a33780e2799724
目盛りの間隔の調整が難しい
スライダーを操作できるくらいの余裕が欲しい
等間隔にしてしまうと時間感覚が無くなってしまう
どういうことだろう?takker.icon
等間隔ではなく、対数スケールで表示したほうがいいとか?
版の生存期間を表現したいということだと思うyosider.icon
あーなるほど!生存期間は版によって異なりますねtakker.icon
勝手に全部同じだと勘違いしてしまった
版の生存期間を長さで表現するのはよさそうだ
たしかに、スクロールUIってツマミで1点を表現するけど、本来は期間を示す場合は長さに意味が出るはずですよねakix.icon
さらに改良できる?
編集履歴は多くなるだろうからツマミで期間調整するのは難しそう
→ 複雑さが増すので思い切って機能を削る
history一つの差分がそこそこ大きいのも、これができた理由の一つかなtakker.icon
一気にジャンプできるUIでないと操作できる
表示領域が狭いので細かい調整をするのには向いていない
一気に数年前のを見たいときは現状のUIだと無理そうbalar.icon
完成形
https://gyazo.com/716bb113453d6ad07ba59b752c27302c/raw
Prev/Nextだけを操作できるボタンを置くことにした
両者を近くに配置することでどちらの方向にもめくりやすい
https://gyazo.com/fd3227ffcd2417899b8b1a8515e12bb4
スライダー上の点は棘状にすることで摘めない雰囲気を醸し出している
どれだけ間隔が狭くなっても、1pxの棘ならば密集しても重なることなく整列できる
タッチデバイスでの文字選択
Scrapboxのエディタはかなり特殊な実装
これにあわせて文字選択操作も自前で作っている
https://gyazo.com/94cd57ea738ee73e39e4ccc574e5146d
カーソルの縦棒はdiv
表示倍率を縮小したときに消えてしまうことがあったので、いまはSVGのrectになってる
緑の範囲選択もdiv3つ
課題
マウスがない環境ではどうやって操作すればいいだろうか
狭い画面でいかに狙い通り選択してもらうか
縦と横のスクロールで微調整していくのが難しいのだけど、なんとかなるものか?
まずは身近な例を観察
iOS
範囲を拡縮するツマミの位置が、選択領域の始点では上側、終点では下側
https://gyazo.com/9513c9bdf96a42f3b02e02d8780451cb/thumb/500#.png
Android
ツマミはともに下側
https://gyazo.com/afd4cf095481402a31458ca2970b1f63/thumb/500#.png
OSでのつまみの位置の違いに着目したことがなかったので面白いですteyoda7.icontakker.icon
iOSだとそうなるんだ!takker.icon
思いつく限りいろいろ試す
想像やモックに頼らずに実際のコンテンツで動かしてみるのがよい
文字、画像、リンクが多いなど、どんなページでも操作しやすいか?
旅行先での移動中にさくっと書けるか?
画像を選択中に記法表示モードに切り替えないほうがスムーズでいい、とか気付ける
画面が広いPC版では問題なかったが、スマホではガタつきが気になる
PC
https://gyazo.com/4a771575454527dd30dbb417462ad2dc
スマホ
https://gyazo.com/e30326b414bd94e878d730fb1f51a9da
ツマミの設計に苦戦
触れる領域が狭すぎるのが問題
複数行選択されたときの見せ方が難しい問題
いろんな形状を検討したけれどどれも納得がいかなかった
https://gyazo.com/fee1bfb688cbd7e416bd9f07753e1ac0
https://gyazo.com/c7c8dcbbed8391ad4e50ed706150bc6e
https://gyazo.com/5be98378342be52777c9c181ee33aa8a
そもそもツマミは必要か?
小さい画面で小さいツマミを出すと誤タップを誘発しやすい問題
システムUIではなく、HTMLの一要素として表現するしかないので他の要素と衝突しがち
かなしいyosider.icontakker.icon
選択範囲の両端を直接触ってもらえばよい!
https://gyazo.com/d5dfaeca62dd53e89625fa730eaf3166
ツマミの色を分ける必要もないのでは?
https://gyazo.com/a146ce39d3a6b526ac9b7eaf22725e8c
緑色に同化した結果、見事にツマミが無くなった
→ 不要なものを出さないことでシンプルになった
ツマミが飛んで来てくれるのとても使いやすくて助かっています。mgn901.icon
初めて触ったときOSレベルでもそうなってほしいと思いました
ツマミを付けなかったのはツマミでうまくいかなかったからかtakker.icon 正直ツマミのほうがいいんじゃないかと思っていた
必ずしもツマミにこだわらなくてもいいのではないか?
ツマミをなくすとしたら?
というように問いの切り口を変えてみた、という事例でした daiiz.icon 今後「やはりツマミが必要なのでは?」という問いが戻ってくる可能性もありますね
文字選択がかなり難しい
両端をつかむと、指でどこをつかんでいるのかわからなくなる
選択解除と誤認識してしまうことがある
1文字単位の微調整で多いかも
Firefox for Androidだとほとんど動かなかった覚えがある
1年前のことだから、今改善したかはわからない
「微調整が難しい」に立ち向かう
無意識に次の操作を連続して行っている
① 長押しで初期範囲をつくる
② 目的の行までざっくりと縦スクロールする(画面外までスクロールするときもある)
③ 行内の目的の文字まで横スクロールする
② は不要なのではないか?
選択範囲は連続しているのだから、範囲の両端が決まればそれで十分なはず
指で隠れていて正確な位置を把握しづらい問題も解消される
最終的にこうなった
目的の両端付近の文字をちょっとなぞるだけでよい
初期範囲との位置関係から始点 or 終点を特定できる
終点が画面外にあるときは普通にスクロールすればいい
https://gyazo.com/9ef9303f3734f0dac466289c50845d8e/thumb/1000#.gif
→ 不要な操作を求めないことで、無意識のうちにこなされるタスクが減った!
https://scrapbox.io/files/6284a3a003d718001d20140d.mp4 https://scrapbox.io/files/6284a3a519af5a001d287233.mp4
仕上げ
たしかに便利なんだけど、初見でユーザーに理解してもらえるか?
→ よく知られている一般的な操作方法もサポートする
長押しは理解出来なさそうtakker.iconMijinko_SD.icon
このまえ部活で使ったときに、スマホからどう文字を入力したらいいかわからないという話が出た
すぐカーソルがでて入力されるようになってもいいのかも
ですね、長押しで編集開始するのは難しい。改善していきたいですね daiiz.icon
https://scrapbox.io/files/6284a3a94397d0001df00f63.mp4
表作成ツール
https://gyazo.com/a56a25013a7b945a8d103a517a0b42f1 https://gyazo.com/fac67dffa58406c14f33a8e9b0966f77
既存のライブラリを試したが、あと一歩改良したい気持ちがあった
既存ライブラリでいいかんじのやつあんまりないtakker.icon
React Tableとか個人で試したことがありますが挫折しました
完全にイチから設計する、という挑戦
ほぼプロジェクトXakix.icon
つよいteyoda7.icontakker.iconmeganii.icontetsuya-k.icon
Scrapboxでキレイな表を作りたいときがあるので欲しい!!!!meganii.icon
目標
こういう表を簡単に作れるようになる
https://gyazo.com/192f8c6123c133344764f0cd46d3ee46
課題
極限まで直感的に操作したい
特にセルの結合と分割が難しい
+1akix.icon*3
狭いセルでストレスなく編集するには?
マウスや矢印キーでのセルの選択など
こういうメニューは避けたい
「この行を削除」「C列を削除」「3行目を削除」
「この下に1行追加」
「横方向に3マス結合」
あるあるwakix.icon
セルに対する操作ボタンが並んだツールバーもやめたい
どうする?
各セルに操作用のハンドルを付ける
セルの右と下だけにdiv要素を配置する
これから紹介する操作がこれで綺麗に収まる
最初は4辺のすべてに必要だと思い込んでいた
上と下、左と右の当たり判定が厳しくて困る
色々考え込んだ後の休憩中に2辺だけでいけると確信した
https://gyazo.com/de96119efb531bf67080d93748bf79a9 https://gyazo.com/5e6c9aa60c0dd609c83163d12432a359
喫茶店のお手拭き?
ナプキン!! 増井俊之.icon
サルバドール・ダリみたい
こういう即興のメモ見るの好きteyoda7.iconmeganii.iconk.icon
心の余裕も大事
行や列の追加、削除
まずは最も基本的な操作から
https://gyazo.com/56e7fcdfc94e22e56a28e19309d9dcb9
目的のセルの仕切りの位置にカーソルを持っていくだけでいい
その位置でできる操作だけがサジェストされる
必要なときだけ見せる
ボタンを作用点の近くに出すことで「いま何ができるのか」が明瞭になる
すごく高速で機能にアクセスできるMijinko_SD.icon
セルの結合、分割
一番難しく、もっともこだわりたかった部分
対象のセルをチェックボックスで選んだ後にボタン操作する?
https://gyazo.com/113692d2f62c66816d757e9228472ee7
モードの切替も発生する
編集と選択のモードが必要になる
「見た目が悪い」だけでなく、一気に難しいツールになってしまう
ありそうな上にヤバいUIで良いakix.icon
ホラーUIじゃんtakker.icon
目的の仕切りの位置にカーソルを持っていくだけでいい
結合: 仕切りを取り払いたい場所
分割: 仕切りを作りたい場所
https://gyazo.com/9c78c44fb8c686275afd9078ddd9c031 https://gyazo.com/0bd783e6c24c70f033509b033b546e21
ボタン操作によって影響を及ぼす範囲が事前に示されるので戸惑わない
名付けるならpreview UI?takker.icon
どんな順番で結合や解除をしても思い通りの形状を作れる
→ 順不同で同じ結果が得られる
セルを直接触れている感覚が得られてとても良い
Excelを倒せるのでは?!meganii.iconmgn901.icon
なんで今までこうなっていなかったんだろうっていうレベルの自然さを感じてすごい!yutaro.icon
むちゃくちゃ既視感があるtakker.icon
どこかのなにかで見たことあるような……
いずれにせよどうなるかがすぐわかるUIは好きです
すぐに結果が出てくる
リンク入力補完も、次どうなるかがわかってから補完する
Tips: 結合されたセルの形状情報はどうやって持っておくのがいい?
<td colspan="列の結合数" rowspan="行の結合数"></td>に倣うのが結局一番扱いやすかった。HTMLはよくできてる daiiz.icon
結合範囲の左上のセルで両方向の結合量を持っておく
他のセルでも便宜上の値を持っておく
結合されて独立していないセルでは結合量を0にする
結合の座標情報は左上のセルだけが持っていればいい
他のセルは自身が上または左の辺を構成しているかを0/1で持っておく
例: 括弧内の値は (colspan, rowspan)を表す
列のみ結合
https://gyazo.com/c281a9fd280b4ca0876fbc5a96e5883d/thumb/300#.png
行のみ結合
https://gyazo.com/5849ea8ef9c1dc755d3fe9be027ba843/thumb/300#.png
両方向で結合
https://gyazo.com/ac4d21bdb965b911aa826229f2971e00/thumb/300#.png
https://gyazo.com/c8a0fab419befc06f41993566d65ca89/thumb/390#.png
テキスト編集とセルの横幅調整
選択したセルのそばにエディタが現れる
https://gyazo.com/dd8501335fdc4ddb92271eb67a3ff67a
テキストを書いていると横幅を調整したくなる
編集中にセルの仕切りをドラッグできるといい
横方向だけの移動だが手は縦方向にもブレるものなので、画面全体で移動量を補足できるようにしておく
カーソルがエディタ内部に侵入してしまってもキャンセルされないように
大胆に操作できるような配慮をしておく
セルの高さの調整は?
シンプルさを保つため敢えて実装せず、内部のコンテンツの高さに任せることにした
→ 機能を削る
調整中は縦の青い補助線は出ない?
出さないことにした
セル内に画像が含まれている場合など、高さが激しく変化して再計算するのが大変なので諦める
矢印キーでのセルの移動
結合されているセルを跨いだときの挙動に気を遣う必要がある
同じ列や行内で一貫した選択操作ができているかが大事
例: 「Scrapbox」のセルがある3列目での下移動
横方向に結合されたセル(5行目)を通過した直後に、3列目の「Node.js」が選択される
実装時にサボると通過後に2列目 (横方向の結合された一番左のセルの位置) に移動してしまう
https://gyazo.com/1082f132dad283f69a98aeba525b9371
可逆性を保つ
例: 「Helpfeel」のセルから下移動を開始して跳ね返った後に、元の位置に戻ってこれる
https://gyazo.com/9a59d3e2df5733ffdba93613a5f78c06/thumb/1000#.gif
Undo / Redo
Ctrl + Z, Ctrl + Shift + Z で何度でもやり直しができる
一番簡単な実装はスナップショット方式
各操作後のテーブル全体の結果をすべて蓄積しておき、逆順に適用するだけで実現できる
+1akix.icon*3
https://gyazo.com/b5d6f0dd08bc5d9966876f158a48c13f
セル結合(2回)→ Ctrl+Z(2回)→ Ctrl+Shift+Z(2回)
実質Undo
セルの結合・分割の連続操作はよく観察するとUndo的な挙動をしている
= 分割は結合の逆操作とも捉えられる
同じ作用点で結合と分割が連続して行われたときのみ発動する
結合されたテキストの再分割の結果が直感的になる
普通に分割すると
結合されていたセル内のテキストや画像は分割後のどちらのセルに属するべきか?
一番シンプルな解決法はどちらかに寄せてしまうこと
これでも分割操作としては間違いではないが違和感がある
https://gyazo.com/08d583e9b124f8246bc6c6b4e44d9033
Undoの一種として扱って分割すると
結合前に所属していたセルに再分割することが可能になる
直前までの内容が復元されるので気の利いた賢い動きになる
https://gyazo.com/ac160f5cdff5ec4c2d11233773a4f679
富豪的プログラミングの恩恵?mgn901.icon
Tips: 「実質Undo」の実現方法
分割前後のテキスト履歴を各セルで個別に保持することなく、Undoを応用して実現できる
code:操作履歴 Unmerge前
Op Data
-------------------
Init data0
MergeCol data1 <-- 最新
操作履歴から復元先(Init)を適用する
この際にUnmergeとその逆操作の履歴を作って挿入しておくと、さらにUndo/Redoされても辻褄が合う
code:操作履歴 Unmerge後
Op Data
-------------------
UnmergeCol data0
MergeCol data1
Init data0 <-- 最新
おまけ: 生成物の出力形式
このようなSVG画像
code:svg
<svg>
<foreignObject>
<html>
<style>...</style>
<table>...</table>
</html>
</foreignObject>
</svg>
画像を埋め込む場合はbase64エンコードしておくとよい
嬉しさポイント
HTMLのtableタグとして保持しておけるので他のツールでも使いまわしやすい
SVG画像なのでimgタグでも表示できる
Scrapbox上でプレビューできる!
まとめ
感動するUIを作るには
UIパーツや各操作の本質を考える
身近な例も観察する
オリジナルな快適さを探究するものの、一般的な使い勝手と乖離しすぎないよう気をつける
この塩梅が難しいけれど、頑張ってこだわりを届けていこう
+1akix.icon*6
/icons/応援.icontakker.iconmeganii.iconmgn901.iconyutaro.iconmeganii.icon
触りながら調整を繰り返していくしかない
複雑さを回避するために実装しないという決断を下す勇気を持つ
すごいなー 増井俊之.icon
論文になるレベル... 増井俊之.icon
Scrapbox上でどう展開するんだろう
期待meganii.icon
Scrapboxにもこの表ほしいyosider.icon
ぱっと思いつくとこだとコードブロックにデータ展開?takker.icon
快適さを追求するにはもっと練らないとだけど