{"version":3,"file":"omnedia-ngx-number-ticker.mjs","sources":["../../../projects/ngx-number-ticker/src/lib/ngx-number-ticker.component.ts","../../../projects/ngx-number-ticker/src/lib/ngx-number-ticker.component.html","../../../projects/ngx-number-ticker/src/public-api.ts","../../../projects/ngx-number-ticker/src/omnedia-ngx-number-ticker.ts"],"sourcesContent":["import {CommonModule} from \"@angular/common\";\r\nimport {ChangeDetectionStrategy, Component, Input, signal} from \"@angular/core\";\r\n\r\n@Component({\r\n  selector: \"om-number-ticker\",\r\n  standalone: true,\r\n  imports: [CommonModule],\r\n  templateUrl: \"./ngx-number-ticker.component.html\",\r\n  styleUrl: \"./ngx-number-ticker.component.scss\",\r\n  changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class NgxNumberTickerComponent {\r\n  @Input(\"styleClass\")\r\n  styleClass?: string;\r\n\r\n  @Input(\"countTo\")\r\n  set countTo(number: number) {\r\n    this.targetNumber = number;\r\n    this.countToNumber(number);\r\n  }\r\n\r\n  @Input(\"countDuration\")\r\n  set countDuration(countDuration: number) {\r\n    this.countDurationValue = countDuration;\r\n\r\n    if (this.frameId) {\r\n      cancelAnimationFrame(this.frameId);\r\n      this.frameId = undefined;\r\n      this.countToNumber(this.targetNumber);\r\n    }\r\n  }\r\n\r\n  countDurationValue = 2000;\r\n\r\n  @Input(\"transformFunction\")\r\n  transformFunction?: (number: number) => string;\r\n\r\n  targetNumber = 0;\r\n  currentNumber = 0;\r\n  displayNumber = signal(\"0\");\r\n\r\n  private frameId?: number;\r\n\r\n  private countToNumber(number: number): void {\r\n    if (number > this.currentNumber) {\r\n      this.countUp(number);\r\n      return;\r\n    }\r\n\r\n    this.countDown(number);\r\n  }\r\n\r\n  private countUp(target: number): void {\r\n    const direction = \"up\";\r\n    this.executeCount(target, direction);\r\n  }\r\n\r\n  private countDown(target: number): void {\r\n    const direction = \"down\";\r\n    this.executeCount(target, direction);\r\n  }\r\n\r\n  setCountValue(): void {\r\n    if (!this.transformFunction) {\r\n      this.displayNumber.set(`${this.currentNumber}`);\r\n    } else {\r\n      this.displayNumber.set(this.transformFunction(this.currentNumber));\r\n    }\r\n  }\r\n\r\n  private executeCount(target: number, direction: \"up\" | \"down\"): void {\r\n    const startNumber = this.currentNumber;\r\n    const difference = Math.abs(target - startNumber);\r\n\r\n    // Check if we have fewer than 10 digits to count\r\n    const isSmallDifference = difference <= 10;\r\n    const duration = this.countDurationValue;\r\n\r\n    // If the difference is small, handle all of them in the easing phase\r\n    if (isSmallDifference) {\r\n      const slowCountingDuration = duration;\r\n      const startTime = performance.now();\r\n\r\n      const updateSmallDifference = (currentTime: number) => {\r\n        const elapsed = currentTime - startTime;\r\n        const percentComplete = Math.min(elapsed / slowCountingDuration, 1);\r\n        const easedPercent = this.easeOutQuad(percentComplete);\r\n\r\n        // Calculate the current number based on the eased percent\r\n        this.currentNumber = this.calculateCurrentNumber(\r\n          startNumber,\r\n          target,\r\n          easedPercent,\r\n          direction,\r\n        );\r\n\r\n        if (elapsed < slowCountingDuration) {\r\n          this.setCountValue();\r\n          this.frameId = requestAnimationFrame(updateSmallDifference);\r\n        } else {\r\n          this.currentNumber = target; // Ensure final number is set\r\n          this.setCountValue();\r\n        }\r\n      };\r\n\r\n      this.frameId = requestAnimationFrame(updateSmallDifference);\r\n    } else {\r\n      // Normal case: Handle large differences with two phases\r\n      const last10DigitsDuration = 1000; // 1 second for the last 10 digits\r\n      const mainCountingDuration = duration - last10DigitsDuration;\r\n\r\n      const last10Start = direction === \"up\" ? target - 10 : target + 10;\r\n      const startTime = performance.now();\r\n\r\n      const update = (currentTime: number) => {\r\n        const elapsed = currentTime - startTime;\r\n\r\n        if (\r\n          (direction === \"up\" && this.currentNumber < last10Start) ||\r\n          (direction === \"down\" && this.currentNumber > last10Start)\r\n        ) {\r\n          // Phase 1: Main counting phase\r\n          const percentComplete = Math.min(elapsed / mainCountingDuration, 1);\r\n\r\n          // Calculate current number based on the percentage of completion\r\n          this.currentNumber = this.calculateCurrentNumber(\r\n            startNumber,\r\n            last10Start,\r\n            percentComplete,\r\n            direction,\r\n          );\r\n\r\n          if (elapsed < mainCountingDuration) {\r\n            this.setCountValue();\r\n            this.frameId = requestAnimationFrame(update);\r\n          } else {\r\n            this.currentNumber = last10Start;\r\n            this.setCountValue();\r\n            this.frameId = requestAnimationFrame(update);\r\n          }\r\n        } else {\r\n          // Phase 2: Slow down for the last 10 digits\r\n          const elapsedForLast10 = elapsed - mainCountingDuration;\r\n          const percentComplete = Math.min(\r\n            elapsedForLast10 / last10DigitsDuration,\r\n            1,\r\n          );\r\n          const easedPercent = this.easeOutQuad(percentComplete);\r\n\r\n          // Calculate the number for the last 10 digits\r\n          this.currentNumber = this.calculateCurrentNumber(\r\n            last10Start,\r\n            target,\r\n            easedPercent,\r\n            direction,\r\n          );\r\n\r\n          if (elapsedForLast10 < last10DigitsDuration) {\r\n            this.setCountValue();\r\n            this.frameId = requestAnimationFrame(update);\r\n          } else {\r\n            this.currentNumber = target; // Ensure final number is set\r\n            this.setCountValue();\r\n          }\r\n        }\r\n      };\r\n\r\n      this.frameId = requestAnimationFrame(update);\r\n    }\r\n  }\r\n\r\n  // Helper function to calculate current number based on direction\r\n  private calculateCurrentNumber(\r\n    start: number,\r\n    end: number,\r\n    percent: number,\r\n    direction: \"up\" | \"down\",\r\n  ): number {\r\n    if (direction === \"up\") {\r\n      return Math.floor(start + (end - start) * percent);\r\n    } else {\r\n      return Math.floor(start - (start - end) * percent);\r\n    }\r\n  }\r\n\r\n  // Easing function to slow down progressively\r\n  private easeOutQuad(t: number): number {\r\n    return t * (2 - t);\r\n  }\r\n}\r\n","<p class=\"om-number-ticker\" [ngClass]=\"styleClass\">\r\n  {{ displayNumber() }}\r\n</p>\r\n","/*\r\n * Public API Surface of ngx-number-ticker\r\n */\r\n\r\nexport * from \"./lib/ngx-number-ticker.component\";\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}