105 lines
2.8 KiB
TypeScript
105 lines
2.8 KiB
TypeScript
import { fabric } from 'fabric-with-all'
|
|
import { ref } from 'vue'
|
|
import { createCanvas } from '../tools/canvasFactory'
|
|
import { AnimationManager } from './AnimationManager'
|
|
import { detectDeviceType } from '../tools/index'
|
|
import { CanvasEventManager } from "./events/CanvasEventManager";
|
|
import { OperationType } from '../tools/layerHelper'
|
|
|
|
interface CanvasInitOptions {
|
|
canvasRef: any
|
|
canvasViewWidth?: number
|
|
canvasViewHeight?: number
|
|
canvasWidth?: number
|
|
canvasHeight?: number
|
|
}
|
|
export class CanvasManager {
|
|
stateManager: any
|
|
deviceInfo: any
|
|
canvas: any
|
|
canvasViewWidth: number
|
|
canvasViewHeight: number
|
|
canvasWidth: number
|
|
canvasHeight: number
|
|
currentZoom: any
|
|
animationManager: any
|
|
eventManager: any
|
|
constructor(options) {
|
|
this.stateManager = options.stateManager;
|
|
this.deviceInfo = detectDeviceType();
|
|
this.currentZoom = ref(100)
|
|
}
|
|
setCanvasViewSize(options) {
|
|
this.canvasViewWidth = options.canvasViewWidth || 1920
|
|
this.canvasViewHeight = options.canvasViewHeight || 1080
|
|
}
|
|
initCanvas(options: CanvasInitOptions) {
|
|
this.setCanvasViewSize(options)
|
|
this.canvasWidth = options.canvasWidth || 750
|
|
this.canvasHeight = options.canvasHeight || 600
|
|
this.canvas = createCanvas(options.canvasRef.value, {
|
|
width: this.canvasViewWidth,
|
|
height: this.canvasViewHeight,
|
|
preserveObjectStacking: true,
|
|
enableRetinaScaling: true,
|
|
stopContextMenu: true,
|
|
fireRightClick: true,
|
|
backgroundColor: '#fff',
|
|
})
|
|
this.canvas.clipPath = new fabric.Rect({
|
|
left: 0,
|
|
top: 0,
|
|
width: this.canvasWidth,
|
|
height: this.canvasHeight
|
|
})
|
|
// 画布居中
|
|
const canvasX = this.canvasViewWidth / 2 - this.canvasWidth / 2
|
|
const canvasY = this.canvasViewHeight / 2 - this.canvasHeight / 2
|
|
this.canvas.viewportTransform = [1, 0, 0, 1, canvasX, canvasY]
|
|
// 创建矩形
|
|
const rect = new fabric.Rect({
|
|
left: 20,
|
|
top: 20,
|
|
width: 100,
|
|
height: 100,
|
|
fill: '#f00'
|
|
})
|
|
this.canvas.add(rect)
|
|
//创建圆形
|
|
const circle = new fabric.Circle({
|
|
left: 200,
|
|
top: 200,
|
|
radius: 50,
|
|
fill: '#0f0'
|
|
})
|
|
this.canvas.add(circle)
|
|
this.animationManager = new AnimationManager(this.canvas, {
|
|
currentZoom: this.currentZoom,
|
|
canvasManager: this,
|
|
wheelThrottleTime: 15, // 降低滚轮事件节流时间,提高响应性
|
|
defaultEase: "power2.lin",
|
|
defaultDuration: 0.3, // 缩短默认动画时间
|
|
});
|
|
this.setupCanvasEvents()
|
|
this.stateManager.toolManager.setTool(OperationType.PAN)
|
|
|
|
|
|
}
|
|
setupCanvasEvents() {
|
|
// 创建画布事件管理器
|
|
this.eventManager = new CanvasEventManager(this.canvas, {
|
|
canvasManager: this,
|
|
animationManager: this.animationManager,
|
|
toolManager: this.stateManager.toolManager,
|
|
});
|
|
// 设置动画交互效果
|
|
this.animationManager.setupInteractionAnimations();
|
|
}
|
|
resetZoom() {
|
|
this.animationManager.resetZoom()
|
|
}
|
|
|
|
|
|
|
|
}
|