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

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

クリックした箇所を起点に絵文字を一刀両断する 🔪

以前つくったDEMOをもとに、左上に入力した絵文字を一刀両断するDEMOをつくりました。

blog.kimizuka.org

DEMO


ソースコード(抜粋)

絵文字の判定

document.querySelector('input').addEventListener('input', (evt) => {
  if (evt.target.value.length === 2 && [ ...evt.target.value ].length === 1) {
    // テキストの長さが2で、配列に収納した際の要素数が1であれば絵文字と判定する
  }
});

すべての絵文字に対応できるわけではありませんが、サロゲートペアのlengthがうまく取得できない場合を絵文字と判定しています。

blog.kimizuka.org

クリックしたところを起点に一刀両断する

以前のものとほぼほぼ変わりません。

indes.html
<input type="text" value="🎂" maxlength="2" /><!--inputを追加-->
<div class="box">
  <div>
    <div class="emoji">🎂</div><!--divを入れ子にする-->
  </div>
  <div>
    <div class="emoji">🎂</div><!--divを入れ子にする-->
  </div>
</div>
index.js(抜粋)
document.querySelector('.box').addEventListener('click', (evt) => {
  const width = 300; // サイズ変更
  const { offsetX, target } = evt;
  const ratio = offsetX / width;
  const left = document.querySelector('.box > div:first-child'); // セレクタを変更
  const right = document.querySelector('.box > div:last-child'); // セレクタを変更

  clearTimeout(timer);
  target.dataset.isHit = true;
  left.style.width = `${ ratio * 100 }%`;
  right.style.width = `${ (1 - ratio) * 100 }%`;

  timer = setTimeout(() => {
    target.dataset.isHit = false;
    left.style.width = right.style.width = `100%`;
  }, 1000);
});
index.scss
.box {
  position: absolute;
  top: 0; bottom: 0;
  left: 0; right: 0;
  margin: auto;
  width: 300px; height: 300px;
  font-size: 300px;
  cursor: pointer;

  > div {
    position: absolute;
    width: 100%;
    transition: opacity .1s ease-out;
    overflow: hidden;
    pointer-events: none;

    > div { 
      display: flex;
      align-items: center;
      justify-content: center;
      position: absolute;
      width: 300px; height: 300px;
    }

    &:first-child {
      top: 0; bottom: 0;
      left: 0;

      > div {
        left: 0;
      }
    }

    &:last-child {
      top: 0; bottom: 0;
      right: 0;

      > div {
        right: 0;
      }
    }
  }

  &[data-is-hit='true'] {
    > div {
      opacity: 0;
      transition: transform .1s ease-out, opacity .1s .4s ease-out;
  
      &:first-child {
        transform: translateY(-25%);
      }
      
      &:last-child {
        transform: translateY(25%);
      }
    } 
  }
}

divを入れ子にして、テキストをセンタリングして表示するように変更しました。