웹솔루션개발 25년 노하우! 해피CGI의 모든것

[해피CGI][cgimall] 가격이 올라가는 카운터 애니메이션 본문

웹프로그램밍 자료실/HTML 자료

[해피CGI][cgimall] 가격이 올라가는 카운터 애니메이션

해피CGI윤실장 2025. 8. 27. 09:04



상금의 금액이 올라가는 카운터 애니메이션입니다.

소스를 변경하여 다양하게 응용 가능합니다.


HTML 구조

<div id="app">

  <div id="prize">

    <div id="prize-lines" class="prize-filter"></div>

    <div id="prize-shadow" class="prize-filter"></div>

    <h2 id="prize-label">

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

      <span>CASH PRIZE</span>

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

    </h2>

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

  </div>

  

  <div id="shapes">

    <i class="fa-regular fa-circle"></i>

    <i class="fa-regular fa-square"></i>

    <i class="fa-regular fa-triangle"></i>

  </div>

  

  <div id="actions-wrapper">

    <div id="actions">

      <div id="theme-actions">

        <button class="theme-button" data-theme="green" data-selected="true" onclick="handleChangeTheme(event)">

          <i class="fa-regular fa-circle"></i>

        </button>

        <button class="theme-button" data-theme="blue" onclick="handleChangeTheme(event)">

          <i class="fa-regular fa-square"></i>

        </button>

        <button class="theme-button" data-theme="pink" onclick="handleChangeTheme(event)">

          <i class="fa-regular fa-triangle"></i>

        </button>

      </div>

      <button id="redo-button" type="button" onclick="handleRedo()">

        <i class="fa-solid fa-arrows-repeat"></i>

        <span>Rerun</span>

      </button>

    </div>

  </div>

</div>

 



CSS 소스

:root {

  --dark-rgb: 23 28 28;

  --darker-rgb: 8 13 7;

  

  --green: 9 252 8;

  --blue: 59 130 246;

  --pink: 231 60 126;

  

  --background-rgb: 12 12 12;

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

}

 

body {

  background-color: black;

  height: 100vh;  

  overflow: hidden;

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

}

 

button {  

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

}

 

* {

  box-sizing: border-box;

  margin: 0;

  padding: 0;

}

 

#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%

  );

}

 

#shapes {

  height: calc(100% - 2rem);

  width: calc(100% - 2rem);  

  position: fixed;

  left: 0%;

  top: 0%;

  z-index: 1;

  margin: 1rem;

  border: 0.15rem dashed rgb(var(--theme-rgb) / 30%);

  pointer-events: none;

}

 

.
.
.

 

JS 소스

const MINIMUM_ADDITIONAL_ITERATION_COUNT = 2;

 

const config = {  

  additionalIterationCount: Math.max(MINIMUM_ADDITIONAL_ITERATION_COUNT, 3),

  transitionDuration: 3000,

  prize: 4560000,

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

}

 

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

  style: "currency",

  currency: "USD",

  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`;

  });

}

 

.
.
.


해당 사이트로 이동하거나 첨부파일을 다운로드하여
전체 소스를 확인하실 수 있습니다.

 

Comments