import { CursorController } from "./CursorController" ; import { $isTouch , $MIDDLE } from "./Share" ; import type { Studio } from "bp/env" ; /**
 *  ScrollController 類別負責管理視圖區域的捲動。
  export class ScrollController { private static readonly _TIMEOUT = 50 ; private _studio : Studio ; private _scrolling : boolean ; private _timeout : number ; constructor ( studio ) { this . _studio = studio ; document . addEventListener ( "mousemove" , this . _bodyMousemove . bind ( this ) , { passive : true } ) ; document . addEventListener ( "touchmove" , this . _bodyMousemove . bind ( this ) , { passive : true } ) ; document . addEventListener ( "contextmenu" , this . _bodyMenu . bind ( this ) ) ; document . addEventListener ( "mouseup" , this . _bodyMouseup . bind ( this ) , { passive : true } ) ; document . addEventListener ( "touchend" , this . _bodyMouseup . bind ( this ) , { passive : true } ) ; studio . $el . addEventListener ( "scroll" , this . _onScroll . bind ( this ) , { passive : true } ) ; studio . $display . $onSheetChange = ( x , y ) => this . to ( x , y ) ; } public get on ( ) : boolean { return this . _scrolling ; } public $init ( ) { this . _scrolling = true ; } public $tryEnd ( event ) { if ( this . _scrolling ) { if ( event . event instanceof MouseEvent ) { this . _scrolling = false ; } return true ; } return false ; } private _scrollLock = false ; private _onScroll ( ) { if ( this . _scrollLock ) { this . _scrollLock = false ; return ; } if ( this . _scrolling ) return ; let sheet = this . _studio . $design ?. sheet ; if ( sheet ) { sheet . $scroll . x = this . _studio . $el . scrollLeft ; sheet . $scroll . y = this . _studio . $el . scrollTop ; } window . clearTimeout ( this . _timeout ) ; this . _timeout = window . setTimeout ( ( ) => this . _timeoutHandler ( ) , ScrollController . _TIMEOUT ) ; } private _timeoutHandler ( ) { let sheet = this . _studio . $design ?. sheet ; if ( sheet && ( sheet . $scroll . x != this . _studio . $el . scrollLeft || sheet . $scroll . y != this . _studio . $el . scrollTop ) ) { this . _onScroll ( ) ; } } public to ( x , y ) { this . _scrollLock = true ; this . _studio . $el . scrollTo ( x , y ) ; } private _bodyMenu ( event ) { event . preventDefault ( ) ; this . _scrolling = false ; } private _bodyMouseup ( event ) { if ( $isTouch ( event ) && event . touches . length == 0 || event instanceof MouseEvent && event . button == $MIDDLE ) { this . _scrolling = false ; } } private _bodyMousemove ( event ) { if ( ! this . _studio . $design ) return ; if ( this . _scrolling && ( event instanceof MouseEvent || event . touches . length >= 2 ) ) { let diff = CursorController . $diff ( event ) ; this . _studio . $display . $scrollBy ( this . _studio . $design , diff ) ; if ( $isTouch ( event ) ) this . _studio . $system . $zoom . $process ( event ) ; } } }