@@ -90,7 +90,10 @@ function ShaderToyLite(canvasId) {
9090
9191 // uniforms
9292 var iFrame = 0 ;
93+ // iMouse state: xy = current position (only updates when button down)
94+ // zw = click start position (positive when down, negative when released)
9395 var iMouse = { x : 0 , y : 0 , clickX : 0 , clickY : 0 } ;
96+ var isMouseDown = false ;
9497
9598 // shader common source
9699 var common = "" ;
@@ -145,19 +148,75 @@ function ShaderToyLite(canvasId) {
145148 gl . viewport ( 0 , 0 , gl . canvas . width , gl . canvas . height ) ;
146149 } ) ;
147150
151+ // Mouse event handlers - match official Shadertoy iMouse behavior:
152+ // iMouse.xy: current position (only updates when button is down)
153+ // iMouse.zw: click position (positive when down, negated when released)
148154 canvas . addEventListener ( "mousemove" , ( event ) => {
149- iMouse . x = event . offsetX ;
150- iMouse . y = canvas . height - event . offsetY ;
155+ if ( isMouseDown ) {
156+ iMouse . x = event . offsetX ;
157+ iMouse . y = canvas . height - event . offsetY ;
158+ }
151159 } ) ;
152160
153161 canvas . addEventListener ( "mousedown" , ( event ) => {
154- iMouse . clickX = event . offsetX ;
155- iMouse . clickY = canvas . height - event . offsetY ;
162+ isMouseDown = true ;
163+ var x = event . offsetX ;
164+ var y = canvas . height - event . offsetY ;
165+ iMouse . x = x ;
166+ iMouse . y = y ;
167+ iMouse . clickX = x ;
168+ iMouse . clickY = y ;
156169 } ) ;
157170
158171 canvas . addEventListener ( "mouseup" , ( ) => {
159- iMouse . clickX = 0 ;
160- iMouse . clickY = 0 ;
172+ isMouseDown = false ;
173+ // Negate click position to indicate button released (Shadertoy convention)
174+ iMouse . clickX = - Math . abs ( iMouse . clickX ) ;
175+ iMouse . clickY = - Math . abs ( iMouse . clickY ) ;
176+ } ) ;
177+
178+ // Prevent context menu on right-click to avoid interrupting interaction
179+ canvas . addEventListener ( "contextmenu" , ( event ) => {
180+ event . preventDefault ( ) ;
181+ } ) ;
182+
183+ // Touch support for mobile devices
184+ canvas . addEventListener ( "touchstart" , ( event ) => {
185+ event . preventDefault ( ) ;
186+ if ( event . touches . length > 0 ) {
187+ var touch = event . touches [ 0 ] ;
188+ var rect = canvas . getBoundingClientRect ( ) ;
189+ var x = touch . clientX - rect . left ;
190+ var y = canvas . height - ( touch . clientY - rect . top ) ;
191+ isMouseDown = true ;
192+ iMouse . x = x ;
193+ iMouse . y = y ;
194+ iMouse . clickX = x ;
195+ iMouse . clickY = y ;
196+ }
197+ } , { passive : false } ) ;
198+
199+ canvas . addEventListener ( "touchmove" , ( event ) => {
200+ event . preventDefault ( ) ;
201+ if ( isMouseDown && event . touches . length > 0 ) {
202+ var touch = event . touches [ 0 ] ;
203+ var rect = canvas . getBoundingClientRect ( ) ;
204+ iMouse . x = touch . clientX - rect . left ;
205+ iMouse . y = canvas . height - ( touch . clientY - rect . top ) ;
206+ }
207+ } , { passive : false } ) ;
208+
209+ canvas . addEventListener ( "touchend" , ( event ) => {
210+ event . preventDefault ( ) ;
211+ isMouseDown = false ;
212+ iMouse . clickX = - Math . abs ( iMouse . clickX ) ;
213+ iMouse . clickY = - Math . abs ( iMouse . clickY ) ;
214+ } , { passive : false } ) ;
215+
216+ canvas . addEventListener ( "touchcancel" , ( ) => {
217+ isMouseDown = false ;
218+ iMouse . clickX = - Math . abs ( iMouse . clickX ) ;
219+ iMouse . clickY = - Math . abs ( iMouse . clickY ) ;
161220 } ) ;
162221 }
163222
0 commit comments