"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); var fc_hotkeys_1 = require("fc-hotkeys"); var debounce = require("lodash.debounce"); var index_1 = require("./../Baseboard/index"); var toolbar_items_1 = require("./../../toolbar/toolbar-items"); var Synthetizer_1 = require("../../renderer/Synthetizer"); var Toolbar_1 = require("../../toolbar/Toolbar"); require("./index.less"); var layout_1 = require("../../utils/layout"); var index_2 = require("../../markers/RectMarker/index"); var index_3 = require("../../markers/HighlightMarker/index"); var index_4 = require("../../markers/CoverMarker/index"); var index_5 = require("../../markers/LineMarker/index"); var index_6 = require("../../markers/ArrowMarker/index"); var index_7 = require("../../markers/TextMarker/index"); var Drawboard = (function (_super) { __extends(Drawboard, _super); function Drawboard(source, _a) { var _b = _a === void 0 ? {} : _a, _c = _b.allowKeyboard, allowKeyboard = _c === void 0 ? true : _c, extraToolbarItems = _b.extraToolbarItems, mountContainer = _b.mountContainer, page = _b.page, zIndex = _b.zIndex, onChange = _b.onChange; var _this = _super.call(this, source) || this; _this.mountContainer = document.body; _this.scale = 1.0; _this.zIndex = 999; _this.allowKeyboard = true; _this.onComplete = function () { }; _this.onChange = function () { }; _this.open = function (onComplete, onCancel) { if (onComplete) { _this.onComplete = onComplete; } if (onCancel) { _this.onCancel = onCancel; } _this.setTargetRect(); _this.initBoard(_this.mountContainer); _this.attachEvents(); _this.setStyles(); window.addEventListener('resize', _this.adjustUI); if ((_this.page && _this.page.mode === 'master') || !_this.page) { _this.showUI(); } }; _this.hide = function () { if (_this.source.imgSrc) { _this.target.style.display = 'none'; } _this.boardHolder.style.visibility = 'hidden'; _this.boardHolder.style.zIndex = '-1'; if (_this.toolbar) { _this.toolbar.hide(); } }; _this.show = function () { if (_this.source.imgSrc) { _this.target.style.display = 'block'; } _this.boardHolder.style.visibility = 'visible'; _this.boardHolder.style.zIndex = "" + _this.zIndex; if (_this.toolbar) { _this.toolbar.show(); } }; _this.destroy = function () { if (_this.toolbarUI) { _this.mountContainer.removeChild(_this.toolbarUI); } if (_this.boardCanvas) { _this.mountContainer.removeChild(_this.boardHolder); } if (_this.listener) { _this.listener.reset(); } }; _this.render = function (onComplete, onCancel) { _this.onComplete = onComplete; if (onCancel) { _this.onCancel = onCancel; } _this.selectMarker(null); _this.startRender(_this.renderFinished); }; _this.addMarker = function (markerType, _a) { var _b = _a === void 0 ? {} : _a, id = _b.id, originX = _b.originX, originY = _b.originY; var marker = markerType.createMarker(_this.page); if (id) { marker.id = id; } marker.drawboard = _this; marker.onSelected = _this.selectMarker; marker.onChange = _this.onChange; if (marker.defs && marker.defs.length > 0) { for (var _i = 0, _c = marker.defs; _i < _c.length; _i++) { var d = _c[_i]; if (d.id && !_this.boardCanvas.getElementById(d.id)) { _this.defs.appendChild(d); } } } _this.markers.push(marker); _this.selectMarker(marker); _this.boardCanvas.appendChild(marker.visual); var x; var y; if (originX && originY) { x = originX; y = originY; } else { var bbox = marker.visual.getBBox(); x = _this.width / 2 / _this.scale - bbox.width / 2; y = _this.height / 2 / _this.scale - bbox.height / 2; } _this.onChange({ target: 'marker', parentId: _this.page ? _this.page.id : _this.id, event: 'addMarker', marker: { type: marker.type, id: marker.id, dx: x, dy: y } }); marker.moveTo(x, y); return marker; }; _this.deleteActiveMarker = function () { _this.deleteMarkerWithEvent(_this.activeMarker); }; _this.clearMarkers = function () { _this.markers.slice().forEach(function (marker) { _this.deleteMarkerWithEvent(marker); }); }; _this.deleteMarkerWithEvent = function (marker) { if (marker) { if (_this.onChange) { _this.onChange({ event: 'removeMarker', id: marker.id, target: 'marker', marker: { id: marker.id } }); } _this.deleteMarker(marker); } }; _this.setTargetRect = function () { var targetRect = _this.target.getBoundingClientRect(); var bodyRect = document.body.parentElement.getBoundingClientRect(); _this.targetRect = { left: targetRect.left - bodyRect.left, top: targetRect.top - bodyRect.top }; }; _this.startRender = function (done) { var renderer = new Synthetizer_1.Synthetizer(); renderer.rasterize(_this.target, _this.boardCanvas, done); }; _this.attachEvents = function () { _this.boardCanvas.addEventListener('mousedown', _this.mouseDown); _this.boardCanvas.addEventListener('mousemove', _this.mouseMove); _this.boardCanvas.addEventListener('mouseup', _this.mouseUp); }; _this.mouseDown = function (ev) { if (_this.activeMarker && (ev.buttons & 1) > 0) { _this.activeMarker.deselect(); _this.activeMarker = null; } }; _this.mouseMove = function (ev) { if (_this.activeMarker && (ev.buttons & 1) > 0) { _this.activeMarker.manipulate(ev); } }; _this.mouseUp = function (ev) { if (_this.activeMarker) { _this.activeMarker.endManipulation(); } }; _this.onKeyboard = function (e, _a) { var hotkey = _a.hotkey; switch (hotkey) { case 'Shift+R': _this.addMarker(index_2.RectMarker); return; case 'Shift+H': _this.addMarker(index_3.HighlightMarker); return; case 'Shift+C': _this.addMarker(index_4.CoverMarker); return; case 'Shift+L': _this.addMarker(index_5.LineMarker); return; case 'Shift+A': _this.addMarker(index_6.ArrowMarker); return; case 'Shift+T': _this.addMarker(index_7.TextMarker); return; case 'ESC': _this.page.whiteboard.rollbackSnap(); return; default: break; } if (!_this.activeMarker) { return; } switch (hotkey) { case 'UP': _this.activeMarker.move(0, -10); return; case 'LEFT': _this.activeMarker.move(-10, 0); return; case 'RIGHT': _this.activeMarker.move(10, 0); return; case 'DOWN': _this.activeMarker.move(0, 10); return; case 'BACKSPACE': _this.deleteActiveMarker(); return; default: return; } }; _this.adjustUI = function (ev) { _this.adjustSize(); _this.positionUI(); }; _this.adjustSize = function () { _this.width = _this.target.clientWidth; _this.height = _this.target.clientHeight; var scale = _this.target.clientWidth / _this.boardHolder.clientWidth; if (scale !== 1.0) { _this.scale *= scale; _this.boardHolder.style.width = _this.width + "px"; _this.boardHolder.style.height = _this.height + "px"; _this.boardHolder.style.transform = "scale(" + _this.scale + ")"; } }; _this.positionUI = function () { _this.setTargetRect(); _this.positionBoard(); _this.positionToolbar(); }; _this.positionToolbar = function () { if (_this.toolbarUI && _this.targetRect) { _this.toolbarUI.style.left = _this.targetRect.left + _this.target.offsetWidth - _this.toolbarUI.clientWidth + "px"; _this.toolbarUI.style.top = _this.targetRect.top - _this.toolbarUI.clientHeight + "px"; } }; _this.showUI = function () { _this.toolbar = new Toolbar_1.Toolbar(_this.toolbarItems, _this.toolbarClick); _this.toolbar.zIndex = _this.zIndex + 1; _this.toolbarUI = _this.toolbar.getUI(_this); _this.boardHolder.appendChild(_this.toolbarUI); _this.toolbarUI.style.position = 'absolute'; _this.positionToolbar(); _this.toolbar.show(); _this.toolbar.toolbarButtons.forEach(function (button) { if (button.toolbarItem.draggable) { button.container.draggable = true; button.container.ondragstart = function (ev) { if (ev) { ev.dataTransfer.setData('id', button.id); } }; } }); _this.boardCanvas.ondragover = function (ev) { ev.preventDefault(); }; _this.boardCanvas.ondrop = function (ev) { var markerX = ev.x; var markerY = ev.y; var rect = _this.boardHolder.getBoundingClientRect(); if (layout_1.rectContains(rect, { x: markerX, y: markerY })) { var buttonId = ev.dataTransfer.getData('id'); var button = _this.toolbar.toolbarButtonMap[buttonId]; if (button.toolbarItem && button.toolbarItem.markerType) { _this.addMarker(button.toolbarItem.markerType, { originX: markerX - rect.left, originY: markerY - rect.top }); } } }; }; _this.setStyles = function () { var editorStyleSheet = document.createElementNS('http://www.w3.org/2000/svg', 'style'); editorStyleSheet.innerHTML = "\n .rect-marker .render-visual {\n stroke: #ff0000;\n stroke-width: 3;\n fill: transparent;\n }\n .cover-marker .render-visual {\n stroke-width: 0;\n fill: #000000;\n }\n .highlight-marker .render-visual {\n stroke: transparent;\n stroke-width: 0;\n fill: #ffff00;\n fill-opacity: 0.4;\n }\n .line-marker .render-visual {\n stroke: #ff0000;\n stroke-width: 3;\n fill: transparent;\n }\n .arrow-marker .render-visual {\n stroke: #ff0000;\n stroke-width: 3;\n fill: transparent;\n }\n .arrow-marker-tip {\n stroke-width: 0;\n fill: #ff0000;\n }\n .text-marker text {\n fill: #ff0000;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\",\n Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\",\n \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n }\n .fc-whiteboard-rect-control-box .fc-whiteboard-rect-control-rect {\n stroke: black;\n stroke-width: 1;\n stroke-opacity: 0.5;\n stroke-dasharray: 3, 2;\n fill: transparent;\n }\n .fc-whiteboard-control-grip {\n fill: #cccccc;\n stroke: #333333;\n stroke-width: 2;\n }\n "; _this.boardCanvas.appendChild(editorStyleSheet); }; _this.toolbarClick = function (ev, toolbarItem) { if (toolbarItem.onClick) { toolbarItem.onClick(); } else if (toolbarItem.markerType) { _this.addMarker(toolbarItem.markerType); } else { switch (toolbarItem.name) { case 'delete': { _this.deleteActiveMarker(); break; } case 'pointer': { if (_this.activeMarker) { _this.selectMarker(null); } break; } case 'close': { _this.cancel(); break; } case 'ok': { _this.complete(); break; } default: break; } } }; _this.selectMarker = function (marker) { if (_this.activeMarker && _this.activeMarker !== marker) { _this.activeMarker.deselect(); } _this.activeMarker = marker; }; _this.deleteMarker = function (marker) { _this.boardCanvas.removeChild(marker.visual); if (_this.activeMarker === marker) { _this.activeMarker = null; } _this.markers.splice(_this.markers.indexOf(marker), 1); }; _this.complete = function () { _this.selectMarker(null); _this.startRender(_this.renderFinishedClose); }; _this.cancel = function () { _this.destroy(); if (_this.onCancel) { _this.onCancel(); } }; _this.renderFinished = function (dataUrl) { _this.onComplete(dataUrl); }; _this.renderFinishedClose = function (dataUrl) { _this.destroy(); _this.onComplete(dataUrl); }; if (page) { _this.page = page; } if (zIndex) { _this.zIndex = zIndex; } _this.allowKeyboard = allowKeyboard; _this.markers = []; _this.activeMarker = null; var toolbarItems = toolbar_items_1.getToolbars(page); if (extraToolbarItems) { toolbarItems.push.apply(toolbarItems, extraToolbarItems); } _this.toolbarItems = toolbarItems; if (onChange) { _this.onChange = onChange; } if (allowKeyboard && _this.page && _this.page.mode === 'master') { _this.listener = new fc_hotkeys_1.HotkeysListener(); _this.listener.on(fc_hotkeys_1.KEY_ALL, debounce(_this.onKeyboard, 150)); } if (mountContainer) { _this.mountContainer = mountContainer; } return _this; } Object.defineProperty(Drawboard.prototype, "markerMap", { get: function () { var map = {}; this.markers.forEach(function (marker) { map[marker.id] = marker; }); return map; }, enumerable: true, configurable: true }); return Drawboard; }(index_1.Baseboard)); exports.Drawboard = Drawboard;