$30 off During Our Annual Pro Sale. View Details »

スワイプで閉じれる画像ビューアを作る

 スワイプで閉じれる画像ビューアを作る

動画

P3 スワイプで閉じれる画像ビューアを作りました:
上下にスワイプで画面を閉じる/ピンチ・ダブルタップで拡大・縮小できる様子
https://drive.google.com/file/d/1bYcB8Pq-xXB5TV-MghxzPMMdXqfcHLaZ/view

P6 GestureDetector + InteractionViewer:
ピンチイン・ピンチアウト・ダブルタップができる様子
https://drive.google.com/file/d/1pfmXk91LpyszvBsmZayWyb_SpzuUU5Ki/view

P8 Listener + SlideTransition:
ドラッグすると画像の位置と背景の透明度が変わっている様子
https://drive.google.com/file/d/1t6pLwjIzEYw7bGMagZQpCQNhSNSpMSj4/view

kumamotone

July 24, 2023
Tweet

More Decks by kumamotone

Other Decks in Technology

Transcript

  1. スワイプで閉じれる
    画像ビューアを作る
    2023/07/24 YOUTRUST x ゆめみ Flutter LT会 #2
    @kumamo_tone

    View Slide

  2. @kumamo_tone
    株式会社YOUTRUSTでFlutterアプリ開発をやっています
    @kumamo_tone
    @kumamo_tone

    View Slide

  3. スワイプで閉じれる画像ビューアを作りました
    画像ビューアの改善
    ● 上下にスワイプで画面を閉じる
    ○ ドラッグ量に応じて画像の位置が移動
    ○ ドラッグ量に応じて透明度が変化
    ● ピンチ・ダブルタップで拡大・縮小
    ○ スクロールで表示位置を調整できる
    YOUTRUST App v2.5.3〜

    View Slide

  4. 画面構成
    GestureDetector ダブルタップ(ズーム)のキャッチ
    InteractiveViewer
    Listener
    拡大したときにスクロール可能にするための標準
    Widget
    ドラッグ量を取得
    DecoratedBoxTransition
    (content)
    ドラッグ量に応じて透明度を変更
    ドラッグ量に応じて位置を変更
    SlideTransition

    View Slide

  5. 画面構成
    GestureDetector ダブルタップ(ズーム)のキャッチ
    InteractiveViewer
    Listener
    拡大したときにスクロール可能にするための標準
    Widget
    ドラッグ量を取得
    DecoratedBoxTransition
    (content)
    ドラッグ量に応じて透明度を変更
    ドラッグ量に応じて位置を変更
    SlideTransition

    View Slide

  6. GestureDetector + InteractionViewer
    ● InteractionViewer: childのpanとzoomを可能にするWidget [*1]
    ○ いわゆるピンチイン・ピンチアウト
    ○ 標準でダブルタップでズームする機能はない
    ダブルタップの機能の追加 [*2]
    1. transformationController を InteractionViewer の引数に渡す
    2. GestureDetector の onDoubleTapDown: で、
    ダブルタップ位置 details.localPosition を保存
    3. GestureDetector の onDoubleTap: で、
    保存した位置を使って transformationController の値を変更
    [*1] https://api.flutter.dev/flutter/widgets/InteractiveViewer-class.html
    [*2] https://stackoverflow.com/questions/65408346/flutter-enable-image-zoom-in-out-on-double-tap-using-interactiveviewer

    View Slide

  7. 画面構成
    GestureDetector ダブルタップ(ズーム)のキャッチ
    InteractiveViewer
    Listener
    拡大したときにスクロール可能にするための標準
    Widget
    ドラッグ量を取得
    DecoratedBoxTransition
    (content)
    ドラッグ量に応じて透明度を変更
    ドラッグ量に応じて位置を変更
    SlideTransition

    View Slide

  8. Listener + SlideTransition
    ● onPointer[Down|Up|Cancel|Move] メソッド
    ○ ドラッグ量を変数に保存
    ○ SlideTransition/DecoratedBoxTransitionでドラッグ量
    に応じて位置/透明度を変更
    ○ GestureDetector の onVerticalDragUpdate だと、
    拡大中でも閉じれてしまう問題を解決できなかった
    ○ 指を離したタイミングで、
    ■ しきい値以内ならドラッグ量を0に戻して
    animationController.reverse() する
    ■ しきい値以上なら画面を閉じる

    View Slide

  9. そのほか
    自然っぽい感じになるようにチューニングしたり、細かいアニメーションが入ったりしています
    ● 画面遷移のトランジション
    ○ 開くときに PageRoute の buildTransitions でふわっと開く
    ○ Heroウィジェットで位置を補間する
    ● インタラクション中は閉じるボタンが引っ込む
    ○ SlideTransition/FadeTransition の組み合わせでふわっと引っ込む
    ● スワイプ中に新しい指が追加されたり、
    3本以上指が触れている場合はキャンセルする

    View Slide

  10. まとめ
    ● スワイプで閉じれる画像Viewerを作った
    ○ パン・ズームのために GestureDetector + InteractiveViewer を使う
    ○ Listener で取得したドラッグ量を使って位置や透明度を変更することで、少しず
    つ前の画面に戻っている感を出す
    ■ 指を離した時点でしきい値を越えていたら、画面を閉じる

    View Slide