上下左右

Web


Warning: Attempt to read property "site_name" on bool in /home/goodhokkaido/sixwheel.net/public_html/muguruma/wp/wp-content/themes/frame/functions.php on line 208

Warning: Attempt to read property "title" on bool in /home/goodhokkaido/sixwheel.net/public_html/muguruma/wp/wp-content/themes/frame/functions.php on line 211

Warning: Attempt to read property "description" on bool in /home/goodhokkaido/sixwheel.net/public_html/muguruma/wp/wp-content/themes/frame/functions.php on line 217

Warning: Attempt to read property "site_name" on bool in /home/goodhokkaido/sixwheel.net/public_html/muguruma/wp/wp-content/themes/frame/functions.php on line 208

Warning: Attempt to read property "title" on bool in /home/goodhokkaido/sixwheel.net/public_html/muguruma/wp/wp-content/themes/frame/functions.php on line 211

Warning: Attempt to read property "description" on bool in /home/goodhokkaido/sixwheel.net/public_html/muguruma/wp/wp-content/themes/frame/functions.php on line 217

カーソルの入出方向で、ホバーアニメーションの方向を変える

縦スクと同様に、米国科学アカデミー紀要のウェブサイトを偶然見ていて、画像にホバーした動きが面白く、それを取り入れられないか調べたので、メモ。ちなみにホーバー系なので、PCのみで、スマホは動きません

ホバーアニメーションの入出方向

さっそく検索するとそのものズバリなウェブサイトを発見。おおよそ下記サイトを普通のJSに変換しながら作業しました。たまに凡ミスをしながらもなんとか同様の動きを得ることに成功。ありがとう!

マウスの進入方向によってオーバーレイ要素を追随させる
モバイルファーストだと余りやりませんが、マウスの進入方向でマウスオーバーの要素を差し込む方法。

HTMLとCSSは主要部分のみ抜粋。以下です。HTML内は適当なdivとそれを覆うtagを配置しました。cssもdivにposition: relativeし、中のタグにposition: absoluteしています。

<body>
  <div class="element__box--div">
    <a href="#" target="_blank" class="overlay">ppp</a>
  </div>
  <div class="element__box--div">
    <a href="#" target="_blank" class="overlay">ppp</a>
  </div>
  <div class="element__box--div">
    <a href="#" target="_blank" class="overlay">ppp</a>
  </div>
</bidy<
  body {
    margin: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 100vh;
  }
  .element__box--div {
    position: relative;
    overflow: hidden;
    width: 200px;
    height: 300px;
    margin-right: 1em;
    background: #666;
  }
  .overlay {
    position: absolute;
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 10;
    top: 0;
    left: -100%;
    width: 100%;
    height: 100%;
    background: #c00;
  }

JS部分は以下です。ほぼほぼ参考サイトのままです。上記HTMLに合わせた部分を変更。あと、偶にhiddenされている部分で、アニメーションすることがありました。それを修正するために、overlay.style.transform = “translate(0, 0)”で位置を直しています。アニメーション部分はanime.jsを使っているので、適宜置き換えるのが良いでしょう。

    const targetBox = document.querySelectorAll('.element__box--div')

    const setMouseOver = (e) => {
        const overlay = e.target.querySelector('.overlay')
        const box = e.target
        const w = box.clientWidth
        const h = box.clientHeight
        const x = (e.pageX - box.offsetLeft - (w / 2)) * (w > h ? (h / w) : 1)
        const y = (e.pageY - box.offsetTop - (h / 2)) * (h > w ? (w / h) : 1)
        const direction = Math.round((((Math.atan2(y, x) * 180 / Math.PI) + 180) / 90)) % 4

        let styles = { top: 0, left: 0 }

        switch (direction) {
          case 0:
            styles.left = -w
            overlay.style.left = -w
            break
          case 1:
            styles.top = -h
            overlay.style.top = -h
            break
          case 2:
            styles.left = w
            overlay.style.left = w
            break
          case 3:
            styles.top = h
            overlay.style.top = h
            break
            default: return false
        }
        overlay.style.top = 0
        overlay.style.left = 0

        if (e.type === 'mouseenter') {
          overlay.style.transform = "translate(0, 0)"
          if ((direction + 1) % 2 === 0) {
            overlay.style.top = styles.top
            overlay.style.left = 0
            animation('vertical', styles.top, 0)
          } else {
            overlay.style.top = 0
            overlay.style.left = styles.left
            animation('horizontal', styles.left, 0)
          }
        } else {
          //anime.jsの動きを削除
          anime.remove(overlay)
          overlay.style.transform = "translate(0, 0)"
          if ((direction + 1) % 2 === 0) {
            animation('vertical', 0, styles.top)
          } else {
            animation('horizontal', 0, styles.left)
          }
        }

        function animation(direction, startPos, endPos) {
          if (direction === 'vertical') {
            //anime.js部分
            anime({
              targets: overlay,
              easing: 'easeOutQuart',
              translateY: [startPos, endPos],
              duration: 300,
            })
          } else {
            //anime.js部分
            anime({
              targets: overlay,
              easing: 'easeOutQuart',
              translateX: [startPos, endPos],
              duration: 300,
            })
          }
        }
      }

    targetBox.forEach(element => {
      element.addEventListener('mouseenter', setMouseOver)
      element.addEventListener('mouseleave', setMouseOver)
    })

コメント