1+ import { playSound } from './sounds.js' ;
2+
3+ export async function animateExplosion ( container ) {
4+ const containerRect = container . getBoundingClientRect ( ) ;
5+
6+ // Create explosion particles (yellow, smaller)
7+ for ( let i = 0 ; i < 50 ; i ++ ) {
8+ const particle = document . createElement ( 'div' ) ;
9+ particle . classList . add ( 'explosion-particle' ) ;
10+ particle . style . width = `${ Math . random ( ) * 10 + 5 } px` ;
11+ particle . style . height = particle . style . width ;
12+ particle . style . left = `${ containerRect . left + containerRect . width / 2 } px` ;
13+ particle . style . top = `${ containerRect . top + containerRect . height / 2 } px` ;
14+ const angle = Math . random ( ) * Math . PI * 2 ;
15+ const distance = Math . random ( ) * 200 + 50 ;
16+ particle . style . setProperty ( '--x' , `${ Math . cos ( angle ) * distance } px` ) ;
17+ particle . style . setProperty ( '--y' , `${ Math . sin ( angle ) * distance } px` ) ;
18+ document . body . appendChild ( particle ) ;
19+ particle . addEventListener ( 'animationend' , ( ) => particle . remove ( ) ) ;
20+ }
21+
22+ // Create huge smoke particles (grey, larger, slower fade)
23+ // This will be replaced by the new corner smoke system during the raccoon transition
24+ // For standard generate button explosion, keep a few smoke particles
25+ for ( let i = 0 ; i < 10 ; i ++ ) { // Reduced number for normal explosion
26+ const smokeParticle = document . createElement ( 'div' ) ;
27+ smokeParticle . classList . add ( 'smoke-particle' ) ;
28+ smokeParticle . style . width = `${ Math . random ( ) * 60 + 30 } px` ;
29+ smokeParticle . style . height = smokeParticle . style . width ;
30+ smokeParticle . style . left = `${ containerRect . left + containerRect . width / 2 } px` ;
31+ smokeParticle . style . top = `${ containerRect . top + containerRect . height / 2 } px` ;
32+ const angle = Math . random ( ) * Math . PI * 2 ;
33+ const distance = Math . random ( ) * 200 + 50 ;
34+ smokeParticle . style . setProperty ( '--x' , `${ Math . cos ( angle ) * distance } px` ) ;
35+ smokeParticle . style . setProperty ( '--y' , `${ Math . sin ( angle ) * distance } px` ) ;
36+ document . body . appendChild ( smokeParticle ) ;
37+ smokeParticle . addEventListener ( 'animationend' , ( ) => smokeParticle . remove ( ) ) ;
38+ }
39+
40+ // Shatter the container into pieces
41+ container . classList . add ( 'container-shattered' ) ;
42+ const numPieces = 10 ; // Number of pieces to break into
43+ for ( let i = 0 ; i < numPieces ; i ++ ) {
44+ const piece = document . createElement ( 'div' ) ;
45+ piece . classList . add ( 'container-piece' ) ;
46+ piece . style . width = `${ Math . random ( ) * 50 + 20 } px` ;
47+ piece . style . height = `${ Math . random ( ) * 50 + 20 } px` ;
48+ piece . style . left = `${ containerRect . left + containerRect . width / 2 } px` ;
49+ piece . style . top = `${ containerRect . top + containerRect . height / 2 } px` ;
50+
51+ const angle = Math . random ( ) * Math . PI * 2 ;
52+ const distance = Math . random ( ) * 300 + 100 ;
53+ piece . style . setProperty ( '--x' , `${ Math . cos ( angle ) * distance } px` ) ;
54+ piece . style . setProperty ( '--y' , `${ Math . sin ( angle ) * distance } px` ) ;
55+ piece . style . setProperty ( '--rotate' , `${ Math . random ( ) * 720 - 360 } deg` ) ; // Random rotation
56+ document . body . appendChild ( piece ) ;
57+ piece . addEventListener ( 'animationend' , ( ) => piece . remove ( ) ) ;
58+ }
59+
60+ return new Promise ( resolve => {
61+ // We resolve immediately as the container's visual disappearance is handled by CSS,
62+ // and its 'display: none' is managed in main.js after smoke starts.
63+ // The shattering animation runs in parallel.
64+ setTimeout ( ( ) => resolve ( ) , 500 ) ; // Allow some time for pieces to start moving
65+ } ) ;
66+ }
67+
68+ export function animatePageExplosion ( hugeSmoke = false ) {
69+ // Clear previous smoke-dragger elements, but not the new corner-smoke-cloud
70+ document . querySelectorAll ( '.smoke-dragger' ) . forEach ( el => el . remove ( ) ) ;
71+
72+ const body = document . body ;
73+ const numParticles = hugeSmoke ? 0 : 100 ; // No traditional explosion particles if hugeSmoke
74+ // const smokeCloudCount = hugeSmoke ? 20 : 0; // Number of drifting smoke clouds - handled by new corner smoke now
75+
76+ // Drifting smoke clouds (kept for other general smoke effects if needed)
77+ if ( ! hugeSmoke ) {
78+ for ( let i = 0 ; i < 20 ; i ++ ) {
79+ const smokeDragger = document . createElement ( 'div' ) ;
80+ smokeDragger . classList . add ( 'smoke-dragger' ) ;
81+
82+ // Random start position
83+ const startX = Math . random ( ) * window . innerWidth - window . innerWidth / 2 ;
84+ const startY = Math . random ( ) * window . innerHeight - window . innerHeight / 2 ;
85+ // Random end position
86+ const endX = Math . random ( ) * window . innerWidth * 2 - window . innerWidth ;
87+ const endY = Math . random ( ) * window . innerHeight * 2 - window . innerHeight ;
88+
89+ smokeDragger . style . setProperty ( '--startX' , `${ startX } px` ) ;
90+ smokeDragger . style . setProperty ( '--startY' , `${ startY } px` ) ;
91+ smokeDragger . style . setProperty ( '--endX' , `${ endX } px` ) ;
92+ smokeDragger . style . setProperty ( '--endY' , `${ endY } px` ) ;
93+ smokeDragger . style . animationDelay = `${ Math . random ( ) * 2 } s` ; // Stagger animation start
94+ smokeDragger . style . animationDuration = `${ 5 + Math . random ( ) * 3 } s` ; // Random duration, slightly shorter
95+ smokeDragger . style . width = `${ 100 + Math . random ( ) * 100 } px` ; // Random size
96+ smokeDragger . style . height = smokeDragger . style . width ;
97+
98+ body . appendChild ( smokeDragger ) ;
99+ smokeDragger . addEventListener ( 'animationend' , ( ) => smokeDragger . remove ( ) ) ;
100+ }
101+ }
102+
103+ // Traditional page explosion particles (only if not hugeSmoke mode)
104+ for ( let i = 0 ; i < numParticles ; i ++ ) {
105+ const particle = document . createElement ( 'div' ) ;
106+ particle . classList . add ( 'page-explosion-particle' ) ;
107+ particle . style . width = `${ Math . random ( ) * 30 + 10 } px` ;
108+ particle . style . height = particle . style . width ;
109+ particle . style . left = `${ Math . random ( ) * window . innerWidth } px` ;
110+ particle . style . top = `${ Math . random ( ) * window . innerHeight } px` ;
111+
112+ const angle = Math . random ( ) * Math . PI * 2 ;
113+ const distance = Math . random ( ) * 500 + 200 ;
114+ particle . style . setProperty ( '--x' , `${ Math . cos ( angle ) * distance } px` ) ;
115+ particle . style . setProperty ( '--y' , `${ Math . sin ( angle ) * distance } px` ) ;
116+ body . appendChild ( particle ) ;
117+ particle . addEventListener ( 'animationend' , ( ) => particle . remove ( ) ) ;
118+ }
119+ }
120+
121+ // These functions are no longer used for the "forever long" glitch/shake,
122+ // as classes are added directly. Kept for potential other uses.
123+ export function animatePageShake ( ) {
124+ return new Promise ( resolve => {
125+ document . body . classList . add ( 'shake' ) ;
126+ document . body . addEventListener ( 'animationend' , function handler ( ) {
127+ document . body . removeEventListener ( 'animationend' , handler ) ;
128+ document . body . classList . remove ( 'shake' ) ;
129+ resolve ( ) ;
130+ } , { once : true } ) ;
131+ } ) ;
132+ }
133+
134+ export function animatePageBreak ( ) {
135+ return new Promise ( resolve => {
136+ document . body . classList . add ( 'page-break' ) ;
137+ document . body . addEventListener ( 'animationend' , function handler ( ) {
138+ document . body . removeEventListener ( 'animationend' , handler ) ;
139+ document . body . classList . remove ( 'page-break' ) ;
140+ resolve ( ) ;
141+ } , { once : true } ) ;
142+ } ) ;
143+ }
144+
145+ export function animatePageGlitches ( duration = 1000 ) {
146+ document . body . classList . add ( 'glitch' ) ;
147+ return new Promise ( resolve => {
148+ setTimeout ( ( ) => {
149+ document . body . classList . remove ( 'glitch' ) ;
150+ resolve ( ) ;
151+ } , duration ) ;
152+ } ) ;
153+ }
154+
155+ export function createCenterSmoke ( overlayElement ) {
156+ const smokeClouds = [ ] ;
157+ const numClouds = 45 ; // Increased number of clouds
158+
159+ for ( let i = 0 ; i < numClouds ; i ++ ) {
160+ const smokeCloud = document . createElement ( 'div' ) ;
161+ smokeCloud . classList . add ( 'center-smoke-cloud' ) ;
162+
163+ // Position near the center initially
164+ smokeCloud . style . left = `calc(50% + ${ Math . random ( ) * 150 - 75 } px)` ; // Slightly wider initial spread
165+ smokeCloud . style . top = `calc(50% + ${ Math . random ( ) * 150 - 75 } px)` ;
166+
167+ // Random initial size (smaller than before to grow aggressively)
168+ const initialSize = 15 + Math . random ( ) * 25 ; // From 15 to 40px (slightly larger start)
169+ smokeCloud . style . width = `${ initialSize } px` ;
170+ smokeCloud . style . height = `${ initialSize } px` ;
171+
172+ const initialRotation = Math . random ( ) * 360 ;
173+ const finalRotation = initialRotation + ( Math . random ( ) > 0.5 ? 1 : - 1 ) * ( 360 + Math . random ( ) * 360 ) ; // Spin 1 to 2 times
174+
175+ // Randomized movement values - Increased for more movement
176+ const startMoveX = Math . random ( ) * 600 - 300 ; // Wider initial random movement
177+ const startMoveY = Math . random ( ) * 600 - 300 ;
178+ const endMoveX = Math . random ( ) * 2000 - 1000 ; // Even wider range for final drift
179+ const endMoveY = Math . random ( ) * 2000 - 1000 ;
180+
181+ // Random final scale, ensuring they grow large to block view significantly - Increased scale
182+ const finalScale = 20 + Math . random ( ) * 20 ; // Scale from 20x to 40x (larger final scale)
183+
184+ // Set CSS variables for animation
185+ smokeCloud . style . setProperty ( '--initial-rotation' , `${ initialRotation } deg` ) ;
186+ smokeCloud . style . setProperty ( '--final-rotation' , `${ finalRotation } deg` ) ;
187+ // The individual cloud animation should be longer than the total obscuring phase
188+ smokeCloud . style . setProperty ( '--animation-duration' , `${ 5 + Math . random ( ) * 3 } s` ) ; // 5-8 seconds duration
189+ smokeCloud . style . setProperty ( '--start-move-x' , `${ startMoveX } px` ) ;
190+ smokeCloud . style . setProperty ( '--start-move-y' , `${ startMoveY } px` ) ;
191+ smokeCloud . style . setProperty ( '--end-move-x' , `${ endMoveX } px` ) ;
192+ smokeCloud . style . setProperty ( '--end-move-y' , `${ endMoveY } px` ) ;
193+ smokeCloud . style . setProperty ( '--final-scale' , finalScale ) ; // Pass final scale
194+
195+ overlayElement . appendChild ( smokeCloud ) ;
196+ smokeClouds . push ( smokeCloud ) ;
197+ }
198+ return smokeClouds ;
199+ }
0 commit comments