1import { Controller } from "@hotwired/stimulus"; 2import "number-flow"; // Ensure number-flow is imported 3import { continuous } from "number-flow"; // For the slot machine effect 4 5export default class extends Controller { 6 static values = { 7 initial: { type: Number, default: 42 }, // Initial value 8 min: { type: Number, default: 0 }, // Minimum value 9 max: { type: Number, default: 999 }, // Maximum value 10 duration: { type: Number, default: 700 }, // Animation duration in ms 11 }; 12 13 connect() { 14 this.element.innerHTML = "<number-flow></number-flow>"; 15 this.flow = this.element.querySelector("number-flow"); 16 17 // Configure spin and transform timings 18 this.flow.spinTiming = { 19 duration: this.durationValue, 20 easing: "ease-in-out", 21 }; 22 this.flow.transformTiming = { 23 duration: this.durationValue, 24 easing: "ease-in-out", 25 }; 26 this.flow.plugins = [continuous]; // Keep slot machine effect 27 28 // Store the target initial value 29 const targetInitialValue = this.initialValue; 30 31 // Set display to 0 initially without animation (or a very brief one if needed by number-flow) 32 // For number-flow, a direct update usually doesn't animate unless configured to. 33 // If it does, we might need to temporarily set duration to 0 for this first update. 34 35 // Temporarily set duration to 0 for the very first update to 0 36 const originalSpinDuration = this.flow.spinTiming.duration; 37 const originalTransformDuration = this.flow.transformTiming.duration; 38 this.flow.spinTiming.duration = 0; 39 this.flow.transformTiming.duration = 0; 40 41 this.flow.update(0); // Set to 0 without animation 42 43 // Restore original animation durations 44 this.flow.spinTiming.duration = originalSpinDuration; 45 this.flow.transformTiming.duration = originalTransformDuration; 46 47 // Set current value for future clicks 48 this.currentValue = targetInitialValue; 49 50 // Animate to the target initial value 51 // Use a timeout to ensure the "0" is rendered before animating 52 setTimeout(() => { 53 this.flow.update(targetInitialValue); 54 }, 50); // A small delay like 50ms should be enough 55 } 56 57 changeNumber() { 58 const oldVal = this.currentValue; 59 let newVal = Math.floor(Math.random() * (this.maxValue - this.minValue + 1)) + this.minValue; 60 61 // Ensure new value is different from the old one if possible within the range 62 if (this.maxValue > this.minValue) { 63 // only try to get a different number if range allows 64 while (newVal === oldVal) { 65 newVal = Math.floor(Math.random() * (this.maxValue - this.minValue + 1)) + this.minValue; 66 } 67 } 68 69 this.currentValue = newVal; 70 this.flow.update(this.currentValue); 71 } 72 73 disconnect() { 74 if (this.flow && typeof this.flow.destroy === "function") { 75 // this.flow.destroy(); // If number-flow has a destroy method 76 } 77 } 78};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.