@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.4 kB
JavaScript
"use strict";
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);
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const fabric = require("fabric");
const emitter = require("../emitter.js");
const arrow = require("./arrow.js");
const initControls = require("./initControls.js");
const initControlsRotate = require("./initControlsRotate.js");
const useMitt = require("../../../hooks/useMitt.js");
const type = require("../type.js");
class FabricCanvas extends emitter.default {
constructor(canvasId) {
super();
__publicField(this, "canvas");
__publicField(this, "currentShape", null);
__publicField(this, "drawingTool", type.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.fabric.Canvas(canvasId, {
isDrawingMode: true,
selection: false,
includeDefaultValues: false,
perPixelTargetFind: true
});
this.setDrawingTool(type.DrawingTool.Pencil);
initControls.default(this.canvas);
initControlsRotate.default(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.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.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();
useMitt.default.emit("reload-canvas");
this.setDrawingTool(type.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 type.DrawingTool.Pencil:
this.drawFreeDraw();
break;
case type.DrawingTool.Eraser:
this.setEvented();
this.setEraser();
break;
case type.DrawingTool.Select:
this.setObjectsSelectable(true);
this.resetActiveObject();
this.canvas.defaultCursor = "move";
break;
case type.DrawingTool.Arrow:
this.canvas.defaultCursor = "crosshair";
break;
case type.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.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.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.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.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.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$1 = new arrow.default([x1, y1, x2, y2], {
...this.options,
...customOptions,
selectable: false,
evented: false,
strokeUniform: true,
noScaleCache: false
});
this.canvas.add(arrow$1);
this.currentShape = arrow$1;
this.canvas.defaultCursor = "crosshair";
}
drawFreeDraw() {
this.canvas.freeDrawingBrush = new fabric.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.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.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(type.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));
useMitt.default.on("exitTextEditing", this.exitTextEditing.bind(this));
}
onMouseDown(event) {
var _a;
if (this.drawingTool === type.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 type.DrawingTool.Pencil:
this.setPencilBrushOptions();
break;
case type.DrawingTool.Rectangle:
this.drawRect({
left: x,
top: y,
width: 0,
height: 0
});
break;
case type.DrawingTool.Triangle:
this.drawTriangle({
left: x,
top: y,
width: 0,
height: 0
});
break;
case type.DrawingTool.Circle:
this.drawCircle({
left: x,
top: y,
radius: 0
});
break;
case type.DrawingTool.Ellipse:
this.drawEllipse({
left: x,
top: y,
rx: 0,
ry: 0
});
break;
case type.DrawingTool.Line:
this.drawLine(x, y, x, y);
break;
case type.DrawingTool.Arrow:
this.drawArrow(x, y, x, y, {
arrowWidth: this.options.strokeWidth,
arrowHeight: this.options.strokeWidth
});
break;
case type.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 === type.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 type.DrawingTool.Rectangle:
this.currentShape.set({
left,
top,
width,
height
});
break;
case type.DrawingTool.Triangle:
this.currentShape.set({
left,
top,
width,
height
});
break;
case type.DrawingTool.Circle:
{
const radius = Math.sqrt(width * width + height * height) / 2;
this.currentShape.set({
left,
top,
radius
});
}
break;
case type.DrawingTool.Ellipse:
this.currentShape.set({
left,
top,
rx: width / 2,
ry: height / 2
});
break;
case type.DrawingTool.Line:
this.currentShape.set({
x2: x,
y2: y
});
break;
case type.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 === type.DrawingTool.Text || this.isValidEraser === false && this.drawingTool === type.DrawingTool.Eraser || this.isValidSelection === false && this.drawingTool === type.DrawingTool.Pointer || this.isValidSelection === false && this.drawingTool === type.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.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();
}
}
exports.default = FabricCanvas;