<script>
/* 모든 버튼을 선택해서 배열처럼 저장 */
const buttons = document.querySelectorAll(".scramble-button");
/* 랜덤하게 변환될 문자들 (영어 대문자 + 숫자) */
const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
/* 버튼마다 이벤트를 개별적으로 적용하기 위해 반복문 사용 */
buttons.forEach(button => {
/* 현재 버튼 안의 <span> 요소를 찾음 (버튼 안의 텍스트 부분) */
const textElement = button.querySelector("span");
/* 원래의 텍스트 값을 저장 (애니메이션 후 원래대로 복구하기 위해) */
const originalText = textElement.innerText;
/* 버튼 위에 마우스를 올렸을 때 실행될 함수 */
function scrambleText() {
const textArray = originalText.split(""); // 글자를 배열로 변환 (각 글자를 개별적으로 조작하기 위해)
let completed = 0; // 모든 글자가 원래대로 돌아왔는지 확인하기 위한 변수
/* 각 글자를 개별적으로 변경 */
textArray.forEach((char, index) => {
let changes = Math.floor(Math.random() * 2) + 2; // 2~3번 변경 (무작위)
let delay = Math.random() * 300; // 0~300ms 랜덤한 시간 차이로 변경 (각 글자가 서로 다른 속도로 바뀜)
let counter = 0; // 현재 몇 번 변경했는지 저장하는 변수
const interval = setInterval(() => {
/* 무작위 문자로 변경 */
textArray[index] = letters[Math.floor(Math.random() * letters.length)];
textElement.innerText = textArray.join(""); // 변경된 글자들을 다시 합쳐서 표시
counter++; // 변경 횟수 증가
if (counter >= changes) { // 설정된 변경 횟수(2~3번)를 넘으면
clearInterval(interval); // 더 이상 변경하지 않고 원래 글자로 복구
textArray[index] = originalText[index]; // 원래 글자로 되돌리기
completed++; // 원래 글자로 돌아온 글자 개수 증가
/* 모든 글자가 원래대로 복구되면 최종적으로 원래 텍스트로 고정 */
if (completed === textArray.length) {
textElement.innerText = originalText;
}
}
}, delay); // 설정된 랜덤 시간 간격으로 실행
});
}
/* 버튼에 마우스를 올리면 scrambleText 함수 실행 */
button.addEventListener("mouseenter", scrambleText);
});
</script>
글자를 여러 번 랜덤하게 변경하려면, setTimeout보다 setInterval이 더 적합
Math.random() * 300 → 0~300ms 사이의 랜덤한 딜레이를 설정해서, 각 글자가 다른 속도로 변경되게 만듦.
setInterval()은 자동으로 멈추지 않기 때문에, 일정 횟수(2~3번)만 실행되도록 clearInterval()로 중지시킴.
모든 글자가 원래대로 돌아오면 텍스트를 확정하기 위해.
completed === textArray.length → 모든 글자가 원래 상태로 돌아왔을 때만 최종적으로 원래 텍스트를 유지.
포폴 만드려고 레퍼런스 참고 중, 텍스트 스크램블 효과라는 처음 보는 효과가 있길래, 내 포폴에도 넣기 위해서 정리한 다음 작성