@@ -13,7 +13,7 @@ import {
1313 ConveyerOptions , FindItemOptions , ConveyerReactiveState ,
1414 ScrollIntoViewOptions ,
1515} from "./types" ;
16- import { instanceOfElement , isString } from "./utils" ;
16+ import { instanceOfElement , isIntersection , isString } from "./utils" ;
1717
1818
1919/**
@@ -45,6 +45,7 @@ class Conveyer extends Component<ConveyerEvents> {
4545 protected _options : ConveyerOptions ;
4646 protected _animateParam : {
4747 expectedPos : number ;
48+ offset : number ;
4849 } | null = null ;
4950
5051 private _resizeObserver : ResizeObserver | null = null ;
@@ -54,6 +55,9 @@ class Conveyer extends Component<ConveyerEvents> {
5455 private _isAnimationScroll = false ;
5556 private _scrollArea : string | HTMLElement | Ref < HTMLElement > ;
5657
58+ private _panInput : PanInput | null = null ;
59+ private _wheelInput : WheelInput | null = null ;
60+
5761 /**
5862 * Whether the scroll has reached the start.
5963 * @ko 스크롤이 시작에 닿았는지 여부.
@@ -193,7 +197,7 @@ class Conveyer extends Component<ConveyerEvents> {
193197 const dist2 = dist + itemSize ;
194198
195199 return ( dist >= 0 )
196- || ( dist2 > 0 && intersection )
200+ || ( dist2 > 0 && isIntersection ( dist , dist2 , "end" , intersection ) )
197201 || ( dist2 >= 0 && ( ! itemSize || Math . abs ( dist2 ) / itemSize >= hitTest ) ) ;
198202 } ) ;
199203
@@ -208,7 +212,7 @@ class Conveyer extends Component<ConveyerEvents> {
208212 const dist2 = dist - itemSize ;
209213
210214 return dist <= 0
211- || ( dist2 < 0 && intersection )
215+ || ( dist2 < 0 && isIntersection ( dist2 , dist , "start" , intersection ) )
212216 || ( dist2 <= 0 && ( ! itemSize || Math . abs ( dist2 ) / itemSize >= hitTest ) ) ;
213217 } ) . reverse ( ) ;
214218
@@ -220,19 +224,19 @@ class Conveyer extends Component<ConveyerEvents> {
220224 const dist2 = dist - itemSize ;
221225
222226 return dist <= 0
223- || ( dist2 < 0 && intersection )
227+ || ( dist2 < 0 && isIntersection ( dist2 , dist , "start" , intersection ) )
224228 || ( dist2 <= 0 && ( ! itemSize || Math . abs ( dist2 ) / itemSize >= hitTest ) ) ;
225- } ) . reverse ( ) [ 0 ] ;
229+ } ) . reverse ( ) [ 0 ] || startVirtualItem ;
226230 } else if ( target === "next" ) {
227231 selectedItem = items . filter ( item => {
228232 const itemSize = item . size ;
229233 const dist = item . pos - endPos ;
230234 const dist2 = dist + itemSize ;
231235
232236 return dist >= 0
233- || ( dist2 > 0 && intersection )
237+ || ( dist2 > 0 && isIntersection ( dist , dist2 , "end" , intersection ) )
234238 || ( dist2 >= 0 && ( ! itemSize || Math . abs ( dist2 ) / itemSize >= hitTest ) ) ;
235- } ) [ 0 ] ;
239+ } ) [ 0 ] || endVirtualItem ;
236240 } else {
237241 return this . _getItem ( target ) ;
238242 }
@@ -292,7 +296,7 @@ class Conveyer extends Component<ConveyerEvents> {
292296 * @param - Duration to scroll by that position. <ko>해당 위치만큼 스크롤하는 시간</ko>
293297 */
294298 public scrollBy ( pos : number , duration = 0 ) {
295- this . _createAnimationParam ( ) ;
299+ this . _createAnimationParam ( pos ) ;
296300 this . _axes ! . setBy ( { scroll : - pos } , duration ) ;
297301 }
298302 /**
@@ -302,8 +306,7 @@ class Conveyer extends Component<ConveyerEvents> {
302306 * @param - Duration to scroll to that position. <ko>해당 위치로 스크롤하는 시간</ko>
303307 */
304308 public scrollTo ( pos : number , duration = 0 ) {
305- this . _createAnimationParam ( ) ;
306- this . _axes ! . setBy ( { scroll : this . _pos - pos } , duration ) ;
309+ this . scrollBy ( pos - this . _pos , duration ) ;
307310 }
308311 /**
309312 * Set the items directly to the Conveyer.
@@ -328,7 +331,7 @@ class Conveyer extends Component<ConveyerEvents> {
328331 ) ;
329332 this . setItems ( itemElements . map ( ( el ) => this . _getItem ( el ) ) ) ;
330333
331- if ( resizeObserver ) {
334+ if ( resizeObserver ) {
332335 const changed = diff ( prevItemElements , itemElements ) ;
333336 const removed = changed . removed ;
334337 const added = changed . added ;
@@ -378,6 +381,22 @@ class Conveyer extends Component<ConveyerEvents> {
378381 this . updateItems ( ) ;
379382 this . updateContainer ( ) ;
380383 }
384+ /**
385+ * Enables PanInput and WheelInput operations in mouse case.
386+ * @ko mouse 케이스에서 PanInput, WheelInput의 동작을 활성화한다.
387+ */
388+ public enableInput ( ) {
389+ this . _panInput ?. enable ( ) ;
390+ this . _wheelInput ?. enable ( ) ;
391+ }
392+ /**
393+ * Disables PanInput and WheelInput operations in mouse case.
394+ * @ko mouse 케이스에서 PanInput, WheelInput의 동작을 비활성화한다.
395+ */
396+ public disableInput ( ) {
397+ this . _panInput ?. disable ( ) ;
398+ this . _wheelInput ?. disable ( ) ;
399+ }
381400 /**
382401 * If you use the autoInit option as false, you can initialize it directly through the init method.
383402 * @ko autoInit 옵션을 false로 사용하는 경우 직접 init 메서드를 통해 초기화 할 수 있다.
@@ -446,9 +465,9 @@ class Conveyer extends Component<ConveyerEvents> {
446465 if ( ! e . isTrusted && animateParam ) {
447466 animateParam . expectedPos -= scroll ;
448467 if ( options . horizontal ) {
449- scrollAreaElement . scrollLeft = animateParam . expectedPos ;
468+ scrollAreaElement . scrollLeft = animateParam . expectedPos + animateParam . offset ;
450469 } else {
451- scrollAreaElement . scrollTop = animateParam . expectedPos ;
470+ scrollAreaElement . scrollTop = animateParam . expectedPos + animateParam . offset ;
452471 }
453472 } else {
454473 this . _animateParam = null ;
@@ -473,17 +492,19 @@ class Conveyer extends Component<ConveyerEvents> {
473492
474493 this . _axes = axes ;
475494 if ( options . useDrag ) {
476- axes . connect ( options . horizontal ? [ "scroll" , "" ] : [ "" , "scroll" ] , new PanInput ( scrollAreaElement , {
495+ this . _panInput = new PanInput ( scrollAreaElement , {
477496 preventClickOnDrag : options . preventClickOnDrag ,
478497 preventDefaultOnDrag : options . preventDefaultOnDrag ,
479498 inputType : [ "mouse" ] ,
480499 touchAction : "auto" ,
481- } ) ) ;
500+ } ) ;
501+ axes . connect ( options . horizontal ? [ "scroll" , "" ] : [ "" , "scroll" ] , this . _panInput ) ;
482502 }
483503 if ( options . useSideWheel ) {
484- axes . connect ( options . horizontal ? [ "scroll" , "" ] : [ "" , "scroll" ] , new WheelInput ( scrollAreaElement , {
504+ this . _wheelInput = new WheelInput ( scrollAreaElement , {
485505 useNormalized : false ,
486- } ) ) ;
506+ } ) ;
507+ axes . connect ( options . horizontal ? [ "scroll" , "" ] : [ "" , "scroll" ] , this . _wheelInput ) ;
487508 }
488509 if ( options . useResizeObserver && window . ResizeObserver ) {
489510 this . _resizeObserver = new ResizeObserver ( ( entries : ResizeObserverEntry [ ] ) => {
@@ -530,6 +551,8 @@ class Conveyer extends Component<ConveyerEvents> {
530551 window . removeEventListener ( "resize" , this . update ) ;
531552 }
532553 this . off ( ) ;
554+ this . _panInput = null ;
555+ this . _wheelInput = null ;
533556 this . _axes = null ;
534557 this . _resizeObserver = null ;
535558 }
@@ -663,9 +686,12 @@ class Conveyer extends Component<ConveyerEvents> {
663686 } , this . _options . scrollDebounce ) ;
664687 }
665688
666- private _createAnimationParam ( ) {
689+ private _createAnimationParam ( pos : number ) {
690+ // Save a decimal point before starting the animation
691+ // and in case of animation (isTrusted: false), add the offset and scroll.
667692 this . _animateParam = {
668693 expectedPos : this . _pos ,
694+ offset : pos % 1 ,
669695 } ;
670696 }
671697}
0 commit comments