UNPKG

fcr-core

Version:

Core APIs for building online scenes

290 lines (287 loc) 10.7 kB
"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;