以前つくったDEMOをもとに、左上に入力した絵文字を一刀両断するDEMOをつくりました。
DEMO
ソースコード(抜粋)
絵文字の判定
document.querySelector('input').addEventListener('input', (evt) => { if (evt.target.value.length === 2 && [ ...evt.target.value ].length === 1) { // テキストの長さが2で、配列に収納した際の要素数が1であれば絵文字と判定する } });
すべての絵文字に対応できるわけではありませんが、サロゲートペアのlengthがうまく取得できない場合を絵文字と判定しています。
クリックしたところを起点に一刀両断する
以前のものとほぼほぼ変わりません。
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を入れ子にして、テキストをセンタリングして表示するように変更しました。