|
|
@@ -31,6 +31,14 @@ export default {
|
|
|
options:TextboxConfig.fontFamily,
|
|
|
fontFamilyStyle:"",
|
|
|
opacityValue: 1,
|
|
|
+ clipPreview: {
|
|
|
+ dataUrl: '',
|
|
|
+ maxOffsetX: 0,
|
|
|
+ maxOffsetY: 0,
|
|
|
+ maxWidth: 0,
|
|
|
+ maxHeight: 0,
|
|
|
+ maxRadius: 0,
|
|
|
+ },
|
|
|
layerState: {
|
|
|
fontSize: 16,
|
|
|
lineHeight: 1.2,
|
|
|
@@ -135,6 +143,7 @@ export default {
|
|
|
if (this.editLayer.strokeObj) {
|
|
|
this.fcanvas.add(markRaw(this.editLayer.strokeObj));
|
|
|
}
|
|
|
+ this.updateClipPreview && this.updateClipPreview()
|
|
|
break;
|
|
|
}
|
|
|
},
|
|
|
@@ -407,11 +416,70 @@ export default {
|
|
|
this.updateClipStroke()
|
|
|
this.updateCanvasState();
|
|
|
this.fcanvas.requestRenderAll();
|
|
|
+ this.updateClipPreview && this.updateClipPreview(true)
|
|
|
} catch (error) {
|
|
|
console.error('剪裁区域创建失败:', error);
|
|
|
this.$message.error('剪裁设置错误: ' + error.message);
|
|
|
}
|
|
|
},
|
|
|
+ // 切换剪裁形状,自动填充默认值(位置跟随图层,尺寸为画布一半)
|
|
|
+ onClipShapeChange(shape){
|
|
|
+ if(!this.editLayer || this.editLayer.type !== 'image'){
|
|
|
+ this.clipSettings.shape = shape
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if(!shape){
|
|
|
+ this.clipSettings.shape = ''
|
|
|
+ this.clearClipPath()
|
|
|
+ this.updateClipPreview && this.updateClipPreview(true)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const obj = this.editLayer
|
|
|
+ const bounds = obj.getBoundingRect(true)
|
|
|
+ const canvasW = this.fcanvas?.width || obj.canvas?.width || 800
|
|
|
+ const canvasH = this.fcanvas?.height || obj.canvas?.height || 800
|
|
|
+ const initWidth = Math.max(10, Math.round(canvasW / 2))
|
|
|
+ const initHeight = Math.max(10, Math.round(canvasH / 2))
|
|
|
+ const initRadius = Math.max(5, Math.round(Math.min(canvasW, canvasH) / 4))
|
|
|
+ const initSettings = {
|
|
|
+ shape,
|
|
|
+ offsetX: Math.round(bounds.left),
|
|
|
+ offsetY: Math.round(bounds.top),
|
|
|
+ width: initWidth,
|
|
|
+ height: initHeight,
|
|
|
+ radius: initRadius,
|
|
|
+ rectRadius: this.clipSettings.rectRadius || 0,
|
|
|
+ }
|
|
|
+ this.clipSettings = { ...this.clipSettings, ...initSettings }
|
|
|
+ this.applyClipPath()
|
|
|
+ },
|
|
|
+ // 预览辅助,若用户保持旧样式可忽略 dataUrl
|
|
|
+ updateClipPreview(force=false){
|
|
|
+ if(!this.editLayer || this.editLayer.type !== 'image') return
|
|
|
+ const obj = this.editLayer
|
|
|
+ const bounds = obj.getBoundingRect(true)
|
|
|
+ this.clipPreview = {
|
|
|
+ ...this.clipPreview,
|
|
|
+ maxOffsetX: Math.max(0, Math.floor(bounds.width)),
|
|
|
+ maxOffsetY: Math.max(0, Math.floor(bounds.height)),
|
|
|
+ maxWidth: Math.max(10, Math.floor(bounds.width)),
|
|
|
+ maxHeight: Math.max(10, Math.floor(bounds.height)),
|
|
|
+ maxRadius: Math.max(5, Math.floor(Math.min(bounds.width, bounds.height)/2)),
|
|
|
+ }
|
|
|
+ if(force || this.clipPreview.dataUrl === ''){
|
|
|
+ try{
|
|
|
+ const cloned = obj.clone()
|
|
|
+ const tmp = new fabric.Canvas(document.createElement('canvas'), { width: Math.min(200, bounds.width), height: Math.min(200, bounds.height) })
|
|
|
+ cloned.scaleToWidth(tmp.width)
|
|
|
+ tmp.add(cloned)
|
|
|
+ tmp.renderAll()
|
|
|
+ this.clipPreview.dataUrl = tmp.toDataURL({ format:'png', multiplier:1 })
|
|
|
+ tmp.dispose()
|
|
|
+ }catch(e){
|
|
|
+ console.warn('clip preview failed', e)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
updateClipStroke() {
|
|
|
if (!this.judge() || !this.clipSettings.showClipStroke) return;
|
|
|
|