/* Animate: each second, show the number with a fade from full
* opacity to transparent, then switch to the next number. */
- const animate = () => {
- const start = Date.now();
- const step = () => {
- this.setState(prev => {
- const r = { ...prev.revealing };
- const entry = r[tile.id];
- if (!entry) return { revealing: r };
-
- const elapsed = Date.now() - start;
-
- if (elapsed >= entry.seconds * 1000) {
- /* Countdown complete — reveal the letter. */
- delete r[tile.id];
- return { revealing: r };
- }
-
- const current_second = entry.seconds - Math.floor(elapsed / 1000);
- const frac = (elapsed % 1000) / 1000;
- r[tile.id] = { seconds: current_second, opacity: 1 - frac };
+ const total_ms = seconds * 1000;
+ const start = Date.now();
+ const step = () => {
+ this.setState(prev => {
+ const r = { ...prev.revealing };
+ const entry = r[tile.id];
+ if (!entry) return { revealing: r };
+
+ const elapsed = Date.now() - start;
+
+ if (elapsed >= total_ms) {
+ delete r[tile.id];
return { revealing: r };
- });
-
- if (this.state.revealing[tile.id]) {
- requestAnimationFrame(step);
}
- };
- requestAnimationFrame(step);
+
+ const current_second = seconds - Math.floor(elapsed / 1000);
+ const frac = (elapsed % 1000) / 1000;
+ r[tile.id] = { seconds: current_second, opacity: 1 - frac };
+ return { revealing: r };
+ });
+
+ if (this.state.revealing[tile.id]) {
+ requestAnimationFrame(step);
+ }
};
- animate();
+ requestAnimationFrame(step);
}
receive_bag_count(data) {
!claim_active && !is_revealing ? "grab" : "default"
};
- let letter, className = "";
+ let className = "";
if (is_revealing) {
- letter = rev.seconds;
className = "revealing";
- style.opacity = rev.opacity;
- } else {
- letter = tile.letter;
}
return (
? (e) => this.on_center_touch_start(e, tile) : null}
onClick={claim_active && !is_revealing
? () => this.take_letter(tile) : null}>
- {letter}
+ {is_revealing
+ ? <span style={{opacity: rev.opacity}}>{rev.seconds}</span>
+ : tile.letter}
</div>
);
})}