@@ -27,6 +27,7 @@ class WorkspacePlugin implements IPluginTempl {
2727 workspaceEl ! : HTMLElement ;
2828 workspace : null | fabric . Rect ;
2929 resizeObserver ! : ResizeObserver ;
30+ coverMask : null | fabric . Rect = null ;
3031 option : any ;
3132 zoomRatio : number ;
3233 constructor ( public canvas : fabric . Canvas , public editor : IEditor ) {
@@ -148,6 +149,69 @@ class WorkspacePlugin implements IPluginTempl {
148149 this . auto ( ) ;
149150 }
150151
152+ setCoverMask ( hack = false ) {
153+ if ( ! this . coverMask || ! this . workspace ) {
154+ return ;
155+ }
156+ const center = this . canvas . getCenter ( ) ;
157+ const zoom = this . canvas . getZoom ( ) ;
158+ this . canvas . zoomToPoint (
159+ new fabric . Point ( center . left , center . top ) ,
160+ hack ? zoom - 0.0000001 : zoom // 比较hack的方法,判断为fabric内部的数据更新问题
161+ ) ;
162+ if ( zoom ) {
163+ const { workspaceEl } = this ;
164+ const width = workspaceEl . offsetWidth ;
165+ const height = workspaceEl . offsetHeight ;
166+ const cWidth = width / zoom ;
167+ const cHeight = height / zoom ;
168+ this . coverMask . width = cWidth ;
169+ this . coverMask . height = cHeight ;
170+ this . coverMask . left = ( this . workspace . left || 0 ) + ( this . workspace . width ! - cWidth ) / 2 ;
171+ this . coverMask . top = ( this . workspace . top || 0 ) + ( this . workspace . height ! - cHeight ) / 2 ;
172+ this . workspace . clone ( ( clone : fabric . Rect ) => {
173+ clone . left = - clone . width ! / 2 ;
174+ clone . top = - clone . height ! / 2 ;
175+ clone . inverted = true ;
176+ this . coverMask ! . objectCaching = false ;
177+ this . coverMask ! . clipPath = clone ;
178+ this . canvas . requestRenderAll ( ) ;
179+ } ) ;
180+ }
181+ }
182+
183+ clipPath ( ) {
184+ if ( this . coverMask ) {
185+ return ;
186+ }
187+ // 超出画布不展示
188+ this . workspace ?. clone ( ( cloned : fabric . Rect ) => {
189+ this . canvas . clipPath = cloned ;
190+ this . canvas . requestRenderAll ( ) ;
191+ } ) ;
192+ }
193+
194+ maskEnable ( needBindLoadJSON = true ) {
195+ const coverMask = new fabric . Rect ( {
196+ fill : 'rgba(0,0,0,0.7)' ,
197+ id : 'coverMask' ,
198+ strokeWidth : 0 ,
199+ } ) ;
200+ coverMask . set ( 'selectable' , false ) ;
201+ coverMask . set ( 'hasControls' , false ) ;
202+ coverMask . set ( 'evented' , false ) ;
203+ coverMask . hoverCursor = 'default' ;
204+ this . canvas . on ( 'object:added' , ( ) => {
205+ coverMask . bringToFront ( ) ;
206+ } ) ;
207+ this . canvas . clipPath = undefined ;
208+ this . canvas . add ( coverMask ) ;
209+ this . coverMask = coverMask ;
210+ this . setCoverMask ( ) ;
211+ // 适配模板和psd的loadjson,在加载完成后再入mask
212+ needBindLoadJSON && this . editor . on ( 'loadJson' , ( ) => this . maskEnable ( false ) ) ;
213+ }
214+
151215 setZoomAuto ( scale : number , cb ?: ( left ?: number , top ?: number ) => void ) {
152216 const { workspaceEl } = this ;
153217 const width = workspaceEl . offsetWidth ;
@@ -159,12 +223,8 @@ class WorkspacePlugin implements IPluginTempl {
159223 this . canvas . zoomToPoint ( new fabric . Point ( center . left , center . top ) , scale ) ;
160224 if ( ! this . workspace ) return ;
161225 this . setCenterFromObject ( this . workspace ) ;
162-
163- // 超出画布不展示
164- this . workspace . clone ( ( cloned : fabric . Rect ) => {
165- this . canvas . clipPath = cloned ;
166- this . canvas . requestRenderAll ( ) ;
167- } ) ;
226+ this . setCoverMask ( ) ;
227+ this . clipPath ( ) ;
168228 if ( cb ) cb ( this . workspace . left , this . workspace . top ) ;
169229 }
170230
@@ -212,14 +272,15 @@ class WorkspacePlugin implements IPluginTempl {
212272 }
213273
214274 _bindWheel ( ) {
215- this . canvas . on ( 'mouse:wheel' , function ( this : fabric . Canvas , opt ) {
275+ this . canvas . on ( 'mouse:wheel' , ( opt ) => {
216276 const delta = opt . e . deltaY ;
217- let zoom = this . getZoom ( ) ;
277+ let zoom = this . canvas . getZoom ( ) ;
218278 zoom *= 0.999 ** delta ;
219279 if ( zoom > 20 ) zoom = 20 ;
220280 if ( zoom < 0.01 ) zoom = 0.01 ;
221- const center = this . getCenter ( ) ;
222- this . zoomToPoint ( new fabric . Point ( center . left , center . top ) , zoom ) ;
281+ const center = this . canvas . getCenter ( ) ;
282+ this . canvas . zoomToPoint ( new fabric . Point ( center . left , center . top ) , zoom ) ;
283+ this . setCoverMask ( ) ;
223284 opt . e . preventDefault ( ) ;
224285 opt . e . stopPropagation ( ) ;
225286 } ) ;
0 commit comments