jackmiwamiwa devblog

フロントエンドをメインに行ったことをまとめていくサイトになります。

SPのtouchmoveで自由に移動できる要素を配置する

SPのtouchアクションに合わせて自由に要素を動かすことができるスニペットを作成したので、作成したときのメモ。

制作物

制作手順

ボタンの要素を作成

<button type='button' class='buttonIcon jsButton'></button>
.buttonIcon {
  position: fixed;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 60px;
  height: 60px;
  border: none;
  border-radius: 50%;
  background: #ddd;
  &::before {
    content: '';
    display: block;
    background: linear-gradient (/* 横線の背景色記載 */); // 背景色についてはcodepen参照
  }
}

ここまでで以下のようになっていると思います。

f:id:jackswim3411:20200429142317p:plain

ボタンが移動するように変更

.buttonIcon {
  // ボタンの移動に関してアニメーションを実装したいため「.1s」を追加
  transition: transform .1s;
  // ウィンドウのサイズ - 空けたい余白のサイズ - ボタンのサイズ
  transform: translate(calc(100vw - 20px - 60px), 20px);
}
const button = document.querySelector('.jsButton') // button要素の取得

const onTouchMove = e => {
  const touchObject = e.changedTouches[0] // タッチ情報のオブジェクト
  const width = button.offsetWidth // ボタンの横幅
  const height = button.offsetHeight // ボタンの縦幅
  let x, y //x, yの位置を取得するための変数
  if(touchObject.clientX < width / 2) { // 左端まできたら
    x = width / 2 // xの位置を左端に固定させる
  } else if(touchObject.clientX > window.innerWidth - width / 2) { // 右端まできたら
    x = window.innerWidth - width / 2 // xの位置を右端に固定させる
  } else { // その他
    x = touchObject.clientX // xの値をタッチの座標の位置にする
  }
  if(touchObject.clientY < height / 2) { // 上まできたら
    y = height / 2 // yの位置を上に固定させる
  } else if(touchObject.clientY > window.innerHeight - height / 2) { // 下まできたら
    y = window.innerHeight - height / 2 // yの位置を下に固定させる
  } else { // その他
    y = touchObject.clientY // yの値をタッチの座標の位置にする
  }
  button.style.transform = `translate(${x - width / 2}px, ${y - height / 2}px)` // ボタンの位置のcssを修正
}

button.addEventListener("touchmove", e => {
  e.preventDefault() // 要素のデフォルト挙動敵視
  onTouchMove(e) // 要素移動アニメーションを実行
}, false)

jsイベント参考

developer.mozilla.org

developer.mozilla.org

developer.mozilla.org

www.w3schools.com

その他タッチイベント

developer.mozilla.org

補足

クリックイベントを別途付けたい場合、以下のような感じでつけることもできる。

button.addEventListener("click", () => {
  // 何かの処理
}, false)