@@ -23,8 +23,30 @@ class NinjaCursorForWindow {
2323 ad . body . appendChild ( this . wrapperElement ) ;
2424 this . cursorElement . addClass ( "x-cursor" ) ;
2525 const root = ad . documentElement ;
26-
27- const moveCursor = ( ) => {
26+ let datumTop = 0 ;
27+ let datumElement : HTMLElement ;
28+ let cursorVisibility = false ;
29+ const moveCursor = ( e ?: Event , noAnimate ?: boolean ) => {
30+ if ( e && e . target instanceof HTMLElement && ( e . target . isContentEditable || e . target . tagName == "INPUT" ) ) {
31+ // If it caused by clicking an element and it is editable.
32+ datumElement = e . target ;
33+ if ( ! cursorVisibility ) {
34+ root . style . setProperty ( "--cursor-visibility" , `visible` ) ;
35+ cursorVisibility = true ;
36+ }
37+ } else if ( e != null ) {
38+ // If it caused by clicking an element but it is not editable.
39+ if ( cursorVisibility ) {
40+ root . style . setProperty ( "--cursor-visibility" , `hidden` ) ;
41+ cursorVisibility = false ;
42+ }
43+ return ;
44+ }
45+ if ( e && e . target instanceof HTMLElement ) {
46+ // Memo datum element for scroll.
47+ datumElement = e . target ;
48+ }
49+ datumTop = datumElement . getBoundingClientRect ( ) . top ;
2850 const selection = aw . getSelection ( ) ;
2951 if ( ! selection ) {
3052 console . log ( "Could not find selection" ) ;
@@ -45,15 +67,15 @@ class NinjaCursorForWindow {
4567 if ( textRect . x == 0 && textRect . y == 0 ) {
4668 textRange . setStart ( range . endContainer , range . endOffset - 1 ) ;
4769 textRange . setEnd ( range . endContainer , range . endOffset ) ;
48- const textRectx = textRange . getClientRects ( ) ;
49- const txx = textRectx . item ( textRectx . length - 1 ) ;
50- if ( ! txx ) {
70+ const textRects = textRange . getClientRects ( ) ;
71+ const tempRect = textRects . item ( textRects . length - 1 ) ;
72+ if ( ! tempRect ) {
5173 console . log ( "Could not found" ) ;
5274 return ;
5375 }
54- textRect = txx ;
55- textRect . x = txx . right ;
56- textRect . y = txx . bottom - txx . height ;
76+ textRect = tempRect ;
77+ textRect . x = tempRect . right ;
78+ textRect . y = tempRect . bottom - tempRect . height ;
5779 }
5880
5981 if ( textRect . x == 0 && textRect . y == 0 ) {
@@ -78,6 +100,7 @@ class NinjaCursorForWindow {
78100 Math . abs ( Math . sin ( cursorDragAngle ) ) * 8 +
79101 Math . abs ( Math . cos ( cursorDragAngle ) ) * rect . height ;
80102 const cursorDragWidth = cursorDragDistance ;
103+
81104 root . style . setProperty (
82105 "--cursor-drag-height" ,
83106 `${ cursorDragHeight } px`
@@ -92,37 +115,50 @@ class NinjaCursorForWindow {
92115 ) ;
93116 root . style . setProperty ( "--cursor-height" , `${ rect . height } px` ) ;
94117 root . style . setProperty ( "--cursor-x1" , `${ this . lastPos . x } px` ) ;
95- root . style . setProperty ( "--cursor-y1 " , `${ this . lastPos . y } px` ) ;
118+ root . style . setProperty ( "--cursor-y1src " , `${ this . lastPos . y } px` ) ;
96119 root . style . setProperty ( "--cursor-x2" , `${ rect . x } px` ) ;
97- root . style . setProperty ( "--cursor-y2" , `${ rect . y } px` ) ;
120+ root . style . setProperty ( "--cursor-y2src" , `${ rect . y } px` ) ;
121+ root . style . setProperty ( "--cursor-offset-y" , `${ 0 } px` ) ;
122+ if ( noAnimate ) {
123+ this . lastPos = rect ;
124+ return ;
125+ }
98126 this . cursorElement . removeClass ( "x-cursor0" ) ;
99127 this . cursorElement . removeClass ( "x-cursor1" ) ;
100128 this . cursorElement . getAnimations ( ) . forEach ( ( anim ) => anim . cancel ( ) ) ;
101129
130+ datumTop = datumElement . getBoundingClientRect ( ) . top ;
102131 aw . requestAnimationFrame ( ( time ) => {
103132 this . cursorElement . addClass ( `x-cursor${ this . styleCount } ` ) ;
104133 this . lastPos = rect ;
105134 } ) ;
106135 } ;
107136
108137
109- registerDomEvent ( aw , "keydown" , ( ) => {
110- moveCursor ( ) ;
111- } ) ;
112- registerDomEvent ( aw , "keyup" , ( ) => {
113- moveCursor ( ) ;
114- } ) ;
115- registerDomEvent ( aw , "mousedown" , ( ) => {
116- moveCursor ( ) ;
117- } ) ;
118- registerDomEvent ( aw , "mouseup" , ( ) => {
119- moveCursor ( ) ;
120- } ) ;
121- registerDomEvent ( aw , "touchend" , ( ) => {
122- moveCursor ( ) ;
123- } ) ;
124- registerDomEvent ( aw , "touchstart" , ( ) => {
125- moveCursor ( ) ;
138+ const supportVIMMode = true ;
139+ const eventNames = [ "keydown" , "mousedown" , "touchend" , ...( supportVIMMode ? [ "keyup" , "mouseup" , "touchstart" ] : [ ] ) ] ;
140+ for ( const event of eventNames ) {
141+ registerDomEvent ( aw , event , ( ev : Event ) => {
142+ moveCursor ( ev ) ;
143+ } ) ;
144+ }
145+ // Handles scroll till scroll is finish.
146+ const applyWheelScroll = ( last ?: number | boolean ) => {
147+ requestAnimationFrame ( ( ) => {
148+ if ( datumElement ) {
149+ const curTop = datumElement . getBoundingClientRect ( ) . top ;
150+ const diff = curTop - datumTop ;
151+ root . style . setProperty ( "--cursor-offset-y" , `${ diff } px` ) ;
152+ if ( last === false || last != diff ) {
153+ requestAnimationFrame ( ( ) => applyWheelScroll ( diff ) ) ;
154+ } else if ( last == diff ) {
155+ moveCursor ( undefined , true ) ;
156+ }
157+ }
158+ } ) ;
159+ }
160+ registerDomEvent ( aw , "wheel" , ( e : WheelEvent ) => {
161+ applyWheelScroll ( false ) ;
126162 } ) ;
127163 }
128164
0 commit comments