1
1
import {
2
2
DOMWidgetModel ,
3
3
DOMWidgetView ,
4
+ WidgetModel ,
4
5
ISerializers ,
5
6
unpack_models ,
6
7
} from '@jupyter-widgets/base' ;
8
+
7
9
import * as utils from './utils' ;
8
10
9
11
import { MODULE_VERSION } from './version' ;
@@ -14,8 +16,9 @@ export class MPLCanvasModel extends DOMWidgetModel {
14
16
requested_size : Array < number > | null ;
15
17
resize_requested : boolean ;
16
18
ratio : number ;
17
- waiting : any ;
19
+ waiting_for_image : boolean ;
18
20
image : HTMLImageElement ;
21
+
19
22
defaults ( ) {
20
23
return {
21
24
...super . defaults ( ) ,
@@ -32,6 +35,7 @@ export class MPLCanvasModel extends DOMWidgetModel {
32
35
toolbar_position : 'horizontal' ,
33
36
resizable : true ,
34
37
capture_scroll : false ,
38
+ _data_url : null ,
35
39
_width : 0 ,
36
40
_height : 0 ,
37
41
_figure_label : 'Figure' ,
@@ -70,6 +74,9 @@ export class MPLCanvasModel extends DOMWidgetModel {
70
74
this . requested_size = null ;
71
75
this . resize_requested = false ;
72
76
this . ratio = ( window . devicePixelRatio || 1 ) / backingStore ;
77
+
78
+ this . resize_canvas ( this . get ( '_width' ) , this . get ( '_height' ) ) ;
79
+
73
80
this . _init_image ( ) ;
74
81
75
82
this . on ( 'msg:custom' , this . on_comm_message . bind ( this ) ) ;
@@ -78,10 +85,30 @@ export class MPLCanvasModel extends DOMWidgetModel {
78
85
view . update_canvas ( ) ;
79
86
} ) ;
80
87
} ) ;
88
+ this . on ( 'comm_live_update' , this . update_disabled . bind ( this ) ) ;
89
+
90
+ this . update_disabled ( ) ;
81
91
82
92
this . send_initialization_message ( ) ;
83
93
}
84
94
95
+ get disabled ( ) : boolean {
96
+ return ! this . comm_live ;
97
+ }
98
+
99
+ update_disabled ( ) : void {
100
+ this . set ( 'resizable' , ! this . disabled ) ;
101
+ }
102
+
103
+ sync ( method : string , model : WidgetModel , options : any = { } ) {
104
+ // Make sure we don't sync the data_url, we don't need it to be synced
105
+ if ( options . attrs ) {
106
+ delete options . attrs [ '_data_url' ] ;
107
+ }
108
+
109
+ super . sync ( method , model , options ) ;
110
+ }
111
+
85
112
send_message ( type : string , message : { [ index : string ] : any } = { } ) {
86
113
message [ 'type' ] = type ;
87
114
@@ -96,15 +123,15 @@ export class MPLCanvasModel extends DOMWidgetModel {
96
123
} ) ;
97
124
}
98
125
99
- this . send_message ( 'send_image_mode' ) ;
100
126
this . send_message ( 'refresh' ) ;
127
+ this . send_message ( 'send_image_mode' ) ;
101
128
102
129
this . send_message ( 'initialized' ) ;
103
130
}
104
131
105
132
send_draw_message ( ) {
106
- if ( ! this . waiting ) {
107
- this . waiting = true ;
133
+ if ( ! this . waiting_for_image ) {
134
+ this . waiting_for_image = true ;
108
135
this . send_message ( 'draw' ) ;
109
136
}
110
137
}
@@ -160,8 +187,8 @@ export class MPLCanvasModel extends DOMWidgetModel {
160
187
}
161
188
162
189
resize_canvas ( width : number , height : number ) {
163
- this . offscreen_canvas . setAttribute ( ' width' , ` ${ width * this . ratio } ` ) ;
164
- this . offscreen_canvas . setAttribute ( ' height' , ` ${ height * this . ratio } ` ) ;
190
+ this . offscreen_canvas . width = width * this . ratio ;
191
+ this . offscreen_canvas . height = height * this . ratio ;
165
192
}
166
193
167
194
handle_rubberband ( msg : any ) {
@@ -204,7 +231,9 @@ export class MPLCanvasModel extends DOMWidgetModel {
204
231
205
232
this . image . src = image_url ;
206
233
207
- this . waiting = false ;
234
+ this . set ( '_data_url' , this . offscreen_canvas . toDataURL ( ) ) ;
235
+
236
+ this . waiting_for_image = false ;
208
237
}
209
238
210
239
handle_history_buttons ( msg : any ) {
@@ -240,7 +269,8 @@ export class MPLCanvasModel extends DOMWidgetModel {
240
269
}
241
270
242
271
_init_image ( ) {
243
- this . image = document . createElement ( 'img' ) ;
272
+ this . image = new Image ( ) ;
273
+
244
274
this . image . onload = ( ) => {
245
275
if ( this . get ( '_image_mode' ) === 'full' ) {
246
276
// Full images could contain transparency (where diff images
@@ -259,6 +289,12 @@ export class MPLCanvasModel extends DOMWidgetModel {
259
289
view . update_canvas ( ) ;
260
290
} ) ;
261
291
} ;
292
+
293
+ const dataUrl = this . get ( '_data_url' ) ;
294
+
295
+ if ( dataUrl !== null ) {
296
+ this . image . src = dataUrl ;
297
+ }
262
298
}
263
299
264
300
_for_each_view ( callback : any ) {
@@ -285,12 +321,12 @@ export class MPLCanvasView extends DOMWidgetView {
285
321
context : CanvasRenderingContext2D ;
286
322
top_canvas : HTMLCanvasElement ;
287
323
top_context : CanvasRenderingContext2D ;
288
- waiting : boolean ;
289
324
footer : HTMLDivElement ;
290
325
model : MPLCanvasModel ;
291
326
private _key : string | null ;
292
327
private _resize_event : ( event : MouseEvent ) => void ;
293
328
private _stop_resize_event : ( ) => void ;
329
+
294
330
render ( ) {
295
331
this . resizing = false ;
296
332
this . resize_handle_size = 20 ;
@@ -313,8 +349,6 @@ export class MPLCanvasView extends DOMWidgetView {
313
349
window . addEventListener ( 'mousemove' , this . _resize_event ) ;
314
350
window . addEventListener ( 'mouseup' , this . _stop_resize_event ) ;
315
351
316
- this . waiting = false ;
317
-
318
352
return this . create_child_view ( this . model . get ( 'toolbar' ) ) . then (
319
353
( toolbar_view ) => {
320
354
this . toolbar_view = toolbar_view ;
0 commit comments