@@ -60,281 +60,7 @@ function getProjectHTML(projectName) {
6060// ============================================
6161// DICE ROLLING
6262// ============================================
63- function getDiceRollingHTML ( ) {
64- return `
65- <div class="project-content">
66- <h2>🎲 Dice Rolling</h2>
67- <div class="dice-container">
68- <div class="dice-display">
69- <div class="dice-scene">
70- <div class="dice-cube" id="dice1">
71- <div class="cube-face face-1"></div>
72- <div class="cube-face face-2"></div>
73- <div class="cube-face face-3"></div>
74- <div class="cube-face face-4"></div>
75- <div class="cube-face face-5"></div>
76- <div class="cube-face face-6"></div>
77- </div>
78- <div class="dice-shadow"></div>
79- </div>
80-
81- <div class="dice-scene">
82- <div class="dice-cube" id="dice2">
83- <div class="cube-face face-1"></div>
84- <div class="cube-face face-2"></div>
85- <div class="cube-face face-3"></div>
86- <div class="cube-face face-4"></div>
87- <div class="cube-face face-5"></div>
88- <div class="cube-face face-6"></div>
89- </div>
90- <div class="dice-shadow"></div>
91- </div>
92- </div>
93-
94- <div class="dice-total">
95- <span>Total: </span>
96- <span id="diceTotal">2</span>
97- </div>
98-
99- <button class="btn-roll" id="rollDice">🎲 Roll Dice</button>
100- </div>
101- </div>
102-
103- <style>
104- .dice-container {
105- text-align: center;
106- padding: 3rem 2rem;
107- }
108-
109- .dice-display {
110- display: flex;
111- gap: 2rem;
112- justify-content: center;
113- margin-bottom: 2rem;
114- flex-wrap: wrap;
115- }
116-
117- .dice-scene {
118- position: relative;
119- width: 120px;
120- height: 150px;
121- perspective: 700px;
122- transform-origin: center bottom;
123- }
124-
125- .dice-cube {
126- --rx: 0deg;
127- --ry: 0deg;
128- width: 120px;
129- height: 120px;
130- position: relative;
131- transform-style: preserve-3d;
132- transform: rotateX(var(--rx)) rotateY(var(--ry));
133- transition: transform 1.3s cubic-bezier(0.2, 0.75, 0.15, 1), filter 0.3s ease;
134- }
135-
136- .dice-shadow {
137- position: absolute;
138- left: 50%;
139- bottom: 6px;
140- width: 78px;
141- height: 14px;
142- transform: translateX(-50%);
143- border-radius: 50%;
144- background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.35) 0%, rgba(0, 0, 0, 0.05) 70%, transparent 100%);
145- transition: opacity 0.3s ease;
146- }
147-
148- .dice-scene.rolling .dice-shadow {
149- animation: diceShadowFloat 1.3s ease;
150- }
151-
152- .dice-scene.impact {
153- animation: diceLanding 0.4s ease-out;
154- }
155-
156- .dice-scene.impact .dice-shadow {
157- animation: diceShadowImpact 0.4s ease-out;
158- }
159-
160- .cube-face {
161- --size: 120px;
162- --dot: 14px;
163- position: absolute;
164- width: var(--size);
165- height: var(--size);
166- border-radius: 18px;
167- background: linear-gradient(160deg, #ffffff, #e6ebf2);
168- border: 2px solid #d8dee8;
169- box-shadow: inset -8px -8px 12px rgba(0, 0, 0, 0.08), inset 8px 8px 12px rgba(255, 255, 255, 0.85);
170- }
171-
172- .cube-face::before {
173- content: '';
174- position: absolute;
175- inset: 0;
176- border-radius: 18px;
177- background-repeat: no-repeat;
178- }
179-
180- .face-1 { transform: translateZ(60px); }
181- .face-2 { transform: rotateY(90deg) translateZ(60px); }
182- .face-3 { transform: rotateY(180deg) translateZ(60px); }
183- .face-4 { transform: rotateY(-90deg) translateZ(60px); }
184- .face-5 { transform: rotateX(90deg) translateZ(60px); }
185- .face-6 { transform: rotateX(-90deg) translateZ(60px); }
186-
187- .face-1::before {
188- background-image: radial-gradient(circle at 50% 50%, #111 0 var(--dot), transparent calc(var(--dot) + 1px));
189- }
190-
191- .face-2::before {
192- background-image:
193- radial-gradient(circle at 28% 28%, #111 0 var(--dot), transparent calc(var(--dot) + 1px)),
194- radial-gradient(circle at 72% 72%, #111 0 var(--dot), transparent calc(var(--dot) + 1px));
195- }
196-
197- .face-3::before {
198- background-image:
199- radial-gradient(circle at 28% 28%, #111 0 var(--dot), transparent calc(var(--dot) + 1px)),
200- radial-gradient(circle at 50% 50%, #111 0 var(--dot), transparent calc(var(--dot) + 1px)),
201- radial-gradient(circle at 72% 72%, #111 0 var(--dot), transparent calc(var(--dot) + 1px));
202- }
203-
204- .face-4::before {
205- background-image:
206- radial-gradient(circle at 28% 28%, #111 0 var(--dot), transparent calc(var(--dot) + 1px)),
207- radial-gradient(circle at 72% 28%, #111 0 var(--dot), transparent calc(var(--dot) + 1px)),
208- radial-gradient(circle at 28% 72%, #111 0 var(--dot), transparent calc(var(--dot) + 1px)),
209- radial-gradient(circle at 72% 72%, #111 0 var(--dot), transparent calc(var(--dot) + 1px));
210- }
211-
212- .face-5::before {
213- background-image:
214- radial-gradient(circle at 28% 28%, #111 0 var(--dot), transparent calc(var(--dot) + 1px)),
215- radial-gradient(circle at 72% 28%, #111 0 var(--dot), transparent calc(var(--dot) + 1px)),
216- radial-gradient(circle at 50% 50%, #111 0 var(--dot), transparent calc(var(--dot) + 1px)),
217- radial-gradient(circle at 28% 72%, #111 0 var(--dot), transparent calc(var(--dot) + 1px)),
218- radial-gradient(circle at 72% 72%, #111 0 var(--dot), transparent calc(var(--dot) + 1px));
219- }
220-
221- .face-6::before {
222- background-image:
223- radial-gradient(circle at 28% 24%, #111 0 var(--dot), transparent calc(var(--dot) + 1px)),
224- radial-gradient(circle at 72% 24%, #111 0 var(--dot), transparent calc(var(--dot) + 1px)),
225- radial-gradient(circle at 28% 50%, #111 0 var(--dot), transparent calc(var(--dot) + 1px)),
226- radial-gradient(circle at 72% 50%, #111 0 var(--dot), transparent calc(var(--dot) + 1px)),
227- radial-gradient(circle at 28% 76%, #111 0 var(--dot), transparent calc(var(--dot) + 1px)),
228- radial-gradient(circle at 72% 76%, #111 0 var(--dot), transparent calc(var(--dot) + 1px));
229- }
230-
231- .dice-total {
232- font-size: 2rem;
233- margin: 2rem 0;
234- font-weight: bold;
235- }
236-
237- .btn-roll {
238- background: linear-gradient(135deg, #ff6b6b, #ee5a6f);
239- color: white;
240- border: none;
241- padding: 1rem 3rem;
242- border-radius: 50px;
243- font-size: 1.3rem;
244- cursor: pointer;
245- transition: var(--transition);
246- }
247-
248- .btn-roll:hover {
249- transform: scale(1.05);
250- box-shadow: 0 5px 20px rgba(255, 107, 107, 0.4);
251- }
252-
253- @keyframes diceLanding {
254- 0% { transform: translateY(-10px); }
255- 55% { transform: translateY(4px); }
256- 80% { transform: translateY(-2px); }
257- 100% { transform: translateY(0); }
258- }
259-
260- @keyframes diceShadowFloat {
261- 0%, 100% { transform: translateX(-50%) scale(1); opacity: 0.32; }
262- 45% { transform: translateX(-50%) scale(0.72); opacity: 0.2; }
263- }
264-
265- @keyframes diceShadowImpact {
266- 0% { transform: translateX(-50%) scale(0.74); opacity: 0.2; }
267- 55% { transform: translateX(-50%) scale(1.08); opacity: 0.38; }
268- 100% { transform: translateX(-50%) scale(1); opacity: 0.32; }
269- }
270- </style>
271- ` ;
272- }
273-
274- function initDiceRolling ( ) {
275- const dice1 = document . getElementById ( 'dice1' ) ;
276- const dice2 = document . getElementById ( 'dice2' ) ;
277- const diceScene1 = dice1 . closest ( '.dice-scene' ) ;
278- const diceScene2 = dice2 . closest ( '.dice-scene' ) ;
279- const rollBtn = document . getElementById ( 'rollDice' ) ;
280- const totalDisplay = document . getElementById ( 'diceTotal' ) ;
281-
282- const faceRotation = {
283- 1 : { x : 0 , y : 0 } ,
284- 2 : { x : 0 , y : - 90 } ,
285- 3 : { x : 0 , y : 180 } ,
286- 4 : { x : 0 , y : 90 } ,
287- 5 : { x : - 90 , y : 0 } ,
288- 6 : { x : 90 , y : 0 }
289- } ;
290-
291- let spins1 = 0 ;
292- let spins2 = 0 ;
293-
294- function setCubeFace ( cube , value , spinSeed ) {
295- const target = faceRotation [ value ] ;
296- const rx = target . x + 360 * ( 2 + ( spinSeed % 3 ) ) ;
297- const ry = target . y + 360 * ( 3 + ( spinSeed % 2 ) ) ;
298- cube . style . setProperty ( '--rx' , `${ rx } deg` ) ;
299- cube . style . setProperty ( '--ry' , `${ ry } deg` ) ;
300- }
301-
302- function triggerLanding ( scene ) {
303- scene . classList . remove ( 'impact' ) ;
304- void scene . offsetWidth ;
305- scene . classList . add ( 'impact' ) ;
306- setTimeout ( ( ) => {
307- scene . classList . remove ( 'impact' ) ;
308- } , 420 ) ;
309- }
310-
311- setCubeFace ( dice1 , 1 , 0 ) ;
312- setCubeFace ( dice2 , 1 , 1 ) ;
313- totalDisplay . textContent = '2' ;
314-
315- rollBtn . addEventListener ( 'click' , ( ) => {
316- rollBtn . disabled = true ;
317- diceScene1 . classList . add ( 'rolling' ) ;
318- diceScene2 . classList . add ( 'rolling' ) ;
319-
320- const value1 = Math . floor ( Math . random ( ) * 6 ) + 1 ;
321- const value2 = Math . floor ( Math . random ( ) * 6 ) + 1 ;
322- spins1 += 1 ;
323- spins2 += 1 ;
324-
325- setCubeFace ( dice1 , value1 , spins1 ) ;
326- setCubeFace ( dice2 , value2 , spins2 ) ;
327-
328- setTimeout ( ( ) => {
329- diceScene1 . classList . remove ( 'rolling' ) ;
330- diceScene2 . classList . remove ( 'rolling' ) ;
331- triggerLanding ( diceScene1 ) ;
332- triggerLanding ( diceScene2 ) ;
333- totalDisplay . textContent = value1 + value2 ;
334- rollBtn . disabled = false ;
335- } , 1300 ) ;
336- } ) ;
337- }
63+ // Moved to js/projects/dice-rolling.js
33864
33965// ============================================
34066// COIN FLIP
0 commit comments