diff --git a/src/component/Canvas/CanvasEditor/managers/BrushIndicator.js b/src/component/Canvas/CanvasEditor/managers/BrushIndicator.js index b16d3a4e..8f6dccdc 100644 --- a/src/component/Canvas/CanvasEditor/managers/BrushIndicator.js +++ b/src/component/Canvas/CanvasEditor/managers/BrushIndicator.js @@ -38,6 +38,14 @@ export class BrushIndicator { this.currentSize = 10; this.isEnabled = false; this.currentPosition = { x: 0, y: 0 }; + + // 缓存画布状态,用于优化性能 + this._lastCanvasState = { + width: null, + height: null, + zoom: null, + viewportTransform: null, + }; } /** @@ -88,24 +96,80 @@ export class BrushIndicator { _syncCanvasProperties() { if (!this.staticCanvas || !this.canvas) return; - // 同步画布尺寸 - this.staticCanvas.setWidth(this.canvas.width); - this.staticCanvas.setHeight(this.canvas.height); + // 检查是否为笔刷或橡皮擦模式,非相关模式直接返回 + const isBrushMode = + this.canvas.isDrawingMode && this.canvas.freeDrawingBrush; + const isEraserMode = + this.canvas.isDrawingMode && + this.canvas.freeDrawingBrush && + this.canvas.freeDrawingBrush.type === "eraser"; - // 同步缩放 - this.staticCanvas.setZoom(this.canvas.getZoom()); - - // 同步视口变换 - const vpt = this.canvas.viewportTransform; - if (vpt) { - this.staticCanvas.setViewportTransform([...vpt]); + if (!isBrushMode && !isEraserMode) { + return; } - // 同步背景色(可选,通常保持透明) - // this.staticCanvas.backgroundColor = 'transparent'; + let hasChanges = false; - // 重新渲染 - this.staticCanvas.renderAll(); + // 检查画布尺寸是否变化 + const currentWidth = this.canvas.width; + const currentHeight = this.canvas.height; + if ( + currentWidth !== this._lastCanvasState.width || + currentHeight !== this._lastCanvasState.height + ) { + this.staticCanvas.setWidth(currentWidth); + this.staticCanvas.setHeight(currentHeight); + this._lastCanvasState.width = currentWidth; + this._lastCanvasState.height = currentHeight; + hasChanges = true; + } + + // 检查缩放比例是否变化 + const currentZoom = this.canvas.getZoom(); + if (Math.abs(currentZoom - (this._lastCanvasState.zoom || 0)) > 0.001) { + this.staticCanvas.setZoom(currentZoom); + this._lastCanvasState.zoom = currentZoom; + hasChanges = true; + } + + // 检查视口变换是否变化 + const currentVpt = this.canvas.viewportTransform; + if ( + currentVpt && + !this._areViewportTransformsEqual( + currentVpt, + this._lastCanvasState.viewportTransform + ) + ) { + this.staticCanvas.setViewportTransform([...currentVpt]); + this._lastCanvasState.viewportTransform = [...currentVpt]; + hasChanges = true; + } + + // 只有在有变化时才重新渲染 + if (hasChanges) { + this.staticCanvas.renderAll(); + } + } + + /** + * 比较两个视口变换矩阵是否相等 + * @private + * @param {Array} vpt1 视口变换矩阵1 + * @param {Array} vpt2 视口变换矩阵2 + * @returns {Boolean} 是否相等 + */ + _areViewportTransformsEqual(vpt1, vpt2) { + if (!vpt1 || !vpt2) return false; + if (vpt1.length !== vpt2.length) return false; + + const tolerance = 0.001; + for (let i = 0; i < vpt1.length; i++) { + if (Math.abs(vpt1[i] - vpt2[i]) > tolerance) { + return false; + } + } + return true; } /**