LoginSignup
2
2

More than 1 year has passed since last update.

ありそうでないWeb部品: リング状プログレスUIとその応用例としてのポインター長押し判定えぐざんぷる

Posted at

リング状プログレスUI

⇩これ
Animation.gif

今回は⇧これを Web Component で作って、その応用例としてのポインター長押し判定も雑に書いてみたところ、とりあえず期待通りに動作するものはできたのでそのメモ。

CodePen

See the Pen progress-ring web-component usagi ver. by Usagi Ito (@usagi-network) on CodePen.

作り方

ProgressRing (=<progress-ring>)

  1. class ProgressRing extends HTMLElement で Web Component のクラスを定義
  2. うまいこと innerHTML<svg> でそれっぽいUIを作る
  3. そのままだと createElementsetAttribute に対応できないので、HTMLで静的にタグを定義するほかに ES で動的に作って弄れるように
  4. static get observedAttributes()
  5. attributeChangedCallback(name, _old_value, new_value) を定義
  6. <svg><circle>r 属性は read-only なのでこれの更新が必用になる場合(strokeradiusが変更された場合)はルート要素内部の innerHTML をごっそり this.regenerate() しちゃう仕組みに調整
  7. opacity transform transition で簡単な演出を仕込む

ProgressRing を応用した「ポインター長押し判定」

  1. pointerdown(e) & begin_ring({...}) で判定時間や完了時/キャンセル時のファンクターなどパラメーターを受け取りつつ、
  2. let pr = <progress-ring> を生成
  3. let begin = new Date().getTime() で開始時刻を保持
  4. requestAnimationFrameprbegin からの経過時間と判定時間から完了までの進捗を setProgress
  5. キャンセル処理用に prlet cancelation = false ステートをキャプチャーした .cancel() を追加して return、呼び出し元側で .cancel() をトリガー可能に
    1. 同様に begin_ring 側で移動距離によるキャンセル判定用に初期の x ypr.initial_position に追加で保持させています
  6. pointerup(e) で、
  7. .cancel()
  8. pointermove(e)
  9. pr.initial_position e.x, e.y から移動距離が一定以上か判定して
  10. .cancel()

おまけ

できた表示を見ていたらアニメの演出とかでありがちな「たくさんロックオン!」みたいな絵もこれで再現できちゃいそうなので遊んでみました。中ボタン押しで⇩こうなります。

Animation.gif

参考

2
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2