tag:crieit.net,2005:https://crieit.net/tags/UI/feed 「UI」の記事 - Crieit Crieitでタグ「UI」に投稿された最近の記事 2022-01-11T17:18:59+09:00 https://crieit.net/tags/UI/feed tag:crieit.net,2005:PublicArticle/17924 2022-01-07T16:19:06+09:00 2022-01-11T17:18:59+09:00 https://crieit.net/posts/Flutter-61d7e96a4daa2 Flutterベースのモバイル向けタイムラインの作成 <h1><a target="_blank" rel="nofollow noopener" href="https://quire.io">Quire</a>タイムライン(モバイル向け)の構造を初公開</h1> <p>2018年に初めてFlutterベースのアプリを作ったときは、とても楽しく興奮しました。それから3年経ち、<a target="_blank" rel="nofollow noopener" href="https://quire.io">Quireアプリ</a>もかなり充実して、従来のモバイル向けプロジェクト管理アプリの域を超えるまでになりました。Quireモバイルアプリの現行バージョンは、階層表示、ボード表示だけでなく、タイムライン表示にも対応しています。</p> <p>モバイルアプリ向けのタイムライン表示の作成を決めたときは、簡単にできるとは思いませんでした。当時は類似の既成コンポーネントもなかったためですが、驚いたのは、インターネットでタイムライン表示の構造についての情報も見当たらなかったことです。そこで、いちかばちか、自分たちで作ってみることにしました。</p> <h5><a target="_blank" rel="nofollow noopener" href="https://quire.io">Quire</a>モバイルアプリ用のタイムラインでは、以下を計画していました。</h5> <ol> <li>横方向への無限日付スクロール</li> <li>レンダリングオンデマンド(ROD)。ビューポートにあるときのみ実行されるWidgetのState</li> <li>任意の位置に素早く配置</li> <li>操作がかんたんで使いやすいインターフェースと、スムーズなユーザーエクスペリエンス</li> </ol> <p>数週間で初期開発が完了し、以下のような構造になりました。</p> <p><img src="https://storage.googleapis.com/zenn-user-upload/52c3e5779da7-20220105.png" alt="" /></p> <ol> <li>タイムラインペインのコアベース(週、週末のセクションなど)</li> <li>タスクリスト(階層構造のタスクリスト)</li> <li>タイムラインペインのビューポートベース双方向リスト</li> <li>1ペインのみのとき、2ペインにまたがるときの両方に対応した期間の横棒</li> <li>期間の横棒上の固定ラベル</li> </ol> <p>上図のように、タスクごとにタイムラインペインが割り当てられ、すべてのタイムラインのスクロール位置は互いに同期されます。</p> <h2 id="インデックスベースのスクロールビュー"><a href="#%E3%82%A4%E3%83%B3%E3%83%87%E3%83%83%E3%82%AF%E3%82%B9%E3%83%99%E3%83%BC%E3%82%B9%E3%81%AE%E3%82%B9%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%AB%E3%83%93%E3%83%A5%E3%83%BC">インデックスベースのスクロールビュー</a></h2> <p>Google Flutter Widgetに似たインデックスベースのスクロールビューを作るために、Centerに引数のあるカスタムスクロールビューを使用します。実装すると、任意の位置まで素早くスクロールできるようになります。スクロール中のどの時点でも、各位置とインデックスを表示できます。</p> <p>イメージ的には、少しスクロールした時点で、新しいCenterの引数でタイムラインをリロードしてビューポートの外に移し、またスクロールするとビューポート内に配置される、という感じです。</p> <h2 id="タイムラインペイン"><a href="#%E3%82%BF%E3%82%A4%E3%83%A0%E3%83%A9%E3%82%A4%E3%83%B3%E3%83%9A%E3%82%A4%E3%83%B3">タイムラインペイン</a></h2> <p>タイムラインをスムーズに使えるように、インデックスベースのスクロール表示と似た発想で、横方向にスクロールできるカスタム「無限双方向スクロールビュー」を実現しました。実装すると、タイムラインをなめらかにスクロールできます。</p> <p>無限双方向スクロールビューには、Flutterの強力なViewportの考え方を活用しました。そして、Backwardリストのインデックスを-1から始まる負の数に変更しました。Index 0に当たる日付が分かるようにフラグも設定して、任意の日付まで素早くスクロールできるようにしました。</p> <pre><code class="js">Widget forwardList = SliverList( delegate: SliverChildBuilderDelegate((BuildContext context, int index) { return cellBuilder(context, _getIndex(forward: true, index: index)); }) ); Widget backwardList = SliverList( delegate: SliverChildBuilderDelegate((BuildContext context, int index) { return cellBuilder(context, _getIndex(forward: false, index: index)); }), ); Scrollable( viewportBuilder: (BuildContext context, ViewportOffset offset) { return Viewport( offset: offset, center: forwardListKey, slivers: [ backwardList, forwardList, ] ); }, ) </code></pre> <h2 id="2ペインにまたがるときの問題と解決方法"><a href="#2%E3%83%9A%E3%82%A4%E3%83%B3%E3%81%AB%E3%81%BE%E3%81%9F%E3%81%8C%E3%82%8B%E3%81%A8%E3%81%8D%E3%81%AE%E5%95%8F%E9%A1%8C%E3%81%A8%E8%A7%A3%E6%B1%BA%E6%96%B9%E6%B3%95">2ペインにまたがるときの問題と解決方法</a></h2> <p>ビューポートには無限のリスト2つがスクロールされるため、期間の横棒が2つのリストにまたがることもあります。そこで、どちらのリストにも完全に同じ期間の横棒を作成し、ぴったり重ねて、リストがビューポートの外に移動してもリスト内のアンカーが壊れないようにしました。</p> <p><img src="https://storage.googleapis.com/zenn-user-upload/a56ed0583195-20220105.gif" alt="" /></p> <h2 id="固定ラベルで解決"><a href="#%E5%9B%BA%E5%AE%9A%E3%83%A9%E3%83%99%E3%83%AB%E3%81%A7%E8%A7%A3%E6%B1%BA">固定ラベルで解決</a></h2> <p>モバイル機器の小さい画面ではプロジェクトのどこを見ているかが分かりにくく、使っていると混乱してきます。この問題は、できるだけ多くの情報を提供することで軽減できます。そこで便利なのが固定ラベルです。</p> <p>最初はとにかくシンプルにするため、スクロールビューのスクロール通知に従って、位置を取得してから配置されたラベルに設定していました。固定ラベルを各タイムラインペインの開始位置に表示するには、期間の横棒の現在位置の計算がベースとなります。</p> <p>しかし、新しく配置されたラベルは次のフレームまでしか更新されず、スクロールビューと同じ時間枠で同期されないため、ずれて見えてしまいました。</p> <p>幸いFlutterコミュニティーが、レンダリングレイヤー固定ヘッダーというすばらしい解決方法を教えてくれました。つまりレイアウトのタイミングによる方法です。レンダリングレイヤーにすべてのWidgetをサイズとともに入れるだけでなく、そのピクセルすべてを計算する必要があります。最後にlocalToGlobal関数を、スクロール位置、および2ペインにまたがるときのペイン切り替えに基づいた演算操作と置き換えて、パフォーマンスを向上させました。</p> <h2 id="始まりはこれから"><a href="#%E5%A7%8B%E3%81%BE%E3%82%8A%E3%81%AF%E3%81%93%E3%82%8C%E3%81%8B%E3%82%89">始まりはこれから</a></h2> <p>今は大変な時代ですが、だからこそテクノロジーの分野で貢献したいと考えています。タイムライン表示の作成でまず考えたのは、どうやってFlutterの強力なフレームワークを活用して、ビューコンポーネントを一から作り直すことなく、軽く安定したゴージャスなUIを実現するか、ということでした。</p> <p>各日付単位はインデックスとして、FlutterのSliverに組み込まれています。ほとんどのものはWidgetレイヤーの高レベルの開発概念に留まり、固定ビューのときのみレンダリングレベルに移動します。</p> <p><a target="_blank" rel="nofollow noopener" href="https://quire.io">Quireアプリ</a>をインストールして、Flutterベースのモバイルアプリを使ってみませんか。Quireタイムラインについて気になることは、コメントを投稿するか、<a target="_blank" rel="nofollow noopener" href="https://twitter.com/quire_io">@quire_io</a>でツイートしてお知らせください!</p> <p>※転載許可済み: https://zenn.dev/quireteam/articles/2b2c44c3e49fac</p> uniyeh tag:crieit.net,2005:PublicArticle/14726 2019-01-18T09:29:07+09:00 2019-01-18T12:23:31+09:00 https://crieit.net/posts/UI-HTML UIを整えるためにHTMLをデバッグするする方法 <p>HTMLを書いてブラウザで確認している時にどうしても上手く思った通りにならない場合があったりします。配置がうまくいかなかったり、marginやpaddingが思い通りにならなかったりなど。その時の確認方法などをまとめてみました。</p> <p>昔はtableやfloat等が主なレイアウト方法だったのでシンプルでわかりやすかったのですが、CSS3も一般的になり色々と便利になる一方、惑わされる要素も増えてきたような気がします。</p> <p>※ <a href="https://crieit.net/boards/post-request/2e7d073b46d856eccb4e591fa599cb88">記事投稿リクエストボード</a> に投稿していただいた件に対する記事となります。</p> <h2 id="基本的な確認方法"><a href="#%E5%9F%BA%E6%9C%AC%E7%9A%84%E3%81%AA%E7%A2%BA%E8%AA%8D%E6%96%B9%E6%B3%95">基本的な確認方法</a></h2> <p>具体的な話の前にひとまず念の為基本的な確認方法を書いておきます。ご存知の方も多いと思うので適宜読み飛ばしてください。Chromeでの話です。</p> <p>調べたい要素の上で右クリックをするとこのようなメニューが出てきますので、「検証」を選択します。これでその要素が選択された状態でChrome DevToolsが開きます。もしくはF12キーを押して直接Developer Toolsを開いても構いません。</p> <p><a href="https://crieit.now.sh/upload_images/f445e18b21a560b6a255b19346aa348d5c3fca15d4d75.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/f445e18b21a560b6a255b19346aa348d5c3fca15d4d75.png?mw=700" alt="rightmenu.png" /></a></p> <p>するとこのような画面が開きます。</p> <p><a href="https://crieit.now.sh/upload_images/08b1043105d7bcfeebbf2a55d16812c85c3fcb664c73c.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/08b1043105d7bcfeebbf2a55d16812c85c3fcb664c73c.png?mw=700" alt="devtool.png" /></a></p> <p>右上はElementsタブを開いている状態です。右クリックしたあたりが表示されています。マウスカーソルを合わせると、左の画面のようにその箇所がハイライトされます。</p> <p>また、Elementsの要素をクリックすると、その下にCSSの一覧(左)、最終的なサイズやCSSの情報(右)が表示されています。これはDevToolsをウィンドウの右側にドッキングしている状態ですので、実際にどのような使い方をしているかによってこのあたりは変わってきます。適宜使いやすい方法にしてください。</p> <p>謎の挙動がなければ、だいたいはこれでほとんど問題があれば原因は分かると思います。</p> <p>また、CSSの一覧の一番上に<code>element.style</code>という空のスタイルがあると思います。これはその場で自由にスタイルを指定できますので、「このスタイルのせいで動きがおかしくなっているんじゃないか」みたいなものに気づいたらとりあえずここでそれを上書きして試すことで、それが原因か、そうでなく他に原因があるか、というのをすぐ確認することができます。</p> <h2 id="謎の挙動"><a href="#%E8%AC%8E%E3%81%AE%E6%8C%99%E5%8B%95">謎の挙動</a></h2> <p>とはいえ謎の挙動も増えている感じがするので、思いつく限り書いてみます。</p> <h3 id="要素のサイズが思ったとおりにならない"><a href="#%E8%A6%81%E7%B4%A0%E3%81%AE%E3%82%B5%E3%82%A4%E3%82%BA%E3%81%8C%E6%80%9D%E3%81%A3%E3%81%9F%E3%81%A8%E3%81%8A%E3%82%8A%E3%81%AB%E3%81%AA%E3%82%89%E3%81%AA%E3%81%84">要素のサイズが思ったとおりにならない</a></h3> <p>横幅を指定したのに思ったとおりのサイズにならなかったりすると思います。これはわりとCSSのdisplayの設定であることが多いので、displayに指定した値によってどう変わるのかは一通りある程度把握しておいたほうが良いと思います。</p> <h4 id="inline"><a href="#inline">inline</a></h4> <p>これはspanタグやaタグのように、文章中にそのまま含めるようなタグのデフォルトのdisplayとして使われています。下記のような特徴があります。</p> <ul> <li>要素のサイズを指定しても無視される</li> <li>marginやpaddingも指定しても無視される</li> </ul> <p>しかしこれらを変えたい、という場合もあると思います。その場合は下記を使います。</p> <h4 id="inline-block"><a href="#inline-block">inline-block</a></h4> <p>これを指定すると、inline要素として文章中に並べながら要素のサイズやmargin, paddingのようなスペースを設定することができます。</p> <h4 id="block"><a href="#block">block</a></h4> <p>これは文章中などには含まず、ページ上のレイアウトを構成するための基本的な枠になります。何も指定しなければ基本的には横幅100%の要素となります。これも要素のサイズやpadding, marginは自由に設定することができます。</p> <h4 id="その他"><a href="#%E3%81%9D%E3%81%AE%E4%BB%96">その他</a></h4> <p>とりあえず基本的には上記のdisplayがベースになっています。ただ、最近は色々増えていたりするので後述します。その他、このあたりはどんどん増えていっているのでだんだんと新しいものを覚えていく必要があります。しっかり覚える必要はないと思いますが、何かあった時の問題解決のために「そういえばこういうのもあったな」くらいのフォローはしていったほうが良さそうです。</p> <h3 id="heightが0になる"><a href="#height%E3%81%8C0%E3%81%AB%E3%81%AA%E3%82%8B">heightが0になる</a></h3> <p>要素内にfloatスタイルの要素のみがある場合、親要素のサイズは連動しないためheightが0になります。</p> <p><a href="https://crieit.now.sh/upload_images/ccc543ce9d27c586c2b2b08f8dc757175c411798ada33.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/ccc543ce9d27c586c2b2b08f8dc757175c411798ada33.png?mw=700" alt="" /></a></p> <p>問題がある場合はclearfixを入れたり、あとはoverflowスタイルを入れることでも対処できるようです。もしくはflexbox等に変更するなどで対応しましょう。</p> <h3 id="位置調整をしても無視される"><a href="#%E4%BD%8D%E7%BD%AE%E8%AA%BF%E6%95%B4%E3%82%92%E3%81%97%E3%81%A6%E3%82%82%E7%84%A1%E8%A6%96%E3%81%95%E3%82%8C%E3%82%8B">位置調整をしても無視される</a></h3> <p>左に1つ目の要素を起き、そのすぐ右隣に2つ目の要素を起きたいのになぜか2つ目の要素が想定した位置に行かない、という場合。</p> <p>全て自分で作っているCSSなどの場合には気づかないといったことは少ないかもしれませんが、よく使われているCSSフレームワーク等ですと最近はFlexboxがよく使われているため、それによって位置が決まってしまったりします。下記のまとめ等を見るとわかりやすいと思います。</p> <p><a target="_blank" rel="nofollow noopener" href="https://coliss.com/articles/build-websites/operation/css/css3-flexbox-properties-by-scotch.html">CSS Flexbox の各プロパティの使い方を詳しく解説 | コリス</a></p> <h3 id="横幅を指定しても無視される"><a href="#%E6%A8%AA%E5%B9%85%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%A6%E3%82%82%E7%84%A1%E8%A6%96%E3%81%95%E3%82%8C%E3%82%8B">横幅を指定しても無視される</a></h3> <p>前述のFlexboxのページにも解説がありますが、<code>flex-grow</code>を指定すると要素のサイズも固定されてしまいます。</p> <p><a href="https://crieit.now.sh/upload_images/6104d656841f5bdd41de12c15ecba1d85c411b1a28eaf.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/6104d656841f5bdd41de12c15ecba1d85c411b1a28eaf.png?mw=700" alt="flexglow.png" /></a></p> <p>この場合むりやり横幅を指定したりしても正常には動作しません。</p> <h3 id="beforeやafter"><a href="#before%E3%82%84after">beforeやafter</a></h3> <p>現在はbeforeやafterを使うこともできるため、実際の要素でなくそのあたりの設定でズレが生じてしまうこともあります。これもDeveloper Toolsで見ることができるため、確認するようにしてみてください。</p> <p><a href="https://crieit.now.sh/upload_images/c63ae1144a6799ccaf1bea54929e49f75c411ce8d0fbb.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/c63ae1144a6799ccaf1bea54929e49f75c411ce8d0fbb.png?mw=700" alt="after.png" /></a></p> <h3 id="iframeが使われている"><a href="#iframe%E3%81%8C%E4%BD%BF%E3%82%8F%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B">iframeが使われている</a></h3> <p>iframeがあっても一応要素のサイズを見ることはできるのですが、どうも状態によっては正しくDeveloper Toolsでもちゃんとサイズが見れなかったりする場合があるような気がします。この場合はiframe内の謎挙動を無視できるようにCSSを整えていくしかないかもしれません。</p> <h2 id="動きのあるコンテンツを調べたい場合"><a href="#%E5%8B%95%E3%81%8D%E3%81%AE%E3%81%82%E3%82%8B%E3%82%B3%E3%83%B3%E3%83%86%E3%83%B3%E3%83%84%E3%82%92%E8%AA%BF%E3%81%B9%E3%81%9F%E3%81%84%E5%A0%B4%E5%90%88">動きのあるコンテンツを調べたい場合</a></h2> <p>一瞬だけ出てくるアニメーション等を調べたい場合、F8で一時停止することができます。これで時を止めて要素を調べることで解決できます。</p> <h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2> <p>今のところこれくらいしか思いつかなかったので、もし何か思いついたら追記します。他にも追記すべき情報があればコメントいただければ追記させていただきます。(もしくは詳しい方が記事を書いていただけると助かります)</p> <p>昔は本当にDeveloper Toolsでひたすら調べればなんとかなったのですが、FlexboxやGrid等、新しい機能が追加される度に、デバッグするためにはだんだんと頑張るだけではなく、知識も必要になってきています。可能な範囲でHTML、CSSの新しい情報は追っていくといざデバッグする時に役に立つと思われます。</p> だら@Crieit開発者 tag:crieit.net,2005:PublicArticle/14668 2018-12-17T09:02:19+09:00 2018-12-24T23:03:03+09:00 https://crieit.net/posts/polca polcaで支援した代わりにデザインのアドバイスをしてもらった話 <p>先日いつもどおりTwitterのTLを見ていると、polcaでmacを買いたいので支援をしてほしい、という企画が立っているのを見つけました。普段はあまり興味は無いので見ないのですが、その時はたまたまリンクをクリックして詳細を見てみました。それが下記です。</p> <p><a target="_blank" rel="nofollow noopener" href="https://polca.jp/projects/6i8Waf68fh9">https://polca.jp/projects/6i8Waf68fh9</a></p> <h2 id="なぜ支援したか"><a href="#%E3%81%AA%E3%81%9C%E6%94%AF%E6%8F%B4%E3%81%97%E3%81%9F%E3%81%8B">なぜ支援したか</a></h2> <p>僕はあまりこういう個人が何か買いたいから、というクラウドファインディング系は興味が無いのですが、この企画は見てすぐ「あ、支援しようかな」と思いました。理由は下記のような感じです。</p> <blockquote> <p>未経験からプログラマになるまでずっと一緒にお勉強してきたPCがついに壊れました。</p> </blockquote> <p>なんか僕は仕事柄PCが壊れるのに非常に恐怖感を持っているので、この時点で共感してしまいました。辛いなー、と…(一応常時家に開発できるPCが2つあるようにしていますが)。しかも利用用途が僕と同じくプログラミングだったということですし。</p> <blockquote> <p>プログラミングの他に、デザインの勉強にも力を入れたいので馬力のあるPCが必要です。スキル高めて激安給料のブラック会社からも脱出したい。</p> </blockquote> <p>なにかこうよく分からないけどPCがほしいという感じではなく、しっかり未来のことをちゃんと考えて先に進みたいんだな、という気持ちが伝わってきました。</p> <blockquote> <p>デザイン一点その他ご希望あれば伺います</p> </blockquote> <p>なんかよく「お礼に手紙書きます」とかなんの意味があるかよく分からないお礼が書かれていたりします。そういうのは全く興味が持てないのですが、今回はちゃんと普通に納品物があり完全にお互いWin-Winの関係になれるお礼でした。</p> <p>このあたりを見て、ほとんど迷うこともなくすぐ支援をしました。</p> <h2 id="支援の内容"><a href="#%E6%94%AF%E6%8F%B4%E3%81%AE%E5%86%85%E5%AE%B9">支援の内容</a></h2> <p>具体的には、デザインも勉強されている方ということだったのですが、僕がデザインがまったく良くわからないので、そのあたりちょっと見てもらえたらありがたいな、と感じました。</p> <p>そのため、支援額は千円で、その金額の範囲内でよいのでこのCrieitをざっと見てもらって、気になる所があれば教えてほしい、という形にしました。金額もたいしたことがないので、余裕がある時にいつでも大丈夫です、という形にしました。</p> <p>しばらくして返答があり、6件ほど気になるところと改善したところが良さそうな箇所のアドバイスをいただきました。しかもAdobe XDで簡単なイメージも作ってシェアまでしていただけました。例えば下記のようなアドバイスをいただきました。</p> <ul> <li>トップページのヘッダーが長すぎるのでは → たしかに長すぎます…。その他そのあたりのパーツの調整案も頂きました。</li> <li>Primaryカラー1色しか使っていないのでブルーに合うSecondaryカラーをワンポイントなどで使うようにしてみては? → 全く考えてなかったので助かりました。今のデフォルトのSecondaryがグレーなのであまり使ってなかったんですよね…。ちゃんと黄色のclassを作ってやってみます。</li> <li>新規登録/ログインが乱立している → たしかに見直したら乱立していました。誘導したい場面ではきっちりわかりやすく表示する、というのは何かで見かけて参考にしていたのですが、なにか勘違いして無駄に大量に配置してしまっていたようです。気づかせてもらえたので良かったです。</li> <li>余白やフォントを調整したほうが良いのでは</li> </ul> <p>なんにしろ、どれも早く修正したいなーと思うくらいには個人的にはありがたい情報でした。</p> <h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2> <p>とりあえず僕はケチ&心が狭い人間なので、あまり支援には興味がありません。でも、今回はすぐ支援しましたし、そういえば以前もコーヒーの購入はほとんど迷わず支援(というか購入)しました。</p> <p><a href="https://crieit.net/posts/CODE-COFFEE">CODE COFFEEをいくつか飲んでみた</a></p> <p>本気で支援が必要な方は、なぜ支援した方がいいのか分かりづらい企画をたてるより、こんな感じで普通にお互いにWin-Winとなるような、あたかも単なる商品の購入のような企画を立てた方が成立しやすいと思いますしみんなが幸せになれる気がします。そしてその人に対して好感が持てて応援したくなると思います。</p> <p>今回の企画をたてていたのは <a target="_blank" rel="nofollow noopener" href="https://twitter.com/qsb3uy">@qsb3uy</a> さんでした。プログラムとデザインが両方できるというのは素晴らしいことなので、きっとその知識が廻り廻ってより多くの人の役に立つことになるのだろうと思います。</p> だら@Crieit開発者