1212</ head >
1313< body >
1414
15- <!-- top navbar -->
1615 < header class ="header ">
1716 < div class ="logo "> ASTRO< span class ="dot "> .</ span > </ div >
1817
3029 </ div >
3130 </ header >
3231
33- <!-- main product section - 3 columns -->
3432 < div class ="product-section ">
3533
36- <!-- left column - product details -->
3734 < div class ="left-panel ">
3835 < p class ="new-label "> NEW</ p >
3936 < h1 class ="product-title ">
@@ -72,25 +69,19 @@ <h1 class="product-title">
7269 < hr class ="divider ">
7370 </ div >
7471
75- <!-- center column - jacket image with 360 viewer -->
7672 < div class ="center-panel ">
7773
78- <!-- 360 degree viewer -->
7974 < div class ="viewer-360-wrap ">
8075
81- <!-- 360 badge top right -->
8276 < div class ="badge-360 ">
8377 < i class ="fa-solid fa-rotate "> </ i > 360°
8478 </ div >
8579
86- <!-- drag hint shown on first load -->
8780 < div class ="drag-hint " id ="dragHint ">
8881 < i class ="fa-solid fa-hand-pointer "> </ i > Drag to rotate
8982 </ div >
9083
91- <!-- perspective wrapper gives 3D depth -->
9284 < div class ="viewer-perspective-wrap ">
93- <!-- this whole stack physically tilts in 3D as you drag -->
9485 < div class ="viewer-frame-stack " id ="viewerStack ">
9586 < img src ="assets/image.webp " class ="jacket-frame " id ="frame0 " alt ="Front ">
9687 < img src ="assets/jacketRight.png " class ="jacket-frame " id ="frame1 " alt ="Right ">
@@ -99,7 +90,6 @@ <h1 class="product-title">
9990 </ div >
10091 </ div >
10192
102- <!-- controls row -->
10393 < div class ="viewer-controls ">
10494 < button class ="ctrl-btn " id ="spinBtn " title ="Auto spin ">
10595 < i class ="fa-solid fa-play " id ="spinIcon "> </ i >
@@ -117,7 +107,6 @@ <h1 class="product-title">
117107
118108 </ div >
119109
120- <!-- 3 feature badges below jacket image -->
121110 < div class ="badges-row ">
122111 < div class ="badge-item ">
123112 < i class ="fa-solid fa-snowflake "> </ i >
@@ -134,7 +123,6 @@ <h1 class="product-title">
134123 </ div >
135124 </ div >
136125
137- <!-- right column - size, color, buttons -->
138126 < div class ="right-panel ">
139127
140128 < p class ="panel-heading "> SIZE</ p >
@@ -150,7 +138,6 @@ <h1 class="product-title">
150138
151139 < p class ="panel-heading "> COLOR</ p >
152140
153- <!-- 2x2 color grid -->
154141 < div class ="color-grid ">
155142 < div class ="color-option selected ">
156143 < img src ="assets/design.webp " alt ="Beige Jacket ">
@@ -182,7 +169,6 @@ <h1 class="product-title">
182169
183170 </ div >
184171
185- <!-- 4-card features strip -->
186172 < div class ="features-strip ">
187173
188174 < div class ="feat-card ">
@@ -219,7 +205,6 @@ <h3>UTILITY<br>POCKETS</h3>
219205
220206 </ div >
221207
222- <!-- bottom info bar -->
223208 < div class ="info-bar ">
224209
225210 < div class ="info-item ">
@@ -264,67 +249,54 @@ <h3>UTILITY<br>POCKETS</h3>
264249 var dragHint = document . getElementById ( 'dragHint' ) ;
265250
266251 var frames = [
267- document . getElementById ( 'frame0' ) , // 0° front
268- document . getElementById ( 'frame1' ) , // 90° right
269- document . getElementById ( 'frame2' ) , // 180° back
270- document . getElementById ( 'frame3' ) // 270° left
252+ document . getElementById ( 'frame0' ) ,
253+ document . getElementById ( 'frame1' ) ,
254+ document . getElementById ( 'frame2' ) ,
255+ document . getElementById ( 'frame3' )
271256 ] ;
272257
273- var totalAngle = 0 ; // cumulative drag angle (can go beyond 360)
274- var activeFrame = 0 ; // which photo is currently shown
258+ var totalAngle = 0 ;
259+ var activeFrame = 0 ;
275260 var isDragging = false ;
276261 var startX = 0 ;
277262 var lastX = 0 ;
278- var dragAngle = 0 ; // angle at drag start
263+ var dragAngle = 0 ;
279264 var velocity = 0 ;
280265 var spinRAF = null ;
281266 var momentumRAF = null ;
282267 var isSpinning = false ;
283268
284- // show a specific frame instantly (no fade)
285269 function showFrame ( index ) {
286270 if ( index === activeFrame ) return ;
287271 frames [ activeFrame ] . style . opacity = '0' ;
288272 frames [ index ] . style . opacity = '1' ;
289273 activeFrame = index ;
290274 }
291275
292- // core update - called every frame
293- // totalAngle drives everything:
294- // which photo to show + how much to physically tilt the stack
295276 function update ( angle ) {
296277 totalAngle = angle ;
297278
298- var normalized = ( ( angle % 360 ) + 360 ) % 360 ; // 0 - 360
299- var frameFloat = normalized / 90 ; // 0.0 - 4.0
279+ var normalized = ( ( angle % 360 ) + 360 ) % 360 ;
280+ var frameFloat = normalized / 90 ;
300281 var frameIndex = Math . floor ( frameFloat ) % 4 ;
301- var progress = frameFloat - Math . floor ( frameFloat ) ; // 0 - 1 within current frame
282+ var progress = frameFloat - Math . floor ( frameFloat ) ;
302283
303- // swap to the correct photo instantly
304284 showFrame ( frameIndex ) ;
305285
306- // map progress (0→1) to a tilt angle (-45° → +45°)
307- // so at the start of a frame you see it from -45°
308- // at midpoint (0.5) you see it straight on (0°)
309- // at end of frame you see it from +45° before swapping
310286 var tiltY = ( progress - 0.5 ) * 90 ;
311287
312- // apply 3D tilt to the whole stack
313288 stack . style . transform = 'rotateY(' + tiltY + 'deg)' ;
314289
315- // add slight brightness darkening at extreme tilt angles (more realistic)
316290 var brightness = 1 - ( Math . abs ( tiltY ) / 90 ) * 0.18 ;
317291 stack . style . filter = 'brightness(' + brightness + ')' ;
318292
319- // update the 4 position dots
320293 var dotIndex = Math . round ( normalized / 90 ) % 4 ;
321294 for ( var i = 0 ; i < 4 ; i ++ ) {
322295 document . getElementById ( 'dot' + i ) . classList . remove ( 'active' ) ;
323296 }
324297 document . getElementById ( 'dot' + dotIndex ) . classList . add ( 'active' ) ;
325298 }
326299
327- // momentum - keeps spinning after drag release, decelerates naturally
328300 function applyMomentum ( ) {
329301 velocity *= 0.93 ;
330302 if ( Math . abs ( velocity ) < 0.05 ) {
@@ -336,7 +308,6 @@ <h3>UTILITY<br>POCKETS</h3>
336308 momentumRAF = requestAnimationFrame ( applyMomentum ) ;
337309 }
338310
339- // auto spin using rAF
340311 function startSpin ( ) {
341312 isSpinning = true ;
342313 spinIcon . className = 'fa-solid fa-pause' ;
@@ -369,7 +340,6 @@ <h3>UTILITY<br>POCKETS</h3>
369340 update ( 0 ) ;
370341 } ) ;
371342
372- // --- MOUSE ---
373343 stack . addEventListener ( 'mousedown' , function ( e ) {
374344 isDragging = true ;
375345 startX = e . clientX ;
@@ -395,7 +365,6 @@ <h3>UTILITY<br>POCKETS</h3>
395365 applyMomentum ( ) ;
396366 } ) ;
397367
398- // --- TOUCH ---
399368 stack . addEventListener ( 'touchstart' , function ( e ) {
400369 startX = e . touches [ 0 ] . clientX ;
401370 lastX = e . touches [ 0 ] . clientX ;
@@ -417,7 +386,6 @@ <h3>UTILITY<br>POCKETS</h3>
417386 applyMomentum ( ) ;
418387 } ) ;
419388
420- // boot: show front, auto-spin for 2 full rotations then stop
421389 update ( 0 ) ;
422390 startSpin ( ) ;
423391 setTimeout ( function ( ) {
0 commit comments