this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Mobile clouds: smaller zoom + optional Y-flip variety

Lower .cloud-layer zoom at 768px and 480px. Add flipY per cloud with
data-flip-y; parallax applies scale(sx,sy) on viewports ≤768px. Resize
listener refreshes transforms when crossing the breakpoint.

Made-with: Cursor

+22 -5
+2 -2
assets/styles.css
··· 104 104 /* Mobile: fewer clouds + smaller layer (zoom avoids fighting per-SVG parallax transforms) */ 105 105 @media (max-width: 768px) { 106 106 .cloud-layer { 107 - zoom: 0.66; 107 + zoom: 0.52; 108 108 } 109 109 110 110 .cloud-layer svg.cloud-svg--hide-sm { ··· 118 118 119 119 @media (max-width: 480px) { 120 120 .cloud-layer { 121 - zoom: 0.56; 121 + zoom: 0.42; 122 122 } 123 123 } 124 124
+10
components/GlassClouds.tsx
··· 11 11 fillOpacity?: number; 12 12 blurRadius?: number; 13 13 flipX?: boolean; 14 + /** When true, cloud is flipped on Y (applied on narrow viewports in scroll script) */ 15 + flipY?: boolean; 14 16 parallaxSpeed?: number; 15 17 /** Hide on narrow viewports — fewer clouds so the layer doesn’t feel crowded */ 16 18 hideOnMobile?: boolean; ··· 27 29 fillOpacity = 0.2, 28 30 blurRadius = 25, 29 31 flipX = false, 32 + flipY = false, 30 33 parallaxSpeed = -0.05, 31 34 hideOnMobile = false, 32 35 }: CloudProps) { ··· 40 43 class={`cloud-svg${hideOnMobile ? " cloud-svg--hide-sm" : ""}`} 41 44 data-speed={parallaxSpeed} 42 45 data-flip={flipX ? "1" : "0"} 46 + data-flip-y={flipY ? "1" : "0"} 43 47 width={width} 44 48 height={height} 45 49 viewBox={`0 0 ${vbW} ${vbH}`} ··· 135 139 fillOpacity: 0.18, 136 140 blurRadius: 25, 137 141 flipX: false, 142 + flipY: true, 138 143 parallaxSpeed: -0.04, 139 144 style: { position: "absolute", top: "3%", left: "-4%" }, 140 145 }, ··· 147 152 fillOpacity: 0.15, 148 153 blurRadius: 22, 149 154 flipX: true, 155 + flipY: true, 150 156 parallaxSpeed: -0.07, 151 157 hideOnMobile: true, 152 158 style: { position: "absolute", top: "12%", right: "-6%" }, ··· 160 166 fillOpacity: 0.14, 161 167 blurRadius: 28, 162 168 flipX: false, 169 + flipY: false, 163 170 parallaxSpeed: -0.02, 164 171 style: { position: "absolute", top: "36%", left: "5%" }, 165 172 }, ··· 172 179 fillOpacity: 0.2, 173 180 blurRadius: 20, 174 181 flipX: true, 182 + flipY: true, 175 183 parallaxSpeed: -0.1, 176 184 hideOnMobile: true, 177 185 style: { position: "absolute", top: "58%", right: "2%" }, ··· 185 193 fillOpacity: 0.16, 186 194 blurRadius: 24, 187 195 flipX: true, 196 + flipY: false, 188 197 parallaxSpeed: -0.05, 189 198 hideOnMobile: true, 190 199 style: { position: "absolute", top: "76%", left: "-2%" }, ··· 201 210 fillOpacity: 0.19, 202 211 blurRadius: 25, 203 212 flipX: false, 213 + flipY: true, 204 214 parallaxSpeed: -0.13, 205 215 style: { position: "absolute", top: "90%", right: "12%" }, 206 216 },
+10 -3
routes/_app.tsx
··· 85 85 var svgs=document.querySelectorAll('.cloud-svg'); 86 86 var cData=[]; 87 87 svgs.forEach(function(el){ 88 - cData.push({el:el,speed:parseFloat(el.dataset.speed)||0,flip:el.dataset.flip==='1'}); 88 + cData.push({el:el,speed:parseFloat(el.dataset.speed)||0,flip:el.dataset.flip==='1',flipY:el.dataset.flipY==='1'}); 89 89 }); 90 90 91 91 /* ---- Main scroll update ---- */ ··· 169 169 raysEl.style.opacity='0'; 170 170 } 171 171 172 - /* Cloud parallax — frozen at first-load position when static */ 172 + /* Cloud parallax — frozen at first-load position when static; Y-flip on mobile only */ 173 + var mobile=window.innerWidth<=768; 173 174 for(var i=0;i<cData.length;i++){ 174 175 var d=cData[i]; 175 176 var ty=skyAnimated()?scrollY*d.speed:0; 176 - d.el.style.transform='translate3d(0,'+ty+'px,0)'+(d.flip?' scaleX(-1)':''); 177 + var sx=d.flip?-1:1; 178 + var sy=mobile&&d.flipY?-1:1; 179 + var scaleStr=(sx!==1||sy!==1)?' scale('+sx+','+sy+')':''; 180 + d.el.style.transform='translate3d(0,'+ty+'px,0)'+scaleStr; 177 181 } 178 182 179 183 if(nav){ ··· 205 209 } 206 210 207 211 window.addEventListener('scroll',function(){ 212 + if(!ticking){ticking=true;requestAnimationFrame(update);} 213 + },{passive:true}); 214 + window.addEventListener('resize',function(){ 208 215 if(!ticking){ticking=true;requestAnimationFrame(update);} 209 216 },{passive:true}); 210 217 update();