@@ -121,12 +121,8 @@ export default function LiquidEther({
121121 this . diff = new THREE . Vector2 ( ) ;
122122 this . timer = null ;
123123 this . container = null ;
124- this . _onMouseMove = this . onDocumentMouseMove . bind ( this ) ;
125- this . _onTouchStart = this . onDocumentTouchStart . bind ( this ) ;
126- this . _onTouchMove = this . onDocumentTouchMove . bind ( this ) ;
127- this . _onMouseEnter = this . onMouseEnter . bind ( this ) ;
128- this . _onMouseLeave = this . onMouseLeave . bind ( this ) ;
129- this . _onTouchEnd = this . onTouchEnd . bind ( this ) ;
124+ this . docTarget = null ;
125+ this . listenerTarget = null ;
130126 this . isHoverInside = false ;
131127 this . hasUserControl = false ;
132128 this . isAutoActive = false ;
@@ -137,34 +133,61 @@ export default function LiquidEther({
137133 this . takeoverFrom = new THREE . Vector2 ( ) ;
138134 this . takeoverTo = new THREE . Vector2 ( ) ;
139135 this . onInteract = null ;
136+ this . _onMouseMove = this . onDocumentMouseMove . bind ( this ) ;
137+ this . _onTouchStart = this . onDocumentTouchStart . bind ( this ) ;
138+ this . _onTouchMove = this . onDocumentTouchMove . bind ( this ) ;
139+ this . _onTouchEnd = this . onTouchEnd . bind ( this ) ;
140+ this . _onDocumentLeave = this . onDocumentLeave . bind ( this ) ;
140141 }
141142 init ( container ) {
142143 this . container = container ;
143- container . addEventListener ( 'mousemove' , this . _onMouseMove , false ) ;
144- container . addEventListener ( 'touchstart' , this . _onTouchStart , false ) ;
145- container . addEventListener ( 'touchmove' , this . _onTouchMove , false ) ;
146- container . addEventListener ( 'mouseenter' , this . _onMouseEnter , false ) ;
147- container . addEventListener ( 'mouseleave' , this . _onMouseLeave , false ) ;
148- container . addEventListener ( 'touchend' , this . _onTouchEnd , false ) ;
144+ this . docTarget = container . ownerDocument || null ;
145+ const defaultView =
146+ ( this . docTarget && this . docTarget . defaultView ) || ( typeof window !== 'undefined' ? window : null ) ;
147+ if ( ! defaultView ) return ;
148+ this . listenerTarget = defaultView ;
149+ this . listenerTarget . addEventListener ( 'mousemove' , this . _onMouseMove ) ;
150+ this . listenerTarget . addEventListener ( 'touchstart' , this . _onTouchStart , { passive : true } ) ;
151+ this . listenerTarget . addEventListener ( 'touchmove' , this . _onTouchMove , { passive : true } ) ;
152+ this . listenerTarget . addEventListener ( 'touchend' , this . _onTouchEnd ) ;
153+ if ( this . docTarget ) {
154+ this . docTarget . addEventListener ( 'mouseleave' , this . _onDocumentLeave ) ;
155+ }
149156 }
150157 dispose ( ) {
151- if ( ! this . container ) return ;
152- this . container . removeEventListener ( 'mousemove' , this . _onMouseMove , false ) ;
153- this . container . removeEventListener ( 'touchstart' , this . _onTouchStart , false ) ;
154- this . container . removeEventListener ( 'touchmove' , this . _onTouchMove , false ) ;
155- this . container . removeEventListener ( 'mouseenter' , this . _onMouseEnter , false ) ;
156- this . container . removeEventListener ( 'mouseleave' , this . _onMouseLeave , false ) ;
157- this . container . removeEventListener ( 'touchend' , this . _onTouchEnd , false ) ;
158+ if ( this . listenerTarget ) {
159+ this . listenerTarget . removeEventListener ( 'mousemove' , this . _onMouseMove ) ;
160+ this . listenerTarget . removeEventListener ( 'touchstart' , this . _onTouchStart ) ;
161+ this . listenerTarget . removeEventListener ( 'touchmove' , this . _onTouchMove ) ;
162+ this . listenerTarget . removeEventListener ( 'touchend' , this . _onTouchEnd ) ;
163+ }
164+ if ( this . docTarget ) {
165+ this . docTarget . removeEventListener ( 'mouseleave' , this . _onDocumentLeave ) ;
166+ }
167+ this . listenerTarget = null ;
168+ this . docTarget = null ;
169+ this . container = null ;
170+ }
171+ isPointInside ( clientX , clientY ) {
172+ if ( ! this . container ) return false ;
173+ const rect = this . container . getBoundingClientRect ( ) ;
174+ if ( rect . width === 0 || rect . height === 0 ) return false ;
175+ return clientX >= rect . left && clientX <= rect . right && clientY >= rect . top && clientY <= rect . bottom ;
176+ }
177+ updateHoverState ( clientX , clientY ) {
178+ this . isHoverInside = this . isPointInside ( clientX , clientY ) ;
179+ return this . isHoverInside ;
158180 }
159181 setCoords ( x , y ) {
160182 if ( ! this . container ) return ;
161- if ( this . timer ) clearTimeout ( this . timer ) ;
183+ if ( this . timer ) window . clearTimeout ( this . timer ) ;
162184 const rect = this . container . getBoundingClientRect ( ) ;
185+ if ( rect . width === 0 || rect . height === 0 ) return ;
163186 const nx = ( x - rect . left ) / rect . width ;
164187 const ny = ( y - rect . top ) / rect . height ;
165188 this . coords . set ( nx * 2 - 1 , - ( ny * 2 - 1 ) ) ;
166189 this . mouseMoved = true ;
167- this . timer = setTimeout ( ( ) => {
190+ this . timer = window . setTimeout ( ( ) => {
168191 this . mouseMoved = false ;
169192 } , 100 ) ;
170193 }
@@ -173,9 +196,12 @@ export default function LiquidEther({
173196 this . mouseMoved = true ;
174197 }
175198 onDocumentMouseMove ( event ) {
199+ if ( ! this . updateHoverState ( event . clientX , event . clientY ) ) return ;
176200 if ( this . onInteract ) this . onInteract ( ) ;
177201 if ( this . isAutoActive && ! this . hasUserControl && ! this . takeoverActive ) {
202+ if ( ! this . container ) return ;
178203 const rect = this . container . getBoundingClientRect ( ) ;
204+ if ( rect . width === 0 || rect . height === 0 ) return ;
179205 const nx = ( event . clientX - rect . left ) / rect . width ;
180206 const ny = ( event . clientY - rect . top ) / rect . height ;
181207 this . takeoverFrom . copy ( this . coords ) ;
@@ -190,27 +216,24 @@ export default function LiquidEther({
190216 this . hasUserControl = true ;
191217 }
192218 onDocumentTouchStart ( event ) {
193- if ( event . touches . length === 1 ) {
194- const t = event . touches [ 0 ] ;
195- if ( this . onInteract ) this . onInteract ( ) ;
196- this . setCoords ( t . pageX , t . pageY ) ;
197- this . hasUserControl = true ;
198- }
219+ if ( event . touches . length !== 1 ) return ;
220+ const t = event . touches [ 0 ] ;
221+ if ( ! this . updateHoverState ( t . clientX , t . clientY ) ) return ;
222+ if ( this . onInteract ) this . onInteract ( ) ;
223+ this . setCoords ( t . clientX , t . clientY ) ;
224+ this . hasUserControl = true ;
199225 }
200226 onDocumentTouchMove ( event ) {
201- if ( event . touches . length === 1 ) {
202- const t = event . touches [ 0 ] ;
203- if ( this . onInteract ) this . onInteract ( ) ;
204- this . setCoords ( t . pageX , t . pageY ) ;
205- }
227+ if ( event . touches . length !== 1 ) return ;
228+ const t = event . touches [ 0 ] ;
229+ if ( ! this . updateHoverState ( t . clientX , t . clientY ) ) return ;
230+ if ( this . onInteract ) this . onInteract ( ) ;
231+ this . setCoords ( t . clientX , t . clientY ) ;
206232 }
207233 onTouchEnd ( ) {
208234 this . isHoverInside = false ;
209235 }
210- onMouseEnter ( ) {
211- this . isHoverInside = true ;
212- }
213- onMouseLeave ( ) {
236+ onDocumentLeave ( ) {
214237 this . isHoverInside = false ;
215238 }
216239 update ( ) {
0 commit comments