@@ -2,6 +2,52 @@ import * as d3 from 'd3';
22import { Application , Container , Graphics , Text } from 'pixi.js' ;
33import { testData } from './TestData' ;
44
5+ interface AnimatedValues {
6+ zoom : number ;
7+ zoomX : number ;
8+ zoomY : number ;
9+ }
10+
11+ class Animator < Key extends string > {
12+ private values : Record < Key , number > ;
13+ private targetValues : Record < Key , number > ;
14+ private durations : Record < Key , number > ;
15+
16+ constructor ( initialValues : Record < Key , number > , durations : Record < Key , number > ) {
17+ this . values = initialValues ;
18+ this . targetValues = { ... initialValues } ;
19+ this . durations = durations ;
20+ }
21+
22+ public setTarget ( key : Key , value : number ) {
23+ this . targetValues [ key ] = value ;
24+ }
25+
26+ public update ( delta : number ) {
27+ for ( const key in this . values ) {
28+ this . values [ key ] += ( this . targetValues [ key ] - this . values [ key ] ) * ( 1.0 - Math . exp ( - this . durations [ key ] * delta ) ) ;
29+ }
30+ }
31+
32+ public get ( key : Key ) {
33+ return this . values [ key ] ;
34+ }
35+
36+ public isAnimating ( key : Key ) {
37+ return Math . pow ( this . values [ key ] - this . targetValues [ key ] , 2 ) > 0.0000001 ;
38+ }
39+ }
40+
41+ const animator = new Animator < keyof AnimatedValues > ( {
42+ zoom : 1 ,
43+ zoomX : 0 ,
44+ zoomY : 0 ,
45+ } , {
46+ zoom : 0.3 ,
47+ zoomX : 0.3 ,
48+ zoomY : 0.3 ,
49+ } ) ;
50+
551const width = 400 ;
652const height = 400 ;
753const element = document . getElementById ( 'graph-mount-point' ) ! ;
@@ -83,18 +129,28 @@ d3.select(app.canvas).call(
83129 // @ts -ignore
84130 d3 . zoom ( ) . on ( 'zoom' , ( { transform } : { transform : d3 . ZoomTransform } ) => {
85131 zoom = transform ;
86- app . stage . updateTransform ( {
87- scaleX : transform . k ,
88- scaleY : transform . k ,
89- x : transform . x ,
90- y : transform . y ,
91- } ) ;
132+ animator . setTarget ( 'zoom' , transform . k ) ;
133+ animator . setTarget ( 'zoomX' , transform . x ) ;
134+ animator . setTarget ( 'zoomY' , transform . y ) ;
92135 } ) ,
93136) ;
94137
95- app . ticker . add ( ( ) => {
138+ app . ticker . add ( ( ticker ) => {
139+ animator . update ( ticker . deltaTime ) ;
140+
141+ if ( animator . isAnimating ( 'zoom' ) || animator . isAnimating ( 'zoomX' ) || animator . isAnimating ( 'zoomY' ) ) {
142+ console . log ( 'Animating' ) ;
143+
144+ app . stage . updateTransform ( {
145+ scaleX : animator . get ( 'zoom' ) ,
146+ scaleY : animator . get ( 'zoom' ) ,
147+ x : animator . get ( 'zoomX' ) ,
148+ y : animator . get ( 'zoomY' ) ,
149+ } ) ;
150+ }
151+
96152 for ( const node of simulation . nodes ( ) ) {
97- node . text ! . scale . set ( 1 / zoom . k ) ;
153+ node . text ! . scale . set ( 1 / animator . get ( 'zoom' ) ) ;
98154 node . text ! . position . set ( 0 , 10 ) ;
99155 }
100156
@@ -114,7 +170,7 @@ app.ticker.add(() => {
114170 . fill ( )
115171 . stroke ( {
116172 color : 0xffffff ,
117- width : 1 / zoom . k ,
173+ width : 1 / animator . get ( 'zoom' ) ,
118174 } ) ;
119175 }
120176} ) ;
@@ -135,8 +191,8 @@ function dragstarted(event: any) {
135191function dragged ( event : any ) {
136192 if ( ! event . subject ) return ;
137193
138- dragX += event . dx / zoom . k ;
139- dragY += event . dy / zoom . k ;
194+ dragX += event . dx / animator . get ( 'zoom' ) ;
195+ dragY += event . dy / animator . get ( 'zoom' ) ;
140196
141197 event . subject . fx = dragX ;
142198 event . subject . fy = dragY ;
@@ -149,3 +205,4 @@ function dragended(event: any) {
149205 event . subject . fx = null ;
150206 event . subject . fy = null ;
151207}
208+
0 commit comments