import * as d3 from "d3" ; import Map from "../map" ; import { Event } from "./events" ; import { ZoomBehavior } from "d3-zoom" ; import Log from "../../utils/log" ; /**
 * Manage the zoom events of the map.
 */ export default class Zoom { private map : Map ; private zoomBehavior : ZoomBehavior < any , any > ; param { Map } map constructor ( map ) { this . map = map ; this . zoomBehavior = d3 . zoom ( ) . scaleExtent ( [ 0.5 , 2 ] ) . on ( "zoom" , ( ) => { this . map . dom . g . attr ( "transform" , d3 . event . transform ) ; } ) ; } param { number } duration public zoomIn = ( duration ? ) => { if ( duration && typeof duration !== "number" ) { Log . error ( "The parameter must be a number" , "type" ) ; } this . move ( true , duration ) ; this . map . events . call ( Event . zoomIn ) ; } ; param { number } duration public zoomOut = ( duration ? ) => { if ( duration && typeof duration !== "number" ) { Log . error ( "The parameter must be a number" , "type" ) ; } this . move ( false , duration ) ; this . map . events . call ( Event . zoomOut ) ; } ; param { number } duration param { number } type public center = ( type ? , duration = 500 ) => { if ( type && type !== "zoom" && type !== "position" ) { Log . error ( "The type must be a string (\"zoom\" or \"position\")" , "type" ) ; } if ( duration && typeof duration !== "number" ) { Log . error ( "The duration must be a number" , "type" ) ; } let root = this . map . nodes . getRoot ( ) , w = this . map . dom . container . node ( ) . clientWidth , h = this . map . dom . container . node ( ) . clientHeight , x = w / 2 - root . coordinates . x , y = h / 2 - root . coordinates . y , svg = this . map . dom . svg . transition ( ) . duration ( duration ) ; switch ( type ) { case "zoom" : this . zoomBehavior . scaleTo ( svg , 1 ) ; break ; case "position" : this . zoomBehavior . translateTo ( svg , w / 2 - x , h / 2 - y ) ; break ; default : this . zoomBehavior . transform ( svg , d3 . zoomIdentity . translate ( x , y ) ) ; } this . map . events . call ( Event . center ) ; } ; returns { ZoomBehavior } public getZoomBehavior ( ) { return this . zoomBehavior ; } param { boolean } direction param { number } duration private move ( direction , duration = 50 ) { let svg = this . map . dom . svg . transition ( ) . duration ( duration ) ; this . zoomBehavior . scaleBy ( svg , direction ? 4 / 3 : 3 / 4 ) ; } }