feat(BrushIndicator): 优化画布属性同步,添加状态缓存以提升性能
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user