@@ -24,6 +24,10 @@ import type {Coordinate} from 'ol/coordinate';
24
24
import type { FeatureType } from './TrackData' ;
25
25
import type { Snapper } from 'src/snapper' ;
26
26
import { Densifier } from 'src/densifier' ;
27
+ import { Extent } from "ol/extent" ;
28
+ import { EventsKey } from 'ol/events' ;
29
+ import RenderEvent from "ol/render/Event" ;
30
+ import { unByKey } from "ol/Observable" ;
27
31
28
32
export type TrackMode = 'edit' | '' ;
29
33
export type TrackSubMode = 'addpoi' | 'editpoi' | '' ;
@@ -74,6 +78,16 @@ export interface Options {
74
78
* Pixel tolerance for considering the pointer close enough to a segment for snapping.
75
79
*/
76
80
hitTolerance : number ;
81
+
82
+ /**
83
+ * Drawing area extent.
84
+ */
85
+ drawExtent ?: Extent ;
86
+
87
+ /**
88
+ * Drawing mask color. CSS string
89
+ */
90
+ drawMaskColor ?: string ;
77
91
}
78
92
79
93
@@ -115,6 +129,10 @@ export default class TrackManager<POIMeta> {
115
129
private interaction_ : TrackInteraction ;
116
130
private historyManager_ = new HistoryManager < Feature < Point | LineString > [ ] > ( ) ;
117
131
132
+ private drawExtent_ : Extent | undefined ;
133
+ private drawMaskColor_ : string = 'rgba(241, 245, 249, 1)' ;
134
+ private addDrawingMaskKey_ : EventsKey | undefined ;
135
+
118
136
constructor ( options : Options ) {
119
137
this . map_ = options . map ;
120
138
this . source_ = options . trackLayer . getSource ( ) ;
@@ -134,6 +152,11 @@ export default class TrackManager<POIMeta> {
134
152
trackData : this . trackData_
135
153
} ) ;
136
154
155
+ this . drawExtent_ = options . drawExtent ;
156
+ if ( options . drawMaskColor ) {
157
+ this . drawMaskColor_ = options . drawMaskColor ;
158
+ }
159
+
137
160
this . interaction_ = new TrackInteraction ( {
138
161
style : options . style ,
139
162
trackData : this . trackData_ ,
@@ -143,6 +166,7 @@ export default class TrackManager<POIMeta> {
143
166
addLastPointCondition : options . addLastPointCondition ,
144
167
addControlPointCondition : options . addControlPointCondition ,
145
168
hitTolerance : this . hitTolerance_ ,
169
+ drawExtent : options . drawExtent ,
146
170
} ) ;
147
171
148
172
// Hack to test profile synchro
@@ -331,6 +355,10 @@ export default class TrackManager<POIMeta> {
331
355
this . map_ . once ( "postrender" , ( ) => {
332
356
this . interaction_ . addMapInOutEventListeners ( this . map_ . getViewport ( ) ) ;
333
357
} ) ;
358
+
359
+ if ( this . drawExtent_ ) {
360
+ this . addDrawingMaskKey_ = this . map_ . on ( 'postcompose' , ( evt ) => this . addDrawingMask ( evt , this . drawExtent_ ) ) ;
361
+ }
334
362
} else {
335
363
this . historyManager_ . clear ( ) ;
336
364
if ( this . shadowTrackLayer_ ) {
@@ -339,6 +367,10 @@ export default class TrackManager<POIMeta> {
339
367
if ( this . map_ ?. getViewport ( ) ) {
340
368
this . interaction_ . removeMapInOutEventListeners ( this . map_ . getViewport ( ) ) ;
341
369
}
370
+ if ( this . addDrawingMaskKey_ ) {
371
+ unByKey ( this . addDrawingMaskKey_ ) ;
372
+ this . addDrawingMaskKey_ = undefined ;
373
+ }
342
374
}
343
375
this . interaction_ . setActive ( edit ) ;
344
376
this . mode_ = mode || '' ;
@@ -614,4 +646,36 @@ export default class TrackManager<POIMeta> {
614
646
this . source_ . changed ( ) ;
615
647
this . shadowTrackLayer_ . getSource ( ) . changed ( ) ;
616
648
}
649
+
650
+ addDrawingMask ( event : RenderEvent , extent : Extent ) {
651
+ if ( ! extent ?. length ) return ;
652
+ const viewport = event . target . getViewport ( ) ;
653
+ const canvases = viewport . getElementsByTagName ( 'canvas' ) ;
654
+ const canvas = canvases . item ( canvases . length - 1 ) ;
655
+ const context = canvas . getContext ( '2d' ) ;
656
+
657
+ const coordinates = [
658
+ [ extent [ 0 ] , extent [ 1 ] ] , // Bottom-left
659
+ [ extent [ 0 ] , extent [ 3 ] ] , // Top-left
660
+ [ extent [ 2 ] , extent [ 3 ] ] , // Top-right
661
+ [ extent [ 2 ] , extent [ 1 ] ] , // Bottom-right
662
+ ] ;
663
+
664
+ const pixelCoordinates = coordinates . map ( ( coord ) => this . map_ . getPixelFromCoordinate ( coord ) ) ;
665
+
666
+ context . beginPath ( ) ;
667
+
668
+ // outer rectangle
669
+ context . rect ( 0 , 0 , canvas . width , canvas . height ) ;
670
+
671
+ const width = pixelCoordinates [ 3 ] [ 0 ] - pixelCoordinates [ 0 ] [ 0 ] ;
672
+ const height = pixelCoordinates [ 1 ] [ 1 ] - pixelCoordinates [ 0 ] [ 1 ] ;
673
+
674
+ // inner rectangle
675
+ context . rect ( pixelCoordinates [ 0 ] [ 0 ] , pixelCoordinates [ 0 ] [ 1 ] , width , height ) ;
676
+
677
+ context . closePath ( ) ;
678
+ context . fillStyle = this . drawMaskColor_ ;
679
+ context . fill ( 'evenodd' ) ;
680
+ }
617
681
}
0 commit comments