@devrongx/games 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devrongx/games",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Game UI components for sports prediction markets",
5
5
  "license": "MIT",
6
6
  "main": "./src/index.ts",
@@ -13,10 +13,8 @@ interface PreMatchQuestionsProps {
13
13
  onComplete: (selections: IUserBets) => void;
14
14
  }
15
15
 
16
- // ── Sassy typewriter — each word has its own exponential speed curve ──
17
- // Words alternate between snappy bursts and dramatic slow reveals.
18
- // Within each word, character delays follow an exponential curve.
19
- const useSassyTypewriter = (text: string, delay = 0) => {
16
+ // ── Smooth typewriter — constant speed, clean and simple ──
17
+ const useTypewriter = (text: string, speed = 45, delay = 0) => {
20
18
  const [displayed, setDisplayed] = useState("");
21
19
  const [done, setDone] = useState(false);
22
20
 
@@ -24,74 +22,28 @@ const useSassyTypewriter = (text: string, delay = 0) => {
24
22
  setDisplayed("");
25
23
  setDone(false);
26
24
 
27
- // Build per-character delay schedule
28
- const words = text.split(" ");
29
- const charDelays: number[] = [];
30
-
31
- // Alternating word styles for rhythm
32
- // "burst" = types fast then decelerates at end
33
- // "drag" = starts slow, accelerates to finish
34
- // "snap" = entire word appears almost instantly
35
- const wordStyles = ["drag", "snap", "burst", "drag", "snap", "burst"];
36
-
37
- words.forEach((word, wIdx) => {
38
- const style = wordStyles[wIdx % wordStyles.length];
39
- const len = word.length;
40
-
41
- for (let c = 0; c < len; c++) {
42
- const t = len > 1 ? c / (len - 1) : 0; // 0..1 progress through word
43
-
44
- let ms: number;
45
- if (style === "burst") {
46
- // Starts fast (15ms), exponentially decelerates to ~80ms
47
- ms = 15 + 65 * Math.pow(t, 2.5);
48
- } else if (style === "drag") {
49
- // Starts slow (90ms), exponentially accelerates to ~12ms
50
- ms = 90 - 78 * Math.pow(t, 2.2);
51
- } else {
52
- // snap — near instant, 8ms per char
53
- ms = 8;
25
+ const timer = setTimeout(() => {
26
+ let i = 0;
27
+ const interval = setInterval(() => {
28
+ i++;
29
+ setDisplayed(text.slice(0, i));
30
+ if (i >= text.length) {
31
+ clearInterval(interval);
32
+ setDone(true);
54
33
  }
55
- charDelays.push(Math.round(ms));
56
- }
57
- // Pause between words — dramatic breath
58
- charDelays.push(wIdx < words.length - 1 ? 120 : 0);
59
- });
34
+ }, speed);
35
+ return () => clearInterval(interval);
36
+ }, delay);
60
37
 
61
- const timers: ReturnType<typeof setTimeout>[] = [];
62
- let cumulative = delay;
63
- let charIdx = 0;
64
-
65
- // Schedule each character reveal
66
- for (let i = 0; i < charDelays.length; i++) {
67
- cumulative += charDelays[i];
68
- const idx = charIdx;
69
- // The space between words is at charDelays entries where we push 120ms pause
70
- // but we need to track actual characters in text
71
- if (i < charDelays.length && idx <= text.length) {
72
- timers.push(setTimeout(() => {
73
- setDisplayed(text.slice(0, idx + 1));
74
- if (idx + 1 >= text.length) setDone(true);
75
- }, cumulative));
76
- }
77
- // Only increment charIdx for actual characters (not the inter-word pauses)
78
- // Words joined by spaces: after each word's chars, next char is space
79
- charIdx++;
80
- }
81
-
82
- return () => timers.forEach(clearTimeout);
83
- }, [text, delay]);
38
+ return () => clearTimeout(timer);
39
+ }, [text, speed, delay]);
84
40
 
85
41
  return { displayed, done };
86
42
  };
87
43
 
88
44
  // ── Start slide ──
89
45
  const StartSlide = ({ onStart }: { onStart: () => void }) => {
90
- const line1 = useSassyTypewriter("Choose your answers", 300);
91
- const line2 = useSassyTypewriter(
92
- "Pick your predictions first. We'll set up bet amounts after.",
93
- line1.done ? 0 : 1800,
94
- );
46
+ const line1 = useTypewriter("Choose your answers", 45, 300);
95
47
 
96
48
  return (
97
49
  <div className="flex flex-col items-center justify-center h-full px-8 gap-8">
@@ -100,14 +52,10 @@ const StartSlide = ({ onStart }: { onStart: () => void }) => {
100
52
  {line1.displayed}
101
53
  {!line1.done && <span className="inline-block w-[2px] h-[18px] bg-[#22E3E8] ml-[2px] align-middle animate-pulse" />}
102
54
  </p>
103
- <p className="text-[14px] text-white/50 font-medium text-center leading-relaxed max-w-[260px] min-h-[44px]" style={OUTFIT}>
104
- {line2.displayed}
105
- {line1.done && !line2.done && <span className="inline-block w-[2px] h-[14px] bg-white/30 ml-[2px] align-middle animate-pulse" />}
106
- </p>
107
55
  </div>
108
56
 
109
57
  {/* Let's Go — simple cyan text link with arrow */}
110
- {line2.done && (
58
+ {line1.done && (
111
59
  <motion.button
112
60
  initial={{ opacity: 0 }}
113
61
  animate={{ opacity: 1 }}