みかづきブログ・カスタム

基本的にはちょちょいのほいです。

クリックした箇所を起点に画像を一刀両断する 🔪

タイトルの通りですが、クリックした箇所を起点にDOMを真っ二つに一刀両断したいなと思い、コードを書いてみました。
思い出の中のFF6の斬鉄剣のようなイメージで制作しましたが、シンプルに仕上げるためにエフェクトは入れていません。
一応、横方向、縦方向の2種類作成してあります。

横方向


縦方向


ソースコード(横方向)

HTML(抜粋)

<div class="box"><!--DOMの中に同じ背景画像を設定したDOMを2ついれる-->
  <div></div>
  <div></div>
</div>

JavaScript(抜粋)

document.querySelector('.box').addEventListener('click', (evt) => {
  const width = 360;
  const { offsetY, target } = evt;
  const ratio = offsetY / width;
  const left = target.querySelector(':first-child');
  const right = target.querySelector(':last-child');

  target.dataset.isHit = true;
  // クリックした箇所に応じて、中にあるDOMの高さを調整する
  left.style.height = `${ ratio * 100 }%`;
  right.style.height = `${ (1 - ratio) * 100 }%`;
});

SCSS(抜粋)

.box {
  position: absolute;
  top: 0; bottom: 0;
  left: 0; right: 0;
  margin: auto;
  width: 360px; height: 360px;
  cursor: pointer;

  > div {
    position: absolute;
    height: 100%;
    background-image: url(画像のパス);
    background-size: 360px 360px;
    transition: opacity .1s ease-out;
    pointer-events: none;

    &:first-child {
      top: 0;
      left: 0; right: 0;
      background-position: center 0;
    }

    &:last-child {
      bottom: 0;
      left: 0; right: 0;
      background-position: center 100%;
    }
  }
  
  &[data-is-hit='true'] {
    > div {
      opacity: 0;
      transition: transform .1s ease-out, opacity .1s .4s ease-out; // 一刀両断時のアニメーションを設定する
  
      &:first-child {
        transform: translateX(-25%);
      }
      
      &:last-child {
        transform: translateX(25%);
      }
    } 
  }
}

ポイント

  • ❶ DOMの中に上下用のDOMを入れておく
  • ❷ 背景画像の基準点を、それぞれ上と下に設定しておく
  • ❸ クリックした点を基準で、上用DOM、下用DOMの高さを設定する
  • ❹ CSSアニメーションで一刀両断っぽくみせる

という感じです。