@@ -12,6 +12,9 @@ import {
1212} from "ogl" ;
1313import { useEffect , useRef } from "react" ;
1414
15+ const DESKTOP_HEIGHT = 240 ;
16+ const MOBILE_HEIGHT = 340 ;
17+
1518export const HeroASCII = ( ) => {
1619 const containerRef = useRef < HTMLDivElement > ( null ) ;
1720 useEffect ( ( ) => {
@@ -89,12 +92,17 @@ void main() {
8992 const camera = new Camera ( gl , { near : 0.1 , far : 100 } ) ;
9093 camera . position . set ( 2.2 , 2.2 , 2.2 ) ;
9194 camera . lookAt ( new Vec3 ( 0 , 0 , 0 ) ) ;
92- renderer . setSize ( window . innerWidth , window . innerHeight - 240 ) ;
93- const resize = ( ) => {
95+
96+ const isMobile = ( ) => window . innerWidth < 768 ; // Common breakpoint for mobile
97+
98+ const updateSize = ( ) => {
99+ const height = isMobile ( ) ? MOBILE_HEIGHT : DESKTOP_HEIGHT ;
100+ renderer . setSize ( window . innerWidth , window . innerHeight - height ) ;
94101 camera . perspective ( { aspect : gl . canvas . width / gl . canvas . height } ) ;
95102 } ;
96- window . addEventListener ( "resize" , resize ) ;
97- resize ( ) ;
103+
104+ window . addEventListener ( "resize" , updateSize ) ;
105+ updateSize ( ) ;
98106 const boxProgram = new Program ( gl , {
99107 vertex : vertex ,
100108 fragment : fragment ,
@@ -128,13 +136,15 @@ void main() {
128136 const MAX_TILT = 0.2 ;
129137 const LERP_FACTOR = 0.05 ;
130138
131- // Add hover animation
139+ // Add hover and touch animation
132140 let targetRotationX = 0 ;
133141 let targetRotationY = 0 ;
134142 let targetRotationZ = 0 ;
135143 let currentRotationX = 0 ;
136144 let currentRotationY = 0 ;
137145 let currentRotationZ = 0 ;
146+ let isDragging = false ;
147+ let lastTouchX = 0 ;
138148
139149 function onMouseMove ( e : MouseEvent ) {
140150 const x = ( e . clientX / window . innerWidth ) * 2 - 1 ;
@@ -145,7 +155,41 @@ void main() {
145155 targetRotationZ = - y * MAX_TILT ;
146156 }
147157
158+ function onTouchStart ( e : TouchEvent ) {
159+ isDragging = true ;
160+ lastTouchX = e . touches [ 0 ] . clientX ;
161+ // Prevent default touch behavior
162+ e . preventDefault ( ) ;
163+ }
164+
165+ function onTouchMove ( e : TouchEvent ) {
166+ if ( ! isDragging ) return ;
167+
168+ // Prevent default touch behavior
169+ e . preventDefault ( ) ;
170+
171+ const touchX = e . touches [ 0 ] . clientX ;
172+
173+ const deltaX = ( touchX - lastTouchX ) / window . innerWidth ;
174+
175+ // Only update Y rotation (left/right movement)
176+ targetRotationY += deltaX * MAX_TILT * 2 ;
177+ targetRotationY = Math . max (
178+ - MAX_TILT ,
179+ Math . min ( MAX_TILT , targetRotationY )
180+ ) ;
181+
182+ lastTouchX = touchX ;
183+ }
184+
185+ function onTouchEnd ( ) {
186+ isDragging = false ;
187+ }
188+
148189 window . addEventListener ( "mousemove" , onMouseMove ) ;
190+ window . addEventListener ( "touchstart" , onTouchStart , { passive : false } ) ;
191+ window . addEventListener ( "touchmove" , onTouchMove , { passive : false } ) ;
192+ window . addEventListener ( "touchend" , onTouchEnd ) ;
149193
150194 function update ( time : number ) {
151195 const elapsedTime = time * 0.001 ;
@@ -176,8 +220,11 @@ void main() {
176220 }
177221 animationId = requestAnimationFrame ( animate ) ;
178222 return ( ) => {
179- window . removeEventListener ( "resize" , resize ) ;
223+ window . removeEventListener ( "resize" , updateSize ) ;
180224 window . removeEventListener ( "mousemove" , onMouseMove ) ;
225+ window . removeEventListener ( "touchstart" , onTouchStart ) ;
226+ window . removeEventListener ( "touchmove" , onTouchMove ) ;
227+ window . removeEventListener ( "touchend" , onTouchEnd ) ;
181228 cancelAnimationFrame ( animationId ) ;
182229 renderer . gl . getExtension ( "WEBGL_lose_context" ) ?. loseContext ( ) ;
183230 if ( container ?. contains ( gl . canvas ) ) {
0 commit comments