F045 — Deal Animation
| Field | Value |
|---|---|
| ID | F045 |
| Phase | 3 — UI |
| Jira | HEDGE-173 |
| Status | TS ❌ · JS ⬜ · UMA ✅ |
Business Rule
When a deal is triggered (HOLE stage), each hole card flies out from the card shuffler sprite in the top-right corner of the game canvas and travels to its assigned position within the relevant hand panel. Cards are launched in sequence with staggered delays so each one is visually distinct. The animation gives the player a clear sense of cards being physically dealt from a shoe. Community cards are not dealt with this animation — they appear via a flip reveal in place.Technical Design
Card Shuffler (Shoe) Sprite
The card shuffler is a three-layer composite:| Layer | Atlas frame | Position (landscape) |
|---|---|---|
| Shoe body | dealer_shoe_body.png | (1181, 49) |
| Shoe glass | dealer_shoe_glass.png | (1181, 49) |
| Card in shoe | back.png (card back) | (1118, 79) |
(1118, 79) with:
angle: -59°skewY: -0.3scale: (0.58, 0.6)
Animation Sequence
Each hole card goes through two phases:Phase 1 — Quick Launch from Shoe (~100 ms)
The card group snaps from the shoe position toward a mid-air launch point near(1090, 150) while the angle sweeps from -59° → -40°. This phase is linear and brief, simulating the card being pushed out.
Phase 2 — Main Flight to Target (~300–500 ms, path-dependent)
Five parallel tweens run simultaneously:| Tween | Property | Easing |
|---|---|---|
| Shadow | shadowX, shadowY, skewY → 0 | Sinusoidal.Out |
| Card skew | skewY → 0 | Sinusoidal.Out |
| Position + angle | x, y, angle → target | Sinusoidal.Out |
| Scale | scaleX, scaleY → target | Sinusoidal.Out |
| Group reset | container x, y, angle → 0 | Sinusoidal.Out |
PLAY_SPEED = 1).
Stagger Delays
Cards are launched in order with a stagger interval based on their index:CARD_FLY_STEP = 300 ms — interval between successive card launches.
Timing Constants
| Constant | Value | Purpose |
|---|---|---|
CARD_FLY_STEP | 300 ms | Delay between successive card launches |
CARD_FLIP_TIME | 150 ms | Half-duration of flip reveal (community cards) |
CARD_SHOW_WIN_TIME | 350 ms | Win highlight animation duration |
PLAY_SPEED | 0.5 (fast) / 1 (normal) | Global speed multiplier |
V6 Implementation Notes
V6 should replicate this using Phaser 3’sthis.tweens.add(). Key differences from v5 (Phaser 2):
- Use
this.tweens.add({ targets, x, y, angle, duration, ease: 'Sine.easeOut' })instead ofgame.add.tween - Phaser 3 has no native
skewY— omit skew or approximate withscaleXoscillation - Use
this.time.addEvent({ delay, callback })for the stagger scheduling - The shoe sprite should already exist in the v6 atlas (
desktop_glass_uiormain_game_desktop) — confirm frame name before implementing - Launch sequence: start from shoe card position
(1118, 79)withangle: -59, tween to mid-air waypoint(1090, 150)at-40°, then continue to final hand-panel target
V6 Canvas Coordinates
The v6 canvas is 1280 × 720 (landscape). The v5 canvas was the same resolution for desktop. Shoe position(1181, 49) transfers directly.
Mathematics
Dynamic flight duration:(cx, cy) is the hand container origin and (tx, ty) is the card’s local position within the container.
For a card in hand 1 at approximately (200, 400):
Acceptance Criteria
| ID | Criterion | Playwright assertion |
|---|---|---|
| AC-F045-01 | On HOLE stage, each hole card starts at the shoe position (~1118, 79) before animating | expect(cardSprite.x).toBeCloseTo(1118, 0) at frame 0 |
| AC-F045-02 | Each hole card reaches its final target position within 800 ms of its launch | Assert card position equals target within timeout |
| AC-F045-03 | Cards are launched sequentially with ≥ 250 ms stagger between each | Measure launch timestamps per card |
| AC-F045-04 | Card angle transitions from −59° at shoe to ≈ 0° (or hand target angle) at destination | expect(cardSprite.angle).toBeCloseTo(0, 5) after animation |
| AC-F045-05 | Community cards do not use the fly animation — they flip in place | Assert community card x/y does not change during reveal |
| AC-F045-06 | Animation completes correctly at both PLAY_SPEED = 1 (normal) and PLAY_SPEED = 0.5 (fast) | Run game in both speed modes and assert final positions |
Version Parity
| Version | Status | Notes |
|---|---|---|
| JS (v4) | ⬜ Not yet audited | Likely implemented — same Phaser 2 codebase as v5 |
| TypeScript (v6) | ❌ Not implemented | Cards placed statically; no fly animation |
| UMA (v5) | ✅ Implemented | Full two-phase fly with 5 parallel tweens, stagger delays |
V5 Source References
| File | Lines | Purpose |
|---|---|---|
source/client_source/src/js/Game/gameTypes/cardDesktop.js | 42–127 | throwCard() + _launchCard() — desktop deal animation |
source/client_source/src/js/Game/gameTypes/cardDevice.js | 72–135 | Mobile variant (faster fly speed: path/4) |
source/client_source/src/js/Game/gameView.js | 349–365 | Shoe/shuffler sprite setup and coordinates |
source/client_source/src/js/Game/gameView.js | 51–54 | Animation timing constants |