E. m.apping1907@gmail.com

   Insta. @uxui_web_lab

   P. +82(0)70-7799-6299


[아임웹 코드] 슬롯 머신 숫자 완성 애니메이션

시연 동영상 보기



<div class="prizesection">

<div id="app">

  <div id="prize">

    <h2 id="prize-label">

      <span class="asterisk">*</span>

      <span>금액</span>

      <span class="asterisk">*</span>      

    </h2>

    <h1 id="prize-text"></h1>

  </div>

  

 

  </div>

</div>


<style>


.prizesection {

  background-color: black;

  height: 100vh;  

  overflow: hidden;

  font-family: "Orbitron", sans-serif;

}



#app {

  height: 100%;

  width: 100%;

  position: relative;

  display: flex;

  align-items: center;

  justify-content: center;

  background: linear-gradient(

    60deg, 

    rgb(var(--background-rgb)) 30%, 

    rgb(var(--theme-rgb) / 8%) 50%, 

    rgb(var(--background-rgb)) 70%

  );

}



@keyframes float {

  from, to {

    translate: 0% 0%;

  }

  

  50% {

    translate: 0% 10%;

  }

}


#prize {

  width: 105rem;

  display: flex;

  flex-direction: column;

  align-items: center;

  gap: 0.5rem;

  position: relative;

  z-index: 2;

  background-color: rgb(var(--darker-rgb));

  border: 1.5rem solid rgb(255 255 255 / 2.5%);

  padding: 10rem 4rem;  

  box-shadow: 0rem 0rem 10rem 4rem rgb(0 0 0 / 75%);

  backdrop-filter: blur(1rem);

}


#prize-label,

#prize-text {

  color: rgb(var(--theme-rgb));

  text-align: center;

}


#prize-label {

  display: flex;

  align-items: center;

  justify-content: center;

  gap: 2rem;

  font-size: 3rem;

  opacity: 0.75;

}


#prize-label > span {

  display: inline-flex; 

}


#prize-label > .asterisk {

  padding-top: 0.25em;

  line-height: 0.5em;

}


#prize-text {  

  display: flex;

  gap: 1rem;

  height: 10rem;

  line-height: 10rem;

  font-size: 11rem;

}


#prize-text > .digit {  

  width: 8rem;

  position: relative;

  overflow: hidden;

  border-bottom: 0.25rem solid rgb(var(--theme-rgb));

}


#prize-text > .digit > .digit-track {  

  width: 100%;

  display: flex;

  flex-direction: column;

  align-items: center;

  position: absolute; 

  left: 0%;

  top: 0%;

  translate: 0% 0%;

  transition: translate 3000ms cubic-bezier(.1,.67,0,1);

}





@media(max-width: 1700px) {

  #prize {

    scale: 0.75;

  }

}


@media(max-width: 1300px) {

  #prize {

    scale: 0.5;

  }

}


@media(max-width: 900px) {

  #prize {

    scale: 0.3;

  }

}


@media(max-width: 600px) {

  #prize {

    scale: 0.2;

  }

}

</style>


<script>

  const MINIMUM_ADDITIONAL_ITERATION_COUNT = 2;


const config = {  

  additionalIterationCount: Math.max(MINIMUM_ADDITIONAL_ITERATION_COUNT, 3),

  transitionDuration: 3000,

  prize: 120000000,

  digits: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

}


const USD = new Intl.NumberFormat("en-US", {

  style: "currency",

  currency: "KRW",

  maximumFractionDigits: 0

});


const getPrizeText = () => document.getElementById("prize-text"),

      getTracks = () => document.querySelectorAll(".digit > .digit-track");


const getFormattedPrize = () => USD.format(config.prize),

      getPrizeDigitByIndex = index => parseInt(config.prize.toString()[index]),

      determineIterations = index => index + config.additionalIterationCount;


const createElement = (type, className, text) => {

  const element = document.createElement(type);

  element.className = className;

  if(text !== undefined) element.innerText = text;

  return element;

}


const createCharacter = character => createElement("span", "character", character);


const createDigit = (digit, trackIndex) => {

  const digitElement = createElement("span", "digit"),

        trackElement = createElement("span", "digit-track");

  

  let digits = [],

      iterations = determineIterations(trackIndex);

  

  for(let i = 0; i < iterations; i++) {

    digits = [...digits, ...config.digits];

  }

  

  trackElement.innerText = digits.join(" ");

  

  trackElement.style.transitionDuration = `${config.transitionDuration}ms`;

  

  digitElement.appendChild(trackElement);

  

  return digitElement;

}


const setup = () => {

  let index = 0;

  

  const prizeText = getPrizeText();

  

  for(const character of getFormattedPrize()) {

    const element = isNaN(character) 

      ? createCharacter(character) : createDigit(character, index++);

    

    prizeText.appendChild(element);

  }  

}


const animate = () => {

  getTracks().forEach((track, index) => {

    const digit = getPrizeDigitByIndex(index),

          iterations = determineIterations(index),

          activeDigit = ((iterations - 1) * 10) + digit;

    

    track.style.translate = `0rem ${activeDigit * -10}rem`;

  });

}


window.onload = () => {

  setup();

  

  setTimeout(animate);  

};


const handleRedo = () => {

  resetAnimation();

  

  animate();

}



const resetTrackPosition = track => {

  track.style.transitionDuration = "0ms";

  track.style.translate = "0rem 0rem";

  track.offsetHeight;

  track.style.transitionDuration = `${config.transitionDuration}ms`;

}


const resetAnimation = () => {

  for(const track of getTracks()) resetTrackPosition(track);

}


</script>

Copyright 2022. MAPPING All right reserved.

카카오톡 채널 채팅하기 버튼