fcr-core
Version:
Core APIs for building online scenes
290 lines (287 loc) • 10.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.windowClassName = exports.widgetContainerClassName = exports.videoRowClassName = exports.verticalPadding = exports.toolbarClassName = exports.textColors = exports.src2DataURL = exports.sceneNavHeight = exports.mergeCanvasImage = exports.mediaMimeTypes = exports.layoutContentClassName = exports.hexColorToWhiteboardColor = exports.heightPerTool = exports.heightPerColor = exports.getImageSize = exports.fetchImageInfoByUrl = exports.defaultToolsRetain = exports.defaultTextSize = exports.defaultStrokeColor = exports.convertToNetlessStorkeType = exports.convertToNetlessBoardTool = exports.convertToFcrBoardToolShape = exports.WINDOW_TITLE_HEIGHT = exports.WINDOW_REMAIN_SIZE = exports.WINDOW_REMAIN_POSITION = exports.WINDOW_MIN_SIZE = exports.WINDOW_ASPECT_RATIO = void 0;
require("core-js/modules/es.array.push.js");
require("core-js/modules/es.regexp.exec.js");
require("core-js/modules/es.string.replace.js");
require("core-js/modules/web.dom-collections.iterator.js");
var _jsMd = require("js-md5");
var _enum = require("./enum");
var _appliancePlugin = require("@netless/appliance-plugin");
const heightPerTool = exports.heightPerTool = 36;
const heightPerColor = exports.heightPerColor = 18;
const defaultToolsRetain = exports.defaultToolsRetain = heightPerTool * 6;
const verticalPadding = exports.verticalPadding = 10;
const sceneNavHeight = exports.sceneNavHeight = heightPerTool + verticalPadding;
const widgetContainerClassName = exports.widgetContainerClassName = 'netless-whiteboard-wrapper';
const layoutContentClassName = exports.layoutContentClassName = 'fcr-layout-content-main-view';
const videoRowClassName = exports.videoRowClassName = 'fcr-layout-content-video-list-row';
const toolbarClassName = exports.toolbarClassName = 'fcr-board-toolbar';
const windowClassName = exports.windowClassName = 'netless-whiteboard-wrapper';
const WINDOW_TITLE_HEIGHT = exports.WINDOW_TITLE_HEIGHT = 28;
// width / height
const WINDOW_ASPECT_RATIO = exports.WINDOW_ASPECT_RATIO = 1836 / 847;
const WINDOW_MIN_SIZE = exports.WINDOW_MIN_SIZE = {
width: 653,
height: 336
};
const WINDOW_REMAIN_SIZE = exports.WINDOW_REMAIN_SIZE = {
width: 783,
height: 388
};
const WINDOW_REMAIN_POSITION = exports.WINDOW_REMAIN_POSITION = {
x: 0,
y: 171
};
/**
* 根据
* @param imageInnerSize
* @returns
*/
const getImageSize = (imageInnerSize, containerSize) => {
const windowSize = containerSize;
const widthHeightProportion = imageInnerSize.width / imageInnerSize.height;
const maxSize = 960;
if (imageInnerSize.width > maxSize && windowSize.width > maxSize || imageInnerSize.height > maxSize && windowSize.height > maxSize) {
if (widthHeightProportion > 1) {
return {
width: maxSize,
height: maxSize / widthHeightProportion
};
} else {
return {
width: maxSize * widthHeightProportion,
height: maxSize
};
}
} else {
if (imageInnerSize.width > windowSize.width || imageInnerSize.height > windowSize.height) {
if (widthHeightProportion > 1) {
return {
width: windowSize.width,
height: windowSize.width / widthHeightProportion
};
} else {
return {
width: windowSize.height * widthHeightProportion,
height: windowSize.height
};
}
} else {
return {
width: imageInnerSize.width,
height: imageInnerSize.height
};
}
}
};
/**
*
* @param url
* @returns
*/
exports.getImageSize = getImageSize;
const fetchImageInfoByUrl = async (url, containerSize) => {
try {
const res = await fetch(url);
const blob = await res.blob();
const contentType = blob.type;
const image = new Image();
const reader = new FileReader();
const file = new File([blob], url, {
type: contentType
});
const result = await new Promise(resolve => {
reader.readAsDataURL(blob);
reader.onload = () => {
image.addEventListener('load', () => {
const uuid = (0, _jsMd.md5)(reader.result);
const res = getImageSize(image, containerSize);
const result = {
width: res.width,
height: res.height,
file: file,
url,
uuid
};
resolve(result);
}, false);
image.src = reader.result;
};
});
return result;
} catch (err) {
throw err;
}
};
exports.fetchImageInfoByUrl = fetchImageInfoByUrl;
const mergeCanvasImage = async scenes => {
let width = 0,
height = 0;
const bigCanvas = document.createElement('canvas');
const ctx = bigCanvas.getContext('2d');
const canvasArray = [];
for (const canvasPromise of scenes) {
const canvas = await canvasPromise();
if (canvas) {
width = Math.max(canvas.width, width);
height = Math.max(canvas.height, height);
canvasArray.push(canvas);
}
}
bigCanvas.setAttribute('width', "".concat(width));
bigCanvas.setAttribute('height', "".concat(height * canvasArray.length));
canvasArray.forEach((canvas, index) => {
ctx && ctx.drawImage(canvas, 0, index * height, width, height);
});
return bigCanvas;
};
exports.mergeCanvasImage = mergeCanvasImage;
const textColors = exports.textColors = ['#ffffff', '#9b9b9b', '#4a4a4a', '#000000', '#d0021b', '#f5a623', '#f8e71c', '#7ed321', '#9013fe', '#50e3c2', '#0073ff', '#ffc8e2'];
const defaultStrokeColor = exports.defaultStrokeColor = {
r: 0,
g: 115,
b: 255
};
const defaultTextSize = exports.defaultTextSize = 24;
const mediaMimeTypes = exports.mediaMimeTypes = {
opus: 'video/ogg',
ogv: 'video/ogg',
mp4: 'video/mp4',
mov: 'video/mp4',
m4v: 'video/mp4',
mkv: 'video/x-matroska',
m4a: 'audio/mp4',
mp3: 'audio/mpeg',
aac: 'audio/aac',
caf: 'audio/x-caf',
flac: 'audio/flac',
oga: 'audio/ogg',
wav: 'audio/wav',
m3u8: 'application/x-mpegURL',
jpg: 'image/jpeg',
jpeg: 'image/jpeg',
gif: 'image/gif',
png: 'image/png',
svg: 'image/svg+xml',
webp: 'image/webp'
};
const convertToNetlessBoardTool = tool => {
switch (tool) {
case _enum.FcrBoardToolType.SELECTOR:
return [_enum.ApplianceNames.selector];
case _enum.FcrBoardToolType.ERASER:
return [_enum.ApplianceNames.pencilEraser];
case _enum.FcrBoardToolType.LASER_POINTER:
return [_enum.ApplianceNames.laserPointer];
case _enum.FcrBoardToolType.HAND:
return [_enum.ApplianceNames.hand];
case _enum.FcrBoardToolType.TEXT:
return [_enum.ApplianceNames.text];
case _enum.FcrBoardToolType.ARROW:
return [_enum.ApplianceNames.arrow];
case _enum.FcrBoardToolType.RECTANGLE:
return [_enum.ApplianceNames.rectangle];
case _enum.FcrBoardToolType.ELLIPSE:
return [_enum.ApplianceNames.ellipse];
case _enum.FcrBoardToolType.STRAIGHT:
return [_enum.ApplianceNames.straight];
case _enum.FcrBoardToolType.CURVE:
return [_enum.ApplianceNames.pencil];
case _enum.FcrBoardToolType.TRIANGLE:
return [_enum.ApplianceNames.shape, _enum.ShapeType.Triangle];
case _enum.FcrBoardToolType.PENTAGRAM:
return [_enum.ApplianceNames.shape, _enum.ShapeType.Pentagram];
case _enum.FcrBoardToolType.RHOMBUS:
return [_enum.ApplianceNames.shape, _enum.ShapeType.Rhombus];
case _enum.FcrBoardToolType.DOTTED_LINE:
case _enum.FcrBoardToolType.LONG_DOTTED_LINE:
return [_enum.ApplianceNames.straight];
case _enum.FcrBoardToolType.NONE:
return [_enum.ApplianceNames.clicker];
default:
return [];
}
};
exports.convertToNetlessBoardTool = convertToNetlessBoardTool;
const convertToNetlessStorkeType = type => {
switch (type) {
case _enum.FcrBoardToolType.DOTTED_LINE:
return _appliancePlugin.EStrokeType.Dotted;
case _enum.FcrBoardToolType.LONG_DOTTED_LINE:
return _appliancePlugin.EStrokeType.LongDotted;
default:
return _appliancePlugin.EStrokeType.Normal;
}
};
exports.convertToNetlessStorkeType = convertToNetlessStorkeType;
const convertToFcrBoardToolShape = (tool, shape) => {
switch (tool) {
case _enum.ApplianceNames.selector:
return [_enum.FcrBoardToolType.SELECTOR];
case _enum.ApplianceNames.eraser:
return [_enum.FcrBoardToolType.ERASER];
case _enum.ApplianceNames.laserPointer:
return [_enum.FcrBoardToolType.LASER_POINTER];
case _enum.ApplianceNames.text:
return [_enum.FcrBoardToolType.TEXT];
case _enum.ApplianceNames.hand:
return [_enum.FcrBoardToolType.HAND];
}
switch ("".concat(tool || '').concat(shape || '')) {
case "".concat(_enum.ApplianceNames.rectangle):
return [, _enum.FcrBoardShape.Rectangle];
case "".concat(_enum.ApplianceNames.ellipse):
return [, _enum.FcrBoardShape.Ellipse];
case "".concat(_enum.ApplianceNames.straight):
return [, _enum.FcrBoardShape.Straight];
case "".concat(_enum.ApplianceNames.arrow):
return [, _enum.FcrBoardShape.Arrow];
case "".concat(_enum.ApplianceNames.pencil):
return [, _enum.FcrBoardShape.Curve];
case "".concat(_enum.ApplianceNames.shape).concat(_enum.ShapeType.Triangle):
return [, _enum.FcrBoardShape.Triangle];
case "".concat((_enum.ApplianceNames.shape, _enum.ShapeType.Pentagram)):
return [, _enum.FcrBoardShape.Pentagram];
case "".concat(_enum.ApplianceNames.shape).concat(_enum.ShapeType.Rhombus):
return [, _enum.FcrBoardShape.Rhombus];
}
return [];
};
exports.convertToFcrBoardToolShape = convertToFcrBoardToolShape;
const hexColorToWhiteboardColor = val => {
const pattern = /^(#?)[a-fA-F0-9]{6}$/; // 16进制颜色校验规则
if (!pattern.test(val)) {
return [255, 255, 255];
}
const v = val.replace(/#/, '');
const rgbArr = [];
for (let i = 0; i < 3; i++) {
const item = v.substring(i * 2, i * 2 + 2);
const num = parseInt(item, 16);
rgbArr.push(num);
}
return rgbArr;
};
exports.hexColorToWhiteboardColor = hexColorToWhiteboardColor;
const src2DataURL = src => {
return new Promise((resolve, reject) => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const image = new Image();
image.onload = () => {
canvas.setAttribute('width', "".concat(image.width));
canvas.setAttribute('height', "".concat(image.height));
ctx === null || ctx === void 0 || ctx.drawImage(image, 0, 0);
resolve(canvas.toDataURL('image/jpeg', 0.8));
};
image.onerror = () => {
reject('error');
};
image.crossOrigin = 'anonymous';
image.src = src;
});
};
exports.src2DataURL = src2DataURL;