UNPKG

@tencentcloud/roomkit-electron-vue3

Version:

<h1 align="center"> TUIRoomKit</h1> Conference (TUIRoomKit) is a product suitable for multi-person audio and video conversation scenarios such as business meetings, webinars, and online education. By integrating this product, you can add room management,

601 lines (600 loc) 17 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); import { fabric } from "fabric"; import EventEmitter from "../emitter.mjs"; import Arrow from "./arrow.mjs"; import initControls from "./initControls.mjs"; import initControlsRotate from "./initControlsRotate.mjs"; import bus from "../../../hooks/useMitt.mjs"; import { DrawingTool } from "../type.mjs"; class FabricCanvas extends EventEmitter { constructor(canvasId) { super(); __publicField(this, "canvas"); __publicField(this, "currentShape", null); __publicField(this, "drawingTool", DrawingTool.None); __publicField(this, "isDrawing", false); __publicField(this, "startX", 0); __publicField(this, "startY", 0); __publicField(this, "endX", 0); __publicField(this, "endY", 0); __publicField(this, "options", { strokeWidth: 5, stroke: "#22262E", fill: "transparent", lineDash: [], opacity: 1 }); __publicField(this, "images", []); __publicField(this, "curImageIndex", 0); __publicField(this, "isValidEraser", false); __publicField(this, "isValidSelection", false); this.canvas = new fabric.Canvas(canvasId, { isDrawingMode: true, selection: false, includeDefaultValues: false, perPixelTargetFind: true }); this.setDrawingTool(DrawingTool.Pencil); initControls(this.canvas); initControlsRotate(this.canvas); this.initEvent(); } getCanvas() { return this.canvas; } renderCanvas(data) { this.loadFromJSON(data, () => { this.renderAll(); }); } setBackgroundColor(color) { this.canvas.setBackgroundColor(color, () => { this.canvas.renderAll(); }); } setBackgroundImage(imageUrl, options) { fabric.Image.fromURL(imageUrl, (image) => { const canvasWidth = this.canvas.getWidth(); const canvasHeight = this.canvas.getHeight(); const scale = canvasHeight / image.height; const imageWidth = image.width * scale; image.set({ scaleX: scale, scaleY: scale, top: 0, left: (canvasWidth - imageWidth) / 2 }); this.canvas.setBackgroundImage( image, () => { this.canvas.renderAll(); }, options ); }); } addObject(object) { this.canvas.add(object); } removeObject(object) { this.canvas.remove(object); } removeAllObject() { this.canvas.getObjects().forEach((obj) => { this.canvas.remove(obj); }); } getObjects() { return this.canvas.getObjects(); } getActiveObject() { return this.canvas.getActiveObject(); } setActiveObject(object) { this.canvas.setActiveObject(object); } resetActiveObject() { const allObjects = this.canvas.getObjects(); const activeSelection = new fabric.ActiveSelection(allObjects, { canvas: this.canvas }); this.canvas.setActiveObject(activeSelection); this.canvas.discardActiveObject(); } setWidth(value) { this.canvas.setWidth(value); } setHeight(value) { this.canvas.setHeight(value); } exitTextEditing() { const activeObject = this.canvas.getActiveObject(); if (activeObject && activeObject.type === "i-text") { activeObject.exitEditing(); } } setObjectsSelectable(objectsSelectable) { this.canvas.getObjects().forEach((obj) => { obj.selectable = objectsSelectable; obj.evented = objectsSelectable; }); this.canvas.perPixelTargetFind = !objectsSelectable; this.canvas.selection = objectsSelectable; if (!objectsSelectable) { this.canvas.renderAll(); } } setEvented() { this.canvas.getObjects().forEach((obj) => { obj.evented = true; }); this.canvas.renderAll(); } clearCanvas() { this.canvas.clear(); } reloadCanvas() { this.clearCanvas(); this.canvas.renderAll(); bus.emit("reload-canvas"); this.setDrawingTool(DrawingTool.Pencil); this.currentShape = null; } setDrawingTool(tool) { if (this.drawingTool === tool) return; this.canvas.isDrawingMode = false; this.drawingTool = tool; this.canvas.discardActiveObject(); this.setObjectsSelectable(false); switch (tool) { case DrawingTool.Pencil: this.drawFreeDraw(); break; case DrawingTool.Eraser: this.setEvented(); this.setEraser(); break; case DrawingTool.Select: this.setObjectsSelectable(true); this.resetActiveObject(); this.canvas.defaultCursor = "move"; break; case DrawingTool.Arrow: this.canvas.defaultCursor = "crosshair"; break; case DrawingTool.Text: this.canvas.defaultCursor = "text"; break; default: this.canvas.defaultCursor = "crosshair"; break; } } setOptions(toolSetting) { this.options = toolSetting.shapeOptions; this.setPencilBrushOptions(); } setTextOptions() { const options = { fontSize: this.options.strokeWidth, fill: this.options.stroke, padding: 5, selectable: false, evented: false }; return options; } setPencilBrushOptions() { this.canvas.freeDrawingBrush.color = this.options.stroke; this.canvas.freeDrawingBrush.width = this.options.strokeWidth; } discardActiveObject() { this.canvas.discardActiveObject(); } drawRect(options) { const rect = new fabric.Rect({ ...this.options, selectable: false, evented: false, strokeUniform: true, noScaleCache: false, strokeDashArray: this.options.lineDash, ...options }); this.canvas.add(rect); this.currentShape = rect; this.canvas.defaultCursor = "crosshair"; } drawTriangle(options) { const triangle = new fabric.Triangle({ ...this.options, selectable: false, evented: false, strokeUniform: true, noScaleCache: false, strokeDashArray: this.options.lineDash, ...options }); this.canvas.add(triangle); this.currentShape = triangle; this.canvas.defaultCursor = "crosshair"; } drawCircle(options) { const circle = new fabric.Circle({ ...this.options, selectable: false, evented: false, strokeUniform: true, noScaleCache: false, strokeDashArray: this.options.lineDash, ...options }); this.canvas.add(circle); this.currentShape = circle; this.canvas.defaultCursor = "crosshair"; } drawEllipse(options) { const ellipse = new fabric.Ellipse({ ...this.options, selectable: false, evented: false, strokeUniform: true, noScaleCache: false, strokeDashArray: this.options.lineDash, ...options }); this.canvas.add(ellipse); this.currentShape = ellipse; this.canvas.defaultCursor = "crosshair"; } drawLine(x1, y1, x2, y2, options) { const line = new fabric.Line([x1, y1, x2, y2], { ...this.options, ...options, selectable: false, strokeDashArray: this.options.lineDash, evented: false, strokeUniform: true, noScaleCache: false }); this.canvas.add(line); this.currentShape = line; this.canvas.defaultCursor = "crosshair"; } drawArrow(x1, y1, x2, y2, options) { const customOptions = { ...options, arrowWidth: (options == null ? void 0 : options.arrowWidth) ?? this.options.strokeWidth, arrowHeight: (options == null ? void 0 : options.arrowHeight) ?? this.options.strokeWidth }; const arrow = new Arrow([x1, y1, x2, y2], { ...this.options, ...customOptions, selectable: false, evented: false, strokeUniform: true, noScaleCache: false }); this.canvas.add(arrow); this.currentShape = arrow; this.canvas.defaultCursor = "crosshair"; } drawFreeDraw() { this.canvas.freeDrawingBrush = new fabric.PencilBrush(this.canvas); this.canvas.freeDrawingBrush.color = this.options.stroke; this.canvas.freeDrawingBrush.width = this.options.strokeWidth; this.canvas.freeDrawingCursor = "default"; this.canvas.isDrawingMode = true; this.currentShape = null; this.canvas.on("path:created", (event) => { const { path } = event; if (path) { path.set({ perPixelTargetFind: true, objectCaching: false, statefullCache: true, strokeUniform: true, noScaleCache: false, subdivisionScale: 100 }); this.canvas.renderAll(); } }); } drawText(text, options) { const textObj = new fabric.IText(text, { fontSize: this.options.strokeWidth, fill: this.options.stroke, padding: 5, selectable: false, evented: false, ...options }); this.canvas.add(textObj); this.canvas.defaultCursor = "text"; this.currentShape = textObj; textObj.enterEditing(); textObj.hiddenTextarea.focus(); textObj.on("editing:exited", () => { if (textObj.text.length > 0) { this.emit("push-canvas-to-stack", null); } else { this.canvas.remove(textObj); } }); this.setActiveObject(textObj); } insertImage(url, options) { fabric.Image.fromURL(url, (img) => { if (options) { img.set(options); } else { const canvasWidth = this.canvas.getWidth(); const canvasHeight = this.canvas.getHeight(); const imageWidth = img.width * img.scaleX; const imageHeight = img.height * img.scaleY; const aspectRatio = imageWidth / imageHeight; const halfCanvasWidth = canvasWidth / 2; const halfCanvasHeight = canvasHeight / 2; let scaledWidth; let scaledHeight; if (aspectRatio > 1) { scaledWidth = halfCanvasWidth; scaledHeight = scaledWidth / aspectRatio; } else { scaledHeight = halfCanvasHeight; scaledWidth = scaledHeight * aspectRatio; } const scale = scaledWidth / imageWidth; img.scale(scale); const left = (canvasWidth - scaledWidth) / 2; const top = (canvasHeight - scaledHeight) / 2; img.set({ left, top }); } this.canvas.add(img); this.setDrawingTool(DrawingTool.Select); this.setActiveObject(img); this.emit("push-canvas-to-stack", null); this.canvas.requestRenderAll(); this.emit("insert-images", null); }); } insertPPT(urls) { this.images = urls; this.setCurrentScense(0); this.emit("insert:images", urls); } setCurrentScense(index) { this.curImageIndex = index; this.setBackgroundImage(this.images[this.curImageIndex]); this.emit("current:image", index); } setEraser() { this.canvas.renderAll(); } initEvent() { this.canvas.on("mouse:down", this.onMouseDown.bind(this)); this.canvas.on("mouse:move", this.onMouseMove.bind(this)); this.canvas.on("mouse:up", this.onMouseUp.bind(this)); this.canvas.on("object:moving", this.onObjectMoving.bind(this)); this.canvas.on("object:scaling", this.onObjectScaling.bind(this)); this.canvas.on("object:rotating", this.onObjectRotating.bind(this)); bus.on("exitTextEditing", this.exitTextEditing.bind(this)); } onMouseDown(event) { var _a; if (this.drawingTool === DrawingTool.Eraser) { this.isDrawing = true; const target = this.canvas.findTarget(event.e, false); if (target) { ((_a = target.group) == null ? void 0 : _a.removeWithUpdate(target)) || this.canvas.remove(target); this.isValidEraser = true; } this.canvas.renderAll(); return; } const activeObject = this.canvas.getActiveObject(); if (!event.pointer || activeObject) return; this.isDrawing = true; const { x, y } = event.pointer; this.startX = x; this.startY = y; this.endX = this.startX; this.endY = this.startY; switch (this.drawingTool) { case DrawingTool.Pencil: this.setPencilBrushOptions(); break; case DrawingTool.Rectangle: this.drawRect({ left: x, top: y, width: 0, height: 0 }); break; case DrawingTool.Triangle: this.drawTriangle({ left: x, top: y, width: 0, height: 0 }); break; case DrawingTool.Circle: this.drawCircle({ left: x, top: y, radius: 0 }); break; case DrawingTool.Ellipse: this.drawEllipse({ left: x, top: y, rx: 0, ry: 0 }); break; case DrawingTool.Line: this.drawLine(x, y, x, y); break; case DrawingTool.Arrow: this.drawArrow(x, y, x, y, { arrowWidth: this.options.strokeWidth, arrowHeight: this.options.strokeWidth }); break; case DrawingTool.Text: this.drawText("", { options: this.setTextOptions(), left: x, top: y }); break; } } onMouseMove(event) { var _a; if (!event.pointer) { return; } const { x, y } = event.pointer; this.endX = x; this.endY = y; if (this.drawingTool === DrawingTool.Eraser && this.isDrawing) { const target = this.canvas.findTarget(event.e, false); if (target) { ((_a = target.group) == null ? void 0 : _a.removeWithUpdate(target)) || this.canvas.remove(target); this.isValidEraser = true; } this.canvas.renderAll(); } if (!this.isDrawing || !this.currentShape) { return; } const width = Math.abs(x - this.startX); const height = Math.abs(y - this.startY); const left = Math.min(this.startX, x); const top = Math.min(this.startY, y); switch (this.drawingTool) { case DrawingTool.Rectangle: this.currentShape.set({ left, top, width, height }); break; case DrawingTool.Triangle: this.currentShape.set({ left, top, width, height }); break; case DrawingTool.Circle: { const radius = Math.sqrt(width * width + height * height) / 2; this.currentShape.set({ left, top, radius }); } break; case DrawingTool.Ellipse: this.currentShape.set({ left, top, rx: width / 2, ry: height / 2 }); break; case DrawingTool.Line: this.currentShape.set({ x2: x, y2: y }); break; case DrawingTool.Arrow: this.currentShape.set({ x2: x, y2: y }); break; } this.currentShape.setCoords(); this.canvas.renderAll(); } onMouseUp() { if (this.isNeedPushToStack()) { this.emit("push-canvas-to-stack", null); } this.isDrawing = false; this.currentShape = null; this.isValidEraser = false; this.isValidSelection = false; } onObjectMoving(event) { this.canvas.renderAll(); this.isValidSelection = true; } onObjectScaling(event) { this.canvas.renderAll(); this.isValidSelection = true; } onObjectRotating(event) { this.canvas.renderAll(); this.isValidSelection = true; } isNeedPushToStack() { if (this.drawingTool === DrawingTool.Text || this.isValidEraser === false && this.drawingTool === DrawingTool.Eraser || this.isValidSelection === false && this.drawingTool === DrawingTool.Pointer || this.isValidSelection === false && this.drawingTool === DrawingTool.Laser) { return false; } if (this.startX === this.endX && this.startY === this.endY) { if (this.currentShape !== null) { this.canvas.remove(this.currentShape); return false; } } return true; } toDataURL(options) { return this.canvas.toDataURL(options); } toJSON() { return this.canvas.toJSON(); } loadFromJSON(json, callback, reviver) { return this.canvas.loadFromJSON(json, callback, reviver); } renderAll() { return this.canvas.renderAll(); } requestRenderAll() { return this.canvas.requestRenderAll(); } zoom(ratio = 1) { const point = new fabric.Point( this.canvas.width / 2, this.canvas.height / 2 ); this.canvas.zoomToPoint(point, ratio); } getZoom() { return this.canvas.getZoom(); } zoomIn() { this.zoom(this.canvas.getZoom() * 1.1); } zoomOut() { this.zoom(this.canvas.getZoom() / 1.1); } destroy() { this.removeAllListeners(); this.canvas.dispose(); } } export { FabricCanvas as default };