import * as PIXI from 'pixi.js' ; export class Viewport { private size : IPoint ; private viewPortSize : IPoint ; private anchor : IPoint ; private maxZoom : number ; private dirty = true ; private positionX = 0 ; private positionY = 0 ; private scaleX = 1 ; private scaleY = 1 ; private scaleCenterX = 0 ; private scaleCenterY = 0 ; private origTransform = new PIXI . Matrix ( ) ; private transform = new PIXI . Matrix ( ) ; public constructor ( size , viewPortSize , anchor , maxZoom ) { this . size = size ; this . viewPortSize = viewPortSize ; this . anchor = anchor ; this . maxZoom = maxZoom ; } private _updateMatrix ( ) { this . origTransform . append ( new PIXI . Matrix ( 1 , 0 , 0 , 1 , this . scaleCenterX , this . scaleCenterY ) ) ; this . origTransform . append ( new PIXI . Matrix ( this . scaleX , 0 , 0 , this . scaleY , 0 , 0 ) ) ; this . origTransform . append ( new PIXI . Matrix ( 1 , 0 , 0 , 1 , - this . scaleCenterX , - this . scaleCenterY ) ) ; this . scaleX = 1 ; this . scaleY = 1 ; this . transform = this . origTransform . clone ( ) ; const minX = this . size . x * this . transform . a * this . anchor . x - this . transform . tx ; const minY = this . size . y * this . transform . a * this . anchor . y - this . transform . ty ; const maxX = - ( this . size . x * ( 1 - this . anchor . x ) * this . transform . a - this . viewPortSize . x ) - this . transform . tx ; const maxY = - ( this . size . y * ( 1 - this . anchor . y ) * this . transform . a - this . viewPortSize . y ) - this . transform . ty ; if ( maxX - minX > 0 || maxY - minY > 0 ) { this . origTransform = new PIXI . Matrix ( ) ; this . scaleCenterX = this . size . x / 2 ; this . scaleCenterY = this . size . y / 2 ; const maxZoom = Math . max ( this . viewPortSize . x / ( this . size . x * this . transform . a ) , this . viewPortSize . y / ( this . size . y * this . transform . a ) ) * this . transform . a ; this . scaleX = maxZoom ; this . scaleY = maxZoom ; this . _updateMatrix ( ) ; return ; } if ( this . positionX > minX ) { this . positionX = minX ; } if ( this . positionY > minY ) { this . positionY = minY ; } if ( this . positionX < maxX ) { this . positionX = maxX ; } if ( this . positionY < maxY ) { this . positionY = maxY ; } this . transform . translate ( this . positionX , this . positionY ) ; } public centerViewPort ( focusObjectSize , offset ) { this . origTransform = new PIXI . Matrix ( ) ; this . positionX = - this . size . x / 2 + this . viewPortSize . x / 2 + offset . x ; this . positionY = - this . size . y / 2 + this . viewPortSize . y / 2 + offset . y ; this . scaleCenterX = this . size . x / 2 + - offset . x ; this . scaleCenterY = this . size . y / 2 + - offset . y ; const zoom = Math . min ( this . viewPortSize . x / focusObjectSize . x , this . viewPortSize . y / focusObjectSize . y , this . maxZoom ) ; this . scaleX = zoom ; this . scaleY = zoom ; this . dirty = true ; } returns public update ( ) { if ( this . dirty ) { this . _updateMatrix ( ) ; this . dirty = false ; return true ; } return false ; } public getTransform ( ) { return this . transform ; } public setSize ( x , y ) { this . viewPortSize . x = x ; this . viewPortSize . y = y ; this . dirty = true ; } public setPosition ( posX , posY ) { this . positionX = posX ; this . positionY = posY ; this . dirty = true ; } public zoomBy ( deltaX , deltaY ? ) { if ( Math . sign ( deltaX ) === 1 && this . origTransform . a > this . maxZoom ) return ; this . scaleX += deltaX ; this . scaleY += deltaY === undefined ? deltaX : deltaY ; this . dirty = true ; } public translateBy ( deltaX , deltaY ) { this . positionX += deltaX ; this . positionY += deltaY ; this . dirty = true ; } public setCurrentScale ( newScale ) { if ( this . dirty ) { this . _updateMatrix ( ) ; } const scaleFactor = newScale / this . origTransform . a ; this . scaleX = scaleFactor ; this . scaleY = scaleFactor ; this . dirty = true ; } public getCurrentScale ( ) { return this . origTransform . a ; } public setScaleCenter ( posX , posY ) { this . scaleCenterX = posX ; this . scaleCenterY = posY ; this . dirty = true ; } }