@@ -39,8 +39,7 @@ export class MPLCanvasModel extends DOMWidgetModel {
39
39
capture_scroll : false ,
40
40
pan_zoom_throttle : 33 ,
41
41
_data_url : null ,
42
- _width : 0 ,
43
- _height : 0 ,
42
+ _size : [ 0 , 0 ] ,
44
43
_figure_label : 'Figure' ,
45
44
_message : '' ,
46
45
_cursor : 'pointer' ,
@@ -78,7 +77,7 @@ export class MPLCanvasModel extends DOMWidgetModel {
78
77
this . resize_requested = false ;
79
78
this . ratio = ( window . devicePixelRatio || 1 ) / backingStore ;
80
79
81
- this . resize_canvas ( this . get ( '_width' ) , this . get ( '_height' ) ) ;
80
+ this . resize_canvas ( ) ;
82
81
83
82
this . _init_image ( ) ;
84
83
@@ -88,13 +87,21 @@ export class MPLCanvasModel extends DOMWidgetModel {
88
87
view . update_canvas ( ) ;
89
88
} ) ;
90
89
} ) ;
90
+ this . on ( 'change:_size' , ( ) => {
91
+ this . resize_canvas ( ) ;
92
+ this . offscreen_context . drawImage ( this . image , 0 , 0 ) ;
93
+ } ) ;
91
94
this . on ( 'comm_live_update' , this . update_disabled . bind ( this ) ) ;
92
95
93
96
this . update_disabled ( ) ;
94
97
95
98
this . send_initialization_message ( ) ;
96
99
}
97
100
101
+ get size ( ) : [ number , number ] {
102
+ return this . get ( '_size' ) ;
103
+ }
104
+
98
105
get disabled ( ) : boolean {
99
106
return ! this . comm_live ;
100
107
}
@@ -149,13 +156,12 @@ export class MPLCanvasModel extends DOMWidgetModel {
149
156
}
150
157
151
158
handle_resize ( msg : { [ index : string ] : any } ) {
152
- const size = msg [ 'size' ] ;
153
- this . resize_canvas ( size [ 0 ] , size [ 1 ] ) ;
159
+ this . resize_canvas ( ) ;
154
160
this . offscreen_context . drawImage ( this . image , 0 , 0 ) ;
155
161
156
162
if ( ! this . resize_requested ) {
157
163
this . _for_each_view ( ( view : MPLCanvasView ) => {
158
- view . resize_canvas ( size [ 0 ] , size [ 1 ] ) ;
164
+ view . resize_and_update_canvas ( this . size ) ;
159
165
} ) ;
160
166
}
161
167
@@ -169,6 +175,9 @@ export class MPLCanvasModel extends DOMWidgetModel {
169
175
}
170
176
}
171
177
178
+ /*
179
+ * Request a resize to the backend
180
+ */
172
181
resize ( width : number , height : number ) {
173
182
// Do not request a super small size, as it seems to break the back-end
174
183
if ( width <= 5 || height <= 5 ) {
@@ -177,7 +186,7 @@ export class MPLCanvasModel extends DOMWidgetModel {
177
186
178
187
this . _for_each_view ( ( view : MPLCanvasView ) => {
179
188
// Do an initial resize of each view, stretching the old canvas.
180
- view . resize_canvas ( width , height ) ;
189
+ view . resize_and_update_canvas ( [ width , height ] ) ;
181
190
} ) ;
182
191
183
192
if ( this . resize_requested ) {
@@ -189,9 +198,12 @@ export class MPLCanvasModel extends DOMWidgetModel {
189
198
}
190
199
}
191
200
192
- resize_canvas ( width : number , height : number ) {
193
- this . offscreen_canvas . width = width * this . ratio ;
194
- this . offscreen_canvas . height = height * this . ratio ;
201
+ /*
202
+ * Resize the offscreen canvas
203
+ */
204
+ resize_canvas ( ) {
205
+ this . offscreen_canvas . width = this . size [ 0 ] * this . ratio ;
206
+ this . offscreen_canvas . height = this . size [ 1 ] * this . ratio ;
195
207
}
196
208
197
209
handle_rubberband ( msg : any ) {
@@ -275,17 +287,49 @@ export class MPLCanvasModel extends DOMWidgetModel {
275
287
this . image = new Image ( ) ;
276
288
277
289
this . image . onload = ( ) => {
290
+ // In case of an embedded widget, the initial size is not correct
291
+ // and we are not receiving any resize event from the server
292
+ if ( this . disabled ) {
293
+ this . offscreen_canvas . width = this . image . width ;
294
+ this . offscreen_canvas . height = this . image . height ;
295
+
296
+ this . offscreen_context . drawImage ( this . image , 0 , 0 ) ;
297
+
298
+ this . _for_each_view ( ( view : MPLCanvasView ) => {
299
+ // TODO Make this part of the CanvasView API?
300
+ // It feels out of place in the model
301
+ view . canvas . width = this . image . width / this . ratio ;
302
+ view . canvas . height = this . image . height / this . ratio ;
303
+ view . canvas . style . width = view . canvas . width + 'px' ;
304
+ view . canvas . style . height = view . canvas . height + 'px' ;
305
+
306
+ view . top_canvas . width = this . image . width / this . ratio ;
307
+ view . top_canvas . height = this . image . height / this . ratio ;
308
+ view . top_canvas . style . width = view . top_canvas . width + 'px' ;
309
+ view . top_canvas . style . height =
310
+ view . top_canvas . height + 'px' ;
311
+
312
+ view . canvas_div . style . width = view . canvas . width + 'px' ;
313
+ view . canvas_div . style . height = view . canvas . height + 'px' ;
314
+
315
+ view . update_canvas ( true ) ;
316
+ } ) ;
317
+
318
+ return ;
319
+ }
320
+
321
+ // Full images could contain transparency (where diff images
322
+ // almost always do), so we need to clear the canvas so that
323
+ // there is no ghosting.
278
324
if ( this . get ( '_image_mode' ) === 'full' ) {
279
- // Full images could contain transparency (where diff images
280
- // almost always do), so we need to clear the canvas so that
281
- // there is no ghosting.
282
325
this . offscreen_context . clearRect (
283
326
0 ,
284
327
0 ,
285
328
this . offscreen_canvas . width ,
286
329
this . offscreen_canvas . height
287
330
) ;
288
331
}
332
+
289
333
this . offscreen_context . drawImage ( this . image , 0 , 0 ) ;
290
334
291
335
this . _for_each_view ( ( view : MPLCanvasView ) => {
@@ -556,19 +600,32 @@ export class MPLCanvasView extends DOMWidgetView {
556
600
return false ;
557
601
} ) ;
558
602
559
- this . resize_canvas ( this . model . get ( '_width' ) , this . model . get ( '_height' ) ) ;
560
- this . update_canvas ( ) ;
603
+ this . resize_and_update_canvas ( this . model . size ) ;
561
604
}
562
605
563
- update_canvas ( ) {
606
+ /*
607
+ * Update the canvas view
608
+ */
609
+ update_canvas ( stretch = false ) {
564
610
if ( this . canvas . width === 0 || this . canvas . height === 0 ) {
565
611
return ;
566
612
}
567
613
568
614
this . top_context . save ( ) ;
569
615
570
616
this . context . clearRect ( 0 , 0 , this . canvas . width , this . canvas . height ) ;
571
- this . context . drawImage ( this . model . offscreen_canvas , 0 , 0 ) ;
617
+
618
+ if ( stretch ) {
619
+ this . context . drawImage (
620
+ this . model . offscreen_canvas ,
621
+ 0 ,
622
+ 0 ,
623
+ this . canvas . width ,
624
+ this . canvas . height
625
+ ) ;
626
+ } else {
627
+ this . context . drawImage ( this . model . offscreen_canvas , 0 , 0 ) ;
628
+ }
572
629
573
630
this . top_context . clearRect (
574
631
0 ,
@@ -651,18 +708,18 @@ export class MPLCanvasView extends DOMWidgetView {
651
708
this . footer . textContent = this . model . get ( '_message' ) ;
652
709
}
653
710
654
- resize_canvas ( width : number , height : number ) {
711
+ resize_and_update_canvas ( size : [ number , number ] ) {
655
712
// Keep the size of the canvas, and rubber band canvas in sync.
656
- this . canvas . setAttribute ( 'width' , `${ width * this . model . ratio } ` ) ;
657
- this . canvas . setAttribute ( 'height' , `${ height * this . model . ratio } ` ) ;
658
- this . canvas . style . width = width + 'px' ;
659
- this . canvas . style . height = height + 'px' ;
713
+ this . canvas . setAttribute ( 'width' , `${ size [ 0 ] * this . model . ratio } ` ) ;
714
+ this . canvas . setAttribute ( 'height' , `${ size [ 1 ] * this . model . ratio } ` ) ;
715
+ this . canvas . style . width = size [ 0 ] + 'px' ;
716
+ this . canvas . style . height = size [ 1 ] + 'px' ;
660
717
661
- this . top_canvas . setAttribute ( 'width' , String ( width ) ) ;
662
- this . top_canvas . setAttribute ( 'height' , String ( height ) ) ;
718
+ this . top_canvas . setAttribute ( 'width' , String ( size [ 0 ] ) ) ;
719
+ this . top_canvas . setAttribute ( 'height' , String ( size [ 1 ] ) ) ;
663
720
664
- this . canvas_div . style . width = width + 'px' ;
665
- this . canvas_div . style . height = height + 'px' ;
721
+ this . canvas_div . style . width = size [ 0 ] + 'px' ;
722
+ this . canvas_div . style . height = size [ 1 ] + 'px' ;
666
723
667
724
this . update_canvas ( ) ;
668
725
}
0 commit comments