UNPKG

pixiu-number-toolkit

Version:
1 lines 7.68 kB
{"version":3,"sources":["../src/animation/rollerNumber.ts"],"names":["RollerNumber","element","initialValue","digitHeight","newValue","duration","char","_","i","currentDigits","targetDigits","digitElements","newDigit","targetChar","index","digitElement","currentChar","currentDigit","targetDigit","distance","column","targetTop","newTop"],"mappings":"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","file":"chunk-QJRR5Q4O.cjs","sourcesContent":["export class RollerNumber {\r\n private element: HTMLElement;\r\n private value: number;\r\n private targetValue: number;\r\n private animationDuration: number;\r\n private digitHeight: number;\r\n\r\n constructor(element: HTMLElement, initialValue = 0, digitHeight = 40) {\r\n this.element = element;\r\n this.value = initialValue;\r\n this.targetValue = initialValue;\r\n this.animationDuration = 1000; // 默认1秒\r\n this.digitHeight = digitHeight;\r\n this.render();\r\n }\r\n\r\n setValue(newValue: number): void {\r\n this.targetValue = newValue;\r\n this.animateToTarget();\r\n }\r\n\r\n setAnimationDuration(duration: number): void {\r\n this.animationDuration = duration;\r\n this.render();\r\n }\r\n\r\n private render(): void {\r\n this.element.style.overflow = 'hidden';\r\n this.element.style.display = 'flex';\r\n this.element.style.height = `${this.digitHeight}px`;\r\n this.element.innerHTML = this.createDigitElements();\r\n }\r\n\r\n private createDigitElements(): string {\r\n return this.value\r\n .toString()\r\n .split('')\r\n .map((char) => {\r\n if (char === '.') {\r\n return `<div style=\"width: ${\r\n this.digitHeight / 4\r\n }px; display: flex; align-items: flex-end; justify-content: center\">.</div>`;\r\n }\r\n return `\r\n <div style=\"position: relative; width: ${\r\n this.digitHeight / 2\r\n}px; height: ${this.digitHeight}px; overflow: hidden;\">\r\n <div class=\"digit-column\" style=\"position: absolute; top: 0; left: 0; width: 100%; height: ${\r\n this.digitHeight * 20\r\n}px; transition: transform ${\r\n this.animationDuration\r\n}ms cubic-bezier(0.25, 0.1, 0.25, 1);\">\r\n ${Array.from(\r\n { length: 20 },\r\n (_, i) =>\r\n `<div style=\"height: ${\r\n this.digitHeight\r\n }px; display: flex; align-items: center; justify-content: center;\">${\r\n i % 10\r\n }</div>`,\r\n ).join('')}\r\n </div>\r\n </div>\r\n `;\r\n })\r\n .join('');\r\n }\r\n\r\n private animateToTarget(): void {\r\n const currentDigits = this.value.toString().split('');\r\n const targetDigits = this.targetValue.toString().split('');\r\n let digitElements = Array.from(this.element.children);\r\n\r\n // 如果目标值的位数多于当前显示的位数,添加新的数字元素\r\n while (digitElements.length < targetDigits.length) {\r\n const newDigit = document.createElement('div');\r\n newDigit.innerHTML = this.createDigitElements();\r\n this.element.appendChild(newDigit.firstElementChild!);\r\n digitElements = Array.from(this.element.children);\r\n }\r\n\r\n // 从左到右遍历数字\r\n targetDigits.forEach((targetChar, index) => {\r\n const digitElement = digitElements[index];\r\n const currentChar = currentDigits[index] || '0';\r\n\r\n if (targetChar === '.' || currentChar === '.') {\r\n // 如果是小数点,不需要动画\r\n digitElement.textContent = targetChar;\r\n } else {\r\n const currentDigit = parseInt(currentChar);\r\n const targetDigit = parseInt(targetChar);\r\n\r\n let distance = targetDigit - currentDigit;\r\n if (distance < 0) distance += 10; // 如果是负数,加10使其成为正数\r\n\r\n const column = digitElement.firstElementChild as HTMLElement;\r\n const targetTop = -(currentDigit + distance) * this.digitHeight;\r\n column.style.transform = `translateY(${targetTop}px)`;\r\n\r\n // 添加过渡结束事件监听器\r\n column.addEventListener(\r\n 'transitionend',\r\n this.handleTransitionEnd.bind(\r\n this,\r\n column,\r\n currentDigit,\r\n targetDigit,\r\n ),\r\n { once: true },\r\n );\r\n }\r\n });\r\n\r\n this.value = this.targetValue;\r\n }\r\n\r\n private handleTransitionEnd(\r\n column: HTMLElement,\r\n currentDigit: number,\r\n targetDigit: number,\r\n ): void {\r\n // 移除过渡效果\r\n column.style.transition = 'none';\r\n\r\n // 计算新的位置\r\n const newTop = -targetDigit * this.digitHeight;\r\n column.style.transform = `translateY(${newTop}px)`;\r\n\r\n // 强制回流\r\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\r\n column.offsetHeight;\r\n\r\n // 恢复过渡效果\r\n column.style.transition = `transform ${this.animationDuration}ms cubic-bezier(0.25, 0.1, 0.25, 1)`;\r\n }\r\n}\r\n"]}