File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
{"version":3,"file":"markerjs2.esm.js","sources":["../node_modules/tslib/tslib.es6.js","../src/core/SvgHelper.ts","../src/core/Activator.ts","../src/core/Renderer.ts","../src/core/Style.ts","../src/ui/Toolbar.ts","../src/ui/Toolbox.ts","../src/ui/ToolboxPanel.ts","../src/ui/toolbox-panels/ColorPickerPanel.ts","../src/core/MarkerBase.ts","../src/markers/RectangularBoxMarkerGrips.ts","../src/markers/ResizeGrip.ts","../src/core/TransformMatrix.ts","../src/markers/RectangularBoxMarkerBase.ts","../src/markers/RectangleMarker.ts","../src/ui/toolbox-panels/LineWidthPanel.ts","../src/ui/toolbox-panels/LineStylePanel.ts","../src/markers/frame-marker/FrameMarker.ts","../src/core/Settings.ts","../src/markers/LinearMarkerBase.ts","../src/markers/line-marker/LineMarker.ts","../src/ui/toolbox-panels/FontFamilyPanel.ts","../src/markers/text-marker/TextMarker.ts","../src/markers/freehand-marker/FreehandMarker.ts","../src/ui/toolbox-panels/ArrowTypePanel.ts","../src/markers/arrow-marker/ArrowMarker.ts","../src/markers/cover-marker/CoverMarker.ts","../src/ui/toolbox-panels/OpacityPanel.ts","../src/markers/highlight-marker/HighlightMarker.ts","../src/markers/callout-marker/CalloutMarker.ts","../src/markers/ellipse-marker/EllipseMarker.ts","../src/markers/measurement-marker/MeasurementMarker.ts","../src/markers/ellipse-frame-marker/EllipseFrameMarker.ts","../src/core/UndoRedoManager.ts","../src/markers/curve-marker/CurveMarker.ts","../src/markers/caption-frame-marker/CaptionFrameMarker.ts","../src/core/Events.ts","../src/MarkerArea.ts"],"sourcesContent":["/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n};\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, privateMap) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to get private field on non-instance\");\r\n }\r\n return privateMap.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, privateMap, value) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to set private field on non-instance\");\r\n }\r\n privateMap.set(receiver, value);\r\n return value;\r\n}\r\n","/**\r\n * Utility class to simplify SVG operations.\r\n */\r\nexport class SvgHelper {\r\n /**\r\n * Creates SVG \"defs\".\r\n */\r\n public static createDefs(): SVGDefsElement {\r\n const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\r\n\r\n return defs;\r\n }\r\n\r\n /**\r\n * Sets attributes on an arbitrary SVG element\r\n * @param el - target SVG element.\r\n * @param attributes - set of name-value attribute pairs.\r\n */\r\n public static setAttributes(\r\n el: SVGElement,\r\n attributes: Array<[string, string]>\r\n ): void {\r\n for (const [attr, value] of attributes) {\r\n el.setAttribute(attr, value);\r\n }\r\n }\r\n\r\n /**\r\n * Creates an SVG rectangle with the specified width and height.\r\n * @param width \r\n * @param height \r\n * @param attributes - additional attributes.\r\n */\r\n public static createRect(\r\n width: number | string,\r\n height: number | string,\r\n attributes?: Array<[string, string]>\r\n ): SVGRectElement {\r\n const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\r\n\r\n rect.setAttribute('width', width.toString());\r\n rect.setAttribute('height', height.toString());\r\n if (attributes) {\r\n SvgHelper.setAttributes(rect, attributes);\r\n }\r\n\r\n return rect;\r\n }\r\n\r\n /**\r\n * Creates an SVG line with specified end-point coordinates.\r\n * @param x1 \r\n * @param y1 \r\n * @param x2 \r\n * @param y2 \r\n * @param attributes - additional attributes.\r\n */\r\n public static createLine(\r\n x1: number | string,\r\n y1: number | string,\r\n x2: number | string,\r\n y2: number | string,\r\n attributes?: Array<[string, string]>\r\n ): SVGLineElement {\r\n const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');\r\n\r\n line.setAttribute('x1', x1.toString());\r\n line.setAttribute('y1', y1.toString());\r\n line.setAttribute('x2', x2.toString());\r\n line.setAttribute('y2', y2.toString());\r\n if (attributes) {\r\n SvgHelper.setAttributes(line, attributes);\r\n }\r\n\r\n return line;\r\n }\r\n\r\n /**\r\n * Creates an SVG polygon with specified points.\r\n * @param points - points as string.\r\n * @param attributes - additional attributes.\r\n */\r\n public static createPolygon(\r\n points: string,\r\n attributes?: Array<[string, string]>\r\n ): SVGPolygonElement {\r\n const polygon = document.createElementNS(\r\n 'http://www.w3.org/2000/svg',\r\n 'polygon'\r\n );\r\n\r\n polygon.setAttribute('points', points);\r\n if (attributes) {\r\n SvgHelper.setAttributes(polygon, attributes);\r\n }\r\n\r\n return polygon;\r\n }\r\n\r\n /**\r\n * Creates an SVG circle with the specified radius.\r\n * @param radius \r\n * @param attributes - additional attributes.\r\n */\r\n public static createCircle(\r\n radius: number,\r\n attributes?: Array<[string, string]>\r\n ): SVGCircleElement {\r\n const circle = document.createElementNS(\r\n 'http://www.w3.org/2000/svg',\r\n 'circle'\r\n );\r\n\r\n circle.setAttribute('cx', (radius / 2).toString());\r\n circle.setAttribute('cy', (radius / 2).toString());\r\n circle.setAttribute('r', radius.toString());\r\n if (attributes) {\r\n SvgHelper.setAttributes(circle, attributes);\r\n }\r\n\r\n return circle;\r\n }\r\n\r\n /**\r\n * Creates an SVG ellipse with the specified horizontal and vertical radii.\r\n * @param rx \r\n * @param ry \r\n * @param attributes - additional attributes.\r\n */\r\n public static createEllipse(\r\n rx: number,\r\n ry: number,\r\n attributes?: Array<[string, string]>\r\n ): SVGEllipseElement {\r\n const ellipse = document.createElementNS(\r\n 'http://www.w3.org/2000/svg',\r\n 'ellipse'\r\n );\r\n\r\n ellipse.setAttribute('cx', (rx / 2).toString());\r\n ellipse.setAttribute('cy', (ry / 2).toString());\r\n ellipse.setAttribute('rx', (rx / 2).toString());\r\n ellipse.setAttribute('ry', (ry / 2).toString());\r\n if (attributes) {\r\n SvgHelper.setAttributes(ellipse, attributes);\r\n }\r\n\r\n return ellipse;\r\n }\r\n\r\n /**\r\n * Creates an SVG group.\r\n * @param attributes - additional attributes.\r\n */\r\n public static createGroup(attributes?: Array<[string, string]>): SVGGElement {\r\n const g = document.createElementNS('http://www.w3.org/2000/svg', 'g');\r\n if (attributes) {\r\n SvgHelper.setAttributes(g, attributes);\r\n }\r\n return g;\r\n }\r\n\r\n /**\r\n * Creates an SVG transform.\r\n */\r\n public static createTransform(): SVGTransform {\r\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\r\n\r\n return svg.createSVGTransform();\r\n }\r\n\r\n /**\r\n * Creates an SVG marker.\r\n * @param id \r\n * @param orient \r\n * @param markerWidth \r\n * @param markerHeight \r\n * @param refX \r\n * @param refY \r\n * @param markerElement \r\n */\r\n public static createMarker(\r\n id: string,\r\n orient: string,\r\n markerWidth: number | string,\r\n markerHeight: number | string,\r\n refX: number | string,\r\n refY: number | string,\r\n markerElement: SVGGraphicsElement\r\n ): SVGMarkerElement {\r\n const marker = document.createElementNS(\r\n 'http://www.w3.org/2000/svg',\r\n 'marker'\r\n );\r\n SvgHelper.setAttributes(marker, [\r\n ['id', id],\r\n ['orient', orient],\r\n ['markerWidth', markerWidth.toString()],\r\n ['markerHeight', markerHeight.toString()],\r\n ['refX', refX.toString()],\r\n ['refY', refY.toString()],\r\n ]);\r\n\r\n marker.appendChild(markerElement);\r\n\r\n return marker;\r\n }\r\n\r\n /**\r\n * Creaes an SVG text element.\r\n * @param attributes - additional attributes.\r\n */\r\n public static createText(\r\n attributes?: Array<[string, string]>\r\n ): SVGTextElement {\r\n const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');\r\n text.setAttribute('x', '0');\r\n text.setAttribute('y', '0');\r\n\r\n if (attributes) {\r\n SvgHelper.setAttributes(text, attributes);\r\n }\r\n\r\n return text;\r\n }\r\n\r\n /**\r\n * Creates an SVG TSpan.\r\n * @param text - inner text.\r\n * @param attributes - additional attributes.\r\n */\r\n public static createTSpan(\r\n text: string,\r\n attributes?: Array<[string, string]>\r\n ): SVGTSpanElement {\r\n const tspan = document.createElementNS(\r\n 'http://www.w3.org/2000/svg',\r\n 'tspan'\r\n );\r\n tspan.textContent = text;\r\n\r\n if (attributes) {\r\n SvgHelper.setAttributes(tspan, attributes);\r\n }\r\n\r\n return tspan;\r\n }\r\n\r\n /**\r\n * Creates an SVG image element.\r\n * @param attributes - additional attributes.\r\n */\r\n public static createImage(\r\n attributes?: Array<[string, string]>\r\n ): SVGImageElement {\r\n const image = document.createElementNS(\r\n 'http://www.w3.org/2000/svg',\r\n 'image'\r\n );\r\n\r\n if (attributes) {\r\n SvgHelper.setAttributes(image, attributes);\r\n }\r\n\r\n return image;\r\n }\r\n\r\n /**\r\n * Creates an SVG point with the specified coordinates.\r\n * @param x \r\n * @param y \r\n */\r\n public static createPoint( \r\n x: number,\r\n y: number\r\n ): SVGPoint {\r\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\r\n const svgPoint = svg.createSVGPoint();\r\n svgPoint.x = x;\r\n svgPoint.y = y;\r\n \r\n return svgPoint;\r\n }\r\n\r\n /**\r\n * Creates an SVG path with the specified shape (d).\r\n * @param d - path shape\r\n * @param attributes - additional attributes.\r\n */\r\n public static createPath(\r\n d: string,\r\n attributes?: Array<[string, string]>\r\n ): SVGPathElement {\r\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');\r\n\r\n path.setAttribute('d', d);\r\n if (attributes) {\r\n SvgHelper.setAttributes(path, attributes);\r\n }\r\n\r\n return path;\r\n }\r\n}\r\n","/**\r\n * Manages commercial marker.js 2 licenses.\r\n */\r\nexport class Activator {\r\n private static key: string;\r\n\r\n /**\r\n * Add a license key\r\n * @param key license key sent to you after purchase.\r\n */\r\n public static addKey(key: string): void {\r\n Activator.key = key;\r\n }\r\n\r\n /**\r\n * Returns true if the copy of marker.js is commercially licensed.\r\n */\r\n public static get isLicensed(): boolean {\r\n // NOTE:\r\n // before removing or modifying this please consider supporting marker.js\r\n // by visiting https://markerjs.com/ for details\r\n // thank you!\r\n if (Activator.key) {\r\n const keyRegex = new RegExp(/^MJS2-[A-Z][0-9]{3}-[A-Z][0-9]{3}-[0-9]{4}$/, 'i');\r\n return keyRegex.test(Activator.key);\r\n } else {\r\n return false;\r\n }\r\n }\r\n}\r\n","/**\r\n * Renders the original image and markup to a flat raster image.\r\n */\r\nexport class Renderer {\r\n /**\r\n * Whether the image should be rendered at the original (natural) target image size.\r\n */\r\n public naturalSize = false; \r\n /**\r\n * Rendered image type (`image/png`, `image/jpeg`, etc.).\r\n */\r\n public imageType = 'image/png';\r\n /**\r\n * For formats that support it, specifies rendering quality.\r\n * \r\n * In the case of `image/jpeg` you can specify a value between 0 and 1 (lowest to highest quality).\r\n *\r\n * @type {number} - image rendering quality (0..1)\r\n */\r\n public imageQuality?: number;\r\n /**\r\n * When set to true, only the marker layer without the original image will be rendered.\r\n */\r\n public markersOnly = false;\r\n\r\n /**\r\n * When set and {@linkcode naturalSize} is `false` sets the width of the rendered image.\r\n * \r\n * Both `width` and `height` have to be set for this to take effect.\r\n */\r\n public width?: number;\r\n /**\r\n * When set and {@linkcode naturalSize} is `false` sets the height of the rendered image.\r\n * \r\n * Both `width` and `height` have to be set for this to take effect.\r\n */\r\n public height?: number;\r\n\r\n\r\n /**\r\n * Initiates rendering of the result image and returns a promise which when resolved\r\n * contains a data URL for the rendered image.\r\n * \r\n * @param target - target (underlying original) image\r\n * @param markerImage - marker layer\r\n */\r\n public rasterize(\r\n target: HTMLImageElement, \r\n markerImage: SVGSVGElement,\r\n targetCanvas?: HTMLCanvasElement \r\n ): Promise<string> {\r\n return new Promise<string>((resolve) => {\r\n const canvas = targetCanvas !== undefined ? targetCanvas : document.createElement(\"canvas\");\r\n\r\n if (target === null) {\r\n this.markersOnly = true;\r\n this.naturalSize = false;\r\n }\r\n\r\n const markerImageCopy = document.createElementNS(\r\n 'http://www.w3.org/2000/svg',\r\n 'svg'\r\n );\r\n markerImageCopy.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\r\n markerImageCopy.setAttribute('width', markerImage.width.baseVal.valueAsString);\r\n markerImageCopy.setAttribute(\r\n 'height',\r\n markerImage.height.baseVal.valueAsString\r\n );\r\n markerImageCopy.setAttribute(\r\n 'viewBox',\r\n '0 0 ' +\r\n markerImage.viewBox.baseVal.width.toString() +\r\n ' ' +\r\n markerImage.viewBox.baseVal.height.toString()\r\n ); \r\n markerImageCopy.innerHTML = markerImage.innerHTML;\r\n\r\n if (this.naturalSize === true) {\r\n // scale to full image size\r\n markerImageCopy.width.baseVal.value = target.naturalWidth;\r\n markerImageCopy.height.baseVal.value = target.naturalHeight;\r\n } else if (this.width !== undefined && this.height !== undefined) {\r\n // scale to specific dimensions\r\n markerImageCopy.width.baseVal.value = this.width;\r\n markerImageCopy.height.baseVal.value = this.height;\r\n }\r\n \r\n canvas.width = markerImageCopy.width.baseVal.value;\r\n canvas.height = markerImageCopy.height.baseVal.value;\r\n \r\n const data = markerImageCopy.outerHTML;\r\n\r\n const ctx = canvas.getContext(\"2d\");\r\n if (this.markersOnly !== true) { \r\n ctx.drawImage(target, 0, 0, canvas.width, canvas.height);\r\n }\r\n \r\n const DOMURL = window.URL; // || window.webkitURL || window;\r\n \r\n const img = new Image(canvas.width, canvas.height);\r\n img.setAttribute(\"crossOrigin\", \"anonymous\");\r\n \r\n const blob = new Blob([data], { type: \"image/svg+xml\" });\r\n \r\n const url = DOMURL.createObjectURL(blob);\r\n \r\n img.onload = () => {\r\n ctx.drawImage(img, 0, 0);\r\n DOMURL.revokeObjectURL(url);\r\n \r\n const result = canvas.toDataURL(this.imageType, this.imageQuality);\r\n resolve(result);\r\n };\r\n \r\n img.src = url;\r\n });\r\n }\r\n}\r\n","import { IStyleSettings } from './IStyleSettings';\r\n\r\n/**\r\n * @see {@link StyleManager}\r\n * @deprecated use instance level `styles` instead.\r\n */\r\nexport class Style {\r\n /**\r\n * @see {@link StyleManager}\r\n * @deprecated use instance level `styles.styleSheetRoot` instead.\r\n */\r\n public static styleSheetRoot: HTMLElement;\r\n}\r\n\r\n/**\r\n * Simple utility CSS-in-JS implementation.\r\n */\r\nexport class StyleManager {\r\n /**\r\n * Prefix used for all internally created CSS classes.\r\n */\r\n private _classNamePrefixBase = '__markerjs2_';\r\n\r\n /**\r\n * Static CSS class name used for the wrapper element.\r\n */\r\n public get classNamePrefixBase(): string {\r\n return this._classNamePrefixBase;\r\n }\r\n\r\n private _classNamePrefix: string;\r\n /**\r\n * Prefix used for all internally created CSS classes.\r\n */\r\n public get classNamePrefix(): string {\r\n return this._classNamePrefix;\r\n }\r\n\r\n private classes: StyleClass[] = [];\r\n private rules: StyleRule[] = [];\r\n private styleSheet?: HTMLStyleElement;\r\n\r\n /**\r\n * For cases when you need to add the stylesheet to anything\r\n * other than document.head (default), set this property\r\n * befor calling `MarkerArea.show()`.\r\n *\r\n * Example: here we set the rendering/placement root (targetRoot)\r\n * to the `shadowRoot` of a web componet and set `styleSheetRoot`\r\n * to the same value as well.\r\n *\r\n * ```javascript\r\n * const markerArea = new markerjs2.MarkerArea(target);\r\n * markerArea.targetRoot = this.shadowRoot;\r\n * markerArea.styles.styleSheetRoot = this.shadowRoot;\r\n * markerArea.show();\r\n * ```\r\n *\r\n */\r\n public styleSheetRoot: HTMLElement;\r\n\r\n /**\r\n * Returns default UI styles.\r\n */\r\n public get defaultSettings(): IStyleSettings {\r\n return {\r\n canvasBackgroundColor: '#ffffff',\r\n toolbarBackgroundColor: '#111111',\r\n toolbarBackgroundHoverColor: '#333333',\r\n toolbarColor: '#eeeeee',\r\n toolbarHeight: 40,\r\n // toolboxBackgroundColor: '#2a2a2a',\r\n toolboxColor: '#eeeeee',\r\n toolboxAccentColor: '#3080c3',\r\n undoButtonVisible: true,\r\n redoButtonVisible: false,\r\n zoomButtonVisible: false,\r\n zoomOutButtonVisible: false,\r\n clearButtonVisible: false,\r\n resultButtonBlockVisible: true,\r\n logoPosition: 'left',\r\n };\r\n }\r\n\r\n /**\r\n * Holds current UI styles.\r\n */\r\n public settings: IStyleSettings = this.defaultSettings;\r\n\r\n /**\r\n * Returns global fade-in animation class name.\r\n */\r\n public get fadeInAnimationClassName(): string {\r\n return `${this.classNamePrefix}fade_in`;\r\n }\r\n /**\r\n * Returns global fade-out animation class name.\r\n */\r\n public get fadeOutAnimationClassName(): string {\r\n return `${this.classNamePrefix}fade_out`;\r\n }\r\n\r\n /**\r\n * Initializes a new style manager.\r\n * @param instanceNo - instance id.\r\n */\r\n constructor(instanceNo: number) {\r\n this._classNamePrefix = `${this._classNamePrefixBase}_${instanceNo}_`;\r\n }\r\n\r\n /**\r\n * Adds a CSS class declaration.\r\n * @param styleClass - class to add.\r\n */\r\n public addClass(styleClass: StyleClass): StyleClass {\r\n if (this.styleSheet === undefined) {\r\n this.addStyleSheet();\r\n }\r\n styleClass.name = `${this.classNamePrefix}${styleClass.localName}`;\r\n this.classes.push(styleClass);\r\n this.styleSheet.sheet.insertRule(\r\n `.${styleClass.name} {${styleClass.style}}`,\r\n this.styleSheet.sheet.cssRules.length\r\n );\r\n return styleClass;\r\n }\r\n\r\n /**\r\n * Add arbitrary CSS rule\r\n * @param styleRule - CSS rule to add.\r\n */\r\n public addRule(styleRule: StyleRule): void {\r\n if (this.styleSheet === undefined) {\r\n this.addStyleSheet();\r\n }\r\n this.rules.push(styleRule);\r\n this.styleSheet.sheet.insertRule(\r\n `${styleRule.selector} {${styleRule.style}}`,\r\n this.styleSheet.sheet.cssRules.length\r\n );\r\n }\r\n\r\n private addStyleSheet() {\r\n this.styleSheet = document.createElement('style');\r\n (this.styleSheetRoot ?? document.head).appendChild(this.styleSheet);\r\n\r\n // add global rules\r\n this.addRule(\r\n new StyleRule(`.${this.classNamePrefix} h3`, 'font-family: sans-serif')\r\n );\r\n\r\n this.addRule(\r\n new StyleRule(\r\n `@keyframes ${this.classNamePrefix}_fade_in_animation_frames`,\r\n `\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n `\r\n )\r\n );\r\n this.addRule(\r\n new StyleRule(\r\n `@keyframes ${this.classNamePrefix}_fade_out_animation_frames`,\r\n `\r\n from {\r\n opacity: 1;\r\n }\r\n to {\r\n opacity: 0;\r\n }\r\n `\r\n )\r\n );\r\n\r\n this.addClass(\r\n new StyleClass(\r\n 'fade_in',\r\n `\r\n animation-duration: 0.3s;\r\n animation-name: ${this.classNamePrefix}_fade_in_animation_frames;\r\n `\r\n )\r\n );\r\n this.addClass(\r\n new StyleClass(\r\n 'fade_out',\r\n `\r\n animation-duration: 0.3s;\r\n animation-name: ${this.classNamePrefix}_fade_out_animation_frames;\r\n `\r\n )\r\n );\r\n }\r\n\r\n public removeStyleSheet(): void {\r\n if (this.styleSheet) {\r\n (this.styleSheetRoot ?? document.head).removeChild(this.styleSheet);\r\n this.styleSheet = undefined;\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Represents an arbitrary CSS rule.\r\n */\r\nexport class StyleRule {\r\n /**\r\n * CSS selector.\r\n */\r\n public selector: string;\r\n /**\r\n * Style declaration for the rule.\r\n */\r\n public style: string;\r\n /**\r\n * Creates an arbitrary CSS rule using the selector and style rules.\r\n * @param selector - CSS selector\r\n * @param style - styles to apply\r\n */\r\n constructor(selector: string, style: string) {\r\n this.selector = selector;\r\n this.style = style;\r\n }\r\n}\r\n\r\n/**\r\n * Represents a CSS class.\r\n */\r\nexport class StyleClass {\r\n /**\r\n * CSS style rules for the class.\r\n */\r\n public style: string;\r\n\r\n /**\r\n * Class name without the global prefix.\r\n */\r\n public localName: string;\r\n\r\n /**\r\n * Fully qualified CSS class name.\r\n */\r\n public name: string;\r\n\r\n /**\r\n * Creates a CSS class declaration based on supplied (local) name and style rules.\r\n * @param name - local CSS class name (will be prefixed with the marker.js prefix).\r\n * @param style - style declarations.\r\n */\r\n constructor(name: string, style: string) {\r\n this.localName = name;\r\n this.style = style;\r\n }\r\n}\r\n","import { MarkerBase } from './../core/MarkerBase';\r\nimport { StyleManager, StyleClass, StyleRule } from './../core/Style';\r\n\r\nimport CursorIcon from './toolbar-core-icons/cursor.svg';\r\nimport DeleteIcon from './toolbar-core-icons/delete.svg';\r\nimport ClearIcon from './toolbar-core-icons/clear.svg';\r\nimport CheckIcon from './toolbar-core-icons/check.svg';\r\nimport CloseIcon from './toolbar-core-icons/close.svg';\r\nimport OverflowIcon from './toolbar-core-icons/overflow.svg';\r\nimport UndoIcon from './toolbar-core-icons/undo.svg';\r\nimport RedoIcon from './toolbar-core-icons/redo.svg';\r\nimport NotesIcon from './toolbar-core-icons/notes.svg';\r\nimport ZoomIcon from './toolbar-core-icons/zoom.svg';\r\nimport ZoomOutIcon from './toolbar-core-icons/zoom-out.svg';\r\nimport { IStyleSettings } from '../core/IStyleSettings';\r\nimport { DisplayMode } from '../core/Settings';\r\n\r\n/**\r\n * Toolbar button type:\r\n * - `action` for non-marker buttons like select, delete, etc.\r\n * - `marker` for marker type buttons.\r\n */\r\nexport type ToolbarButtonType = 'action' | 'marker';\r\n\r\n/**\r\n * Click handler type for toolbar button click events.\r\n */\r\nexport type ToolbarButtonClickHandler = (\r\n buttonType: ToolbarButtonType,\r\n value?: typeof MarkerBase | string\r\n) => void;\r\n\r\n/**\r\n * Toolbar represents the main toolbar of the marker.js 2 interface.\r\n */\r\nexport class Toolbar {\r\n private markerItems: typeof MarkerBase[];\r\n\r\n private buttons: HTMLDivElement[] = [];\r\n private markerButtons: HTMLDivElement[] = [];\r\n private overflowButton: HTMLDivElement;\r\n\r\n private markerjsContainer: HTMLDivElement;\r\n private displayMode: DisplayMode;\r\n private uiContainer: HTMLDivElement;\r\n\r\n private toolbarStyleClass: StyleClass;\r\n private toolbarStyleColorsClass: StyleClass;\r\n private toolbarBlockStyleClass: StyleClass;\r\n private toolbarOverflowBlockStyleClass: StyleClass;\r\n private toolbarOverflowBlockStyleColorsClass: StyleClass;\r\n private toolbarButtonStyleClass: StyleClass;\r\n private toolbarButtonStyleColorsClass: StyleClass;\r\n private toolbarActiveButtonStyleColorsClass: StyleClass;\r\n\r\n private markerButtonBlock: HTMLDivElement;\r\n private markerButtonOverflowBlock: HTMLDivElement;\r\n\r\n private buttonClickListeners: ToolbarButtonClickHandler[] = [];\r\n\r\n private uiStyleSettings: IStyleSettings;\r\n\r\n private currentMarker?: MarkerBase;\r\n\r\n private styles: StyleManager;\r\n\r\n /**\r\n * Creates the main marker.js toolbar.\r\n * @param markerjsContainer - container for the toolbar in the marker.js UI.\r\n * @param displayMode - marker.js display mode (`inline` or `popup`).\r\n * @param markerItems - available marker types.\r\n * @param uiStyleSettings - settings for styling the tooblar ui.\r\n */\r\n constructor(\r\n markerjsContainer: HTMLDivElement,\r\n displayMode: DisplayMode,\r\n markerItems: typeof MarkerBase[],\r\n uiStyleSettings: IStyleSettings,\r\n styles: StyleManager\r\n ) {\r\n this.markerjsContainer = markerjsContainer;\r\n this.displayMode = displayMode;\r\n this.markerItems = markerItems;\r\n this.uiStyleSettings = uiStyleSettings;\r\n this.styles = styles;\r\n this.addStyles();\r\n\r\n this.adjustLayout = this.adjustLayout.bind(this);\r\n this.overflowButtonClicked = this.overflowButtonClicked.bind(this);\r\n this.setCurrentMarker = this.setCurrentMarker.bind(this);\r\n }\r\n\r\n /**\r\n * Creates and displays the toolbar UI.\r\n */\r\n public show(visiblity: string): void {\r\n this.uiContainer = document.createElement('div');\r\n this.uiContainer.style.visibility = visiblity;\r\n this.uiContainer.className = `${this.toolbarStyleClass.name} ${\r\n this.styles.fadeInAnimationClassName\r\n } ${\r\n this.uiStyleSettings.toolbarStyleColorsClassName\r\n ? this.uiStyleSettings.toolbarStyleColorsClassName\r\n : this.toolbarStyleColorsClass.name\r\n }`;\r\n\r\n const actionButtonBlock = document.createElement('div');\r\n actionButtonBlock.className = this.toolbarBlockStyleClass.name;\r\n actionButtonBlock.style.whiteSpace = 'nowrap';\r\n this.uiContainer.appendChild(actionButtonBlock);\r\n\r\n this.addActionButton(actionButtonBlock, CursorIcon, 'select', 'Select mode');\r\n this.addActionButton(actionButtonBlock, DeleteIcon, 'delete', 'Delete marker');\r\n if (this.uiStyleSettings.clearButtonVisible) {\r\n this.addActionButton(actionButtonBlock, ClearIcon, 'clear', 'Delete all markers');\r\n }\r\n if (this.uiStyleSettings.undoButtonVisible) {\r\n this.addActionButton(actionButtonBlock, UndoIcon, 'undo', 'Undo');\r\n }\r\n if (this.uiStyleSettings.redoButtonVisible) {\r\n this.addActionButton(actionButtonBlock, RedoIcon, 'redo', 'Redo');\r\n }\r\n if (this.uiStyleSettings.zoomButtonVisible) {\r\n this.addActionButton(actionButtonBlock, ZoomIcon, 'zoom', 'Zoom in');\r\n }\r\n if (\r\n this.uiStyleSettings.zoomButtonVisible &&\r\n this.uiStyleSettings.zoomOutButtonVisible\r\n ) {\r\n this.addActionButton(actionButtonBlock, ZoomOutIcon, 'zoom-out', 'Zoom out');\r\n }\r\n if (this.uiStyleSettings.notesButtonVisible) {\r\n this.addActionButton(actionButtonBlock, NotesIcon, 'notes', 'Notes');\r\n }\r\n\r\n this.markerButtonBlock = document.createElement('div');\r\n this.markerButtonBlock.className = this.toolbarBlockStyleClass.name;\r\n this.markerButtonBlock.style.flexGrow = '2';\r\n this.markerButtonBlock.style.textAlign = 'center';\r\n this.uiContainer.appendChild(this.markerButtonBlock);\r\n\r\n this.markerButtonOverflowBlock = document.createElement('div');\r\n this.markerButtonOverflowBlock.className = `${\r\n this.toolbarOverflowBlockStyleClass.name\r\n } ${\r\n this.uiStyleSettings.toolbarOverflowBlockStyleColorsClassName\r\n ? this.uiStyleSettings.toolbarOverflowBlockStyleColorsClassName\r\n : this.toolbarOverflowBlockStyleColorsClass.name\r\n }`;\r\n this.markerButtonOverflowBlock.style.display = 'none';\r\n this.uiContainer.appendChild(this.markerButtonOverflowBlock);\r\n\r\n if (this.markerItems) {\r\n this.markerItems.forEach((mi) => {\r\n const buttonContainer = document.createElement('div');\r\n buttonContainer.className = `${this.toolbarButtonStyleClass.name}`;\r\n buttonContainer.setAttribute('data-type-name', mi.typeName);\r\n buttonContainer.setAttribute('aria-label', mi.title);\r\n buttonContainer.setAttribute('title', mi.title);\r\n // ${\r\n // this.uiStyleSettings.toolbarButtonStyleColorsClassName ?\r\n // this.uiStyleSettings.toolbarButtonStyleColorsClassName : this.toolbarButtonStyleColorsClass.name}`;\r\n buttonContainer.innerHTML = mi.icon;\r\n buttonContainer.addEventListener('click', () => {\r\n this.markerToolbarButtonClicked(buttonContainer, mi);\r\n });\r\n //this.markerButtonBlock.appendChild(buttonContainer);\r\n this.buttons.push(buttonContainer);\r\n this.markerButtons.push(buttonContainer);\r\n });\r\n this.overflowButton = document.createElement('div');\r\n this.overflowButton.className = `${this.toolbarButtonStyleClass.name} ${\r\n this.uiStyleSettings.toolbarButtonStyleColorsClassName\r\n ? this.uiStyleSettings.toolbarButtonStyleColorsClassName\r\n : this.toolbarButtonStyleColorsClass.name\r\n }`;\r\n this.overflowButton.innerHTML = OverflowIcon;\r\n this.overflowButton.addEventListener('click', this.overflowButtonClicked);\r\n this.markerButtonBlock.appendChild(this.overflowButton);\r\n }\r\n\r\n const resultButtonBlock = document.createElement('div');\r\n resultButtonBlock.className = this.toolbarBlockStyleClass.name;\r\n resultButtonBlock.style.whiteSpace = 'nowrap';\r\n resultButtonBlock.style.display =\r\n this.uiStyleSettings.resultButtonBlockVisible !== false ? '' : 'none';\r\n this.uiContainer.appendChild(resultButtonBlock);\r\n\r\n this.addActionButton(resultButtonBlock, CheckIcon, 'render', 'Save and close');\r\n this.addActionButton(resultButtonBlock, CloseIcon, 'close', 'Close');\r\n\r\n this.markerjsContainer.appendChild(this.uiContainer);\r\n this.setSelectMode();\r\n\r\n this.setCurrentMarker();\r\n\r\n this.adjustLayout();\r\n // setTimeout(this.adjustLayout, 10);\r\n }\r\n\r\n /**\r\n * Add a listener to the toolbar button click event.\r\n * @param listener\r\n */\r\n public addButtonClickListener(listener: ToolbarButtonClickHandler): void {\r\n this.buttonClickListeners.push(listener);\r\n }\r\n\r\n /**\r\n * Remove a listener for the toolbar button click event.\r\n * @param listener\r\n */\r\n public removeButtonClickListener(listener: ToolbarButtonClickHandler): void {\r\n if (this.buttonClickListeners.indexOf(listener) > -1) {\r\n this.buttonClickListeners.splice(\r\n this.buttonClickListeners.indexOf(listener),\r\n 1\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Switch toolbar to the `select` mode.\r\n */\r\n public setSelectMode(): void {\r\n this.resetButtonStyles();\r\n this.setActiveButton(this.buttons[0]);\r\n }\r\n\r\n /**\r\n * Adjusts toolbar layout.\r\n */\r\n public adjustLayout(): void {\r\n if (this.markerButtons && this.markerButtons.length > 0) {\r\n const numberToFit =\r\n Math.floor(\r\n this.markerButtonBlock.clientWidth /\r\n this.uiStyleSettings.toolbarHeight\r\n ) - 1;\r\n this.markerButtonBlock.innerHTML = '';\r\n this.markerButtonOverflowBlock.innerHTML = '';\r\n for (\r\n let buttonIndex = 0;\r\n buttonIndex < this.markerButtons.length;\r\n buttonIndex++\r\n ) {\r\n if (\r\n buttonIndex < numberToFit ||\r\n (buttonIndex === numberToFit &&\r\n this.markerButtons.length - 1 === numberToFit)\r\n ) {\r\n this.markerButtonBlock.appendChild(this.markerButtons[buttonIndex]);\r\n } else {\r\n if (buttonIndex === numberToFit) {\r\n this.markerButtonBlock.appendChild(this.overflowButton);\r\n }\r\n this.markerButtonOverflowBlock.appendChild(\r\n this.markerButtons[buttonIndex]\r\n );\r\n }\r\n }\r\n }\r\n }\r\n\r\n private overflowButtonClicked() {\r\n if (this.markerButtonOverflowBlock.style.display !== 'none') {\r\n this.markerButtonOverflowBlock.className = this.markerButtonOverflowBlock.className.replace(\r\n this.styles.fadeInAnimationClassName,\r\n ''\r\n );\r\n this.markerButtonOverflowBlock.style.display = 'none';\r\n } else {\r\n this.markerButtonOverflowBlock.className += ` ${this.styles.fadeInAnimationClassName}`;\r\n this.markerButtonOverflowBlock.style.top = `${\r\n this.uiContainer.offsetTop + this.overflowButton.offsetHeight\r\n }px`;\r\n this.markerButtonOverflowBlock.style.right = `${\r\n this.uiContainer.offsetWidth -\r\n this.overflowButton.offsetLeft -\r\n this.overflowButton.offsetWidth +\r\n this.uiContainer.offsetLeft * 2\r\n }px`;\r\n this.markerButtonOverflowBlock.style.display = 'inline-block';\r\n }\r\n }\r\n\r\n private resetButtonStyles() {\r\n this.buttons.forEach((button) => {\r\n button.className = button.className\r\n .replace(\r\n this.uiStyleSettings.toolbarButtonStyleColorsClassName\r\n ? this.uiStyleSettings.toolbarButtonStyleColorsClassName\r\n : this.toolbarButtonStyleColorsClass.name,\r\n ''\r\n )\r\n .trim();\r\n button.className = button.className\r\n .replace(\r\n this.uiStyleSettings.toolbarActiveButtonStyleColorsClassName\r\n ? this.uiStyleSettings.toolbarActiveButtonStyleColorsClassName\r\n : this.toolbarActiveButtonStyleColorsClass.name,\r\n ''\r\n )\r\n .trim();\r\n button.className += ` ${\r\n this.uiStyleSettings.toolbarButtonStyleColorsClassName\r\n ? this.uiStyleSettings.toolbarButtonStyleColorsClassName\r\n : this.toolbarButtonStyleColorsClass.name\r\n }`;\r\n });\r\n }\r\n\r\n private addActionButton(\r\n container: HTMLDivElement,\r\n icon: string,\r\n value: string,\r\n title: string\r\n ) {\r\n const actionButton = document.createElement('div');\r\n actionButton.className = `${this.toolbarButtonStyleClass.name}`;\r\n // ${\r\n // this.uiStyleSettings.toolbarButtonStyleColorsClassName ?\r\n // this.uiStyleSettings.toolbarButtonStyleColorsClassName : this.toolbarButtonStyleColorsClass.name}`;\r\n actionButton.innerHTML = icon;\r\n actionButton.setAttribute('role', 'button');\r\n actionButton.setAttribute('data-action', value);\r\n actionButton.title = title;\r\n actionButton.setAttribute('aria-label', title);\r\n actionButton.addEventListener('click', () => {\r\n this.actionToolbarButtonClicked(actionButton, value);\r\n });\r\n switch (value) {\r\n case 'select':\r\n actionButton.style.fill = this.uiStyleSettings.selectButtonColor;\r\n break;\r\n case 'delete':\r\n case 'clear':\r\n actionButton.style.fill = this.uiStyleSettings.deleteButtonColor;\r\n break;\r\n case 'undo':\r\n actionButton.style.fill = this.uiStyleSettings.selectButtonColor;\r\n break;\r\n case 'redo':\r\n actionButton.style.fill = this.uiStyleSettings.selectButtonColor;\r\n break;\r\n case 'render':\r\n actionButton.style.fill = this.uiStyleSettings.okButtonColor;\r\n break;\r\n case 'close':\r\n actionButton.style.fill = this.uiStyleSettings.closeButtonColor;\r\n break;\r\n }\r\n\r\n container.appendChild(actionButton);\r\n this.buttons.push(actionButton);\r\n }\r\n\r\n private addStyles() {\r\n this.toolbarStyleClass = this.styles.addClass(\r\n new StyleClass(\r\n 'toolbar',\r\n `\r\n width: 100%;\r\n flex-shrink: 0;\r\n display: flex;\r\n flex-direction: row;\r\n justify-content: space-between; \r\n height: ${this.uiStyleSettings.toolbarHeight}px;\r\n box-sizing: content-box;\r\n ${\r\n this.displayMode === 'inline'\r\n ? `border-top-left-radius: ${Math.round(\r\n this.uiStyleSettings.toolbarHeight / 10\r\n )}px;`\r\n : ''\r\n }\r\n ${\r\n this.displayMode === 'inline'\r\n ? `border-top-right-radius: ${Math.round(\r\n this.uiStyleSettings.toolbarHeight / 10\r\n )}px;`\r\n : ''\r\n }\r\n overflow: hidden;\r\n `\r\n )\r\n );\r\n\r\n this.toolbarStyleColorsClass = this.styles.addClass(\r\n new StyleClass(\r\n 'toolbar_colors',\r\n `\r\n background-color: ${this.uiStyleSettings.toolbarBackgroundColor};\r\n box-shadow: 0px 3px rgba(33, 33, 33, 0.1);\r\n `\r\n )\r\n );\r\n\r\n this.toolbarBlockStyleClass = this.styles.addClass(\r\n new StyleClass(\r\n 'toolbar-block',\r\n `\r\n display: inline-block;\r\n box-sizing: content-box;\r\n `\r\n )\r\n );\r\n\r\n this.toolbarOverflowBlockStyleClass = this.styles.addClass(\r\n new StyleClass(\r\n 'toolbar-overflow-block',\r\n `\r\n position: absolute;\r\n top: ${this.uiStyleSettings.toolbarHeight}px;\r\n max-width: ${this.uiStyleSettings.toolbarHeight * 2}px;\r\n z-index: 10;\r\n box-sizing: content-box;\r\n `\r\n )\r\n );\r\n this.toolbarOverflowBlockStyleColorsClass = this.styles.addClass(\r\n new StyleClass(\r\n 'toolbar-overflow-block_colors',\r\n `\r\n background-color: ${this.uiStyleSettings.toolbarBackgroundColor};\r\n `\r\n )\r\n );\r\n\r\n const buttonPadding = this.uiStyleSettings.toolbarHeight / 4;\r\n this.toolbarButtonStyleClass = this.styles.addClass(\r\n new StyleClass(\r\n 'toolbar_button',\r\n `\r\n display: inline-block;\r\n width: ${this.uiStyleSettings.toolbarHeight - buttonPadding * 2}px;\r\n height: ${this.uiStyleSettings.toolbarHeight - buttonPadding * 2}px;\r\n padding: ${buttonPadding}px;\r\n box-sizing: content-box;\r\n `\r\n )\r\n );\r\n this.toolbarButtonStyleColorsClass = this.styles.addClass(\r\n new StyleClass(\r\n 'toolbar_button_colors',\r\n `\r\n fill: ${this.uiStyleSettings.toolbarColor};\r\n `\r\n )\r\n );\r\n\r\n this.toolbarActiveButtonStyleColorsClass = this.styles.addClass(\r\n new StyleClass(\r\n 'toolbar_active_button',\r\n `\r\n fill: ${this.uiStyleSettings.toolbarColor};\r\n background-color: ${this.uiStyleSettings.toolbarBackgroundHoverColor}\r\n `\r\n )\r\n );\r\n\r\n this.styles.addRule(\r\n new StyleRule(\r\n `.${this.toolbarButtonStyleClass.name} svg`,\r\n `\r\n height: ${this.uiStyleSettings.toolbarHeight / 2}px;\r\n `\r\n )\r\n );\r\n\r\n this.styles.addRule(\r\n new StyleRule(\r\n `.${this.toolbarButtonStyleColorsClass.name}:hover`,\r\n `\r\n background-color: ${this.uiStyleSettings.toolbarBackgroundHoverColor}\r\n `\r\n )\r\n );\r\n }\r\n\r\n private markerToolbarButtonClicked(\r\n button: HTMLDivElement,\r\n markerType: typeof MarkerBase\r\n ) {\r\n this.setActiveButton(button);\r\n if (this.buttonClickListeners && this.buttonClickListeners.length > 0) {\r\n this.buttonClickListeners.forEach((listener) =>\r\n listener('marker', markerType)\r\n );\r\n }\r\n this.markerButtonOverflowBlock.style.display = 'none';\r\n }\r\n\r\n private actionToolbarButtonClicked(button: HTMLDivElement, action: string) {\r\n if (this.buttonClickListeners && this.buttonClickListeners.length > 0) {\r\n this.buttonClickListeners.forEach((listener) =>\r\n listener('action', action)\r\n );\r\n }\r\n this.markerButtonOverflowBlock.style.display = 'none';\r\n this.setActiveButton(this.buttons[0]);\r\n }\r\n\r\n private setActiveButton(button: HTMLDivElement) {\r\n this.resetButtonStyles();\r\n button.className = button.className\r\n .replace(\r\n this.uiStyleSettings.toolbarButtonStyleColorsClassName\r\n ? this.uiStyleSettings.toolbarButtonStyleColorsClassName\r\n : this.toolbarButtonStyleColorsClass.name,\r\n ''\r\n )\r\n .trim();\r\n button.className += ` ${\r\n this.uiStyleSettings.toolbarActiveButtonStyleColorsClassName\r\n ? this.uiStyleSettings.toolbarActiveButtonStyleColorsClassName\r\n : this.toolbarActiveButtonStyleColorsClass.name\r\n }`;\r\n }\r\n\r\n /**\r\n * Selects toolbar button for a specified marker type.\r\n * @param typeName Marker type name\r\n *\r\n * @since 2.17.0\r\n */\r\n public setActiveMarkerButton(typeName: string): void {\r\n const activeBtn = this.markerButtons.find(\r\n (btn) => btn.getAttribute('data-type-name') === typeName\r\n );\r\n if (activeBtn) {\r\n this.setActiveButton(activeBtn);\r\n }\r\n }\r\n\r\n /**\r\n * Sets current marker and enables/disables action buttons accordingly.\r\n * @param marker\r\n */\r\n public setCurrentMarker(marker?: MarkerBase): void {\r\n this.currentMarker = marker;\r\n const activeMarkerButtons = this.buttons.filter((btn) =>\r\n /delete|notes/.test(btn.getAttribute('data-action'))\r\n );\r\n activeMarkerButtons.forEach((btn) => {\r\n if (this.currentMarker === undefined) {\r\n btn.style.fillOpacity = '0.4';\r\n btn.style.pointerEvents = 'none';\r\n } else {\r\n btn.style.fillOpacity = '1';\r\n btn.style.pointerEvents = 'all';\r\n }\r\n });\r\n }\r\n}\r\n","import { ToolboxPanel } from './ToolboxPanel';\r\nimport { StyleManager, StyleClass, StyleRule } from './../core/Style';\r\nimport { DisplayMode } from '../core/Settings';\r\nimport { IStyleSettings } from '../core/IStyleSettings';\r\n\r\n/**\r\n * Represents the contextual toolbox for the selected marker type.\r\n */\r\nexport class Toolbox {\r\n private panels: ToolboxPanel[] = [];\r\n private activePanel: ToolboxPanel;\r\n private panelButtons: HTMLDivElement[] = [];\r\n\r\n private markerjsContainer: HTMLDivElement;\r\n private displayMode: DisplayMode;\r\n private uiContainer: HTMLDivElement;\r\n private buttonRow: HTMLDivElement;\r\n private panelRow: HTMLDivElement;\r\n\r\n private toolboxStyleClass: StyleClass;\r\n private toolboxStyleColorsClass: StyleClass;\r\n private toolboxButtonStyleClass: StyleClass;\r\n private toolboxButtonStyleColorsClass: StyleClass;\r\n private toolboxActiveButtonStyleColorsClass: StyleClass;\r\n private toolboxButtonRowStyleClass: StyleClass;\r\n private toolboxButtonRowStyleColorsClass: StyleClass;\r\n private toolboxPanelRowStyleClass: StyleClass;\r\n private toolboxPanelRowStyleColorsClass: StyleClass;\r\n\r\n private uiStyleSettings: IStyleSettings;\r\n private styles: StyleManager;\r\n \r\n private addStyles() {\r\n this.toolboxStyleClass = this.styles.addClass(\r\n new StyleClass(\r\n 'toolbox',\r\n `\r\n width: 100%;\r\n flex-shrink: 0;\r\n display: flex;\r\n flex-direction: column;\r\n font-family: sans-serif;\r\n ${this.displayMode === 'popup' ? 'height:' + this.uiStyleSettings.toolbarHeight * 2.5 + 'px;' : ''}\r\n box-sizing: content-box;\r\n ${this.displayMode === 'popup' ? `background-color: ${this.uiStyleSettings.canvasBackgroundColor};` : ''}\r\n ${this.displayMode === 'inline' ? `border-bottom-left-radius: ${Math.round(this.uiStyleSettings.toolbarHeight/10)}px;` : ''}\r\n ${this.displayMode === 'inline' ? `border-bottom-right-radius: ${Math.round(this.uiStyleSettings.toolbarHeight/10)}px;` : ''}\r\n overflow: hidden;\r\n `\r\n )\r\n );\r\n this.toolboxStyleColorsClass = this.styles.addClass(\r\n new StyleClass(\r\n 'toolbox_colors',\r\n `\r\n color: ${this.uiStyleSettings.toolboxColor};\r\n `\r\n )\r\n );\r\n\r\n const buttonPadding = this.uiStyleSettings.toolbarHeight / 4;\r\n this.toolboxButtonRowStyleClass = this.styles.addClass(new StyleClass('toolbox-button-row', `\r\n display: flex;\r\n cursor: default;\r\n box-sizing: content-box;\r\n `));\r\n this.toolboxButtonRowStyleColorsClass = this.styles.addClass(new StyleClass('toolbox-button-row_colors', `\r\n background-color: ${this.uiStyleSettings.toolbarBackgroundColor};\r\n `));\r\n\r\n this.toolboxPanelRowStyleClass = this.styles.addClass(new StyleClass('toolbox-panel-row', `\r\n display: flex;\r\n ${this.displayMode === 'inline' ? 'position: absolute;' : '' }\r\n ${this.displayMode === 'inline' ? 'bottom: ' + this.uiStyleSettings.toolbarHeight + 'px;' : '' }\r\n cursor: default;\r\n height: ${this.uiStyleSettings.toolbarHeight * 1.5}px;\r\n ${this.displayMode === 'inline' ? 'width: 100%;' : ''}\r\n box-sizing: content-box;\r\n `));\r\n this.toolboxPanelRowStyleColorsClass = this.styles.addClass(new StyleClass('toolbox-panel-row_colors', `\r\n background-color: ${this.uiStyleSettings.toolboxBackgroundColor ?? this.uiStyleSettings.toolbarBackgroundHoverColor};\r\n `));\r\n\r\n this.toolboxButtonStyleClass = this.styles.addClass(new StyleClass('toolbox_button', `\r\n display: inline-block;\r\n width: ${this.uiStyleSettings.toolbarHeight - buttonPadding * 2}px;\r\n height: ${this.uiStyleSettings.toolbarHeight - buttonPadding * 2}px;\r\n padding: ${buttonPadding}px;\r\n box-sizing: content-box;\r\n `));\r\n this.toolboxButtonStyleColorsClass = this.styles.addClass(new StyleClass('toolbox-button_colors', `\r\n fill: ${this.uiStyleSettings.toolbarColor};\r\n `));\r\n\r\n this.toolboxActiveButtonStyleColorsClass = this.styles.addClass(new StyleClass('toolbox-active-button_colors', `\r\n background-color: ${this.uiStyleSettings.toolbarBackgroundHoverColor};\r\n fill: ${this.uiStyleSettings.toolbarColor};\r\n `));\r\n\r\n this.styles.addRule(\r\n new StyleRule(\r\n `.${this.toolboxButtonStyleColorsClass.name}:hover`,\r\n `\r\n background-color: ${this.uiStyleSettings.toolbarBackgroundHoverColor}\r\n `\r\n )\r\n );\r\n\r\n this.styles.addRule(\r\n new StyleRule(\r\n `.${this.toolboxButtonStyleClass.name} svg`,\r\n `\r\n height: ${this.uiStyleSettings.toolbarHeight / 2}px;\r\n `\r\n )\r\n );\r\n\r\n this.styles.addRule(\r\n new StyleRule(\r\n `.${this.toolboxPanelRowStyleClass.name} > div`,\r\n `\r\n scrollbar-width: thin;\r\n `\r\n )\r\n );\r\n\r\n this.styles.addRule(\r\n new StyleRule(\r\n `.${this.toolboxPanelRowStyleClass.name} > div::-webkit-scrollbar`,\r\n `\r\n height: 10px;\r\n width: 10px;\r\n `\r\n )\r\n );\r\n\r\n this.styles.addRule(\r\n new StyleRule(\r\n `.${this.toolboxPanelRowStyleClass.name} > div::-webkit-scrollbar-track`,\r\n `\r\n background-color: transparent;\r\n `\r\n )\r\n );\r\n\r\n this.styles.addRule(\r\n new StyleRule(\r\n `.${this.toolboxPanelRowStyleClass.name} > div::-webkit-scrollbar-thumb`,\r\n `\r\n background-color: #444;\r\n border-radius: 20px;\r\n border: 2px solid #aaa;\r\n `\r\n )\r\n );\r\n }\r\n\r\n /**\r\n * Creates the toolbox object\r\n * @param markerjsContainer - container for the toolbox in marker.js UI.\r\n * @param displayMode - marker.js display mode (`inline` or `popup`).\r\n * @param uiStyleSettings - settings for styling the toolbox elements.\r\n */\r\n constructor(markerjsContainer: HTMLDivElement, displayMode: DisplayMode, uiStyleSettings: IStyleSettings, styles: StyleManager) {\r\n this.markerjsContainer = markerjsContainer;\r\n this.displayMode = displayMode;\r\n this.uiStyleSettings = uiStyleSettings;\r\n this.styles = styles;\r\n\r\n this.panelButtonClick = this.panelButtonClick.bind(this);\r\n\r\n this.addStyles();\r\n }\r\n\r\n /**\r\n * Creates and displays the main toolbox UI.\r\n */\r\n public show(visiblity: string): void {\r\n this.uiContainer = document.createElement('div');\r\n this.uiContainer.style.visibility = visiblity;\r\n this.uiContainer.className = `${this.toolboxStyleClass.name} ${\r\n this.uiStyleSettings.toolboxStyleColorsClassName ?? this.toolboxStyleColorsClass.name}`;\r\n\r\n this.markerjsContainer.appendChild(this.uiContainer);\r\n }\r\n\r\n /**\r\n * Creaes buttons for the top-level toolbox panel.\r\n * @param panels - available panels.\r\n */\r\n public setPanelButtons(panels: ToolboxPanel[]): void {\r\n this.panels = panels;\r\n if (this.uiContainer !== undefined) {\r\n this.uiContainer.innerHTML = '';\r\n\r\n this.panelRow = document.createElement('div');\r\n this.panelRow.className = `${this.toolboxPanelRowStyleClass.name} ${\r\n this.uiStyleSettings.toolboxPanelRowStyleColorsClassName ?? this.toolboxPanelRowStyleColorsClass.name}`;\r\n this.uiContainer.appendChild(this.panelRow);\r\n this.buttonRow = document.createElement('div');\r\n this.buttonRow.className = `${this.toolboxButtonRowStyleClass.name} ${\r\n this.uiStyleSettings.toolboxButtonRowStyleColorsClassName ?? this.toolboxButtonRowStyleColorsClass.name} `;\r\n this.uiContainer.appendChild(this.buttonRow);\r\n\r\n this.panelButtons.splice(0);\r\n\r\n this.panels.forEach(panel => {\r\n panel.uiStyleSettings = this.uiStyleSettings;\r\n const panelBtnDiv = document.createElement('div');\r\n panelBtnDiv.className = `${this.toolboxButtonStyleClass.name} ${\r\n this.uiStyleSettings.toolboxButtonStyleColorsClassName ?? this.toolboxButtonStyleColorsClass.name}`;\r\n panelBtnDiv.innerHTML = panel.icon;\r\n panelBtnDiv.title = panel.title;\r\n panelBtnDiv.setAttribute('role', 'button');\r\n panelBtnDiv.setAttribute('aria-label', panel.title);\r\n if (panel.id) {\r\n panelBtnDiv.setAttribute('data-action', panel.id);\r\n }\r\n panelBtnDiv.addEventListener('click', () => {\r\n this.panelButtonClick(panel);\r\n })\r\n this.panelButtons.push(panelBtnDiv);\r\n this.buttonRow.appendChild(panelBtnDiv);\r\n });\r\n if (this.displayMode === 'inline') {\r\n this.panelRow.style.display = 'none';\r\n } else {\r\n this.panelRow.style.visibility = 'hidden';\r\n }\r\n }\r\n // if (this.displayMode === 'popup' && this.panels.length > 0) {\r\n // // this.showPanel(this.activePanel ? this.activePanel : this.panels[0]);\r\n // this.panelButtonClick(this.panels[0]);\r\n // }\r\n }\r\n\r\n private panelButtonClick(panel: ToolboxPanel) {\r\n let panelIndex = -1; \r\n if (panel !== this.activePanel) {\r\n panelIndex = this.panels.indexOf(panel);\r\n this.panelRow.innerHTML = '';\r\n const panelUI = panel.getUi();\r\n panelUI.style.margin = `${this.uiStyleSettings.toolbarHeight / 4}px`;\r\n this.panelRow.appendChild(panelUI);\r\n this.panelRow.style.display = 'flex';\r\n this.panelRow.style.visibility = 'visible';\r\n this.panelRow.className = this.panelRow.className.replace(this.styles.fadeOutAnimationClassName, '');\r\n this.panelRow.className += ` ${this.styles.fadeInAnimationClassName}`;\r\n this.activePanel = panel;\r\n } else {\r\n this.activePanel = undefined;\r\n // hide panel\r\n this.panelRow.className = this.panelRow.className.replace(this.styles.fadeInAnimationClassName, '');\r\n this.panelRow.className += ` ${this.styles.fadeOutAnimationClassName}`;\r\n setTimeout(() => {\r\n if (this.displayMode === 'inline') {\r\n this.panelRow.style.display = 'none';\r\n } else {\r\n this.panelRow.style.visibility = 'hidden';\r\n }\r\n }, 200);\r\n }\r\n this.panelButtons.forEach((pb, index) => {\r\n pb.className = `${this.toolboxButtonStyleClass.name} ` +\r\n (index === panelIndex\r\n ? `${this.uiStyleSettings.toolboxActiveButtonStyleColorsClassName ?? this.toolboxActiveButtonStyleColorsClass.name}`\r\n : `${this.uiStyleSettings.toolboxButtonStyleColorsClassName ?? this.toolboxButtonStyleColorsClass.name}`);\r\n });\r\n }\r\n\r\n}\r\n","import { IStyleSettings } from '../core/IStyleSettings';\r\n\r\n/**\r\n * Base class for all toolbox property panels.\r\n */\r\nexport abstract class ToolboxPanel {\r\n protected _id?: string;\r\n /**\r\n * Panel ID.\r\n */\r\n public get id(): string | undefined {\r\n return this._id;\r\n }\r\n /**\r\n * Panel name/title.\r\n */\r\n public title: string;\r\n /**\r\n * Panel button icon as an SVG markup.\r\n */\r\n public icon: string;\r\n\r\n /**\r\n * UI style settings for colors, etc.\r\n */\r\n public uiStyleSettings: IStyleSettings;\r\n\r\n /**\r\n * Create panel with supplied title and icon.\r\n * @param title - panel name (used for accessibility)\r\n * @param icon - panel button icon (SVG image markup)\r\n */\r\n constructor(title: string, icon?: string) {\r\n this.title = title;\r\n this.icon = icon;\r\n }\r\n /**\r\n * Returns toolbox panel UI.\r\n */\r\n public abstract getUi(): HTMLDivElement;\r\n}\r\n","import { ToolboxPanel } from '../ToolboxPanel';\r\nimport Icon from './color-picker-panel-icon.svg';\r\n\r\n/**\r\n * Handler type for the color change event.\r\n */\r\nexport type ColorChangeHandler = (newColor: string) => void;\r\n\r\n/**\r\n * Color picker panel.\r\n */\r\nexport class ColorPickerPanel extends ToolboxPanel {\r\n public colors: string[] = [];\r\n private currentColor?: string;\r\n private addTransparent = false;\r\n\r\n private colorBoxes: HTMLDivElement[] = [];\r\n\r\n /**\r\n * Color change event handler.\r\n */\r\n public onColorChanged?: ColorChangeHandler;\r\n\r\n /**\r\n * Creates a color picker panel.\r\n * @param title - panel title.\r\n * @param colors - available colors.\r\n * @param currentColor - currently selected color.\r\n * @param icon - panel button icon (SVG imager markup).\r\n */\r\n constructor(title: string, colors: string[], currentColor?: string, icon?: string) {\r\n super(title, icon ? icon : Icon);\r\n this.colors = colors;\r\n this.currentColor = currentColor;\r\n\r\n this._id = 'color-picker-panel';\r\n\r\n this.setCurrentColor = this.setCurrentColor.bind(this);\r\n this.getColorBox = this.getColorBox.bind(this);\r\n }\r\n\r\n /**\r\n * Returns panel UI.\r\n */\r\n public getUi(): HTMLDivElement {\r\n const panelDiv = document.createElement('div');\r\n panelDiv.style.overflow = 'hidden';\r\n panelDiv.style.overflowX = 'scroll';\r\n panelDiv.style.whiteSpace = 'nowrap';\r\n this.colors.forEach((color) => {\r\n const colorBoxContainer = this.getColorBox(color);\r\n panelDiv.appendChild(colorBoxContainer);\r\n this.colorBoxes.push(colorBoxContainer);\r\n });\r\n return panelDiv;\r\n }\r\n\r\n private getColorBox(color): HTMLDivElement {\r\n const buttonPadding = this.uiStyleSettings.toolbarHeight / 4;\r\n const buttonHeight = this.uiStyleSettings.toolbarHeight - buttonPadding;\r\n\r\n const colorBoxContainer = document.createElement('div');\r\n colorBoxContainer.style.display = 'inline-block';\r\n colorBoxContainer.style.boxSizing = 'content-box';\r\n colorBoxContainer.style.width = `${buttonHeight - 2}px`;\r\n colorBoxContainer.style.height = `${buttonHeight - 2}px`;\r\n colorBoxContainer.style.padding = '1px';\r\n colorBoxContainer.style.marginRight = '2px';\r\n colorBoxContainer.style.marginBottom = '2px';\r\n colorBoxContainer.style.borderWidth = '2px';\r\n colorBoxContainer.style.borderStyle = 'solid';\r\n colorBoxContainer.style.borderRadius = `${(buttonHeight + 2)/2}px`\r\n colorBoxContainer.style.borderColor =\r\n color === this.currentColor ? this.uiStyleSettings.toolboxAccentColor : 'transparent';\r\n\r\n colorBoxContainer.addEventListener('click', () => {\r\n this.setCurrentColor(color, colorBoxContainer);\r\n })\r\n\r\n const colorBox = document.createElement('div');\r\n colorBox.style.display = 'inline-block';\r\n colorBox.style.width = `${buttonHeight - 2}px`;\r\n colorBox.style.height = `${buttonHeight - 2}px`;\r\n colorBox.style.backgroundColor = color;\r\n colorBox.style.borderRadius = `${buttonHeight/2}px`;\r\n if (color === 'transparent') {\r\n colorBox.style.fill = this.uiStyleSettings.toolboxAccentColor;\r\n colorBox.innerHTML = `<svg viewBox=\"0 0 24 24\">\r\n <path d=\"M2,5.27L3.28,4L20,20.72L18.73,22L15.65,18.92C14.5,19.3 13.28,19.5 12,19.5C7,19.5 2.73,16.39 1,12C1.69,10.24 2.79,8.69 4.19,7.46L2,5.27M12,9A3,3 0 0,1 15,12C15,12.35 14.94,12.69 14.83,13L11,9.17C11.31,9.06 11.65,9 12,9M12,4.5C17,4.5 21.27,7.61 23,12C22.18,14.08 20.79,15.88 19,17.19L17.58,15.76C18.94,14.82 20.06,13.54 20.82,12C19.17,8.64 15.76,6.5 12,6.5C10.91,6.5 9.84,6.68 8.84,7L7.3,5.47C8.74,4.85 10.33,4.5 12,4.5M3.18,12C4.83,15.36 8.24,17.5 12,17.5C12.69,17.5 13.37,17.43 14,17.29L11.72,15C10.29,14.85 9.15,13.71 9,12.28L5.6,8.87C4.61,9.72 3.78,10.78 3.18,12Z\" />\r\n </svg>`;\r\n }\r\n\r\n colorBoxContainer.appendChild(colorBox);\r\n\r\n return colorBoxContainer;\r\n }\r\n\r\n private setCurrentColor(color: string, target: HTMLDivElement) {\r\n this.currentColor = color;\r\n\r\n this.colorBoxes.forEach(box => {\r\n box.style.borderColor = box === target ? this.uiStyleSettings.toolboxAccentColor : 'transparent';\r\n });\r\n\r\n if (this.onColorChanged) {\r\n this.onColorChanged(color);\r\n }\r\n }\r\n}\r\n","import { IPoint } from './IPoint';\r\nimport { ToolboxPanel } from '../ui/ToolboxPanel';\r\nimport { MarkerBaseState, MarkerState } from './MarkerBaseState';\r\nimport { Settings } from './Settings';\r\n\r\n/**\r\n * Base class for all available and custom marker types.\r\n * \r\n * All markers used with marker.js 2 should be descendants of this class.\r\n */\r\nexport class MarkerBase {\r\n /**\r\n * String type name of the marker type. \r\n * \r\n * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\r\n */\r\n public static typeName = 'MarkerBase';\r\n\r\n /**\r\n * Instance property returning marker's type name.\r\n * \r\n * @since 2.16.0\r\n */\r\n public get typeName(): string {\r\n return Object.getPrototypeOf(this).constructor.typeName;\r\n }\r\n\r\n protected _container: SVGGElement;\r\n /**\r\n * SVG container object holding the marker's visual.\r\n */\r\n public get container(): SVGGElement {\r\n return this._container;\r\n }\r\n protected _overlayContainer: HTMLDivElement;\r\n /**\r\n * HTML container that can be used to render overlay objects while the marker is active.\r\n * \r\n * For example, this is used for the text editing layer while editing text in the {@see TextMarker}.\r\n */\r\n public get overlayContainer(): HTMLDivElement {\r\n return this._overlayContainer;\r\n }\r\n protected _state: MarkerState = 'new';\r\n /**\r\n * Current marker state.\r\n *\r\n * Both MarkerArea and the marker itself can react differently to different events based on what state the marker is in.\r\n */\r\n public get state(): MarkerState {\r\n return this._state;\r\n }\r\n protected globalSettings: Settings;\r\n\r\n /**\r\n * Additional information about the marker\r\n */\r\n public notes?: string;\r\n\r\n /**\r\n * Returns the list of toolbox panels for this marker type.\r\n */\r\n public get toolboxPanels(): ToolboxPanel[] {\r\n return [];\r\n }\r\n\r\n /**\r\n * Marker type title (display name) used for accessibility and other attributes.\r\n */\r\n public static title: string;\r\n\r\n /**\r\n * SVG icon markup displayed on toolbar buttons.\r\n */\r\n public static icon: string;\r\n\r\n /**\r\n * Method called when marker creation is finished.\r\n */\r\n public onMarkerCreated: (marker: MarkerBase) => void;\r\n\r\n /**\r\n * Method to call when foreground color changes.\r\n */\r\n public onColorChanged?: (color: string) => void;\r\n /**\r\n * Method to call when background/fill color changes.\r\n */\r\n public onFillColorChanged?: (color: string) => void;\r\n /**\r\n * Method to call when marker state changes.\r\n * \r\n * @since 2.23.0\r\n */\r\n public onStateChanged?: (marker: MarkerBase) => void;\r\n\r\n /**\r\n * Marker's state when it is selected\r\n *\r\n * @since 2.23.0\r\n */\r\n protected manipulationStartState?: MarkerBaseState;\r\n\r\n /**\r\n * Creates a new marker.\r\n *\r\n * @param container - SVG container to hold marker's visual.\r\n * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\r\n * @param settings - settings object containing default markers settings.\r\n */\r\n constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\r\n this._container = container;\r\n this._overlayContainer = overlayContainer;\r\n this.globalSettings = settings;\r\n\r\n this.stateChanged = this.stateChanged.bind(this);\r\n this.colorChanged = this.colorChanged.bind(this);\r\n this.fillColorChanged = this.fillColorChanged.bind(this);\r\n }\r\n\r\n /**\r\n * Returns true if passed SVG element belongs to the marker. False otherwise.\r\n * \r\n * @param el - target element.\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n public ownsTarget(el: EventTarget): boolean {\r\n return false;\r\n }\r\n\r\n /**\r\n * Is this marker selected?\r\n * \r\n * @since 2.16.0\r\n */\r\n protected _isSelected = false;\r\n\r\n /**\r\n * Returns true if the marker is currently selected\r\n * \r\n * @since 2.16.0\r\n */\r\n public get isSelected(): boolean {\r\n return this._isSelected;\r\n }\r\n\r\n /**\r\n * Selects this marker and displays appropriate selected marker UI.\r\n */\r\n public select(): void {\r\n this.container.style.cursor = 'move';\r\n this._isSelected = true;\r\n this.manipulationStartState = this.getState();\r\n }\r\n\r\n /**\r\n * Deselects this marker and hides selected marker UI.\r\n */\r\n public deselect(): void {\r\n this.container.style.cursor = 'default';\r\n this._isSelected = false;\r\n this.stateChanged();\r\n }\r\n\r\n /**\r\n * Handles pointer (mouse, touch, stylus, etc.) down event.\r\n * \r\n * @param point - event coordinates.\r\n * @param target - direct event target element.\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function\r\n public pointerDown(point: IPoint, target?: EventTarget):void {}\r\n\r\n /**\r\n * Handles pointer (mouse, touch, stylus, etc.) double click event.\r\n * \r\n * @param point - event coordinates.\r\n * @param target - direct event target element.\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function\r\n public dblClick(point: IPoint, target?: EventTarget):void {}\r\n\r\n /**\r\n * Handles marker manipulation (move, resize, rotate, etc.).\r\n * \r\n * @param point - event coordinates.\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function\r\n public manipulate(point: IPoint):void {}\r\n\r\n /**\r\n * Handles pointer (mouse, touch, stylus, etc.) up event.\r\n * \r\n * @param point - event coordinates.\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function\r\n public pointerUp(point: IPoint):void {\r\n this.stateChanged();\r\n }\r\n\r\n /**\r\n * Disposes the marker and clean's up.\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-empty-function\r\n public dispose(): void {}\r\n\r\n protected addMarkerVisualToContainer(element: SVGElement): void {\r\n if (this.container.childNodes.length > 0) {\r\n this.container.insertBefore(element, this.container.childNodes[0]);\r\n } else {\r\n this.container.appendChild(element);\r\n }\r\n }\r\n\r\n /**\r\n * Returns current marker state that can be restored in the future.\r\n */\r\n public getState(): MarkerBaseState {\r\n return { \r\n typeName: MarkerBase.typeName, \r\n state: this.state,\r\n notes: this.notes\r\n };\r\n }\r\n\r\n /**\r\n * Restores previously saved marker state.\r\n * \r\n * @param state - previously saved state.\r\n */\r\n public restoreState(state: MarkerBaseState): void {\r\n this._state = state.state;\r\n this.notes = state.notes;\r\n }\r\n\r\n /**\r\n * Scales marker. Used after the image resize.\r\n * \r\n * @param scaleX - horizontal scale\r\n * @param scaleY - vertical scale\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars\r\n public scale(scaleX: number, scaleY: number): void {}\r\n\r\n /**\r\n * Called by a marker when its foreground color changes.\r\n * @param color \r\n */\r\n protected colorChanged(color: string): void {\r\n if (this.onColorChanged) {\r\n this.onColorChanged(color);\r\n }\r\n this.stateChanged();\r\n }\r\n /**\r\n * Called by a marker when its background/fill color changes.\r\n * @param color \r\n */\r\n protected fillColorChanged(color: string): void {\r\n if (this.onFillColorChanged) {\r\n this.onFillColorChanged(color);\r\n }\r\n this.stateChanged();\r\n }\r\n\r\n /**\r\n * Called by a marker when its state could have changed.\r\n * Does a check if the state has indeed changed before firing the handler.\r\n * \r\n * @since 2.23.0\r\n */\r\n protected stateChanged(): void {\r\n if (this.onStateChanged && this.state !== 'creating' && this.state !== 'new') {\r\n const currentState = this.getState();\r\n // avoid reacting to state (mode) differences\r\n if (this.manipulationStartState !== undefined) {\r\n this.manipulationStartState.state = 'select';\r\n }\r\n currentState.state = 'select';\r\n if (JSON.stringify(this.manipulationStartState) != JSON.stringify(currentState)) {\r\n this.onStateChanged(this);\r\n }\r\n }\r\n }\r\n}\r\n","import { ResizeGrip } from './ResizeGrip';\r\n\r\n/**\r\n * RectangularBoxMarkerGrips is a set of resize/rotation grips for a rectangular marker.\r\n */\r\nexport class RectangularBoxMarkerGrips {\r\n /**\r\n * Top-left grip.\r\n */\r\n public topLeft: ResizeGrip;\r\n /**\r\n * Top-center grip.\r\n */\r\n public topCenter: ResizeGrip;\r\n /**\r\n * Top-right grip.\r\n */\r\n public topRight: ResizeGrip;\r\n /**\r\n * Center-left grip.\r\n */\r\n public centerLeft: ResizeGrip;\r\n /**\r\n * Center-right grip.\r\n */\r\n public centerRight: ResizeGrip;\r\n /**\r\n * Bottom-left grip.\r\n */\r\n public bottomLeft: ResizeGrip;\r\n /**\r\n * Bottom-center grip.\r\n */\r\n public bottomCenter: ResizeGrip;\r\n /**\r\n * Bottom-right grip.\r\n */\r\n public bottomRight: ResizeGrip;\r\n\r\n /**\r\n * Creates a new marker grip set.\r\n */\r\n constructor() {\r\n this.findGripByVisual = this.findGripByVisual.bind(this);\r\n }\r\n\r\n /**\r\n * Returns a marker grip owning the specified visual.\r\n * @param gripVisual - visual for owner to be determined.\r\n */\r\n public findGripByVisual(\r\n gripVisual: EventTarget\r\n ): ResizeGrip | undefined {\r\n if (this.topLeft.ownsTarget(gripVisual)) {\r\n return this.topLeft;\r\n } else if (this.topCenter.ownsTarget(gripVisual)) {\r\n return this.topCenter;\r\n } else if (this.topRight.ownsTarget(gripVisual)) {\r\n return this.topRight;\r\n } else if (this.centerLeft.ownsTarget(gripVisual)) {\r\n return this.centerLeft;\r\n } else if (this.centerRight.ownsTarget(gripVisual)) {\r\n return this.centerRight;\r\n } else if (this.bottomLeft.ownsTarget(gripVisual)) {\r\n return this.bottomLeft;\r\n } else if (this.bottomCenter.ownsTarget(gripVisual)) {\r\n return this.bottomCenter;\r\n } else if (this.bottomRight.ownsTarget(gripVisual)) {\r\n return this.bottomRight;\r\n } else {\r\n return undefined;\r\n }\r\n }\r\n}\r\n","import { SvgHelper } from '../core/SvgHelper';\r\n\r\n/**\r\n * Represents a single resize-manipulation grip used in marker's manipulation controls.\r\n */\r\nexport class ResizeGrip {\r\n /**\r\n * Grip's visual element.\r\n */\r\n public visual: SVGGraphicsElement;\r\n\r\n /**\r\n * Grip's size (raduis).\r\n */\r\n public readonly GRIP_SIZE = 10;\r\n\r\n /**\r\n * Creates a new grip.\r\n */\r\n constructor() {\r\n this.visual = SvgHelper.createGroup();\r\n this.visual.appendChild(\r\n SvgHelper.createCircle(this.GRIP_SIZE * 1.5, [['fill', 'transparent']])\r\n );\r\n this.visual.appendChild(\r\n SvgHelper.createCircle(this.GRIP_SIZE, [\r\n ['fill', '#cccccc'],\r\n ['fill-opacity', '0.7'],\r\n ['stroke', '#333333'],\r\n ['stroke-width', '2'],\r\n ['stroke-opacity', '0.7']\r\n ])\r\n );\r\n }\r\n\r\n /**\r\n * Returns true if passed SVG element belongs to the grip. False otherwise.\r\n * \r\n * @param el - target element.\r\n */\r\n public ownsTarget(el: EventTarget): boolean {\r\n if (\r\n el === this.visual ||\r\n el === this.visual.childNodes[0] ||\r\n el === this.visual.childNodes[1]\r\n ) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n}\r\n","/**\r\n * Represents a simplified version of the SVGMatrix.\r\n */\r\nexport interface ITransformMatrix {\r\n a: number;\r\n b: number;\r\n c: number;\r\n d: number;\r\n e: number;\r\n f: number;\r\n}\r\n\r\n/**\r\n * A utility class to transform between SVGMatrix and its simplified representation.\r\n */\r\nexport class TransformMatrix {\r\n public static toITransformMatrix(matrix: SVGMatrix): ITransformMatrix {\r\n return {\r\n a: matrix.a,\r\n b: matrix.b,\r\n c: matrix.c,\r\n d: matrix.d,\r\n e: matrix.e,\r\n f: matrix.f\r\n }\r\n }\r\n public static toSVGMatrix(currentMatrix: SVGMatrix, newMatrix: ITransformMatrix): SVGMatrix {\r\n currentMatrix.a = newMatrix.a;\r\n currentMatrix.b = newMatrix.b;\r\n currentMatrix.c = newMatrix.c;\r\n currentMatrix.d = newMatrix.d;\r\n currentMatrix.e = newMatrix.e;\r\n currentMatrix.f = newMatrix.f;\r\n return currentMatrix;\r\n }\r\n}","import { MarkerBase } from '../core/MarkerBase';\r\n\r\nimport { IPoint } from '../core/IPoint';\r\nimport { SvgHelper } from '../core/SvgHelper';\r\n\r\nimport { RectangularBoxMarkerGrips } from './RectangularBoxMarkerGrips';\r\nimport { ResizeGrip } from './ResizeGrip';\r\nimport { Settings } from '../core/Settings';\r\nimport { RectangularBoxMarkerBaseState } from './RectangularBoxMarkerBaseState';\r\nimport { MarkerBaseState } from '../core/MarkerBaseState';\r\nimport { TransformMatrix } from '../core/TransformMatrix';\r\n\r\n/**\r\n * RectangularBoxMarkerBase is a base class for all marker's with rectangular controls such as all rectangle markers,\r\n * text and callout markers.\r\n * \r\n * It creates and manages the rectangular control box and related resize, move, and rotate manipulations.\r\n */\r\nexport class RectangularBoxMarkerBase extends MarkerBase {\r\n /**\r\n * x coordinate of the top-left corner.\r\n */\r\n protected left = 0;\r\n /**\r\n * y coordinate of the top-left corner.\r\n */\r\n protected top = 0;\r\n /**\r\n * Marker width.\r\n */\r\n protected width = 0;\r\n /**\r\n * Marker height.\r\n */\r\n protected height = 0;\r\n\r\n /**\r\n * The default marker size when the marker is created with a click (without dragging).\r\n */\r\n protected defaultSize: IPoint = {x: 50, y: 20};\r\n\r\n /**\r\n * x coordinate of the top-left corner at the start of manipulation.\r\n */\r\n protected manipulationStartLeft: number;\r\n /**\r\n * y coordinate of the top-left corner at the start of manipulation.\r\n */\r\n protected manipulationStartTop: number;\r\n /**\r\n * Width at the start of manipulation.\r\n */\r\n protected manipulationStartWidth: number;\r\n /**\r\n * Height at the start of manipulation.\r\n */\r\n protected manipulationStartHeight: number;\r\n\r\n /**\r\n * x coordinate of the pointer at the start of manipulation.\r\n */\r\n protected manipulationStartX: number;\r\n /**\r\n * y coordinate of the pointer at the start of manipulation.\r\n */\r\n protected manipulationStartY: number;\r\n\r\n /**\r\n * Pointer's horizontal distance from the top left corner.\r\n */\r\n protected offsetX = 0;\r\n /**\r\n * Pointer's vertical distance from the top left corner.\r\n */\r\n protected offsetY = 0;\r\n\r\n /**\r\n * Marker's rotation angle.\r\n */\r\n protected rotationAngle = 0;\r\n\r\n /**\r\n * x coordinate of the marker's center.\r\n */\r\n protected get centerX(): number {\r\n return this.left + this.width / 2;\r\n }\r\n /**\r\n * y coordinate of the marker's center.\r\n */\r\n protected get centerY(): number {\r\n return this.top + this.height / 2;\r\n }\r\n\r\n private _visual: SVGGraphicsElement;\r\n /**\r\n * Container for the marker's visual.\r\n */\r\n protected get visual(): SVGGraphicsElement {\r\n return this._visual;\r\n }\r\n protected set visual(value: SVGGraphicsElement) {\r\n this._visual = value;\r\n const translate = SvgHelper.createTransform();\r\n this._visual.transform.baseVal.appendItem(translate);\r\n }\r\n\r\n /**\r\n * Container for the marker's editing controls.\r\n */\r\n protected controlBox: SVGGElement;\r\n private readonly CB_DISTANCE: number = 10;\r\n private controlRect: SVGRectElement;\r\n private rotatorGripLine: SVGLineElement;\r\n\r\n private controlGrips: RectangularBoxMarkerGrips;\r\n private rotatorGrip: ResizeGrip;\r\n private activeGrip: ResizeGrip;\r\n\r\n /**\r\n * Creates a new marker.\r\n *\r\n * @param container - SVG container to hold marker's visual.\r\n * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\r\n * @param settings - settings object containing default markers settings.\r\n */\r\n constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\r\n super(container, overlayContainer, settings);\r\n\r\n // add rotation transform\r\n this.container.transform.baseVal.appendItem(SvgHelper.createTransform());\r\n\r\n this.setupControlBox();\r\n }\r\n\r\n /**\r\n * Returns true if passed SVG element belongs to the marker. False otherwise.\r\n * \r\n * @param el - target element.\r\n */\r\n public ownsTarget(el: EventTarget): boolean {\r\n if (super.ownsTarget(el)) {\r\n return true;\r\n } else if (\r\n this.controlGrips.findGripByVisual(el) !== undefined ||\r\n (this.rotatorGrip !== undefined && this.rotatorGrip.ownsTarget(el))\r\n ) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Handles pointer (mouse, touch, stylus, etc.) down event.\r\n * \r\n * @param point - event coordinates.\r\n * @param target - direct event target element.\r\n */\r\n public pointerDown(point: IPoint, target?: EventTarget): void {\r\n super.pointerDown(point, target);\r\n\r\n if (this.state === 'new') {\r\n this.left = point.x;\r\n this.top = point.y;\r\n }\r\n\r\n this.manipulationStartLeft = this.left;\r\n this.manipulationStartTop = this.top;\r\n this.manipulationStartWidth = this.width;\r\n this.manipulationStartHeight = this.height;\r\n\r\n const rotatedPoint = this.unrotatePoint(point);\r\n this.manipulationStartX = rotatedPoint.x;\r\n this.manipulationStartY = rotatedPoint.y;\r\n\r\n this.offsetX = rotatedPoint.x - this.left;\r\n this.offsetY = rotatedPoint.y - this.top;\r\n\r\n if (this.state !== 'new') {\r\n this.select();\r\n this.activeGrip = this.controlGrips.findGripByVisual(target as SVGGraphicsElement);\r\n if (this.activeGrip !== undefined) {\r\n this._state = 'resize';\r\n } else if (this.rotatorGrip !== undefined && this.rotatorGrip.ownsTarget(target)) {\r\n this.activeGrip = this.rotatorGrip;\r\n\r\n const rotatedCenter = this.rotatePoint({x: this.centerX, y: this.centerY});\r\n this.left = rotatedCenter.x - this.width / 2;\r\n this.top = rotatedCenter.y - this.height / 2;\r\n this.moveVisual({ x: this.left, y: this.top });\r\n\r\n const rotate = this.container.transform.baseVal.getItem(0);\r\n rotate.setRotate(this.rotationAngle, this.centerX, this.centerY);\r\n this.container.transform.baseVal.replaceItem(rotate, 0);\r\n\r\n this.adjustControlBox();\r\n\r\n this._state = 'rotate';\r\n } else {\r\n this._state = 'move';\r\n }\r\n }\r\n }\r\n\r\n protected _suppressMarkerCreateEvent = false;\r\n /**\r\n * Handles pointer (mouse, touch, stylus, etc.) up event.\r\n * \r\n * @param point - event coordinates.\r\n * @param target - direct event target element.\r\n */\r\n public pointerUp(point: IPoint): void {\r\n const inState = this.state;\r\n super.pointerUp(point);\r\n if (this.state === 'creating' && this.width < 10 && this.height < 10) {\r\n this.width = this.defaultSize.x;\r\n this.height = this.defaultSize.y;\r\n } else {\r\n this.manipulate(point);\r\n }\r\n this._state = 'select';\r\n if (inState === 'creating' && this.onMarkerCreated && this._suppressMarkerCreateEvent === false) {\r\n this.onMarkerCreated(this);\r\n }\r\n }\r\n\r\n /**\r\n * Moves visual to the specified coordinates.\r\n * @param point - coordinates of the new top-left corner of the visual.\r\n */\r\n protected moveVisual(point: IPoint): void {\r\n this.visual.style.transform = `translate(${point.x}px, ${point.y}px)`;\r\n // const translate = this.visual.transform.baseVal.getItem(0);\r\n // translate.setTranslate(point.x, point.y);\r\n // this.visual.transform.baseVal.replaceItem(translate, 0);\r\n }\r\n\r\n /**\r\n * Handles marker manipulation (move, resize, rotate, etc.).\r\n * \r\n * @param point - event coordinates.\r\n */\r\n public manipulate(point: IPoint): void {\r\n const rotatedPoint = this.unrotatePoint(point);\r\n\r\n if (this.state === 'creating') {\r\n this.resize(point);\r\n } else if (this.state === 'move') {\r\n this.left =\r\n this.manipulationStartLeft +\r\n (rotatedPoint.x - this.manipulationStartLeft) -\r\n this.offsetX;\r\n this.top =\r\n this.manipulationStartTop +\r\n (rotatedPoint.y - this.manipulationStartTop) -\r\n this.offsetY;\r\n this.moveVisual({x: this.left, y: this.top});\r\n this.adjustControlBox();\r\n } else if (this.state === 'resize') {\r\n this.resize(rotatedPoint);\r\n } else if (this.state === 'rotate') {\r\n this.rotate(point);\r\n }\r\n }\r\n\r\n /**\r\n * Resizes the marker based on pointer coordinates and context.\r\n * @param point - pointer coordinates.\r\n */\r\n protected resize(point: IPoint): void {\r\n let newX = this.manipulationStartLeft;\r\n let newWidth = this.manipulationStartWidth;\r\n let newY = this.manipulationStartTop;\r\n let newHeight = this.manipulationStartHeight;\r\n\r\n switch(this.activeGrip) {\r\n case this.controlGrips.bottomLeft:\r\n case this.controlGrips.centerLeft:\r\n case this.controlGrips.topLeft:\r\n newX = this.manipulationStartLeft + point.x - this.manipulationStartX;\r\n newWidth = this.manipulationStartWidth + this.manipulationStartLeft - newX;\r\n break; \r\n case this.controlGrips.bottomRight:\r\n case this.controlGrips.centerRight:\r\n case this.controlGrips.topRight:\r\n case undefined:\r\n newWidth = this.manipulationStartWidth + point.x - this.manipulationStartX;\r\n break; \r\n }\r\n\r\n switch(this.activeGrip) {\r\n case this.controlGrips.topCenter:\r\n case this.controlGrips.topLeft:\r\n case this.controlGrips.topRight:\r\n newY = this.manipulationStartTop + point.y - this.manipulationStartY;\r\n newHeight = this.manipulationStartHeight + this.manipulationStartTop - newY;\r\n break; \r\n case this.controlGrips.bottomCenter:\r\n case this.controlGrips.bottomLeft:\r\n case this.controlGrips.bottomRight:\r\n case undefined:\r\n newHeight = this.manipulationStartHeight + point.y - this.manipulationStartY;\r\n break; \r\n }\r\n\r\n if (newWidth >= 0) {\r\n this.left = newX;\r\n this.width = newWidth;\r\n } else {\r\n this.left = newX + newWidth;\r\n this.width = -newWidth;\r\n }\r\n if (newHeight >= 0) {\r\n this.top = newY;\r\n this.height = newHeight;\r\n } else {\r\n this.top = newY + newHeight;\r\n this.height = -newHeight;\r\n }\r\n\r\n this.setSize();\r\n }\r\n\r\n /**\r\n * Sets control box size and location.\r\n */\r\n protected setSize(): void {\r\n this.moveVisual({x: this.left, y: this.top});\r\n this.adjustControlBox();\r\n }\r\n\r\n private rotate(point: IPoint) {\r\n // avoid glitch when crossing the 0 rotation point\r\n if (Math.abs(point.x - this.centerX) > 0.1) {\r\n const sign = Math.sign(point.x - this.centerX);\r\n this.rotationAngle =\r\n (Math.atan((point.y - this.centerY) / (point.x - this.centerX)) * 180) /\r\n Math.PI +\r\n 90 * sign;\r\n this.applyRotation();\r\n }\r\n }\r\n\r\n private applyRotation() {\r\n const rotate = this.container.transform.baseVal.getItem(0);\r\n rotate.setRotate(this.rotationAngle, this.centerX, this.centerY);\r\n this.container.transform.baseVal.replaceItem(rotate, 0);\r\n }\r\n\r\n /**\r\n * Returns point coordinates based on the actual screen coordinates and marker's rotation.\r\n * @param point - original pointer coordinates\r\n */\r\n protected rotatePoint(point: IPoint): IPoint {\r\n if (this.rotationAngle === 0) {\r\n return point;\r\n }\r\n \r\n const matrix = this.container.getCTM();\r\n let svgPoint = SvgHelper.createPoint(point.x, point.y);\r\n svgPoint = svgPoint.matrixTransform(matrix);\r\n\r\n const result = { x: svgPoint.x, y: svgPoint.y };\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns original point coordinates based on coordinates with rotation applied.\r\n * @param point - rotated point coordinates.\r\n */\r\n protected unrotatePoint(point: IPoint): IPoint {\r\n if (this.rotationAngle === 0) {\r\n return point;\r\n }\r\n \r\n let matrix = this.container.getCTM();\r\n matrix = matrix.inverse();\r\n let svgPoint = SvgHelper.createPoint(point.x, point.y);\r\n svgPoint = svgPoint.matrixTransform(matrix);\r\n\r\n const result = { x: svgPoint.x, y: svgPoint.y };\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Displays marker's controls.\r\n */\r\n public select(): void {\r\n super.select();\r\n this.adjustControlBox();\r\n this.controlBox.style.display = '';\r\n }\r\n\r\n /**\r\n * Hides marker's controls.\r\n */\r\n public deselect(): void {\r\n super.deselect();\r\n this.controlBox.style.display = 'none';\r\n }\r\n\r\n private setupControlBox() {\r\n this.controlBox = SvgHelper.createGroup();\r\n const translate = SvgHelper.createTransform();\r\n translate.setTranslate(-this.CB_DISTANCE / 2, -this.CB_DISTANCE / 2);\r\n this.controlBox.transform.baseVal.appendItem(translate);\r\n\r\n this.container.appendChild(this.controlBox);\r\n\r\n this.controlRect = SvgHelper.createRect(\r\n this.width + this.CB_DISTANCE,\r\n this.height + this.CB_DISTANCE,\r\n [\r\n ['stroke', 'black'],\r\n ['stroke-width', '1'],\r\n ['stroke-opacity', '0.5'],\r\n ['stroke-dasharray', '3, 2'],\r\n ['fill', 'transparent'],\r\n ['pointer-events', 'none']\r\n ]\r\n );\r\n\r\n this.controlBox.appendChild(this.controlRect);\r\n\r\n if (this.globalSettings.disableRotation !== true) {\r\n this.rotatorGripLine = SvgHelper.createLine(\r\n (this.width + this.CB_DISTANCE * 2) / 2,\r\n this.top - this.CB_DISTANCE,\r\n (this.width + this.CB_DISTANCE * 2) / 2,\r\n this.top - this.CB_DISTANCE * 3,\r\n [\r\n ['stroke', 'black'],\r\n ['stroke-width', '1'],\r\n ['stroke-opacity', '0.5'],\r\n ['stroke-dasharray', '3, 2'],\r\n ]\r\n );\r\n\r\n this.controlBox.appendChild(this.rotatorGripLine);\r\n }\r\n\r\n this.controlGrips = new RectangularBoxMarkerGrips();\r\n this.addControlGrips();\r\n\r\n this.controlBox.style.display = 'none';\r\n }\r\n\r\n private adjustControlBox() {\r\n const translate = this.controlBox.transform.baseVal.getItem(0);\r\n translate.setTranslate(\r\n this.left - this.CB_DISTANCE / 2,\r\n this.top - this.CB_DISTANCE / 2\r\n );\r\n this.controlBox.transform.baseVal.replaceItem(translate, 0);\r\n this.controlRect.setAttribute(\r\n 'width',\r\n (this.width + this.CB_DISTANCE).toString()\r\n );\r\n this.controlRect.setAttribute(\r\n 'height',\r\n (this.height + this.CB_DISTANCE).toString()\r\n );\r\n\r\n if (this.rotatorGripLine !== undefined) {\r\n this.rotatorGripLine.setAttribute(\r\n 'x1',\r\n ((this.width + this.CB_DISTANCE) / 2).toString()\r\n );\r\n this.rotatorGripLine.setAttribute('y1', (-this.CB_DISTANCE / 2).toString());\r\n this.rotatorGripLine.setAttribute(\r\n 'x2',\r\n ((this.width + this.CB_DISTANCE) / 2).toString()\r\n );\r\n this.rotatorGripLine.setAttribute('y2', (-this.CB_DISTANCE * 3).toString());\r\n }\r\n \r\n this.positionGrips();\r\n }\r\n\r\n private addControlGrips() {\r\n this.controlGrips.topLeft = this.createGrip();\r\n this.controlGrips.topCenter = this.createGrip();\r\n this.controlGrips.topRight = this.createGrip();\r\n this.controlGrips.centerLeft = this.createGrip();\r\n this.controlGrips.centerRight = this.createGrip();\r\n this.controlGrips.bottomLeft = this.createGrip();\r\n this.controlGrips.bottomCenter = this.createGrip();\r\n this.controlGrips.bottomRight = this.createGrip();\r\n\r\n if (this.globalSettings.disableRotation !== true) {\r\n this.rotatorGrip = this.createGrip();\r\n }\r\n\r\n this.positionGrips();\r\n }\r\n\r\n private createGrip(): ResizeGrip {\r\n const grip = new ResizeGrip();\r\n grip.visual.transform.baseVal.appendItem(SvgHelper.createTransform());\r\n this.controlBox.appendChild(grip.visual);\r\n\r\n return grip;\r\n }\r\n\r\n private positionGrips() {\r\n const gripSize = this.controlGrips.topLeft.GRIP_SIZE;\r\n\r\n const left = -gripSize / 2;\r\n const top = left;\r\n const cx = (this.width + this.CB_DISTANCE) / 2 - gripSize / 2;\r\n const cy = (this.height + this.CB_DISTANCE) / 2 - gripSize / 2;\r\n const bottom = this.height + this.CB_DISTANCE - gripSize / 2;\r\n const right = this.width + this.CB_DISTANCE - gripSize / 2;\r\n\r\n this.positionGrip(this.controlGrips.topLeft.visual, left, top);\r\n this.positionGrip(this.controlGrips.topCenter.visual, cx, top);\r\n this.positionGrip(this.controlGrips.topRight.visual, right, top);\r\n this.positionGrip(this.controlGrips.centerLeft.visual, left, cy);\r\n this.positionGrip(this.controlGrips.centerRight.visual, right, cy);\r\n this.positionGrip(this.controlGrips.bottomLeft.visual, left, bottom);\r\n this.positionGrip(this.controlGrips.bottomCenter.visual, cx, bottom);\r\n this.positionGrip(this.controlGrips.bottomRight.visual, right, bottom);\r\n\r\n if (this.rotatorGrip !== undefined) {\r\n this.positionGrip(this.rotatorGrip.visual, cx, top - this.CB_DISTANCE * 3);\r\n }\r\n }\r\n\r\n private positionGrip(grip: SVGGraphicsElement, x: number, y: number) {\r\n const translate = grip.transform.baseVal.getItem(0);\r\n translate.setTranslate(x, y);\r\n grip.transform.baseVal.replaceItem(translate, 0);\r\n }\r\n\r\n /**\r\n * Hides marker's editing controls.\r\n */\r\n protected hideControlBox(): void {\r\n this.controlBox.style.display = 'none';\r\n }\r\n /**\r\n * Shows marker's editing controls.\r\n */\r\n protected showControlBox(): void {\r\n this.controlBox.style.display = '';\r\n }\r\n\r\n /**\r\n * Returns marker's state.\r\n */\r\n public getState(): RectangularBoxMarkerBaseState {\r\n const result: RectangularBoxMarkerBaseState = Object.assign({\r\n left: this.left,\r\n top: this.top,\r\n width: this.width,\r\n height: this.height,\r\n rotationAngle: this.rotationAngle,\r\n visualTransformMatrix: TransformMatrix.toITransformMatrix(this.visual.transform.baseVal.getItem(0).matrix),\r\n containerTransformMatrix: TransformMatrix.toITransformMatrix(this.container.transform.baseVal.getItem(0).matrix)\r\n },\r\n super.getState());\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Restores marker's state to the previously saved one.\r\n * @param state - previously saved state.\r\n */\r\n public restoreState(state: MarkerBaseState): void {\r\n super.restoreState(state);\r\n const rbmState = state as RectangularBoxMarkerBaseState;\r\n this.left = rbmState.left;\r\n this.top = rbmState.top;\r\n this.width = rbmState.width;\r\n this.height = rbmState.height;\r\n this.rotationAngle = rbmState.rotationAngle;\r\n this.visual.transform.baseVal.getItem(0).setMatrix(\r\n TransformMatrix.toSVGMatrix(this.visual.transform.baseVal.getItem(0).matrix, rbmState.visualTransformMatrix)\r\n );\r\n this.container.transform.baseVal.getItem(0).setMatrix(\r\n TransformMatrix.toSVGMatrix(this.container.transform.baseVal.getItem(0).matrix, rbmState.containerTransformMatrix)\r\n );\r\n // this.moveVisual({x: this.left, y: this.top});\r\n // this.applyRotation();\r\n }\r\n\r\n /**\r\n * Scales marker. Used after the image resize.\r\n * \r\n * @param scaleX - horizontal scale\r\n * @param scaleY - vertical scale\r\n */\r\n public scale(scaleX: number, scaleY: number): void {\r\n super.scale(scaleX, scaleY);\r\n\r\n const rPoint = this.rotatePoint({x: this.left, y: this.top});\r\n const point = this.unrotatePoint({x: rPoint.x * scaleX, y: rPoint.y * scaleY});\r\n\r\n this.left = point.x;\r\n this.top = point.y;\r\n this.width = this.width * scaleX;\r\n this.height = this.height * scaleY;\r\n\r\n this.adjustControlBox();\r\n }\r\n\r\n}\r\n","import { IPoint } from '../core/IPoint';\r\nimport { SvgHelper } from '../core/SvgHelper';\r\nimport { RectangularBoxMarkerBase } from './RectangularBoxMarkerBase';\r\nimport { Settings } from '../core/Settings';\r\nimport { RectangleMarkerState } from './RectangleMarkerState';\r\nimport { MarkerBaseState } from '../core/MarkerBaseState';\r\n\r\n/**\r\n * RecatngleMarker is a base class for all rectangular markers (Frame, Cover, Highlight, etc.)\r\n */\r\nexport abstract class RectangleMarker extends RectangularBoxMarkerBase {\r\n /**\r\n * String type name of the marker type. \r\n * \r\n * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\r\n */\r\n public static title = 'Rectangle marker';\r\n\r\n /**\r\n * Recangle fill color.\r\n */\r\n protected fillColor = 'transparent';\r\n /**\r\n * Rectangle stroke color.\r\n */\r\n protected strokeColor = 'transparent';\r\n /**\r\n * Rectangle border stroke width.\r\n */\r\n protected strokeWidth = 0;\r\n /**\r\n * Rectangle border stroke dash array.\r\n */\r\n protected strokeDasharray = '';\r\n /**\r\n * Rectangle opacity (alpha). 0 to 1.\r\n */\r\n protected opacity = 1;\r\n\r\n /**\r\n * Creates a new marker.\r\n *\r\n * @param container - SVG container to hold marker's visual.\r\n * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\r\n * @param settings - settings object containing default markers settings.\r\n */\r\n constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\r\n super(container, overlayContainer, settings);\r\n\r\n this.setStrokeColor = this.setStrokeColor.bind(this);\r\n this.setFillColor = this.setFillColor.bind(this);\r\n this.setStrokeWidth = this.setStrokeWidth.bind(this);\r\n this.setStrokeDasharray = this.setStrokeDasharray.bind(this);\r\n this.createVisual = this.createVisual.bind(this);\r\n }\r\n\r\n /**\r\n * Returns true if passed SVG element belongs to the marker. False otherwise.\r\n * \r\n * @param el - target element.\r\n */\r\n public ownsTarget(el: EventTarget): boolean {\r\n if (super.ownsTarget(el) || el === this.visual) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Creates the marker's rectangle visual.\r\n */\r\n protected createVisual(): void {\r\n this.visual = SvgHelper.createRect(1, 1, [\r\n ['fill', this.fillColor],\r\n ['stroke', this.strokeColor],\r\n ['stroke-width', this.strokeWidth.toString()],\r\n ['stroke-dasharray', this.strokeDasharray],\r\n ['opacity', this.opacity.toString()]\r\n ]);\r\n this.addMarkerVisualToContainer(this.visual);\r\n }\r\n\r\n /**\r\n * Handles pointer (mouse, touch, stylus, etc.) down event.\r\n * \r\n * @param point - event coordinates.\r\n * @param target - direct event target element.\r\n */\r\n public pointerDown(point: IPoint, target?: EventTarget): void {\r\n super.pointerDown(point, target);\r\n if (this.state === 'new') {\r\n this.createVisual();\r\n\r\n this.moveVisual(point);\r\n\r\n this._state = 'creating';\r\n }\r\n }\r\n\r\n /**\r\n * Handles marker manipulation (move, resize, rotate, etc.).\r\n * \r\n * @param point - event coordinates.\r\n */\r\n public manipulate(point: IPoint): void {\r\n super.manipulate(point);\r\n }\r\n\r\n /**\r\n * Resizes the marker based on the pointer coordinates.\r\n * @param point - current pointer coordinates.\r\n */\r\n protected resize(point: IPoint): void {\r\n super.resize(point);\r\n this.setSize();\r\n }\r\n\r\n /**\r\n * Sets visual's width and height attributes based on marker's width and height.\r\n */\r\n protected setSize(): void {\r\n super.setSize();\r\n SvgHelper.setAttributes(this.visual, [\r\n ['width', this.width.toString()],\r\n ['height', this.height.toString()],\r\n ]);\r\n }\r\n\r\n /**\r\n * Handles pointer (mouse, touch, stylus, etc.) up event.\r\n * \r\n * @param point - event coordinates.\r\n * @param target - direct event target element.\r\n */\r\n public pointerUp(point: IPoint): void {\r\n super.pointerUp(point);\r\n this.setSize();\r\n }\r\n\r\n /**\r\n * Sets rectangle's border stroke color.\r\n * @param color - color as string\r\n */\r\n protected setStrokeColor(color: string): void {\r\n this.strokeColor = color;\r\n if (this.visual) {\r\n SvgHelper.setAttributes(this.visual, [['stroke', this.strokeColor]]);\r\n }\r\n this.colorChanged(color);\r\n this.stateChanged();\r\n }\r\n /**\r\n * Sets rectangle's fill color.\r\n * @param color - color as string\r\n */\r\n protected setFillColor(color: string): void {\r\n this.fillColor = color;\r\n if (this.visual) {\r\n SvgHelper.setAttributes(this.visual, [['fill', this.fillColor]]);\r\n }\r\n this.stateChanged();\r\n }\r\n /**\r\n * Sets rectangle's border stroke (line) width.\r\n * @param color - color as string\r\n */\r\n protected setStrokeWidth(width: number): void {\r\n this.strokeWidth = width;\r\n if (this.visual) {\r\n SvgHelper.setAttributes(this.visual, [['stroke-width', this.strokeWidth.toString()]]);\r\n }\r\n this.stateChanged();\r\n }\r\n /**\r\n * Sets rectangle's border stroke dash array.\r\n * @param color - color as string\r\n */\r\n protected setStrokeDasharray(dashes: string): void {\r\n this.strokeDasharray = dashes;\r\n if (this.visual) {\r\n SvgHelper.setAttributes(this.visual, [['stroke-dasharray', this.strokeDasharray]]);\r\n }\r\n this.stateChanged();\r\n }\r\n\r\n /**\r\n * Returns current marker state that can be restored in the future.\r\n */\r\n public getState(): RectangleMarkerState {\r\n const result: RectangleMarkerState = Object.assign({\r\n fillColor: this.fillColor,\r\n strokeColor: this.strokeColor,\r\n strokeWidth: this.strokeWidth,\r\n strokeDasharray: this.strokeDasharray,\r\n opacity: this.opacity\r\n }, super.getState());\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Restores previously saved marker state.\r\n * \r\n * @param state - previously saved state.\r\n */\r\n public restoreState(state: MarkerBaseState): void {\r\n const rectState = state as RectangleMarkerState;\r\n this.fillColor = rectState.fillColor;\r\n this.strokeColor = rectState.strokeColor;\r\n this.strokeWidth = rectState.strokeWidth;\r\n this.strokeDasharray = rectState.strokeDasharray;\r\n this.opacity = rectState.opacity;\r\n\r\n this.createVisual();\r\n super.restoreState(state);\r\n this.setSize();\r\n }\r\n\r\n /**\r\n * Scales marker. Used after the image resize.\r\n * \r\n * @param scaleX - horizontal scale\r\n * @param scaleY - vertical scale\r\n */\r\n public scale(scaleX: number, scaleY: number): void {\r\n super.scale(scaleX, scaleY);\r\n\r\n this.setSize();\r\n }\r\n\r\n}\r\n","import { ToolboxPanel } from '../ToolboxPanel';\r\nimport Icon from './line-width-panel-icon.svg';\r\n\r\n/**\r\n * Line width change event handler type.\r\n */\r\nexport type WidthChangeHandler = (newWidth: number) => void;\r\n\r\n/**\r\n * Line width toolbox panel.\r\n */\r\nexport class LineWidthPanel extends ToolboxPanel {\r\n private widths: number[] = [];\r\n private currentWidth?: number;\r\n\r\n private widthBoxes: HTMLDivElement[] = [];\r\n\r\n /**\r\n * Line width change event handler.\r\n */\r\n public onWidthChanged?: WidthChangeHandler;\r\n\r\n /**\r\n * Creates a line width toolbox panel.\r\n * @param title - panel title.\r\n * @param widths - available widths.\r\n * @param currentWidth - currently set width.\r\n * @param icon - toolbox panel icon (SVG image markup).\r\n */\r\n constructor(title: string, widths: number[], currentWidth?: number, icon?: string) {\r\n super(title, icon ? icon : Icon);\r\n this.widths = widths;\r\n this.currentWidth = currentWidth;\r\n\r\n this._id = 'line-width-panel';\r\n\r\n this.setCurrentWidth = this.setCurrentWidth.bind(this);\r\n }\r\n\r\n /**\r\n * Returns panel UI.\r\n */\r\n public getUi(): HTMLDivElement {\r\n const panelDiv = document.createElement('div');\r\n panelDiv.style.display = 'flex';\r\n panelDiv.style.overflow = 'hidden';\r\n panelDiv.style.flexGrow = '2';\r\n this.widths.forEach((lineWidth) => {\r\n const widthBoxContainer = document.createElement('div');\r\n widthBoxContainer.style.display = 'flex';\r\n widthBoxContainer.style.flexGrow = '2';\r\n widthBoxContainer.style.alignItems = 'center';\r\n widthBoxContainer.style.justifyContent = 'space-between';\r\n widthBoxContainer.style.padding = '5px';\r\n widthBoxContainer.style.borderWidth = '2px';\r\n widthBoxContainer.style.borderStyle = 'solid';\r\n widthBoxContainer.style.borderColor =\r\n lineWidth === this.currentWidth ? this.uiStyleSettings.toolboxAccentColor : 'transparent';\r\n\r\n widthBoxContainer.addEventListener('click', () => {\r\n this.setCurrentWidth(lineWidth, widthBoxContainer);\r\n })\r\n panelDiv.appendChild(widthBoxContainer);\r\n\r\n const label = document.createElement('div');\r\n label.innerText = lineWidth.toString();\r\n label.style.marginRight = '5px';\r\n widthBoxContainer.appendChild(label);\r\n\r\n const widthBox = document.createElement('div');\r\n widthBox.style.minHeight = '20px';\r\n widthBox.style.flexGrow = '2';\r\n widthBox.style.display = 'flex';\r\n widthBox.style.alignItems = 'center';\r\n\r\n const hr = document.createElement('hr');\r\n hr.style.minWidth = '20px';\r\n hr.style.border = '0px';\r\n hr.style.borderTop = `${lineWidth}px solid ${this.uiStyleSettings.toolboxColor}`;\r\n hr.style.flexGrow = '2';\r\n widthBox.appendChild(hr);\r\n\r\n // widthBox.innerHTML = `<svg viewBox=\"0 0 140 20\" width=\"140\" height=\"20\" xmlns=\"http://www.w3.org/2000/svg\">\r\n // <line x1=\"0\" y1=\"10\" x2=\"140\" y2=\"10\" stroke=\"${this.uiStyleSettings.toolboxColor}\" stroke-width=\"${lineWidth}\" />\r\n // </svg>`;\r\n\r\n widthBoxContainer.appendChild(widthBox);\r\n\r\n this.widthBoxes.push(widthBoxContainer);\r\n });\r\n return panelDiv;\r\n }\r\n\r\n private setCurrentWidth(newWidth: number, target: HTMLDivElement) {\r\n this.currentWidth = newWidth;\r\n\r\n this.widthBoxes.forEach(box => {\r\n box.style.borderColor = box === target ? this.uiStyleSettings.toolboxAccentColor : 'transparent';\r\n });\r\n\r\n if (this.onWidthChanged) {\r\n this.onWidthChanged(this.currentWidth);\r\n }\r\n }\r\n}\r\n","import { ToolboxPanel } from '../ToolboxPanel';\r\nimport Icon from './line-style-panel-icon.svg';\r\n\r\n/**\r\n * Line style change event handler type.\r\n */\r\nexport type StyleChangeHandler = (newStyle: string) => void;\r\n\r\n/**\r\n * Line style (solid, dashed, etc.) toolbox panel.\r\n */\r\nexport class LineStylePanel extends ToolboxPanel {\r\n private styles: string[] = [];\r\n private currentStyle?: string;\r\n\r\n private styleBoxes: HTMLDivElement[] = [];\r\n\r\n /**\r\n * Handler for the style change event.\r\n */\r\n public onStyleChanged?: StyleChangeHandler;\r\n\r\n /**\r\n * Creates a line style toolbox panel.\r\n * @param title - panel title\r\n * @param styles - available line styles (dash array).\r\n * @param currentStyle - currently selected style.\r\n * @param icon - panel button icon (SVG image markup).\r\n */\r\n constructor(title: string, styles: string[], currentStyle?: string, icon?: string) {\r\n super(title, icon ? icon : Icon);\r\n this.styles = styles;\r\n this.currentStyle = currentStyle;\r\n\r\n this._id = 'line-style-panel';\r\n\r\n this.setCurrentStyle = this.setCurrentStyle.bind(this);\r\n }\r\n\r\n /**\r\n * Returns panel UI.\r\n */\r\n public getUi(): HTMLDivElement {\r\n const panelDiv = document.createElement('div');\r\n panelDiv.style.display = 'flex';\r\n panelDiv.style.overflow = 'hidden';\r\n panelDiv.style.flexGrow = '2';\r\n this.styles.forEach((lineStyle) => {\r\n const styleBoxContainer = document.createElement('div');\r\n styleBoxContainer.style.display = 'flex'; //'inline-block';\r\n styleBoxContainer.style.alignItems = 'center';\r\n styleBoxContainer.style.justifyContent = 'space-between';\r\n styleBoxContainer.style.padding = '5px';\r\n styleBoxContainer.style.borderWidth = '2px';\r\n styleBoxContainer.style.borderStyle = 'solid';\r\n styleBoxContainer.style.overflow = 'hidden';\r\n styleBoxContainer.style.maxWidth = `${100 / this.styles.length - 5}%`;\r\n styleBoxContainer.style.borderColor =\r\n lineStyle === this.currentStyle ? this.uiStyleSettings.toolboxAccentColor : 'transparent';\r\n\r\n styleBoxContainer.addEventListener('click', () => {\r\n this.setCurrentStyle(lineStyle, styleBoxContainer);\r\n })\r\n panelDiv.appendChild(styleBoxContainer);\r\n\r\n const styleBox = document.createElement('div');\r\n styleBox.style.minHeight = '20px';\r\n styleBox.style.flexGrow = '2';\r\n styleBox.style.overflow = 'hidden';\r\n\r\n const styleSample = `<svg width=\"100\" height=\"20\">\r\n <line x1=\"0\" y1=\"10\" x2=\"100\" y2=\"10\" stroke=\"${\r\n this.uiStyleSettings.toolboxColor}\" stroke-width=\"3\" ${\r\n lineStyle !== '' ? 'stroke-dasharray=\"' + lineStyle + '\"' : ''} />\r\n </svg>`;\r\n\r\n styleBox.innerHTML = styleSample;\r\n\r\n styleBoxContainer.appendChild(styleBox);\r\n\r\n this.styleBoxes.push(styleBoxContainer);\r\n });\r\n return panelDiv;\r\n }\r\n\r\n private setCurrentStyle(newStyle: string, target: HTMLDivElement) {\r\n this.currentStyle = newStyle;\r\n\r\n this.styleBoxes.forEach(box => {\r\n box.style.borderColor = box === target ? this.uiStyleSettings.toolboxAccentColor : 'transparent';\r\n });\r\n\r\n if (this.onStyleChanged) {\r\n this.onStyleChanged(this.currentStyle);\r\n }\r\n }\r\n}\r\n","import Icon from './frame-marker-icon.svg';\r\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\r\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\r\nimport { Settings } from '../../core/Settings';\r\nimport { RectangleMarker } from '../RectangleMarker';\r\nimport { LineWidthPanel } from '../../ui/toolbox-panels/LineWidthPanel';\r\nimport { LineStylePanel } from '../../ui/toolbox-panels/LineStylePanel';\r\nimport { RectangleMarkerState } from '../RectangleMarkerState';\r\n\r\nexport class FrameMarker extends RectangleMarker {\r\n /**\r\n * String type name of the marker type. \r\n * \r\n * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\r\n */\r\n public static typeName = 'FrameMarker';\r\n \r\n /**\r\n * Marker type title (display name) used for accessibility and other attributes.\r\n */\r\n public static title = 'Frame marker';\r\n /**\r\n * SVG icon markup displayed on toolbar buttons.\r\n */\r\n public static icon = Icon;\r\n\r\n private strokePanel: ColorPickerPanel;\r\n private strokeWidthPanel: LineWidthPanel;\r\n private strokeStylePanel: LineStylePanel;\r\n\r\n /**\r\n * Creates a new marker.\r\n *\r\n * @param container - SVG container to hold marker's visual.\r\n * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\r\n * @param settings - settings object containing default markers settings.\r\n */\r\n constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\r\n super(container, overlayContainer, settings);\r\n\r\n this.strokeColor = settings.defaultColor;\r\n this.strokeWidth = settings.defaultStrokeWidth;\r\n this.strokeDasharray = settings.defaultStrokeDasharray;\r\n\r\n this.strokePanel = new ColorPickerPanel(\r\n 'Line color',\r\n settings.defaultColorSet,\r\n settings.defaultColor\r\n );\r\n this.strokePanel.onColorChanged = this.setStrokeColor;\r\n\r\n this.strokeWidthPanel = new LineWidthPanel(\r\n 'Line width',\r\n settings.defaultStrokeWidths,\r\n settings.defaultStrokeWidth\r\n );\r\n this.strokeWidthPanel.onWidthChanged = this.setStrokeWidth;\r\n\r\n this.strokeStylePanel = new LineStylePanel(\r\n 'Line style',\r\n settings.defaultStrokeDasharrays,\r\n settings.defaultStrokeDasharray\r\n );\r\n this.strokeStylePanel.onStyleChanged = this.setStrokeDasharray;\r\n }\r\n\r\n /**\r\n * Returns the list of toolbox panels for this marker type.\r\n */\r\n public get toolboxPanels(): ToolboxPanel[] {\r\n return [this.strokePanel, this.strokeWidthPanel, this.strokeStylePanel];\r\n }\r\n\r\n /**\r\n * Returns current marker state that can be restored in the future.\r\n */\r\n public getState(): RectangleMarkerState {\r\n const result = super.getState();\r\n result.typeName = FrameMarker.typeName;\r\n return result;\r\n }\r\n}\r\n","/**\r\n * Represents a list of colors.\r\n */\r\nexport type ColorSet = string[];\r\n\r\n/**\r\n * marker.js 2 display mode - `inline` or `popup`.\r\n */\r\nexport type DisplayMode = 'inline' | 'popup';\r\n\r\n/**\r\n * Default settings for marker.js 2 markers.\r\n */\r\nexport class Settings {\r\n /**\r\n * List of colors used in color pickers.\r\n */\r\n public defaultColorSet: ColorSet = [\r\n '#EF4444', // red\r\n '#10B981', // green\r\n '#2563EB', // blue\r\n '#FFFF00', // yellow\r\n '#7C3AED', // purple\r\n '#F472B6', // pink\r\n '#000000', // black\r\n '#FFFFFF' //white\r\n ];\r\n\r\n /**\r\n * Default foreground color.\r\n */\r\n public defaultColor = this.defaultColorSet[0];\r\n /**\r\n * Default fill color.\r\n */\r\n public defaultFillColor = this.defaultColorSet[0];\r\n /**\r\n * Default stroke color for markers with background (eg. {@link CalloutMarker}).\r\n */\r\n public defaultStrokeColor = this.defaultColorSet[7];\r\n /**\r\n * Default highlighter color.\r\n */\r\n public defaultHighlightColor = this.defaultColorSet[3];\r\n /**\r\n * Default stroke (line) width.\r\n */\r\n public defaultStrokeWidth = 3;\r\n /**\r\n * Default line dash array\r\n */\r\n public defaultStrokeDasharray = '';\r\n /**\r\n * Default opacity (alpha) of the {@link HighlightMarker} (and other highlighters).\r\n */\r\n public defaultHighlightOpacity = 0.5;\r\n /**\r\n * Default font family for text-based markers (eg. {@link TextMarker} and {@link CalloutMarker}).\r\n *\r\n */\r\n public defaultFontFamily = 'Helvetica, Arial, sans-serif';\r\n\r\n /**\r\n * Stroke (line) width options.\r\n */\r\n public defaultStrokeWidths = [1, 2, 3, 5, 10];\r\n \r\n /**\r\n * Stroke dash array options.\r\n */\r\n public defaultStrokeDasharrays = ['', '3', '12 3', '9 6 3 6'];\r\n\r\n /**\r\n * Opacity options.\r\n */\r\n public defaultOpacitySteps = [0.1, 0.25, 0.5, 0.75, 1];\r\n\r\n /**\r\n * Default display mode.\r\n */\r\n public displayMode: DisplayMode = 'inline';\r\n\r\n /**\r\n * Font family options.\r\n */\r\n public defaultFontFamilies = [\r\n 'Times, \"Times New Roman\", serif',\r\n 'Helvetica, Arial, sans-serif',\r\n 'Courier, \"Courier New\", monospace',\r\n 'cursive',\r\n 'fantasy'\r\n ];\r\n\r\n /**\r\n * Margin in pixels between marker.js popup UI and window borders.\r\n */\r\n public popupMargin = 30;\r\n\r\n /**\r\n * Create a new Freehand marker for every stroke.\r\n */\r\n public newFreehandMarkerOnPointerUp = false;\r\n\r\n /**\r\n * If set to true, when colors on a marker are changed \r\n * it changes the default color for other markers as well.\r\n * \r\n * @since 2.7.0\r\n */\r\n public defaultColorsFollowCurrentColors = false;\r\n\r\n /**\r\n * Increase this setting for smoother FreehandMarker lines.\r\n * Note that it will also take more space when you save the state.\r\n *\r\n * @since 2.20.0\r\n */\r\n public freehandPixelRatio = 1;\r\n\r\n /**\r\n * When set to true rotation feature is disabled on markers.\r\n * This doesn't affect markers restored from a previously saved state.\r\n * \r\n * @since 2.22.0\r\n */\r\n public disableRotation = false;\r\n\r\n /**\r\n * If set, the UI will be offset by the specified value, \r\n * otherwise it will be offset by -toolbarHeight or 0 if \r\n * there's less space than toolbarHeight on top.\r\n * \r\n * Use this if you want to control the position inside a\r\n * `position: relative` parent, as auto-calculation\r\n * will calculate available space from the relative\r\n * container and not the whole page.\r\n * \r\n * Common usage when used with a relatively positioned parent would be:\r\n * \r\n * ```typescript\r\n * markerArea.targetRoot = document.getElementById('relativeParent');\r\n * markerArea.settings.uiOffsetTop = -markerArea.styles.settings.toolbarHeight;\r\n * ```\r\n * This would ensure that the toolbar is placed above the image\r\n * even if the image's offset from the relative parent is 0.\r\n * \r\n * @since 2.28.0\r\n */\r\n public uiOffsetTop?: number;\r\n \r\n /**\r\n * If set, the UI will be offset by the specefied number of pixels on the left.\r\n * \r\n * @since 2.31.0\r\n */\r\n public uiOffsetLeft?: number;\r\n\r\n /**\r\n * Default font size for the `CaptionFrameMarker`\r\n * \r\n * @since 2.29.0\r\n */\r\n public defaultCaptionFontSize = '1rem';\r\n /**\r\n * Default caption text for the `CaptionFrameMarker`\r\n * \r\n * @since 2.29.0\r\n */\r\n public defaultCaptionText = 'Text';\r\n /**\r\n * Enable word wrapping in text markers (`TextMarker`, `CalloutMarker`)\r\n * \r\n * @since 2.30.0\r\n */\r\n public wrapText = false;\r\n}\r\n","import { MarkerBase } from '../core/MarkerBase';\r\n\r\nimport { IPoint } from '../core/IPoint';\r\nimport { SvgHelper } from '../core/SvgHelper';\r\n\r\nimport { ResizeGrip } from './ResizeGrip';\r\nimport { Settings } from '../core/Settings';\r\nimport { LinearMarkerBaseState } from './LinearMarkerBaseState';\r\nimport { MarkerBaseState } from '../core/MarkerBaseState';\r\n\r\n/**\r\n * LinearMarkerBase is a base class for all line-type markers (Line, Arrow, Measurement Tool, etc.).\r\n */\r\nexport class LinearMarkerBase extends MarkerBase {\r\n /**\r\n * x coordinate of the first end-point\r\n */\r\n protected x1 = 0;\r\n /**\r\n * y coordinate of the first end-point\r\n */\r\n protected y1 = 0;\r\n /**\r\n * x coordinate of the second end-point\r\n */\r\n protected x2 = 0;\r\n /**\r\n * y coordinate of the second end-point\r\n */\r\n protected y2 = 0;\r\n\r\n /**\r\n * Default line length when marker is created with a simple click (without dragging).\r\n */\r\n protected defaultLength = 50;\r\n\r\n /**\r\n * Pointer coordinates at the satart of move or resize.\r\n */\r\n protected manipulationStartX = 0;\r\n protected manipulationStartY = 0;\r\n\r\n private manipulationStartX1 = 0;\r\n private manipulationStartY1 = 0;\r\n private manipulationStartX2 = 0;\r\n private manipulationStartY2 = 0;\r\n\r\n /**\r\n * Marker's main visual.\r\n */\r\n protected visual: SVGGraphicsElement;\r\n\r\n /**\r\n * Container for control elements.\r\n */\r\n protected controlBox: SVGGElement;\r\n\r\n /**\r\n * First manipulation grip\r\n */\r\n protected grip1: ResizeGrip;\r\n /**\r\n * Second manipulation grip.\r\n */\r\n protected grip2: ResizeGrip;\r\n /**\r\n * Active manipulation grip.\r\n */\r\n protected activeGrip: ResizeGrip;\r\n\r\n /**\r\n * Creates a LineMarkerBase object.\r\n * \r\n * @param container - SVG container to hold marker's visual.\r\n * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\r\n * @param settings - settings object containing default markers settings.\r\n */\r\n constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\r\n super(container, overlayContainer, settings);\r\n\r\n this.setupControlBox();\r\n }\r\n\r\n /**\r\n * Returns true if passed SVG element belongs to the marker. False otherwise.\r\n * \r\n * @param el - target element.\r\n */\r\n public ownsTarget(el: EventTarget): boolean {\r\n if (super.ownsTarget(el)) {\r\n return true;\r\n } else if (\r\n this.grip1.ownsTarget(el) || this.grip2.ownsTarget(el)\r\n ) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n \r\n /**\r\n * Handles pointer (mouse, touch, stylus, etc.) down event.\r\n * \r\n * @param point - event coordinates.\r\n * @param target - direct event target element.\r\n */\r\n public pointerDown(point: IPoint, target?: EventTarget): void {\r\n super.pointerDown(point, target);\r\n\r\n this.manipulationStartX = point.x;\r\n this.manipulationStartY = point.y;\r\n\r\n if (this.state === 'new') {\r\n this.x1 = point.x;\r\n this.y1 = point.y;\r\n this.x2 = point.x;\r\n this.y2 = point.y;\r\n }\r\n\r\n this.manipulationStartX1 = this.x1;\r\n this.manipulationStartY1 = this.y1;\r\n this.manipulationStartX2 = this.x2;\r\n this.manipulationStartY2 = this.y2;\r\n\r\n if (this.state !== 'new') {\r\n this.select();\r\n if (this.grip1.ownsTarget(target)) {\r\n this.activeGrip = this.grip1;\r\n } else if (this.grip2.ownsTarget(target)) {\r\n this.activeGrip = this.grip2;\r\n } else {\r\n this.activeGrip = undefined;\r\n }\r\n\r\n if (this.activeGrip) {\r\n this._state = 'resize';\r\n } else {\r\n this._state = 'move';\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Handles pointer (mouse, touch, stylus, etc.) up event.\r\n * \r\n * @param point - event coordinates.\r\n * @param target - direct event target element.\r\n */\r\n public pointerUp(point: IPoint): void {\r\n const inState = this.state;\r\n super.pointerUp(point);\r\n if (this.state === 'creating' && Math.abs(this.x1 - this.x2) < 10 && Math.abs(this.y1 - this.y2) < 10) {\r\n this.x2 = this.x1 + this.defaultLength;\r\n this.adjustVisual();\r\n this.adjustControlBox()\r\n } else {\r\n this.manipulate(point);\r\n }\r\n this._state = 'select';\r\n if (inState === 'creating' && this.onMarkerCreated) {\r\n this.onMarkerCreated(this);\r\n }\r\n }\r\n\r\n /**\r\n * When implemented adjusts marker visual after manipulation when needed.\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-empty-function\r\n protected adjustVisual(): void {}\r\n\r\n /**\r\n * Handles marker manipulation (move, resize, rotate, etc.).\r\n * \r\n * @param point - event coordinates.\r\n */\r\n public manipulate(point: IPoint): void {\r\n if (this.state === 'creating') {\r\n this.resize(point);\r\n } else if (this.state === 'move') {\r\n this.x1 = this.manipulationStartX1 + point.x - this.manipulationStartX;\r\n this.y1 = this.manipulationStartY1 + point.y - this.manipulationStartY;\r\n this.x2 = this.manipulationStartX2 + point.x - this.manipulationStartX;\r\n this.y2 = this.manipulationStartY2 + point.y - this.manipulationStartY;\r\n this.adjustVisual();\r\n this.adjustControlBox();\r\n } else if (this.state === 'resize') {\r\n this.resize(point);\r\n }\r\n }\r\n\r\n /**\r\n * Resizes the line marker.\r\n * @param point - current manipulation coordinates.\r\n */\r\n protected resize(point: IPoint): void {\r\n switch(this.activeGrip) {\r\n case this.grip1:\r\n this.x1 = point.x;\r\n this.y1 = point.y;\r\n break; \r\n case this.grip2:\r\n case undefined:\r\n this.x2 = point.x;\r\n this.y2 = point.y;\r\n break; \r\n }\r\n this.adjustVisual();\r\n this.adjustControlBox();\r\n }\r\n\r\n /**\r\n * Displays marker's controls.\r\n */\r\n public select(): void {\r\n super.select();\r\n this.adjustControlBox();\r\n this.controlBox.style.display = '';\r\n }\r\n\r\n /**\r\n * Hides marker's controls.\r\n */\r\n public deselect(): void {\r\n super.deselect();\r\n this.controlBox.style.display = 'none';\r\n }\r\n\r\n /**\r\n * Creates control box for manipulation controls.\r\n */\r\n protected setupControlBox(): void {\r\n this.controlBox = SvgHelper.createGroup();\r\n this.container.appendChild(this.controlBox);\r\n\r\n this.addControlGrips();\r\n\r\n this.controlBox.style.display = 'none';\r\n }\r\n\r\n private adjustControlBox() {\r\n this.positionGrips();\r\n }\r\n\r\n /**\r\n * Adds control grips to control box.\r\n */\r\n protected addControlGrips(): void {\r\n this.grip1 = this.createGrip();\r\n this.grip2 = this.createGrip();\r\n\r\n this.positionGrips();\r\n }\r\n\r\n /**\r\n * Creates manipulation grip.\r\n * @returns - manipulation grip.\r\n */\r\n protected createGrip(): ResizeGrip {\r\n const grip = new ResizeGrip();\r\n grip.visual.transform.baseVal.appendItem(SvgHelper.createTransform());\r\n this.controlBox.appendChild(grip.visual);\r\n\r\n return grip;\r\n }\r\n\r\n /**\r\n * Updates manipulation grip layout.\r\n */\r\n protected positionGrips(): void {\r\n const gripSize = this.grip1.GRIP_SIZE;\r\n\r\n this.positionGrip(this.grip1.visual, this.x1 - gripSize / 2, this.y1 - gripSize / 2);\r\n this.positionGrip(this.grip2.visual, this.x2 - gripSize / 2, this.y2 - gripSize / 2);\r\n }\r\n\r\n /**\r\n * Positions manipulation grip.\r\n * @param grip - grip to position\r\n * @param x - new X coordinate\r\n * @param y - new Y coordinate\r\n */\r\n protected positionGrip(grip: SVGGraphicsElement, x: number, y: number): void {\r\n const translate = grip.transform.baseVal.getItem(0);\r\n translate.setTranslate(x, y);\r\n grip.transform.baseVal.replaceItem(translate, 0);\r\n }\r\n\r\n /**\r\n * Returns marker's state.\r\n */\r\n public getState(): LinearMarkerBaseState {\r\n const result: LinearMarkerBaseState = Object.assign({\r\n x1: this.x1,\r\n y1: this.y1,\r\n x2: this.x2,\r\n y2: this.y2\r\n }, super.getState());\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Restores marker's state to the previously saved one.\r\n * @param state - previously saved state.\r\n */\r\n public restoreState(state: MarkerBaseState): void {\r\n super.restoreState(state);\r\n const lmbState = state as LinearMarkerBaseState;\r\n this.x1 = lmbState.x1;\r\n this.y1 = lmbState.y1;\r\n this.x2 = lmbState.x2;\r\n this.y2 = lmbState.y2;\r\n }\r\n\r\n /**\r\n * Scales marker. Used after the image resize.\r\n * \r\n * @param scaleX - horizontal scale\r\n * @param scaleY - vertical scale\r\n */\r\n public scale(scaleX: number, scaleY: number): void {\r\n super.scale(scaleX, scaleY);\r\n\r\n this.x1 = this.x1 * scaleX;\r\n this.y1 = this.y1 * scaleY;\r\n this.x2 = this.x2 * scaleX;\r\n this.y2 = this.y2 * scaleY;\r\n\r\n this.adjustVisual();\r\n this.adjustControlBox();\r\n }\r\n}\r\n","import { IPoint } from '../../core/IPoint';\r\nimport { SvgHelper } from '../../core/SvgHelper';\r\nimport { Settings } from '../../core/Settings';\r\nimport { LinearMarkerBase } from '../LinearMarkerBase';\r\nimport Icon from './line-marker-icon.svg';\r\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\r\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\r\nimport { LineWidthPanel } from '../../ui/toolbox-panels/LineWidthPanel';\r\nimport { LineStylePanel } from '../../ui/toolbox-panels/LineStylePanel';\r\nimport { LineMarkerState } from './LineMarkerState';\r\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\r\n\r\nexport class LineMarker extends LinearMarkerBase {\r\n /**\r\n * String type name of the marker type. \r\n * \r\n * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\r\n */\r\n public static typeName = 'LineMarker';\r\n \r\n /**\r\n * Marker type title (display name) used for accessibility and other attributes.\r\n */\r\n public static title = 'Line marker';\r\n /**\r\n * SVG icon markup displayed on toolbar buttons.\r\n */\r\n public static icon = Icon;\r\n\r\n /**\r\n * Invisible wider line to make selection easier/possible.\r\n */\r\n protected selectorLine: SVGLineElement;\r\n /**\r\n * Visible marker line.\r\n */\r\n protected visibleLine: SVGLineElement;\r\n\r\n /**\r\n * Line color.\r\n */\r\n protected strokeColor = 'transparent';\r\n /**\r\n * Line width.\r\n */\r\n protected strokeWidth = 0;\r\n /**\r\n * Line dash array.\r\n */\r\n protected strokeDasharray = '';\r\n\r\n /**\r\n * Color pickar panel for line color.\r\n */\r\n protected strokePanel: ColorPickerPanel;\r\n /**\r\n * Line width toolbox panel.\r\n */\r\n protected strokeWidthPanel: LineWidthPanel;\r\n /**\r\n * Line dash array toolbox panel.\r\n */\r\n protected strokeStylePanel: LineStylePanel;\r\n\r\n /**\r\n * Creates a new marker.\r\n *\r\n * @param container - SVG container to hold marker's visual.\r\n * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\r\n * @param settings - settings object containing default markers settings.\r\n */\r\n constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\r\n super(container, overlayContainer, settings);\r\n\r\n this.setStrokeColor = this.setStrokeColor.bind(this);\r\n this.setStrokeWidth = this.setStrokeWidth.bind(this);\r\n this.setStrokeDasharray = this.setStrokeDasharray.bind(this);\r\n\r\n this.strokeColor = settings.defaultColor;\r\n this.strokeWidth = settings.defaultStrokeWidth;\r\n this.strokeDasharray = settings.defaultStrokeDasharray;\r\n\r\n this.strokePanel = new ColorPickerPanel(\r\n 'Line color',\r\n settings.defaultColorSet,\r\n settings.defaultColor\r\n );\r\n this.strokePanel.onColorChanged = this.setStrokeColor;\r\n\r\n this.strokeWidthPanel = new LineWidthPanel(\r\n 'Line width',\r\n settings.defaultStrokeWidths,\r\n settings.defaultStrokeWidth\r\n );\r\n this.strokeWidthPanel.onWidthChanged = this.setStrokeWidth;\r\n\r\n this.strokeStylePanel = new LineStylePanel(\r\n 'Line style',\r\n settings.defaultStrokeDasharrays,\r\n settings.defaultStrokeDasharray\r\n );\r\n this.strokeStylePanel.onStyleChanged = this.setStrokeDasharray;\r\n }\r\n\r\n /**\r\n * Returns true if passed SVG element belongs to the marker. False otherwise.\r\n * \r\n * @param el - target element.\r\n */\r\n public ownsTarget(el: EventTarget): boolean {\r\n if (\r\n super.ownsTarget(el) ||\r\n el === this.visual ||\r\n el === this.selectorLine ||\r\n el === this.visibleLine\r\n ) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n private createVisual() {\r\n this.visual = SvgHelper.createGroup();\r\n this.selectorLine = SvgHelper.createLine(\r\n this.x1,\r\n this.y1,\r\n this.x2,\r\n this.y2,\r\n [\r\n ['stroke', 'transparent'],\r\n ['stroke-width', (this.strokeWidth + 10).toString()],\r\n ]\r\n );\r\n this.visibleLine = SvgHelper.createLine(\r\n this.x1,\r\n this.y1,\r\n this.x2,\r\n this.y2,\r\n [\r\n ['stroke', this.strokeColor],\r\n ['stroke-width', this.strokeWidth.toString()],\r\n ]\r\n );\r\n this.visual.appendChild(this.selectorLine);\r\n this.visual.appendChild(this.visibleLine);\r\n\r\n this.addMarkerVisualToContainer(this.visual);\r\n }\r\n\r\n /**\r\n * Handles pointer (mouse, touch, stylus, etc.) down event.\r\n * \r\n * @param point - event coordinates.\r\n * @param target - direct event target element.\r\n */\r\n public pointerDown(point: IPoint, target?: EventTarget): void {\r\n super.pointerDown(point, target);\r\n if (this.state === 'new') {\r\n this.createVisual();\r\n this.adjustVisual();\r\n\r\n this._state = 'creating';\r\n }\r\n }\r\n\r\n /**\r\n * Adjusts visual after manipulation.\r\n */\r\n protected adjustVisual(): void {\r\n if (this.selectorLine && this.visibleLine) {\r\n this.selectorLine.setAttribute('x1', this.x1.toString());\r\n this.selectorLine.setAttribute('y1', this.y1.toString());\r\n this.selectorLine.setAttribute('x2', this.x2.toString());\r\n this.selectorLine.setAttribute('y2', this.y2.toString());\r\n\r\n this.visibleLine.setAttribute('x1', this.x1.toString());\r\n this.visibleLine.setAttribute('y1', this.y1.toString());\r\n this.visibleLine.setAttribute('x2', this.x2.toString());\r\n this.visibleLine.setAttribute('y2', this.y2.toString());\r\n\r\n SvgHelper.setAttributes(this.visibleLine, [['stroke', this.strokeColor]]);\r\n SvgHelper.setAttributes(this.visibleLine, [['stroke-width', this.strokeWidth.toString()]]);\r\n SvgHelper.setAttributes(this.visibleLine, [['stroke-dasharray', this.strokeDasharray.toString()]]);\r\n }\r\n }\r\n\r\n /**\r\n * Sets line color.\r\n * @param color - new color.\r\n */\r\n protected setStrokeColor(color: string): void {\r\n this.strokeColor = color;\r\n this.adjustVisual();\r\n this.colorChanged(color);\r\n }\r\n /**\r\n * Sets line width.\r\n * @param width - new width.\r\n */\r\n protected setStrokeWidth(width: number): void {\r\n this.strokeWidth = width\r\n this.adjustVisual();\r\n }\r\n\r\n /**\r\n * Sets line dash array.\r\n * @param dashes - new dash array.\r\n */\r\n protected setStrokeDasharray(dashes: string): void {\r\n this.strokeDasharray = dashes;\r\n this.adjustVisual();\r\n this.stateChanged();\r\n }\r\n\r\n /**\r\n * Returns the list of toolbox panels for this marker type.\r\n */\r\n public get toolboxPanels(): ToolboxPanel[] {\r\n return [this.strokePanel, this.strokeWidthPanel, this.strokeStylePanel];\r\n }\r\n\r\n /**\r\n * Returns current marker state that can be restored in the future.\r\n */\r\n public getState(): LineMarkerState {\r\n const result: LineMarkerState = Object.assign({\r\n strokeColor: this.strokeColor,\r\n strokeWidth: this.strokeWidth,\r\n strokeDasharray: this.strokeDasharray\r\n }, super.getState());\r\n result.typeName = LineMarker.typeName;\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Restores previously saved marker state.\r\n * \r\n * @param state - previously saved state.\r\n */\r\n public restoreState(state: MarkerBaseState): void {\r\n super.restoreState(state);\r\n\r\n const lmState = state as LineMarkerState;\r\n this.strokeColor = lmState.strokeColor;\r\n this.strokeWidth = lmState.strokeWidth;\r\n this.strokeDasharray = lmState.strokeDasharray;\r\n\r\n this.createVisual();\r\n this.adjustVisual();\r\n }\r\n}\r\n","import { ToolboxPanel } from '../ToolboxPanel';\r\nimport Icon from './font-family-panel-icon.svg';\r\n\r\n/**\r\n * Font change event handler type.\r\n */\r\nexport type FontChangeHandler = (newFont: string) => void;\r\n\r\n/**\r\n * Font family selection toolbox panel.\r\n */\r\nexport class FontFamilyPanel extends ToolboxPanel {\r\n private fonts: string[] = [];\r\n private currentFont?: string;\r\n\r\n private fontBoxes: HTMLDivElement[] = [];\r\n\r\n /**\r\n * Handler for the font family change event.\r\n */\r\n public onFontChanged?: FontChangeHandler;\r\n\r\n /**\r\n * Creates a font family toolbox panel.\r\n * @param title - panel title.\r\n * @param fonts - available font families.\r\n * @param currentFont - currently selected font family.\r\n * @param icon - panel button icon (SVG image markup).\r\n */\r\n constructor(title: string, fonts: string[], currentFont?: string, icon?: string) {\r\n super(title, icon ? icon : Icon);\r\n this.fonts = fonts;\r\n this.currentFont = currentFont;\r\n\r\n this._id = 'font-family-panel';\r\n\r\n this.setCurrentFont = this.setCurrentFont.bind(this);\r\n }\r\n\r\n /**\r\n * Returns panel UI.\r\n */\r\n public getUi(): HTMLDivElement {\r\n const panelDiv = document.createElement('div');\r\n // panelDiv.style.display = 'flex';\r\n panelDiv.style.overflow = 'hidden';\r\n panelDiv.style.flexGrow = '2';\r\n this.fonts.forEach((font) => {\r\n const fontBoxContainer = document.createElement('div');\r\n fontBoxContainer.style.display = 'inline-block';\r\n // fontBoxContainer.style.flexGrow = '2';\r\n fontBoxContainer.style.alignItems = 'center';\r\n fontBoxContainer.style.justifyContent = 'space-between';\r\n fontBoxContainer.style.padding = '5px';\r\n fontBoxContainer.style.borderWidth = '2px';\r\n fontBoxContainer.style.borderStyle = 'solid';\r\n fontBoxContainer.style.overflow = 'hidden';\r\n fontBoxContainer.style.maxWidth = `${100 / this.fonts.length - 5}%`;\r\n fontBoxContainer.style.borderColor =\r\n font === this.currentFont ? this.uiStyleSettings.toolboxAccentColor : 'transparent';\r\n\r\n fontBoxContainer.addEventListener('click', () => {\r\n this.setCurrentFont(font, fontBoxContainer);\r\n })\r\n panelDiv.appendChild(fontBoxContainer);\r\n\r\n const fontBox = document.createElement('div');\r\n fontBox.style.display = 'flex';\r\n fontBox.style.minHeight = '20px';\r\n fontBox.style.flexGrow = '2';\r\n fontBox.style.fontFamily = font;\r\n fontBox.style.overflow = 'hidden';\r\n\r\n const fontLabel = document.createElement('div');\r\n fontLabel.style.whiteSpace = 'nowrap';\r\n fontLabel.style.overflow = 'hidden';\r\n fontLabel.style.textOverflow = 'ellipsis';\r\n fontLabel.innerHTML = 'The quick brown fox jumps over the lazy dog';\r\n\r\n fontBox.appendChild(fontLabel);\r\n\r\n fontBoxContainer.appendChild(fontBox);\r\n\r\n this.fontBoxes.push(fontBoxContainer);\r\n });\r\n return panelDiv;\r\n }\r\n\r\n private setCurrentFont(newFont: string, target: HTMLDivElement) {\r\n this.currentFont = newFont;\r\n\r\n this.fontBoxes.forEach(box => {\r\n box.style.borderColor = box === target ? this.uiStyleSettings.toolboxAccentColor : 'transparent';\r\n });\r\n\r\n if (this.onFontChanged) {\r\n this.onFontChanged(this.currentFont);\r\n }\r\n }\r\n}\r\n","import { IPoint } from '../../core/IPoint';\r\nimport { SvgHelper } from '../../core/SvgHelper';\r\nimport { RectangularBoxMarkerBase } from '../RectangularBoxMarkerBase';\r\nimport { Settings } from '../../core/Settings';\r\nimport Icon from './text-marker-icon.svg';\r\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\r\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\r\nimport { FontFamilyPanel } from '../../ui/toolbox-panels/FontFamilyPanel';\r\nimport { TextMarkerState } from './TextMarkerState';\r\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\r\n\r\nexport class TextMarker extends RectangularBoxMarkerBase {\r\n /**\r\n * String type name of the marker type.\r\n *\r\n * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\r\n */\r\n public static typeName = 'TextMarker';\r\n\r\n /**\r\n * Marker type title (display name) used for accessibility and other attributes.\r\n */\r\n public static title = 'Text marker';\r\n /**\r\n * SVG icon markup displayed on toolbar buttons.\r\n */\r\n public static icon = Icon;\r\n\r\n /**\r\n * Text color.\r\n */\r\n protected color = 'transparent';\r\n /**\r\n * Text's font family.\r\n */\r\n protected fontFamily: string;\r\n /**\r\n * Padding inside of the marker's bounding box in percents.\r\n */\r\n protected padding = 5;\r\n\r\n /**\r\n * Text color picker toolbox panel.\r\n */\r\n protected colorPanel: ColorPickerPanel;\r\n /**\r\n * Text font family toolbox panel.\r\n */\r\n protected fontFamilyPanel: FontFamilyPanel;\r\n\r\n private readonly DEFAULT_TEXT = 'your text here';\r\n private text: string = this.DEFAULT_TEXT;\r\n /**\r\n * Visual text element.\r\n */\r\n protected textElement: SVGTextElement;\r\n /**\r\n * Text background rectangle.\r\n */\r\n protected bgRectangle: SVGRectElement;\r\n /**\r\n * Div element for the text editor container.\r\n */\r\n protected textEditDiv: HTMLDivElement;\r\n /**\r\n * Editable text element.\r\n */\r\n protected textEditor: HTMLDivElement;\r\n\r\n protected isMoved = false;\r\n private pointerDownPoint: IPoint;\r\n private pointerDownTimestamp: number;\r\n\r\n /**\r\n * Creates a new marker.\r\n *\r\n * @param container - SVG container to hold marker's visual.\r\n * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\r\n * @param settings - settings object containing default markers settings.\r\n */\r\n constructor(\r\n container: SVGGElement,\r\n overlayContainer: HTMLDivElement,\r\n settings: Settings\r\n ) {\r\n super(container, overlayContainer, settings);\r\n\r\n this.color = settings.defaultColor;\r\n this.fontFamily = settings.defaultFontFamily;\r\n\r\n this.defaultSize = { x: 100, y: 30 };\r\n\r\n this.setColor = this.setColor.bind(this);\r\n this.setFont = this.setFont.bind(this);\r\n this.renderText = this.renderText.bind(this);\r\n this.sizeText = this.sizeText.bind(this);\r\n this.textEditDivClicked = this.textEditDivClicked.bind(this);\r\n this.showTextEditor = this.showTextEditor.bind(this);\r\n this.setSize = this.setSize.bind(this);\r\n this.positionTextEditor = this.positionTextEditor.bind(this);\r\n this.wrapText = this.wrapText.bind(this);\r\n\r\n this.colorPanel = new ColorPickerPanel(\r\n 'Color',\r\n settings.defaultColorSet,\r\n settings.defaultColor\r\n );\r\n this.colorPanel.onColorChanged = this.setColor;\r\n\r\n this.fontFamilyPanel = new FontFamilyPanel(\r\n 'Font',\r\n settings.defaultFontFamilies,\r\n settings.defaultFontFamily\r\n );\r\n this.fontFamilyPanel.onFontChanged = this.setFont;\r\n }\r\n\r\n /**\r\n * Returns true if passed SVG element belongs to the marker. False otherwise.\r\n *\r\n * @param el - target element.\r\n */\r\n public ownsTarget(el: EventTarget): boolean {\r\n if (\r\n super.ownsTarget(el) ||\r\n el === this.visual ||\r\n el === this.textElement ||\r\n el === this.bgRectangle\r\n ) {\r\n return true;\r\n } else {\r\n let found = false;\r\n this.textElement.childNodes.forEach((span) => {\r\n if (span === el) {\r\n found = true;\r\n }\r\n });\r\n return found;\r\n }\r\n }\r\n\r\n /**\r\n * Creates text marker visual.\r\n */\r\n protected createVisual(): void {\r\n this.visual = SvgHelper.createGroup();\r\n\r\n this.bgRectangle = SvgHelper.createRect(1, 1, [['fill', 'transparent']]);\r\n this.visual.appendChild(this.bgRectangle);\r\n\r\n this.textElement = SvgHelper.createText([\r\n ['fill', this.color],\r\n ['font-family', this.fontFamily],\r\n ['font-size', '16px'],\r\n ['x', '0'],\r\n ['y', '0'],\r\n ]);\r\n this.textElement.transform.baseVal.appendItem(SvgHelper.createTransform()); // translate transorm\r\n this.textElement.transform.baseVal.appendItem(SvgHelper.createTransform()); // scale transorm\r\n\r\n this.visual.appendChild(this.textElement);\r\n\r\n this.addMarkerVisualToContainer(this.visual);\r\n this.renderText();\r\n }\r\n\r\n /**\r\n * Handles pointer (mouse, touch, stylus, etc.) down event.\r\n *\r\n * @param point - event coordinates.\r\n * @param target - direct event target element.\r\n */\r\n public pointerDown(point: IPoint, target?: EventTarget): void {\r\n super.pointerDown(point, target);\r\n\r\n this.isMoved = false;\r\n this.pointerDownPoint = point;\r\n this.pointerDownTimestamp = Date.now();\r\n\r\n if (this.state === 'new') {\r\n this.createVisual();\r\n this.moveVisual(point);\r\n this._state = 'creating';\r\n }\r\n }\r\n\r\n private wrapText(): string {\r\n function getTextAspectRatio(textLines: string[]): number {\r\n const charsLinesAspectRatio = 0.35;\r\n\r\n let longestLineChars = textLines[0].length;\r\n textLines.forEach(line => {\r\n if (line.length > longestLineChars) {\r\n longestLineChars = line.length;\r\n }\r\n });\r\n\r\n return longestLineChars * charsLinesAspectRatio / textLines.length;\r\n }\r\n\r\n if (this.text !== '') {\r\n const lines = this.text.split(/\\r\\n|[\\n\\v\\f\\r\\x85\\u2028\\u2029]/);\r\n const boxAspectRatio = this.width * 1.0 / this.height;\r\n let processedLines = new Array<string>(...lines);\r\n \r\n let textAspectRatio = getTextAspectRatio(processedLines);\r\n\r\n let maxLineLength = Number.MAX_VALUE;\r\n while (textAspectRatio > boxAspectRatio) {\r\n let longestLine = processedLines[0];\r\n processedLines.forEach(line => {\r\n if (line.length > longestLine.length) {\r\n longestLine = line;\r\n }\r\n });\r\n maxLineLength = longestLine.lastIndexOf(' ', maxLineLength - 1);\r\n\r\n if (maxLineLength > 0) {\r\n processedLines = [];\r\n lines.forEach(line => {\r\n let reminderLine = line;\r\n while (reminderLine.length > maxLineLength) {\r\n let maxEnd = reminderLine.lastIndexOf(' ', maxLineLength);\r\n if (maxEnd < 0) {\r\n // if the first word is longer than max, at least wrap after it\r\n maxEnd = reminderLine.indexOf(' ');\r\n }\r\n if (maxEnd > 0) {\r\n processedLines.push(reminderLine.substring(0, maxEnd));\r\n reminderLine = reminderLine.substring(maxEnd).trim();\r\n } else {\r\n processedLines.push(reminderLine);\r\n reminderLine = '';\r\n }\r\n }\r\n processedLines.push(reminderLine);\r\n });\r\n textAspectRatio = getTextAspectRatio(processedLines);\r\n } else {\r\n // can't wrap no more\r\n textAspectRatio = -1;\r\n }\r\n }\r\n\r\n return processedLines.join(`\\r\\n`);\r\n } else {\r\n return this.text;\r\n }\r\n }\r\n\r\n private renderText() {\r\n const LINE_SIZE = '1.2em';\r\n\r\n if (this.textElement) {\r\n while (this.textElement.lastChild) {\r\n this.textElement.removeChild(this.textElement.lastChild);\r\n }\r\n\r\n const processedText = this.globalSettings.wrapText ? this.wrapText() : this.text;\r\n const lines = processedText.split(/\\r\\n|[\\n\\v\\f\\r\\x85\\u2028\\u2029]/);\r\n lines.forEach((line) => {\r\n this.textElement.appendChild(\r\n SvgHelper.createTSpan(\r\n // workaround for swallowed empty lines\r\n line.trim() === '' ? ' ' : line.trim(), [\r\n ['x', '0'],\r\n ['dy', LINE_SIZE],\r\n ])\r\n );\r\n });\r\n\r\n setTimeout(this.sizeText, 10);\r\n }\r\n }\r\n\r\n private getTextScale(): number {\r\n const textSize = this.textElement.getBBox();\r\n let scale = 1.0;\r\n if (textSize.width > 0 && textSize.height > 0) {\r\n const xScale =\r\n (this.width * 1.0 - (this.width * this.padding * 2) / 100) /\r\n textSize.width;\r\n const yScale =\r\n (this.height * 1.0 - (this.height * this.padding * 2) / 100) /\r\n textSize.height;\r\n scale = Math.min(xScale, yScale);\r\n }\r\n return scale;\r\n }\r\n\r\n private getTextPosition(scale: number): IPoint {\r\n const xSign = window.getComputedStyle(this.textElement).direction === 'rtl' ? 1 : -1;\r\n const textSize = this.textElement.getBBox();\r\n let x = 0;\r\n let y = 0;\r\n if (textSize.width > 0 && textSize.height > 0) {\r\n x = (this.width + xSign * textSize.width * scale) / 2;\r\n y = this.height / 2 - (textSize.height * scale) / 2;\r\n }\r\n return { x: x, y: y };\r\n }\r\n\r\n private sizeText() {\r\n const textBBox = this.textElement.getBBox();\r\n const scale = this.getTextScale();\r\n const position = this.getTextPosition(scale);\r\n position.y -= textBBox.y * scale; // workaround adjustment for text not being placed at y=0\r\n\r\n if (navigator.userAgent.indexOf('Edge/') > -1) {\r\n // workaround for legacy Edge as transforms don't work otherwise but this way it doesn't work in Safari\r\n this.textElement.style.transform = `translate(${position.x}px, ${position.y}px) scale(${scale}, ${scale})`;\r\n } else {\r\n this.textElement.transform.baseVal\r\n .getItem(0)\r\n .setTranslate(position.x, position.y);\r\n this.textElement.transform.baseVal.getItem(1).setScale(scale, scale);\r\n }\r\n }\r\n\r\n /**\r\n * Handles marker manipulation (move, resize, rotate, etc.).\r\n *\r\n * @param point - event coordinates.\r\n */\r\n public manipulate(point: IPoint): void {\r\n super.manipulate(point);\r\n if (this.pointerDownPoint !== undefined) {\r\n this.isMoved =\r\n Math.abs(point.x - this.pointerDownPoint.x) > 5 ||\r\n Math.abs(point.y - this.pointerDownPoint.y) > 5;\r\n }\r\n }\r\n\r\n /**\r\n * Resize marker based on current pointer coordinates and context.\r\n * @param point\r\n */\r\n protected resize(point: IPoint): void {\r\n super.resize(point);\r\n this.isMoved = true;\r\n this.setSize();\r\n if (this.globalSettings.wrapText) {\r\n this.renderText();\r\n } else {\r\n this.sizeText();\r\n }\r\n }\r\n\r\n /**\r\n * Sets size of marker elements after manipulation.\r\n */\r\n protected setSize(): void {\r\n super.setSize();\r\n if (this.visual && this.bgRectangle) {\r\n SvgHelper.setAttributes(this.visual, [\r\n ['width', this.width.toString()],\r\n ['height', this.height.toString()],\r\n ]);\r\n SvgHelper.setAttributes(this.bgRectangle, [\r\n ['width', this.width.toString()],\r\n ['height', this.height.toString()],\r\n ]);\r\n }\r\n }\r\n\r\n /**\r\n * Handles pointer (mouse, touch, stylus, etc.) up event.\r\n *\r\n * @param point - event coordinates.\r\n */\r\n public pointerUp(point: IPoint): void {\r\n const inState = this.state;\r\n if (inState === 'creating') {\r\n this._suppressMarkerCreateEvent = true;\r\n }\r\n super.pointerUp(point);\r\n this.setSize();\r\n if (\r\n inState === 'creating' ||\r\n (!this.isMoved && Date.now() - this.pointerDownTimestamp > 500)\r\n ) {\r\n this.showTextEditor();\r\n }\r\n this.pointerDownPoint = undefined;\r\n }\r\n\r\n private showTextEditor() {\r\n this._state = 'edit';\r\n this.overlayContainer.innerHTML = '';\r\n\r\n this.textEditDiv = document.createElement('div');\r\n // textEditDiv.style.display = 'flex';\r\n this.textEditDiv.style.flexGrow = '2';\r\n //textEditDiv.style.backgroundColor = 'rgb(0,0,0,0.7)';\r\n this.textEditDiv.style.alignItems = 'center';\r\n this.textEditDiv.style.justifyContent = 'center';\r\n this.textEditDiv.style.pointerEvents = 'auto';\r\n this.textEditDiv.style.overflow = 'hidden';\r\n\r\n this.textEditor = document.createElement('div');\r\n this.textEditor.style.position = 'absolute';\r\n this.textEditor.style.fontFamily = this.fontFamily;\r\n this.textEditor.style.lineHeight = '1em';\r\n this.textEditor.innerText = this.text;\r\n this.textEditor.contentEditable = 'true';\r\n this.textEditor.style.color = this.color;\r\n this.textEditor.style.whiteSpace = 'pre';\r\n //this.textEditor.style.outline = 'none';\r\n this.positionTextEditor();\r\n this.textEditor.addEventListener('pointerup', (ev) => {\r\n ev.stopPropagation();\r\n });\r\n if (!this.globalSettings.wrapText) {\r\n this.textEditor.addEventListener('input', () => {\r\n let fontSize = Number.parseFloat(this.textEditor.style.fontSize);\r\n while (\r\n this.textEditor.clientWidth >=\r\n Number.parseInt(this.textEditor.style.maxWidth) &&\r\n fontSize > 0.9\r\n ) {\r\n fontSize -= 0.1;\r\n this.textEditor.style.fontSize = `${Math.max(fontSize, 0.9)}em`;\r\n }\r\n });\r\n }\r\n this.textEditor.addEventListener('keyup', (ev) => {\r\n ev.cancelBubble = true;\r\n });\r\n this.textEditor.addEventListener('paste', (ev) => {\r\n if (ev.clipboardData) {\r\n // paste plain text\r\n const content = ev.clipboardData.getData('text');\r\n const selection = window.getSelection();\r\n if (!selection.rangeCount) return false;\r\n selection.deleteFromDocument();\r\n selection.getRangeAt(0).insertNode(document.createTextNode(content));\r\n ev.preventDefault();\r\n }\r\n });\r\n\r\n this.textEditDiv.addEventListener('pointerup', () => {\r\n this.textEditDivClicked(this.textEditor.innerText);\r\n });\r\n this.textEditDiv.appendChild(this.textEditor);\r\n this.overlayContainer.appendChild(this.textEditDiv);\r\n\r\n this.hideVisual();\r\n\r\n this.textEditor.focus();\r\n document.execCommand('selectAll');\r\n }\r\n\r\n private positionTextEditor() {\r\n if (this.state === 'edit') {\r\n if (this.textEditor === undefined) {\r\n this.showTextEditor();\r\n } else {\r\n if (this.globalSettings.wrapText) {\r\n this.textEditor.style.left = `${this.left + this.padding}px`;\r\n this.textEditor.style.top = `${this.top + this.padding}px`;\r\n this.textEditor.style.width = `${this.width - this.padding * 2}px`;\r\n this.textEditor.style.height = `${this.height - this.padding * 2}px`;\r\n this.textEditor.style.maxHeight = this.textEditor.style.height;\r\n this.textEditor.style.whiteSpace = 'wrap';\r\n } else {\r\n this.textElement.style.display = '';\r\n const textScale = this.getTextScale();\r\n // const textPosition = this.getTextPosition(textScale);\r\n const rPosition = this.rotatePoint({\r\n x: this.left + this.width / 2,\r\n y: this.top + this.height / 2,\r\n });\r\n const textSize = this.textElement.getBBox();\r\n const rWH = {\r\n x: textSize.width * textScale,\r\n y: textSize.height * textScale,\r\n };\r\n rPosition.x -= rWH.x / 2;\r\n rPosition.y -= rWH.y / 2;\r\n\r\n this.textEditor.style.top = `${rPosition.y}px`;\r\n this.textEditor.style.left = `${rPosition.x}px`;\r\n this.textEditor.style.maxWidth = `${\r\n this.overlayContainer.offsetWidth - rPosition.x\r\n }px`;\r\n this.textEditor.style.fontSize = `${Math.max(16 * textScale, 12)}px`;\r\n this.textElement.style.display = 'none';\r\n }\r\n }\r\n }\r\n }\r\n\r\n private textEditDivClicked(text: string) {\r\n this.text = text.trim();\r\n this.overlayContainer.innerHTML = '';\r\n this.renderText();\r\n this.showVisual();\r\n if (this._suppressMarkerCreateEvent) {\r\n this._suppressMarkerCreateEvent = false;\r\n if (this.onMarkerCreated) {\r\n this.onMarkerCreated(this);\r\n }\r\n }\r\n this.stateChanged();\r\n }\r\n\r\n public select(): void {\r\n super.select(); \r\n if (this.state === 'edit') {\r\n this.textEditDivClicked(this.textEditor.innerText);\r\n }\r\n }\r\n\r\n /**\r\n * Deselects this marker, renders text (if necessary), and hides selected marker UI.\r\n */\r\n public deselect(): void {\r\n if (this.state === 'edit') {\r\n this.textEditDivClicked(this.textEditor.innerText);\r\n }\r\n super.deselect();\r\n }\r\n\r\n /**\r\n * Opens text editor on double-click.\r\n * @param point\r\n * @param target\r\n */\r\n public dblClick(point: IPoint, target?: EventTarget): void {\r\n super.dblClick(point, target);\r\n\r\n this.showTextEditor();\r\n }\r\n\r\n /**\r\n * Sets text color.\r\n * @param color - new text color.\r\n */\r\n protected setColor(color: string): void {\r\n if (this.textElement) {\r\n SvgHelper.setAttributes(this.textElement, [['fill', color]]);\r\n }\r\n this.color = color;\r\n if (this.textEditor) {\r\n this.textEditor.style.color = this.color;\r\n }\r\n this.colorChanged(color);\r\n }\r\n\r\n /**\r\n * Sets font family.\r\n * @param font - new font family.\r\n */\r\n protected setFont(font: string): void {\r\n if (this.textElement) {\r\n SvgHelper.setAttributes(this.textElement, [['font-family', font]]);\r\n }\r\n this.fontFamily = font;\r\n if (this.textEditor) {\r\n this.textEditor.style.fontFamily = this.fontFamily;\r\n }\r\n this.renderText();\r\n this.stateChanged();\r\n }\r\n\r\n /**\r\n * Hides marker visual.\r\n */\r\n protected hideVisual(): void {\r\n this.textElement.style.display = 'none';\r\n this.hideControlBox();\r\n }\r\n /**\r\n * Shows marker visual.\r\n */\r\n protected showVisual(): void {\r\n if (this.state === 'edit') {\r\n this._state = 'select';\r\n }\r\n this.textElement.style.display = '';\r\n this.showControlBox();\r\n }\r\n\r\n /**\r\n * Returns the list of toolbox panels for this marker type.\r\n */\r\n public get toolboxPanels(): ToolboxPanel[] {\r\n return [this.colorPanel, this.fontFamilyPanel];\r\n }\r\n\r\n /**\r\n * Returns current marker state that can be restored in the future.\r\n */\r\n public getState(): TextMarkerState {\r\n const result: TextMarkerState = Object.assign(\r\n {\r\n color: this.color,\r\n fontFamily: this.fontFamily,\r\n padding: this.padding,\r\n text: this.text,\r\n wrapText: this.globalSettings.wrapText\r\n },\r\n super.getState()\r\n );\r\n result.typeName = TextMarker.typeName;\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Restores previously saved marker state.\r\n *\r\n * @param state - previously saved state.\r\n */\r\n public restoreState(state: MarkerBaseState): void {\r\n const textState = state as TextMarkerState;\r\n this.color = textState.color;\r\n this.fontFamily = textState.fontFamily;\r\n this.padding = textState.padding;\r\n this.text = textState.text;\r\n\r\n this.createVisual();\r\n super.restoreState(state);\r\n this.setSize();\r\n if (this.globalSettings.wrapText) {\r\n // need a rerender post setting size for wrapping\r\n this.renderText();\r\n }\r\n }\r\n\r\n /**\r\n * Scales marker. Used after the image resize.\r\n *\r\n * @param scaleX - horizontal scale\r\n * @param scaleY - vertical scale\r\n */\r\n public scale(scaleX: number, scaleY: number): void {\r\n super.scale(scaleX, scaleY);\r\n\r\n this.setSize();\r\n this.sizeText();\r\n this.positionTextEditor();\r\n }\r\n}\r\n","import { IPoint } from '../../core/IPoint';\r\nimport { SvgHelper } from '../../core/SvgHelper';\r\nimport { RectangularBoxMarkerBase } from '../RectangularBoxMarkerBase';\r\nimport { Settings } from '../../core/Settings';\r\nimport Icon from './freehand-marker-icon.svg';\r\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\r\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\r\nimport { FreehandMarkerState } from './FreehandMarkerState';\r\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\r\nimport { LineWidthPanel } from '../../ui/toolbox-panels/LineWidthPanel';\r\n\r\n\r\nexport class FreehandMarker extends RectangularBoxMarkerBase {\r\n /**\r\n * String type name of the marker type. \r\n * \r\n * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\r\n */\r\n public static typeName = 'FreehandMarker';\r\n\r\n /**\r\n * Marker type title (display name) used for accessibility and other attributes.\r\n */\r\n public static title = 'Freehand marker';\r\n /**\r\n * SVG icon markup displayed on toolbar buttons.\r\n */\r\n public static icon = Icon;\r\n\r\n /**\r\n * Marker color.\r\n */\r\n protected color = 'transparent';\r\n /**\r\n * Marker's stroke width.\r\n */\r\n protected lineWidth = 3;\r\n\r\n private colorPanel: ColorPickerPanel;\r\n private lineWidthPanel: LineWidthPanel;\r\n\r\n\r\n private canvasElement: HTMLCanvasElement;\r\n private canvasContext: CanvasRenderingContext2D;\r\n\r\n private drawingImage: SVGImageElement;\r\n private drawingImgUrl: string;\r\n\r\n private drawing = false;\r\n\r\n private pixelRatio = 1;\r\n\r\n /**\r\n * Creates a new marker.\r\n *\r\n * @param container - SVG container to hold marker's visual.\r\n * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\r\n * @param settings - settings object containing default markers settings.\r\n */\r\n constructor(\r\n container: SVGGElement,\r\n overlayContainer: HTMLDivElement,\r\n settings: Settings\r\n ) {\r\n super(container, overlayContainer, settings);\r\n\r\n this.color = settings.defaultColor;\r\n this.lineWidth = settings.defaultStrokeWidth;\r\n this.pixelRatio = settings.freehandPixelRatio;\r\n\r\n this.setColor = this.setColor.bind(this);\r\n this.addCanvas = this.addCanvas.bind(this);\r\n this.finishCreation = this.finishCreation.bind(this);\r\n this.setLineWidth = this.setLineWidth.bind(this);\r\n\r\n this.colorPanel = new ColorPickerPanel(\r\n 'Color',\r\n settings.defaultColorSet,\r\n settings.defaultColor\r\n );\r\n this.colorPanel.onColorChanged = this.setColor;\r\n\r\n this.lineWidthPanel = new LineWidthPanel(\r\n 'Line width',\r\n settings.defaultStrokeWidths,\r\n settings.defaultStrokeWidth\r\n );\r\n this.lineWidthPanel.onWidthChanged = this.setLineWidth;\r\n\r\n }\r\n\r\n /**\r\n * Returns true if passed SVG element belongs to the marker. False otherwise.\r\n * \r\n * @param el - target element.\r\n */\r\n public ownsTarget(el: EventTarget): boolean {\r\n if (\r\n super.ownsTarget(el) ||\r\n el === this.visual ||\r\n el === this.drawingImage\r\n ) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n private createVisual() {\r\n this.visual = SvgHelper.createGroup();\r\n this.drawingImage = SvgHelper.createImage();\r\n this.visual.appendChild(this.drawingImage);\r\n\r\n const translate = SvgHelper.createTransform();\r\n this.visual.transform.baseVal.appendItem(translate);\r\n this.addMarkerVisualToContainer(this.visual);\r\n }\r\n\r\n /**\r\n * Handles pointer (mouse, touch, stylus, etc.) down event.\r\n * \r\n * @param point - event coordinates.\r\n * @param target - direct event target element.\r\n */\r\n public pointerDown(point: IPoint, target?: EventTarget): void {\r\n if (this.state === 'new') {\r\n this.addCanvas();\r\n\r\n this.createVisual();\r\n\r\n this._state = 'creating';\r\n }\r\n\r\n if (this.state === 'creating') {\r\n this.canvasContext.strokeStyle = this.color;\r\n this.canvasContext.lineWidth = this.lineWidth;\r\n this.canvasContext.beginPath();\r\n this.canvasContext.moveTo(point.x, point.y);\r\n this.drawing = true;\r\n } else {\r\n super.pointerDown(point, target);\r\n }\r\n }\r\n\r\n /**\r\n * Handles marker manipulation (move, resize, rotate, etc.).\r\n * \r\n * @param point - event coordinates.\r\n */\r\n public manipulate(point: IPoint): void {\r\n if (this.state === 'creating') {\r\n if (this.drawing) {\r\n this.canvasContext.lineTo(point.x, point.y);\r\n this.canvasContext.stroke();\r\n }\r\n } else {\r\n super.manipulate(point);\r\n }\r\n }\r\n\r\n /**\r\n * Resize marker based on current pointer coordinates and context.\r\n * @param point \r\n */\r\n protected resize(point: IPoint): void {\r\n super.resize(point);\r\n SvgHelper.setAttributes(this.visual, [\r\n ['width', this.width.toString()],\r\n ['height', this.height.toString()],\r\n ]);\r\n SvgHelper.setAttributes(this.drawingImage, [\r\n ['width', this.width.toString()],\r\n ['height', this.height.toString()],\r\n ]);\r\n }\r\n\r\n /**\r\n * Handles pointer (mouse, touch, stylus, etc.) up event.\r\n * \r\n * @param point - event coordinates.\r\n */\r\n public pointerUp(point: IPoint): void {\r\n if (this._state === 'creating') {\r\n if (this.drawing) {\r\n this.canvasContext.closePath();\r\n this.drawing = false;\r\n if (this.globalSettings.newFreehandMarkerOnPointerUp) {\r\n this.finishCreation();\r\n }\r\n }\r\n } else {\r\n super.pointerUp(point);\r\n }\r\n }\r\n\r\n private addCanvas() {\r\n this.overlayContainer.innerHTML = '';\r\n\r\n this.canvasElement = document.createElement('canvas');\r\n this.canvasElement.width = this.overlayContainer.clientWidth * this.pixelRatio;\r\n this.canvasElement.height = this.overlayContainer.clientHeight * this.pixelRatio;\r\n this.canvasContext = this.canvasElement.getContext('2d');\r\n this.canvasContext.scale(this.pixelRatio, this.pixelRatio);\r\n this.overlayContainer.appendChild(this.canvasElement);\r\n }\r\n\r\n /**\r\n * Selects this marker and displays appropriate selected marker UI.\r\n */\r\n public select(): void {\r\n if (this.state === 'creating') {\r\n this.finishCreation();\r\n }\r\n super.select();\r\n }\r\n\r\n /**\r\n * Deselects this marker and hides selected marker UI.\r\n */\r\n public deselect(): void {\r\n if (this.state === 'creating') {\r\n this.finishCreation();\r\n }\r\n super.deselect();\r\n }\r\n\r\n private finishCreation() {\r\n const imgData = this.canvasContext.getImageData(\r\n 0,\r\n 0,\r\n this.canvasElement.width,\r\n this.canvasElement.height\r\n );\r\n\r\n let [startX, startY, endX, endY] = [\r\n this.canvasElement.width + 1,\r\n this.canvasElement.height + 1,\r\n -1,\r\n -1,\r\n ];\r\n let containsData = false;\r\n for (let row = 0; row < this.canvasElement.height; row++) {\r\n for (let col = 0; col < this.canvasElement.width; col++) {\r\n const pixAlpha =\r\n imgData.data[row * this.canvasElement.width * 4 + col * 4 + 3];\r\n if (pixAlpha > 0) {\r\n containsData = true;\r\n if (row < startY) {\r\n startY = row;\r\n }\r\n if (col < startX) {\r\n startX = col;\r\n }\r\n if (row > endY) {\r\n endY = row;\r\n }\r\n if (col > endX) {\r\n endX = col;\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (containsData) {\r\n this.left = startX / this.pixelRatio;\r\n this.top = startY / this.pixelRatio;\r\n this.width = (endX - startX) / this.pixelRatio;\r\n this.height = (endY - startY) / this.pixelRatio;\r\n\r\n const tmpCanvas = document.createElement('canvas');\r\n tmpCanvas.width = endX - startX;\r\n tmpCanvas.height = endY - startY;\r\n const tmpCtx = tmpCanvas.getContext('2d');\r\n tmpCtx.putImageData(\r\n this.canvasContext.getImageData(\r\n startX,\r\n startY,\r\n endX - startX,\r\n endY - startY\r\n ),\r\n 0,\r\n 0\r\n );\r\n\r\n this.drawingImgUrl = tmpCanvas.toDataURL('image/png');\r\n this.setDrawingImage();\r\n\r\n this._state = 'select';\r\n if (this.onMarkerCreated) {\r\n this.onMarkerCreated(this);\r\n }\r\n }\r\n this.overlayContainer.innerHTML = '';\r\n }\r\n\r\n private setDrawingImage() {\r\n SvgHelper.setAttributes(this.drawingImage, [\r\n ['width', this.width.toString()],\r\n ['height', this.height.toString()],\r\n ]);\r\n SvgHelper.setAttributes(this.drawingImage, [['href', this.drawingImgUrl]]);\r\n this.moveVisual({ x: this.left, y: this.top });\r\n }\r\n\r\n /**\r\n * Sets marker drawing color.\r\n * @param color - new color.\r\n */\r\n protected setColor(color: string): void {\r\n this.color = color;\r\n this.colorChanged(color);\r\n }\r\n\r\n /**\r\n * Sets line width.\r\n * @param width - new line width\r\n */\r\n protected setLineWidth(width: number): void {\r\n this.lineWidth = width;\r\n }\r\n\r\n\r\n /**\r\n * Returns the list of toolbox panels for this marker type.\r\n */\r\n public get toolboxPanels(): ToolboxPanel[] {\r\n if (this.state === 'new' || this.state === 'creating') {\r\n return [this.colorPanel, this.lineWidthPanel];\r\n } else {\r\n return [];\r\n }\r\n }\r\n\r\n /**\r\n * Returns current marker state that can be restored in the future.\r\n */\r\n public getState(): FreehandMarkerState {\r\n const result: FreehandMarkerState = Object.assign({\r\n drawingImgUrl: this.drawingImgUrl\r\n }, super.getState());\r\n result.typeName = FreehandMarker.typeName;\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Restores previously saved marker state.\r\n * \r\n * @param state - previously saved state.\r\n */\r\n public restoreState(state: MarkerBaseState): void {\r\n this.createVisual();\r\n super.restoreState(state);\r\n this.drawingImgUrl = (state as FreehandMarkerState).drawingImgUrl;\r\n this.setDrawingImage();\r\n }\r\n\r\n /**\r\n * Scales marker. Used after the image resize.\r\n * \r\n * @param scaleX - horizontal scale\r\n * @param scaleY - vertical scale\r\n */\r\n public scale(scaleX: number, scaleY: number): void {\r\n super.scale(scaleX, scaleY);\r\n\r\n this.setDrawingImage();\r\n }\r\n\r\n}\r\n","import { ToolboxPanel } from '../ToolboxPanel';\r\nimport Icon from './arrow-type-panel-icon.svg';\r\n\r\n/**\r\n * Represents available arrow types.\r\n *\r\n * - `both` - arrow tips on both sides.\r\n * - `start` - arrow tip on the starting point of line.\r\n * - `end` - arrow tip on the ending point of line.\r\n * - `none` - no arrow tips.\r\n */\r\nexport type ArrowType = 'both' | 'start' | 'end' | 'none';\r\n/**\r\n * Handler for arrow type change event.\r\n */\r\nexport type ArrowTypeChangeHandler = (newType: ArrowType) => void;\r\n\r\n/**\r\n * Arrow type selection panel.\r\n */\r\nexport class ArrowTypePanel extends ToolboxPanel {\r\n private currentType?: ArrowType;\r\n\r\n private typeBoxes: HTMLDivElement[] = [];\r\n\r\n /**\r\n * Event handler for the arrow type change event.\r\n */\r\n public onArrowTypeChanged?: ArrowTypeChangeHandler;\r\n\r\n /**\r\n * Creates an ArrowTypePanel.\r\n * @param title - panel title.\r\n * @param currentType - currently set arrow type.\r\n * @param icon - panel button icon (SVG image markup).\r\n */\r\n constructor(\r\n title: string,\r\n currentType?: ArrowType,\r\n icon?: string\r\n ) {\r\n super(title, icon ? icon : Icon);\r\n this.currentType = currentType;\r\n\r\n this._id = 'arrow-type-panel';\r\n\r\n this.setCurrentType = this.setCurrentType.bind(this);\r\n }\r\n\r\n /**\r\n * Returns panel UI.\r\n */\r\n public getUi(): HTMLDivElement {\r\n const panelDiv = document.createElement('div');\r\n panelDiv.style.display = 'flex';\r\n panelDiv.style.overflow = 'hidden';\r\n panelDiv.style.flexGrow = '2';\r\n for (let ti = 0; ti < 4; ti++) {\r\n let arrowType: ArrowType = 'both';\r\n switch (ti) {\r\n case 0:\r\n arrowType = 'both';\r\n break;\r\n case 1:\r\n arrowType = 'start';\r\n break;\r\n case 2:\r\n arrowType = 'end';\r\n break;\r\n case 3:\r\n arrowType = 'none';\r\n break;\r\n }\r\n const typeBoxContainer = document.createElement('div');\r\n typeBoxContainer.style.display = 'flex';\r\n typeBoxContainer.style.flexGrow = '2';\r\n typeBoxContainer.style.alignItems = 'center';\r\n typeBoxContainer.style.justifyContent = 'space-between';\r\n typeBoxContainer.style.padding = '5px';\r\n typeBoxContainer.style.borderWidth = '2px';\r\n typeBoxContainer.style.borderStyle = 'solid';\r\n typeBoxContainer.style.borderColor =\r\n arrowType === this.currentType\r\n ? this.uiStyleSettings.toolboxAccentColor\r\n : 'transparent';\r\n\r\n typeBoxContainer.addEventListener('click', () => {\r\n this.setCurrentType(arrowType, typeBoxContainer);\r\n });\r\n panelDiv.appendChild(typeBoxContainer);\r\n\r\n if (arrowType === 'both' || arrowType === 'start') {\r\n const leftTip = document.createElement('div');\r\n leftTip.style.display = 'flex';\r\n leftTip.style.alignItems = 'center';\r\n leftTip.style.minHeight = '20px';\r\n leftTip.innerHTML = `<svg viewBox=\"0 0 10 10\" width=\"10\" height=\"10\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <polygon points=\"0,5 10,0 10,10\" fill=\"${\r\n this.uiStyleSettings !== undefined\r\n ? this.uiStyleSettings.toolboxColor\r\n : '#eeeeee'\r\n }\" />\r\n </svg>`;\r\n leftTip.style.marginLeft = '5px';\r\n typeBoxContainer.appendChild(leftTip);\r\n }\r\n\r\n const lineBox = document.createElement('div');\r\n lineBox.style.display = 'flex';\r\n lineBox.style.alignItems = 'center';\r\n lineBox.style.minHeight = '20px';\r\n lineBox.style.flexGrow = '2';\r\n\r\n const hr = document.createElement('hr');\r\n hr.style.minWidth = '20px';\r\n hr.style.border = '0px';\r\n hr.style.borderTop = `3px solid ${\r\n this.uiStyleSettings !== undefined\r\n ? this.uiStyleSettings.toolboxColor\r\n : '#eeeeee'\r\n }`;\r\n hr.style.flexGrow = '2';\r\n lineBox.appendChild(hr);\r\n\r\n typeBoxContainer.appendChild(lineBox);\r\n\r\n if (arrowType === 'both' || arrowType === 'end') {\r\n const rightTip = document.createElement('div');\r\n rightTip.style.display = 'flex';\r\n rightTip.style.alignItems = 'center';\r\n rightTip.style.minHeight = '20px';\r\n rightTip.innerHTML = `<svg viewBox=\"0 0 10 10\" width=\"10\" height=\"10\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <polygon points=\"0,0 10,5 0,10\" fill=\"${\r\n this.uiStyleSettings !== undefined\r\n ? this.uiStyleSettings.toolboxColor\r\n : '#eeeeee'\r\n }\" />\r\n </svg>`;\r\n rightTip.style.marginRight = '5px';\r\n typeBoxContainer.appendChild(rightTip);\r\n }\r\n\r\n this.typeBoxes.push(typeBoxContainer);\r\n }\r\n return panelDiv;\r\n }\r\n\r\n private setCurrentType(newType: ArrowType, target: HTMLDivElement) {\r\n this.currentType = newType;\r\n\r\n this.typeBoxes.forEach((box) => {\r\n box.style.borderColor =\r\n box === target\r\n ? this.uiStyleSettings !== undefined\r\n ? this.uiStyleSettings.toolboxAccentColor\r\n : '#3080c3'\r\n : 'transparent';\r\n });\r\n\r\n if (this.onArrowTypeChanged) {\r\n this.onArrowTypeChanged(this.currentType);\r\n }\r\n }\r\n}\r\n","import { IPoint } from '../../core/IPoint';\r\nimport { SvgHelper } from '../../core/SvgHelper';\r\nimport { Settings } from '../../core/Settings';\r\nimport Icon from './arrow-marker-icon.svg';\r\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\r\nimport { LineMarker } from '../line-marker/LineMarker';\r\nimport { ArrowType, ArrowTypePanel } from '../../ui/toolbox-panels/ArrowTypePanel';\r\nimport { ArrowMarkerState } from './ArrowMarkerState';\r\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\r\n\r\n/**\r\n * Represents an arrow marker.\r\n */\r\nexport class ArrowMarker extends LineMarker {\r\n /**\r\n * String type name of the marker type. \r\n * \r\n * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\r\n */\r\n public static typeName = 'ArrowMarker';\r\n\r\n /**\r\n * Marker type title (display name) used for accessibility and other attributes.\r\n */\r\n public static title = 'Arrow marker';\r\n /**\r\n * SVG icon markup displayed on toolbar buttons.\r\n */\r\n public static icon = Icon;\r\n\r\n private arrow1: SVGPolygonElement;\r\n private arrow2: SVGPolygonElement;\r\n\r\n private arrowType: ArrowType = 'end';\r\n\r\n private arrowBaseHeight = 10;\r\n private arrowBaseWidth = 10;\r\n\r\n /**\r\n * Toolbox panel for arrow type selection.\r\n */\r\n protected arrowTypePanel: ArrowTypePanel;\r\n\r\n /**\r\n * Creates a new marker.\r\n *\r\n * @param container - SVG container to hold marker's visual.\r\n * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\r\n * @param settings - settings object containing default markers settings.\r\n */\r\n constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\r\n super(container, overlayContainer, settings);\r\n\r\n this.getArrowPoints = this.getArrowPoints.bind(this);\r\n this.setArrowType = this.setArrowType.bind(this);\r\n\r\n this.arrowTypePanel = new ArrowTypePanel('Arrow type', 'end');\r\n this.arrowTypePanel.onArrowTypeChanged = this.setArrowType;\r\n }\r\n\r\n /**\r\n * Returns true if passed SVG element belongs to the marker. False otherwise.\r\n * \r\n * @param el - target element.\r\n */\r\n public ownsTarget(el: EventTarget): boolean {\r\n if (\r\n super.ownsTarget(el) ||\r\n el === this.arrow1 || el === this.arrow2\r\n ) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n private getArrowPoints(offsetX: number, offsetY: number): string {\r\n const width = this.arrowBaseWidth + this.strokeWidth * 2;\r\n const height = this.arrowBaseHeight + this.strokeWidth * 2;\r\n return `${offsetX - width / 2},${\r\n offsetY + height / 2\r\n } ${offsetX},${offsetY - height / 2} ${\r\n offsetX + width / 2},${offsetY + height / 2}`;\r\n }\r\n\r\n private createTips() {\r\n this.arrow1 = SvgHelper.createPolygon(this.getArrowPoints(this.x1, this.y1), [['fill', this.strokeColor]]);\r\n this.arrow1.transform.baseVal.appendItem(SvgHelper.createTransform());\r\n this.visual.appendChild(this.arrow1);\r\n\r\n this.arrow2 = SvgHelper.createPolygon(this.getArrowPoints(this.x2, this.y2), [['fill', this.strokeColor]]);\r\n this.arrow2.transform.baseVal.appendItem(SvgHelper.createTransform());\r\n this.visual.appendChild(this.arrow2);\r\n }\r\n\r\n /**\r\n * Handles pointer (mouse, touch, stylus, etc.) down event.\r\n * \r\n * @param point - event coordinates.\r\n * @param target - direct event target element.\r\n */\r\n public pointerDown(point: IPoint, target?: EventTarget): void {\r\n super.pointerDown(point, target);\r\n if (this.state === 'creating') {\r\n this.createTips();\r\n }\r\n }\r\n\r\n /**\r\n * Adjusts marker visual after manipulation.\r\n */\r\n protected adjustVisual(): void {\r\n super.adjustVisual();\r\n\r\n if (this.arrow1 && this.arrow2) {\r\n this.arrow1.style.display = (this.arrowType === 'both' || this.arrowType === 'start') ? '' : 'none';\r\n this.arrow2.style.display = (this.arrowType === 'both' || this.arrowType === 'end') ? '' : 'none';\r\n\r\n SvgHelper.setAttributes(this.arrow1, [\r\n ['points', this.getArrowPoints(this.x1, this.y1)],\r\n ['fill', this.strokeColor]\r\n ]);\r\n SvgHelper.setAttributes(this.arrow2, [\r\n ['points', this.getArrowPoints(this.x2, this.y2)],\r\n ['fill', this.strokeColor]\r\n ]);\r\n\r\n let lineAngle1 = 0;\r\n if (Math.abs(this.x1 - this.x2) > 0.1) {\r\n lineAngle1 =\r\n (Math.atan((this.y2 - this.y1) / (this.x2 - this.x1)) * 180) / Math.PI + 90 * Math.sign(this.x1 - this.x2);\r\n }\r\n const a1transform = this.arrow1.transform.baseVal.getItem(0);\r\n a1transform.setRotate(lineAngle1, this.x1, this.y1);\r\n this.arrow1.transform.baseVal.replaceItem(a1transform, 0);\r\n\r\n const a2transform = this.arrow2.transform.baseVal.getItem(0);\r\n a2transform.setRotate(lineAngle1 + 180, this.x2, this.y2);\r\n this.arrow2.transform.baseVal.replaceItem(a2transform, 0);\r\n }\r\n }\r\n\r\n private setArrowType(arrowType: ArrowType) {\r\n this.arrowType = arrowType;\r\n this.adjustVisual();\r\n this.stateChanged();\r\n }\r\n\r\n /**\r\n * Returns the list of toolbox panels for this marker type.\r\n */\r\n public get toolboxPanels(): ToolboxPanel[] {\r\n return [this.strokePanel, this.strokeWidthPanel, this.strokeStylePanel, this.arrowTypePanel];\r\n }\r\n\r\n /**\r\n * Returns current marker state that can be restored in the future.\r\n */\r\n public getState(): ArrowMarkerState {\r\n const result: ArrowMarkerState = Object.assign({\r\n arrowType: this.arrowType\r\n }, super.getState());\r\n result.typeName = ArrowMarker.typeName;\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Restores previously saved marker state.\r\n * \r\n * @param state - previously saved state.\r\n */\r\n public restoreState(state: MarkerBaseState): void {\r\n super.restoreState(state);\r\n\r\n const amState = state as ArrowMarkerState;\r\n this.arrowType = amState.arrowType;\r\n\r\n this.createTips();\r\n this.adjustVisual();\r\n }\r\n\r\n}\r\n","import Icon from './cover-marker-icon.svg';\r\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\r\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\r\nimport { Settings } from '../../core/Settings';\r\nimport { RectangleMarker } from '../RectangleMarker';\r\nimport { RectangleMarkerState } from '../RectangleMarkerState';\r\n\r\nexport class CoverMarker extends RectangleMarker {\r\n /**\r\n * String type name of the marker type. \r\n * \r\n * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\r\n */\r\n public static typeName = 'CoverMarker';\r\n\r\n /**\r\n * Marker type title (display name) used for accessibility and other attributes.\r\n */\r\n public static title = 'Cover marker';\r\n /**\r\n * SVG icon markup displayed on toolbar buttons.\r\n */\r\n public static icon = Icon;\r\n\r\n /**\r\n * Color picker panel for the background color.\r\n */\r\n protected fillPanel: ColorPickerPanel;\r\n\r\n /**\r\n * Creates a new marker.\r\n *\r\n * @param container - SVG container to hold marker's visual.\r\n * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\r\n * @param settings - settings object containing default markers settings.\r\n */\r\n constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\r\n super(container, overlayContainer, settings);\r\n\r\n this.fillColor = settings.defaultFillColor;\r\n this.strokeWidth = 0;\r\n\r\n this.fillPanel = new ColorPickerPanel(\r\n 'Color',\r\n settings.defaultColorSet,\r\n settings.defaultFillColor\r\n );\r\n this.fillPanel.onColorChanged = this.setFillColor;\r\n }\r\n\r\n /**\r\n * Returns the list of toolbox panels for this marker type.\r\n */\r\n public get toolboxPanels(): ToolboxPanel[] {\r\n return [this.fillPanel];\r\n }\r\n\r\n /**\r\n * Returns current marker state that can be restored in the future.\r\n */\r\n public getState(): RectangleMarkerState {\r\n const result = super.getState();\r\n result.typeName = CoverMarker.typeName;\r\n return result;\r\n }\r\n}\r\n","import { ToolboxPanel } from '../ToolboxPanel';\r\nimport Icon from './opacity-panel-icon.svg';\r\n\r\n/**\r\n * Opacity chage event handler type.\r\n */\r\nexport type OpacityChangeHandler = (newOpacity: number) => void;\r\n\r\n/**\r\n * Opacity panel.\r\n */\r\nexport class OpacityPanel extends ToolboxPanel {\r\n private opacities: number[] = [];\r\n private currentOpacity?: number;\r\n\r\n private opacityBoxes: HTMLDivElement[] = [];\r\n\r\n /**\r\n * Opacity change event handler.\r\n */\r\n public onOpacityChanged?: OpacityChangeHandler;\r\n\r\n /**\r\n * Creates an opacity panel.\r\n * @param title - panel title.\r\n * @param opacities - available opacities.\r\n * @param currentOpacity - current opacity.\r\n * @param icon - toolbox panel button (SVG image markup).\r\n */\r\n constructor(title: string, opacities: number[], currentOpacity?: number, icon?: string) {\r\n super(title, icon ? icon : Icon);\r\n this.opacities = opacities;\r\n this.currentOpacity = currentOpacity;\r\n\r\n this._id = 'opacity-panel';\r\n\r\n this.setCurrentOpacity = this.setCurrentOpacity.bind(this);\r\n }\r\n\r\n /**\r\n * Returns panel UI.\r\n */\r\n public getUi(): HTMLDivElement {\r\n const panelDiv = document.createElement('div');\r\n panelDiv.style.display = 'flex';\r\n panelDiv.style.overflow = 'hidden';\r\n panelDiv.style.flexGrow = '2';\r\n panelDiv.style.justifyContent = 'space-between';\r\n this.opacities.forEach((opacity) => {\r\n const opacityBoxContainer = document.createElement('div');\r\n opacityBoxContainer.style.display = 'flex';\r\n //opacityBoxContainer.style.flexGrow = '2';\r\n opacityBoxContainer.style.alignItems = 'center';\r\n opacityBoxContainer.style.justifyContent = 'center';\r\n opacityBoxContainer.style.padding = '5px';\r\n opacityBoxContainer.style.borderWidth = '2px';\r\n opacityBoxContainer.style.borderStyle = 'solid';\r\n opacityBoxContainer.style.borderColor =\r\n opacity === this.currentOpacity ? this.uiStyleSettings.toolboxAccentColor : 'transparent';\r\n\r\n opacityBoxContainer.addEventListener('click', () => {\r\n this.setCurrentOpacity(opacity, opacityBoxContainer);\r\n })\r\n panelDiv.appendChild(opacityBoxContainer);\r\n\r\n const label = document.createElement('div');\r\n label.innerText = `${(opacity * 100)}%`;\r\n opacityBoxContainer.appendChild(label);\r\n\r\n this.opacityBoxes.push(opacityBoxContainer);\r\n });\r\n return panelDiv;\r\n }\r\n\r\n private setCurrentOpacity(newWidth: number, target: HTMLDivElement) {\r\n this.currentOpacity = newWidth;\r\n\r\n this.opacityBoxes.forEach(box => {\r\n box.style.borderColor = box === target ? this.uiStyleSettings.toolboxAccentColor : 'transparent';\r\n });\r\n\r\n if (this.onOpacityChanged) {\r\n this.onOpacityChanged(this.currentOpacity);\r\n }\r\n }\r\n}\r\n","import Icon from './highlight-marker-icon.svg';\r\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\r\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\r\nimport { Settings } from '../../core/Settings';\r\nimport { CoverMarker } from '../cover-marker/CoverMarker';\r\nimport { OpacityPanel } from '../../ui/toolbox-panels/OpacityPanel';\r\nimport { SvgHelper } from '../../core/SvgHelper';\r\nimport { RectangleMarkerState } from '../RectangleMarkerState';\r\n\r\nexport class HighlightMarker extends CoverMarker {\r\n /**\r\n * String type name of the marker type. \r\n * \r\n * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\r\n */\r\n public static typeName = 'HighlightMarker';\r\n /**\r\n * Marker type title (display name) used for accessibility and other attributes.\r\n */\r\n public static title = 'Highlight marker';\r\n /**\r\n * SVG icon markup displayed on toolbar buttons.\r\n */\r\n public static icon = Icon;\r\n\r\n protected opacityPanel: OpacityPanel;\r\n\r\n /**\r\n * Creates a new marker.\r\n *\r\n * @param container - SVG container to hold marker's visual.\r\n * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\r\n * @param settings - settings object containing default markers settings.\r\n */\r\n constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\r\n super(container, overlayContainer, settings);\r\n\r\n this.setOpacity = this.setOpacity.bind(this);\r\n\r\n this.fillColor = settings.defaultHighlightColor;\r\n this.strokeWidth = 0;\r\n this.opacity = settings.defaultHighlightOpacity;\r\n\r\n this.fillPanel = new ColorPickerPanel(\r\n 'Color',\r\n settings.defaultColorSet,\r\n this.fillColor\r\n );\r\n this.fillPanel.onColorChanged = this.setFillColor;\r\n\r\n this.opacityPanel = new OpacityPanel(\r\n 'Opacity',\r\n settings.defaultOpacitySteps,\r\n this.opacity\r\n );\r\n this.opacityPanel.onOpacityChanged = this.setOpacity;\r\n }\r\n\r\n /**\r\n * Sets marker's opacity (0..1).\r\n * @param opacity - new opacity value.\r\n */\r\n protected setOpacity(opacity: number): void {\r\n this.opacity = opacity;\r\n if (this.visual) {\r\n SvgHelper.setAttributes(this.visual, [['opacity', this.opacity.toString()]]);\r\n }\r\n this.stateChanged();\r\n }\r\n\r\n /**\r\n * Returns the list of toolbox panels for this marker type.\r\n */\r\n public get toolboxPanels(): ToolboxPanel[] {\r\n return [this.fillPanel, this.opacityPanel];\r\n }\r\n\r\n /**\r\n * Returns current marker state that can be restored in the future.\r\n */\r\n public getState(): RectangleMarkerState {\r\n const result = super.getState();\r\n result.typeName = HighlightMarker.typeName;\r\n return result;\r\n }\r\n}\r\n","import { IPoint } from '../../core/IPoint';\r\nimport { SvgHelper } from '../../core/SvgHelper';\r\nimport { Settings } from '../../core/Settings';\r\nimport Icon from './callout-marker-icon.svg';\r\nimport TextColorIcon from '../../ui/toolbox-panels/text-color-icon.svg';\r\nimport FillColorIcon from '../../ui/toolbox-panels/fill-color-icon.svg';\r\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\r\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\r\nimport { FontFamilyPanel } from '../../ui/toolbox-panels/FontFamilyPanel';\r\nimport { TextMarker } from '../text-marker/TextMarker';\r\nimport { ResizeGrip } from '../ResizeGrip';\r\nimport { CalloutMarkerState } from './CalloutMarkerState';\r\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\r\n\r\nexport class CalloutMarker extends TextMarker {\r\n /**\r\n * String type name of the marker type. \r\n * \r\n * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\r\n */\r\n public static typeName = 'CalloutMarker';\r\n\r\n /**\r\n * Marker type title (display name) used for accessibility and other attributes.\r\n */\r\n public static title = 'Callout marker';\r\n /**\r\n * SVG icon markup displayed on toolbar buttons.\r\n */\r\n public static icon = Icon;\r\n\r\n private bgColor = 'transparent';\r\n /**\r\n * Color picker toolbox panel for the background (fill) color.\r\n */\r\n protected bgColorPanel: ColorPickerPanel;\r\n\r\n private tipPosition: IPoint = { x: 0, y: 0 };\r\n private tipBase1Position: IPoint = { x: 0, y: 0 };\r\n private tipBase2Position: IPoint = { x: 0, y: 0 };\r\n private tip: SVGPolygonElement;\r\n private tipGrip: ResizeGrip;\r\n private tipMoving = false;\r\n\r\n /**\r\n * Creates a new marker.\r\n *\r\n * @param container - SVG container to hold marker's visual.\r\n * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\r\n * @param settings - settings object containing default markers settings.\r\n */\r\n constructor(\r\n container: SVGGElement,\r\n overlayContainer: HTMLDivElement,\r\n settings: Settings\r\n ) {\r\n super(container, overlayContainer, settings);\r\n\r\n this.color = settings.defaultStrokeColor;\r\n this.bgColor = settings.defaultFillColor;\r\n this.fontFamily = settings.defaultFontFamily;\r\n\r\n this.defaultSize = { x: 100, y: 30 };\r\n\r\n this.setBgColor = this.setBgColor.bind(this);\r\n this.getTipPoints = this.getTipPoints.bind(this);\r\n this.positionTip = this.positionTip.bind(this);\r\n this.setTipPoints = this.setTipPoints.bind(this);\r\n\r\n this.colorPanel = new ColorPickerPanel(\r\n 'Text color',\r\n settings.defaultColorSet,\r\n this.color,\r\n TextColorIcon\r\n );\r\n this.colorPanel.onColorChanged = this.setColor;\r\n\r\n this.bgColorPanel = new ColorPickerPanel(\r\n 'Fill color',\r\n settings.defaultColorSet,\r\n this.bgColor,\r\n FillColorIcon\r\n );\r\n this.bgColorPanel.onColorChanged = this.setBgColor;\r\n\r\n this.fontFamilyPanel = new FontFamilyPanel(\r\n 'Font',\r\n settings.defaultFontFamilies,\r\n settings.defaultFontFamily\r\n );\r\n this.fontFamilyPanel.onFontChanged = this.setFont;\r\n\r\n this.tipGrip = new ResizeGrip();\r\n this.tipGrip.visual.transform.baseVal.appendItem(\r\n SvgHelper.createTransform()\r\n );\r\n this.controlBox.appendChild(this.tipGrip.visual);\r\n }\r\n\r\n /**\r\n * Returns true if passed SVG element belongs to the marker. False otherwise.\r\n * \r\n * @param el - target element.\r\n */\r\n public ownsTarget(el: EventTarget): boolean {\r\n return (\r\n super.ownsTarget(el) || this.tipGrip.ownsTarget(el) || this.tip === el\r\n );\r\n }\r\n\r\n private createTip() {\r\n SvgHelper.setAttributes(this.bgRectangle, [\r\n ['fill', this.bgColor],\r\n ['rx', '10px'],\r\n ]);\r\n\r\n this.tip = SvgHelper.createPolygon(this.getTipPoints(), [\r\n ['fill', this.bgColor],\r\n ]);\r\n this.visual.appendChild(this.tip);\r\n }\r\n\r\n /**\r\n * Handles pointer (mouse, touch, stylus, etc.) down event.\r\n * \r\n * @param point - event coordinates.\r\n * @param target - direct event target element.\r\n */\r\n public pointerDown(point: IPoint, target?: EventTarget): void {\r\n if (this.state === 'new') {\r\n super.pointerDown(point, target);\r\n }\r\n\r\n if (this.state === 'creating') {\r\n this.createTip();\r\n } else if (this.tipGrip.ownsTarget(target)) {\r\n this.manipulationStartLeft = this.left;\r\n this.manipulationStartTop = this.top;\r\n this.tipMoving = true;\r\n } else {\r\n super.pointerDown(point, target);\r\n }\r\n }\r\n\r\n /**\r\n * Handles pointer (mouse, touch, stylus, etc.) up event.\r\n * \r\n * @param point - event coordinates.\r\n */\r\n public pointerUp(point: IPoint): void {\r\n if (this.tipMoving) {\r\n this.tipMoving = false;\r\n this.isMoved = true;\r\n super.pointerUp(point);\r\n } else {\r\n const isCreating = this.state === 'creating';\r\n super.pointerUp(point);\r\n this.setTipPoints(isCreating);\r\n this.positionTip();\r\n }\r\n }\r\n\r\n /**\r\n * Handles marker manipulation (move, resize, rotate, etc.).\r\n * \r\n * @param point - event coordinates.\r\n */\r\n public manipulate(point: IPoint): void {\r\n if (this.tipMoving) {\r\n const rotatedPoint = this.unrotatePoint(point);\r\n this.tipPosition = {\r\n x: rotatedPoint.x - this.manipulationStartLeft,\r\n y: rotatedPoint.y - this.manipulationStartTop,\r\n };\r\n this.positionTip();\r\n } else {\r\n super.manipulate(point);\r\n }\r\n }\r\n\r\n /**\r\n * Sets marker's background/fill color.\r\n * @param color - new background color.\r\n */\r\n protected setBgColor(color: string): void {\r\n if (this.bgRectangle && this.tip) {\r\n SvgHelper.setAttributes(this.bgRectangle, [['fill', color]]);\r\n SvgHelper.setAttributes(this.tip, [['fill', color]]);\r\n }\r\n this.bgColor = color;\r\n this.fillColorChanged(color);\r\n }\r\n\r\n private getTipPoints(): string {\r\n this.setTipPoints(this.state === 'creating');\r\n return `${this.tipBase1Position.x},${this.tipBase1Position.y\r\n } ${this.tipBase2Position.x},${this.tipBase2Position.y\r\n } ${this.tipPosition.x},${this.tipPosition.y}`;\r\n }\r\n\r\n private setTipPoints(isCreating = false) {\r\n let offset = Math.min(this.height / 2, 15);\r\n let baseWidth = this.height / 5;\r\n if (isCreating) {\r\n this.tipPosition = { x: offset + baseWidth / 2, y: this.height + 20 };\r\n }\r\n\r\n const cornerAngle = Math.atan((this.height / 2) / (this.width / 2));\r\n if (this.tipPosition.x < this.width / 2 && this.tipPosition.y < this.height / 2) {\r\n // top left\r\n const tipAngle = Math.atan((this.height / 2 - this.tipPosition.y) / (this.width / 2 - this.tipPosition.x));\r\n if (cornerAngle < tipAngle) {\r\n baseWidth = this.width / 5;\r\n offset = Math.min(this.width / 2, 15);\r\n this.tipBase1Position = { x: offset, y: 0 };\r\n this.tipBase2Position = { x: offset + baseWidth, y: 0 };\r\n } else {\r\n this.tipBase1Position = { x: 0, y: offset };\r\n this.tipBase2Position = { x: 0, y: offset + baseWidth };\r\n }\r\n } else if (this.tipPosition.x >= this.width / 2 && this.tipPosition.y < this.height / 2) {\r\n // top right\r\n const tipAngle = Math.atan((this.height / 2 - this.tipPosition.y) / (this.tipPosition.x - this.width / 2));\r\n if (cornerAngle < tipAngle) {\r\n baseWidth = this.width / 5;\r\n offset = Math.min(this.width / 2, 15);\r\n this.tipBase1Position = { x: this.width - offset - baseWidth, y: 0 };\r\n this.tipBase2Position = { x: this.width - offset, y: 0 };\r\n } else {\r\n this.tipBase1Position = { x: this.width, y: offset };\r\n this.tipBase2Position = { x: this.width, y: offset + baseWidth };\r\n }\r\n } else if (this.tipPosition.x >= this.width / 2 && this.tipPosition.y >= this.height / 2) {\r\n // bottom right\r\n const tipAngle = Math.atan((this.tipPosition.y - this.height / 2) / (this.tipPosition.x - this.width / 2));\r\n if (cornerAngle < tipAngle) {\r\n baseWidth = this.width / 5;\r\n offset = Math.min(this.width / 2, 15);\r\n this.tipBase1Position = { x: this.width - offset - baseWidth, y: this.height };\r\n this.tipBase2Position = { x: this.width - offset, y: this.height };\r\n } else {\r\n this.tipBase1Position = { x: this.width, y: this.height - offset - baseWidth };\r\n this.tipBase2Position = { x: this.width, y: this.height - offset };\r\n }\r\n } else {\r\n // bottom left\r\n const tipAngle = Math.atan((this.tipPosition.y - this.height / 2) / (this.width / 2 - this.tipPosition.x));\r\n if (cornerAngle < tipAngle) {\r\n baseWidth = this.width / 5;\r\n offset = Math.min(this.width / 2, 15);\r\n this.tipBase1Position = { x: offset, y: this.height };\r\n this.tipBase2Position = { x: offset + baseWidth, y: this.height };\r\n } else {\r\n this.tipBase1Position = { x: 0, y: this.height - offset };\r\n this.tipBase2Position = { x: 0, y: this.height - offset - baseWidth };\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Resize marker based on current pointer coordinates and context.\r\n * @param point \r\n */\r\n protected resize(point: IPoint): void {\r\n super.resize(point);\r\n this.positionTip();\r\n }\r\n\r\n private positionTip() {\r\n SvgHelper.setAttributes(this.tip, [['points', this.getTipPoints()]]);\r\n const translate = this.tipGrip.visual.transform.baseVal.getItem(0);\r\n translate.setTranslate(this.tipPosition.x, this.tipPosition.y);\r\n this.tipGrip.visual.transform.baseVal.replaceItem(translate, 0);\r\n }\r\n\r\n /**\r\n * Returns the list of toolbox panels for this marker type.\r\n */\r\n public get toolboxPanels(): ToolboxPanel[] {\r\n return [this.colorPanel, this.bgColorPanel, this.fontFamilyPanel];\r\n }\r\n\r\n /**\r\n * Selects this marker and displays appropriate selected marker UI.\r\n */\r\n public select(): void {\r\n this.positionTip();\r\n super.select();\r\n }\r\n\r\n /**\r\n * Returns current marker state that can be restored in the future.\r\n */\r\n public getState(): CalloutMarkerState {\r\n const result: CalloutMarkerState = Object.assign({\r\n bgColor: this.bgColor,\r\n tipPosition: this.tipPosition\r\n }, super.getState());\r\n result.typeName = CalloutMarker.typeName;\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Restores previously saved marker state.\r\n * \r\n * @param state - previously saved state.\r\n */\r\n public restoreState(state: MarkerBaseState): void {\r\n const calloutState = state as CalloutMarkerState;\r\n this.bgColor = calloutState.bgColor;\r\n this.tipPosition = calloutState.tipPosition;\r\n\r\n super.restoreState(state);\r\n this.createTip();\r\n this.setTipPoints();\r\n }\r\n\r\n /**\r\n * Scales marker. Used after the image resize.\r\n * \r\n * @param scaleX - horizontal scale\r\n * @param scaleY - vertical scale\r\n */\r\n public scale(scaleX: number, scaleY: number): void {\r\n super.scale(scaleX, scaleY);\r\n\r\n this.tipPosition = {x: this.tipPosition.x * scaleX, y: this.tipPosition.y * scaleY};\r\n\r\n this.positionTip();\r\n }\r\n}\r\n","import Icon from './ellipse-marker-icon.svg';\r\nimport { IPoint } from '../../core/IPoint';\r\nimport { SvgHelper } from '../../core/SvgHelper';\r\nimport { RectangularBoxMarkerBase } from '../RectangularBoxMarkerBase';\r\nimport { Settings } from '../../core/Settings';\r\nimport { RectangleMarkerState } from '../RectangleMarkerState';\r\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\r\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\r\nimport { LineWidthPanel } from '../../ui/toolbox-panels/LineWidthPanel';\r\nimport { LineStylePanel } from '../../ui/toolbox-panels/LineStylePanel';\r\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\r\nimport FillColorIcon from '../../ui/toolbox-panels/fill-color-icon.svg';\r\nimport { OpacityPanel } from '../../ui/toolbox-panels/OpacityPanel';\r\n\r\nexport class EllipseMarker extends RectangularBoxMarkerBase {\r\n /**\r\n * String type name of the marker type. \r\n * \r\n * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\r\n */\r\n public static typeName = 'EllipseMarker';\r\n /**\r\n * Marker type title (display name) used for accessibility and other attributes.\r\n */\r\n public static title = 'Ellipse marker';\r\n /**\r\n * SVG icon markup displayed on toolbar buttons.\r\n */\r\n public static icon = Icon;\r\n\r\n /**\r\n * Ellipse fill color.\r\n */\r\n protected fillColor = 'transparent';\r\n /**\r\n * Ellipse border color.\r\n */\r\n protected strokeColor = 'transparent';\r\n /**\r\n * Ellipse border line width.\r\n */\r\n protected strokeWidth = 0;\r\n /**\r\n * Ellipse border dash array.\r\n */\r\n protected strokeDasharray = '';\r\n /**\r\n * Ellipse opacity (0..1).\r\n */\r\n protected opacity = 1;\r\n\r\n protected strokePanel: ColorPickerPanel;\r\n protected fillPanel: ColorPickerPanel;\r\n protected strokeWidthPanel: LineWidthPanel;\r\n protected strokeStylePanel: LineStylePanel;\r\n protected opacityPanel: OpacityPanel;\r\n\r\n /**\r\n * Creates a new marker.\r\n *\r\n * @param container - SVG container to hold marker's visual.\r\n * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\r\n * @param settings - settings object containing default markers settings.\r\n */\r\n constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\r\n super(container, overlayContainer, settings);\r\n\r\n this.strokeColor = settings.defaultColor;\r\n this.strokeWidth = settings.defaultStrokeWidth;\r\n this.strokeDasharray = settings.defaultStrokeDasharray;\r\n this.fillColor = settings.defaultFillColor;\r\n\r\n this.setStrokeColor = this.setStrokeColor.bind(this);\r\n this.setFillColor = this.setFillColor.bind(this);\r\n this.setStrokeWidth = this.setStrokeWidth.bind(this);\r\n this.setStrokeDasharray = this.setStrokeDasharray.bind(this);\r\n this.setOpacity = this.setOpacity.bind(this);\r\n this.createVisual = this.createVisual.bind(this);\r\n\r\n this.strokePanel = new ColorPickerPanel(\r\n 'Line color',\r\n [...settings.defaultColorSet, 'transparent'],\r\n settings.defaultColor\r\n );\r\n this.strokePanel.onColorChanged = this.setStrokeColor;\r\n\r\n this.fillPanel = new ColorPickerPanel(\r\n 'Fill color',\r\n [...settings.defaultColorSet, 'transparent'],\r\n this.fillColor,\r\n FillColorIcon\r\n );\r\n this.fillPanel.onColorChanged = this.setFillColor;\r\n\r\n this.strokeWidthPanel = new LineWidthPanel(\r\n 'Line width',\r\n settings.defaultStrokeWidths,\r\n settings.defaultStrokeWidth\r\n );\r\n this.strokeWidthPanel.onWidthChanged = this.setStrokeWidth;\r\n\r\n this.strokeStylePanel = new LineStylePanel(\r\n 'Line style',\r\n settings.defaultStrokeDasharrays,\r\n settings.defaultStrokeDasharray\r\n );\r\n this.strokeStylePanel.onStyleChanged = this.setStrokeDasharray;\r\n\r\n this.opacityPanel = new OpacityPanel(\r\n 'Opacity',\r\n settings.defaultOpacitySteps,\r\n this.opacity\r\n );\r\n this.opacityPanel.onOpacityChanged = this.setOpacity;\r\n }\r\n\r\n /**\r\n * Returns true if passed SVG element belongs to the marker. False otherwise.\r\n * \r\n * @param el - target element.\r\n */\r\n public ownsTarget(el: EventTarget): boolean {\r\n if (super.ownsTarget(el) || el === this.visual) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Creates marker visual.\r\n */\r\n protected createVisual(): void {\r\n this.visual = SvgHelper.createEllipse(this.width / 2, this.height / 2, [\r\n ['fill', this.fillColor],\r\n ['stroke', this.strokeColor],\r\n ['stroke-width', this.strokeWidth.toString()],\r\n ['stroke-dasharray', this.strokeDasharray],\r\n ['opacity', this.opacity.toString()]\r\n ]);\r\n this.addMarkerVisualToContainer(this.visual);\r\n }\r\n\r\n /**\r\n * Handles pointer (mouse, touch, stylus, etc.) down event.\r\n * \r\n * @param point - event coordinates.\r\n * @param target - direct event target element.\r\n */\r\n public pointerDown(point: IPoint, target?: EventTarget): void {\r\n super.pointerDown(point, target);\r\n if (this.state === 'new') {\r\n this.createVisual();\r\n\r\n this.moveVisual(point);\r\n\r\n this._state = 'creating';\r\n }\r\n }\r\n\r\n /**\r\n * Handles marker manipulation (move, resize, rotate, etc.).\r\n * \r\n * @param point - event coordinates.\r\n */\r\n public manipulate(point: IPoint): void {\r\n super.manipulate(point);\r\n }\r\n\r\n /**\r\n * Resize marker based on current pointer coordinates and context.\r\n * @param point \r\n */\r\n protected resize(point: IPoint): void {\r\n super.resize(point);\r\n this.setSize();\r\n }\r\n\r\n /**\r\n * Sets marker's visual size after manipulation.\r\n */\r\n protected setSize(): void {\r\n super.setSize();\r\n SvgHelper.setAttributes(this.visual, [\r\n ['cx', (this.width / 2).toString()],\r\n ['cy', (this.height / 2).toString()],\r\n ['rx', (this.width / 2).toString()],\r\n ['ry', (this.height / 2).toString()],\r\n ]);\r\n }\r\n\r\n /**\r\n * Handles pointer (mouse, touch, stylus, etc.) up event.\r\n * \r\n * @param point - event coordinates.\r\n */\r\n public pointerUp(point: IPoint): void {\r\n super.pointerUp(point);\r\n this.setSize();\r\n }\r\n\r\n /**\r\n * Sets marker's line color.\r\n * @param color - new line color.\r\n */\r\n protected setStrokeColor(color: string): void {\r\n this.strokeColor = color;\r\n if (this.visual) {\r\n SvgHelper.setAttributes(this.visual, [['stroke', this.strokeColor]]);\r\n }\r\n this.colorChanged(color);\r\n this.stateChanged();\r\n }\r\n /**\r\n * Sets marker's fill (background) color.\r\n * @param color - new fill color.\r\n */\r\n protected setFillColor(color: string): void {\r\n this.fillColor = color;\r\n if (this.visual) {\r\n SvgHelper.setAttributes(this.visual, [['fill', this.fillColor]]);\r\n }\r\n this.fillColorChanged(color);\r\n this.stateChanged();\r\n }\r\n /**\r\n * Sets marker's line width.\r\n * @param width - new line width\r\n */\r\n protected setStrokeWidth(width: number): void {\r\n this.strokeWidth = width;\r\n if (this.visual) {\r\n SvgHelper.setAttributes(this.visual, [['stroke-width', this.strokeWidth.toString()]]);\r\n }\r\n this.stateChanged();\r\n }\r\n /**\r\n * Sets marker's border dash array.\r\n * @param dashes - new dash array.\r\n */\r\n protected setStrokeDasharray(dashes: string): void {\r\n this.strokeDasharray = dashes;\r\n if (this.visual) {\r\n SvgHelper.setAttributes(this.visual, [['stroke-dasharray', this.strokeDasharray]]);\r\n }\r\n this.stateChanged();\r\n }\r\n /**\r\n * Sets marker's opacity.\r\n * @param opacity - new opacity value (0..1).\r\n */\r\n protected setOpacity(opacity: number): void {\r\n this.opacity = opacity;\r\n if (this.visual) {\r\n SvgHelper.setAttributes(this.visual, [['opacity', this.opacity.toString()]]);\r\n }\r\n this.stateChanged();\r\n }\r\n\r\n /**\r\n * Returns the list of toolbox panels for this marker type.\r\n */\r\n public get toolboxPanels(): ToolboxPanel[] {\r\n return [this.strokePanel, this.fillPanel, this.strokeWidthPanel, this.strokeStylePanel, this.opacityPanel];\r\n }\r\n\r\n /**\r\n * Returns current marker state that can be restored in the future.\r\n */\r\n public getState(): RectangleMarkerState {\r\n const result: RectangleMarkerState = Object.assign({\r\n fillColor: this.fillColor,\r\n strokeColor: this.strokeColor,\r\n strokeWidth: this.strokeWidth,\r\n strokeDasharray: this.strokeDasharray,\r\n opacity: this.opacity\r\n }, super.getState());\r\n result.typeName = EllipseMarker.typeName;\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Restores previously saved marker state.\r\n * \r\n * @param state - previously saved state.\r\n */\r\n public restoreState(state: MarkerBaseState): void {\r\n const rectState = state as RectangleMarkerState;\r\n this.fillColor = rectState.fillColor;\r\n this.strokeColor = rectState.strokeColor;\r\n this.strokeWidth = rectState.strokeWidth;\r\n this.strokeDasharray = rectState.strokeDasharray;\r\n this.opacity = rectState.opacity;\r\n\r\n this.createVisual();\r\n super.restoreState(state);\r\n this.setSize();\r\n }\r\n\r\n /**\r\n * Scales marker. Used after the image resize.\r\n * \r\n * @param scaleX - horizontal scale\r\n * @param scaleY - vertical scale\r\n */\r\n public scale(scaleX: number, scaleY: number): void {\r\n super.scale(scaleX, scaleY);\r\n\r\n this.setSize();\r\n }\r\n}\r\n","import { IPoint } from '../../core/IPoint';\r\nimport { SvgHelper } from '../../core/SvgHelper';\r\nimport { Settings } from '../../core/Settings';\r\nimport Icon from './measurement-marker-icon.svg';\r\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\r\nimport { LineMarker } from '../line-marker/LineMarker';\r\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\r\nimport { LineMarkerState } from '../line-marker/LineMarkerState';\r\n\r\nexport class MeasurementMarker extends LineMarker {\r\n /**\r\n * String type name of the marker type. \r\n * \r\n * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\r\n */\r\n public static typeName = 'MeasurementMarker';\r\n\r\n /**\r\n * Marker type title (display name) used for accessibility and other attributes.\r\n */\r\n public static title = 'Measurement marker';\r\n /**\r\n * SVG icon markup displayed on toolbar buttons.\r\n */\r\n public static icon = Icon;\r\n\r\n private tip1: SVGLineElement;\r\n private tip2: SVGLineElement;\r\n\r\n private get tipLength(): number {\r\n return 10 + this.strokeWidth * 3;\r\n }\r\n\r\n /**\r\n * Creates a new marker.\r\n *\r\n * @param container - SVG container to hold marker's visual.\r\n * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\r\n * @param settings - settings object containing default markers settings.\r\n */\r\n constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\r\n super(container, overlayContainer, settings);\r\n }\r\n\r\n /**\r\n * Returns true if passed SVG element belongs to the marker. False otherwise.\r\n * \r\n * @param el - target element.\r\n */\r\n public ownsTarget(el: EventTarget): boolean {\r\n if (\r\n super.ownsTarget(el) ||\r\n el === this.tip1 || el === this.tip2\r\n ) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n private createTips() {\r\n this.tip1 = SvgHelper.createLine(\r\n this.x1 - this.tipLength / 2, \r\n this.y1, \r\n this.x1 + this.tipLength / 2, \r\n this.y1, \r\n [\r\n ['stroke', this.strokeColor],\r\n ['stroke-width', this.strokeWidth.toString()]\r\n ]);\r\n this.tip1.transform.baseVal.appendItem(SvgHelper.createTransform());\r\n this.visual.appendChild(this.tip1);\r\n\r\n this.tip2 = SvgHelper.createLine(\r\n this.x2 - this.tipLength / 2, \r\n this.y2, \r\n this.x2 + this.tipLength / 2, \r\n this.y2, \r\n [\r\n ['stroke', this.strokeColor],\r\n ['stroke-width', this.strokeWidth.toString()]\r\n ]);\r\n this.tip2.transform.baseVal.appendItem(SvgHelper.createTransform());\r\n this.visual.appendChild(this.tip2);\r\n }\r\n\r\n /**\r\n * Handles pointer (mouse, touch, stylus, etc.) down event.\r\n * \r\n * @param point - event coordinates.\r\n * @param target - direct event target element.\r\n */\r\n public pointerDown(point: IPoint, target?: EventTarget): void {\r\n super.pointerDown(point, target);\r\n if (this.state === 'creating') {\r\n this.createTips();\r\n }\r\n }\r\n\r\n /**\r\n * Adjusts marker visual after manipulation.\r\n */\r\n protected adjustVisual(): void {\r\n super.adjustVisual();\r\n\r\n if (this.tip1 && this.tip2) {\r\n\r\n SvgHelper.setAttributes(this.tip1,[\r\n ['x1', (this.x1 - this.tipLength / 2).toString()], \r\n ['y1', this.y1.toString()], \r\n ['x2', (this.x1 + this.tipLength / 2).toString()], \r\n ['y2', this.y1.toString()], \r\n ['stroke', this.strokeColor],\r\n ['stroke-width', this.strokeWidth.toString()]\r\n ]);\r\n SvgHelper.setAttributes(this.tip2,[\r\n ['x1', (this.x2 - this.tipLength / 2).toString()], \r\n ['y1', this.y2.toString()], \r\n ['x2', (this.x2 + this.tipLength / 2).toString()], \r\n ['y2', this.y2.toString()], \r\n ['stroke', this.strokeColor],\r\n ['stroke-width', this.strokeWidth.toString()]\r\n ]);\r\n\r\n if (Math.abs(this.x1 - this.x2) > 0.1) {\r\n const lineAngle1 =\r\n (Math.atan((this.y2 - this.y1) / (this.x2 - this.x1)) * 180) / Math.PI + 90 * Math.sign(this.x1 - this.x2);\r\n\r\n const a1transform = this.tip1.transform.baseVal.getItem(0);\r\n a1transform.setRotate(lineAngle1, this.x1, this.y1);\r\n this.tip1.transform.baseVal.replaceItem(a1transform, 0);\r\n\r\n const a2transform = this.tip2.transform.baseVal.getItem(0);\r\n a2transform.setRotate(lineAngle1 + 180, this.x2, this.y2);\r\n this.tip2.transform.baseVal.replaceItem(a2transform, 0);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Returns the list of toolbox panels for this marker type.\r\n */\r\n public get toolboxPanels(): ToolboxPanel[] {\r\n return [this.strokePanel, this.strokeWidthPanel, this.strokeStylePanel];\r\n }\r\n\r\n /**\r\n * Returns current marker state that can be restored in the future.\r\n */\r\n public getState(): LineMarkerState {\r\n const result =super.getState();\r\n result.typeName = MeasurementMarker.typeName;\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Restores previously saved marker state.\r\n * \r\n * @param state - previously saved state.\r\n */\r\n public restoreState(state: MarkerBaseState): void {\r\n super.restoreState(state);\r\n\r\n this.createTips();\r\n this.adjustVisual();\r\n }\r\n}\r\n","import Icon from './ellipse-frame-marker-icon.svg';\r\nimport { Settings } from '../../core/Settings';\r\nimport { RectangleMarkerState } from '../RectangleMarkerState';\r\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\r\nimport { EllipseMarker } from '../ellipse-marker/EllipseMarker';\r\n\r\nexport class EllipseFrameMarker extends EllipseMarker {\r\n /**\r\n * String type name of the marker type. \r\n * \r\n * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\r\n */\r\n public static typeName = 'EllipseFrameMarker';\r\n /**\r\n * Marker type title (display name) used for accessibility and other attributes.\r\n */\r\n public static title = 'Ellipse frame marker';\r\n /**\r\n * SVG icon markup displayed on toolbar buttons.\r\n */\r\n public static icon = Icon;\r\n\r\n /**\r\n * Creates a new marker.\r\n *\r\n * @param container - SVG container to hold marker's visual.\r\n * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\r\n * @param settings - settings object containing default markers settings.\r\n */\r\n constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\r\n super(container, overlayContainer, settings);\r\n\r\n // reset colors so 'transparent' is excluded\r\n this.strokePanel.colors= settings.defaultColorSet;\r\n\r\n this.fillColor = 'transparent';\r\n }\r\n\r\n /**\r\n * Returns the list of toolbox panels for this marker type.\r\n */\r\n public get toolboxPanels(): ToolboxPanel[] {\r\n return [this.strokePanel, this.strokeWidthPanel, this.strokeStylePanel];\r\n }\r\n\r\n /**\r\n * Returns current marker state that can be restored in the future.\r\n */\r\n public getState(): RectangleMarkerState {\r\n const result = super.getState();\r\n result.typeName = EllipseFrameMarker.typeName;\r\n return result;\r\n }\r\n}\r\n","/**\r\n * Manages undo and redo stacks.\r\n */\r\nexport class UndoRedoManager<T> {\r\n private undoStack: T[] = [];\r\n private redoStack: T[] = [];\r\n\r\n private lastRedoStep: T;\r\n\r\n /**\r\n * Returns true if there are items in the undo stack.\r\n */\r\n public get isUndoPossible(): boolean {\r\n return this.undoStack.length > 0;\r\n }\r\n\r\n /**\r\n * Returns true if there are items in the redo stack.\r\n */\r\n public get isRedoPossible(): boolean {\r\n return this.redoStack.length > 0;\r\n }\r\n\r\n /**\r\n * Returns the number of items in the undo stack\r\n *\r\n * @since 2.23.0\r\n */\r\n public get undoStepCount(): number {\r\n return this.undoStack.length;\r\n }\r\n\r\n /**\r\n * Returns the number of items in the redo stack\r\n *\r\n * @since 2.23.0\r\n */\r\n public get redoStepCount(): number {\r\n return this.redoStack.length;\r\n }\r\n\r\n /**\r\n * Adds a step to the undo stack.\r\n * @param stepData data representing a state.\r\n */\r\n public addUndoStep(stepData: T): void {\r\n if (\r\n this.undoStack.length === 0 ||\r\n JSON.stringify(this.undoStack[this.undoStack.length - 1]) !==\r\n JSON.stringify(stepData)\r\n ) {\r\n this.undoStack.push(stepData);\r\n if (JSON.stringify(this.lastRedoStep) !== JSON.stringify(stepData)) {\r\n this.redoStack.splice(0, this.redoStack.length);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Replaces the last undo step with step data provided\r\n * @param stepData data representing a state.\r\n */\r\n public replaceLastUndoStep(stepData: T): void {\r\n if (this.undoStack.length > 0) {\r\n this.undoStack[this.undoStack.length - 1] = stepData;\r\n }\r\n }\r\n\r\n /**\r\n * Returns the last step in the undo log\r\n */\r\n public getLastUndoStep(): T | undefined {\r\n if (this.undoStack.length > 0) {\r\n return this.undoStack[this.undoStack.length - 1];\r\n } else {\r\n return undefined;\r\n }\r\n }\r\n\r\n /**\r\n * Returns data for the previous step in the undo stack and adds last step to the redo stack.\r\n * @returns \r\n */\r\n public undo(): T | undefined {\r\n if (this.undoStack.length > 1) {\r\n const lastStep = this.undoStack.pop();\r\n if (lastStep !== undefined) {\r\n this.redoStack.push(lastStep);\r\n }\r\n return this.undoStack.length > 0 ? this.undoStack[this.undoStack.length - 1] : undefined;\r\n }\r\n }\r\n\r\n /**\r\n * Returns most recent item in the redo stack.\r\n * @returns \r\n */\r\n public redo(): T | undefined {\r\n this.lastRedoStep = this.redoStack.pop();\r\n return this.lastRedoStep;\r\n }\r\n}\r\n","import { IPoint } from '../../core/IPoint';\r\nimport { SvgHelper } from '../../core/SvgHelper';\r\nimport { Settings } from '../../core/Settings';\r\nimport { LinearMarkerBase } from '../LinearMarkerBase';\r\nimport Icon from './curve-marker-icon.svg';\r\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\r\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\r\nimport { LineWidthPanel } from '../../ui/toolbox-panels/LineWidthPanel';\r\nimport { LineStylePanel } from '../../ui/toolbox-panels/LineStylePanel';\r\nimport { CurveMarkerState } from './CurveMarkerState';\r\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\r\nimport { ResizeGrip } from '../ResizeGrip';\r\n\r\nexport class CurveMarker extends LinearMarkerBase {\r\n /**\r\n * String type name of the marker type. \r\n * \r\n * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\r\n */\r\n public static typeName = 'CurveMarker';\r\n \r\n /**\r\n * Marker type title (display name) used for accessibility and other attributes.\r\n */\r\n public static title = 'Curve marker';\r\n /**\r\n * SVG icon markup displayed on toolbar buttons.\r\n */\r\n public static icon = Icon;\r\n\r\n /**\r\n * Invisible wider curve to make selection easier/possible.\r\n */\r\n protected selectorCurve: SVGPathElement;\r\n /**\r\n * Visible marker curve.\r\n */\r\n protected visibleCurve: SVGPathElement;\r\n\r\n /**\r\n * Line color.\r\n */\r\n protected strokeColor = 'transparent';\r\n /**\r\n * Line width.\r\n */\r\n protected strokeWidth = 0;\r\n /**\r\n * Line dash array.\r\n */\r\n protected strokeDasharray = '';\r\n\r\n /**\r\n * Color picker panel for line color.\r\n */\r\n protected strokePanel: ColorPickerPanel;\r\n /**\r\n * Line width toolbox panel.\r\n */\r\n protected strokeWidthPanel: LineWidthPanel;\r\n /**\r\n * Line dash array toolbox panel.\r\n */\r\n protected strokeStylePanel: LineStylePanel;\r\n\r\n private curveGrip: ResizeGrip;\r\n private curveX = 0;\r\n private curveY = 0;\r\n\r\n private manipulationStartCurveX = 0;\r\n private manipulationStartCurveY = 0;\r\n\r\n private curveControlLine1: SVGLineElement;\r\n private curveControlLine2: SVGLineElement;\r\n\r\n /**\r\n * Creates a new marker.\r\n *\r\n * @param container - SVG container to hold marker's visual.\r\n * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\r\n * @param settings - settings object containing default markers settings.\r\n */\r\n constructor(container: SVGGElement, overlayContainer: HTMLDivElement, settings: Settings) {\r\n super(container, overlayContainer, settings);\r\n\r\n this.setStrokeColor = this.setStrokeColor.bind(this);\r\n this.setStrokeWidth = this.setStrokeWidth.bind(this);\r\n this.setStrokeDasharray = this.setStrokeDasharray.bind(this);\r\n this.positionGrips = this.positionGrips.bind(this);\r\n this.addControlGrips = this.addControlGrips.bind(this);\r\n this.adjustVisual = this.adjustVisual.bind(this);\r\n this.setupControlBox = this.setupControlBox.bind(this);\r\n this.resize = this.resize.bind(this);\r\n\r\n this.strokeColor = settings.defaultColor;\r\n this.strokeWidth = settings.defaultStrokeWidth;\r\n this.strokeDasharray = settings.defaultStrokeDasharray;\r\n\r\n this.strokePanel = new ColorPickerPanel(\r\n 'Line color',\r\n settings.defaultColorSet,\r\n settings.defaultColor\r\n );\r\n this.strokePanel.onColorChanged = this.setStrokeColor;\r\n\r\n this.strokeWidthPanel = new LineWidthPanel(\r\n 'Line width',\r\n settings.defaultStrokeWidths,\r\n settings.defaultStrokeWidth\r\n );\r\n this.strokeWidthPanel.onWidthChanged = this.setStrokeWidth;\r\n\r\n this.strokeStylePanel = new LineStylePanel(\r\n 'Line style',\r\n settings.defaultStrokeDasharrays,\r\n settings.defaultStrokeDasharray\r\n );\r\n this.strokeStylePanel.onStyleChanged = this.setStrokeDasharray;\r\n }\r\n\r\n /**\r\n * Returns true if passed SVG element belongs to the marker. False otherwise.\r\n * \r\n * @param el - target element.\r\n */\r\n public ownsTarget(el: EventTarget): boolean {\r\n if (\r\n super.ownsTarget(el) ||\r\n el === this.visual ||\r\n el === this.selectorCurve ||\r\n el === this.visibleCurve ||\r\n this.curveGrip.ownsTarget(el)\r\n ) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n private getPathD(): string {\r\n const result = `M ${this.x1} ${this.y1} Q ${this.curveX} ${this.curveY}, ${this.x2} ${this.y2}`;\r\n return result;\r\n }\r\n\r\n private createVisual() {\r\n this.visual = SvgHelper.createGroup();\r\n this.selectorCurve = SvgHelper.createPath(\r\n this.getPathD(),\r\n [\r\n ['stroke', 'transparent'],\r\n ['stroke-width', (this.strokeWidth + 10).toString()],\r\n ['fill', 'transparent'],\r\n ]\r\n );\r\n this.visibleCurve = SvgHelper.createPath(\r\n this.getPathD(),\r\n [\r\n ['stroke', this.strokeColor],\r\n ['stroke-width', this.strokeWidth.toString()],\r\n ['fill', 'transparent'],\r\n ]\r\n );\r\n this.visual.appendChild(this.selectorCurve);\r\n this.visual.appendChild(this.visibleCurve);\r\n\r\n this.addMarkerVisualToContainer(this.visual);\r\n }\r\n\r\n /**\r\n * Handles pointer (mouse, touch, stylus, etc.) down event.\r\n * \r\n * @param point - event coordinates.\r\n * @param target - direct event target element.\r\n */\r\n public pointerDown(point: IPoint, target?: EventTarget): void {\r\n super.pointerDown(point, target);\r\n\r\n this.manipulationStartCurveX = this.curveX;\r\n this.manipulationStartCurveY = this.curveY;\r\n if (this.state === 'new') {\r\n this.curveX = point.x;\r\n this.curveY = point.y;\r\n }\r\n\r\n if (this.state === 'new') {\r\n this.createVisual();\r\n this.adjustVisual();\r\n\r\n this._state = 'creating';\r\n } else if (this.curveGrip.ownsTarget(target)) {\r\n this.activeGrip = this.curveGrip;\r\n this._state = 'resize';\r\n }\r\n }\r\n\r\n /**\r\n * Adjusts visual after manipulation.\r\n */\r\n protected adjustVisual(): void {\r\n if (this.selectorCurve && this.visibleCurve) {\r\n this.selectorCurve.setAttribute('d', this.getPathD());\r\n\r\n this.visibleCurve.setAttribute('d', this.getPathD());\r\n\r\n SvgHelper.setAttributes(this.visibleCurve, [['stroke', this.strokeColor]]);\r\n SvgHelper.setAttributes(this.visibleCurve, [['stroke-width', this.strokeWidth.toString()]]);\r\n SvgHelper.setAttributes(this.visibleCurve, [['stroke-dasharray', this.strokeDasharray.toString()]]);\r\n }\r\n }\r\n\r\n /**\r\n * Sets manipulation grips up.\r\n */\r\n protected setupControlBox(): void {\r\n super.setupControlBox();\r\n this.curveControlLine1 = SvgHelper.createLine(\r\n this.x1,\r\n this.y1,\r\n this.curveX,\r\n this.curveY,\r\n [\r\n ['stroke', 'black'],\r\n ['stroke-width', '1'],\r\n ['stroke-opacity', '0.5'],\r\n ['stroke-dasharray', '3, 2'],\r\n ]\r\n );\r\n this.curveControlLine2 = SvgHelper.createLine(\r\n this.x2,\r\n this.y2,\r\n this.curveX,\r\n this.curveY,\r\n [\r\n ['stroke', 'black'],\r\n ['stroke-width', '1'],\r\n ['stroke-opacity', '0.5'],\r\n ['stroke-dasharray', '3, 2'],\r\n ]\r\n );\r\n\r\n this.controlBox.insertBefore(this.curveControlLine1, this.controlBox.firstChild);\r\n this.controlBox.insertBefore(this.curveControlLine2, this.controlBox.firstChild);\r\n }\r\n\r\n /**\r\n * Add manipulation grips to the control box.\r\n */\r\n protected addControlGrips(): void {\r\n this.curveGrip = this.createGrip();\r\n this.curveX = 0;\r\n this.curveY = 0;\r\n super.addControlGrips();\r\n }\r\n\r\n /**\r\n * Positions manipulation grips.\r\n */\r\n protected positionGrips(): void {\r\n super.positionGrips();\r\n const gripSize = this.curveGrip.GRIP_SIZE;\r\n this.positionGrip(this.curveGrip.visual, this.curveX - gripSize / 2, this.curveY - gripSize / 2);\r\n\r\n if (this.curveControlLine1 && this.curveControlLine2) {\r\n this.curveControlLine1.setAttribute('x1', this.x1.toString());\r\n this.curveControlLine1.setAttribute('y1', this.y1.toString());\r\n this.curveControlLine1.setAttribute('x2', this.curveX.toString());\r\n this.curveControlLine1.setAttribute('y2', this.curveY.toString());\r\n\r\n this.curveControlLine2.setAttribute('x1', this.x2.toString());\r\n this.curveControlLine2.setAttribute('y1', this.y2.toString());\r\n this.curveControlLine2.setAttribute('x2', this.curveX.toString());\r\n this.curveControlLine2.setAttribute('y2', this.curveY.toString());\r\n }\r\n }\r\n\r\n /**\r\n * Moves or resizes the marker.\r\n * @param point event coordinates\r\n */\r\n public manipulate(point: IPoint): void {\r\n if (this.state === 'move') {\r\n this.curveX = this.manipulationStartCurveX + point.x - this.manipulationStartX;\r\n this.curveY = this.manipulationStartCurveY + point.y - this.manipulationStartY;\r\n }\r\n super.manipulate(point);\r\n }\r\n\r\n /**\r\n * Resizes the marker.\r\n * @param point event coordinates.\r\n */\r\n protected resize(point: IPoint): void {\r\n if (this.activeGrip === this.curveGrip) {\r\n this.curveX = point.x;\r\n this.curveY = point.y;\r\n }\r\n super.resize(point);\r\n if (this.state === 'creating') {\r\n this.curveX = this.x1 + (this.x2 - this.x1) / 2;\r\n this.curveY = this.y1 + (this.y2 - this.y1) / 2;\r\n }\r\n }\r\n\r\n /**\r\n * Sets line color.\r\n * @param color - new color.\r\n */\r\n protected setStrokeColor(color: string): void {\r\n this.strokeColor = color;\r\n this.adjustVisual();\r\n this.colorChanged(color);\r\n }\r\n /**\r\n * Sets line width.\r\n * @param width - new width.\r\n */\r\n protected setStrokeWidth(width: number): void {\r\n this.strokeWidth = width\r\n this.adjustVisual();\r\n }\r\n\r\n /**\r\n * Sets line dash array.\r\n * @param dashes - new dash array.\r\n */\r\n protected setStrokeDasharray(dashes: string): void {\r\n this.strokeDasharray = dashes;\r\n this.adjustVisual();\r\n }\r\n\r\n /**\r\n * Scales marker. Used after the image resize.\r\n * \r\n * @param scaleX - horizontal scale\r\n * @param scaleY - vertical scale\r\n */\r\n public scale(scaleX: number, scaleY: number): void {\r\n this.curveX = this.curveX * scaleX;\r\n this.curveY = this.curveY * scaleY;\r\n super.scale(scaleX, scaleY);\r\n }\r\n\r\n\r\n /**\r\n * Returns the list of toolbox panels for this marker type.\r\n */\r\n public get toolboxPanels(): ToolboxPanel[] {\r\n return [this.strokePanel, this.strokeWidthPanel, this.strokeStylePanel];\r\n }\r\n\r\n /**\r\n * Returns current marker state that can be restored in the future.\r\n */\r\n public getState(): CurveMarkerState {\r\n const result: CurveMarkerState = Object.assign({\r\n strokeColor: this.strokeColor,\r\n strokeWidth: this.strokeWidth,\r\n strokeDasharray: this.strokeDasharray,\r\n curveX: this.curveX,\r\n curveY: this.curveY\r\n }, super.getState());\r\n result.typeName = CurveMarker.typeName;\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Restores previously saved marker state.\r\n * \r\n * @param state - previously saved state.\r\n */\r\n public restoreState(state: MarkerBaseState): void {\r\n super.restoreState(state);\r\n\r\n const lmState = state as CurveMarkerState;\r\n this.strokeColor = lmState.strokeColor;\r\n this.strokeWidth = lmState.strokeWidth;\r\n this.strokeDasharray = lmState.strokeDasharray;\r\n this.curveX = lmState.curveX;\r\n this.curveY = lmState.curveY;\r\n\r\n this.createVisual();\r\n this.adjustVisual();\r\n }\r\n}\r\n","import Icon from './caption-frame-marker-icon.svg';\r\nimport { IPoint } from '../../core/IPoint';\r\nimport { SvgHelper } from '../../core/SvgHelper';\r\nimport { RectangularBoxMarkerBase } from '../RectangularBoxMarkerBase';\r\nimport { Settings } from '../../core/Settings';\r\nimport { MarkerBaseState } from '../../core/MarkerBaseState';\r\nimport { ColorPickerPanel } from '../../ui/toolbox-panels/ColorPickerPanel';\r\nimport { LineWidthPanel } from '../../ui/toolbox-panels/LineWidthPanel';\r\nimport { LineStylePanel } from '../../ui/toolbox-panels/LineStylePanel';\r\nimport { ToolboxPanel } from '../../ui/ToolboxPanel';\r\nimport FillColorIcon from '../../ui/toolbox-panels/fill-color-icon.svg';\r\nimport TextColorIcon from '../../ui/toolbox-panels/text-color-icon.svg';\r\nimport { FontFamilyPanel } from '../../ui/toolbox-panels/FontFamilyPanel';\r\nimport { CaptionFrameMarkerState } from './CaptionFrameMarkerState';\r\n\r\nexport class CaptionFrameMarker extends RectangularBoxMarkerBase {\r\n /**\r\n * String type name of the marker type.\r\n *\r\n * Used when adding {@link MarkerArea.availableMarkerTypes} via a string and to save and restore state.\r\n */\r\n public static typeName = 'CaptionFrameMarker';\r\n /**\r\n * Marker type title (display name) used for accessibility and other attributes.\r\n */\r\n public static title = 'Caption frame marker';\r\n /**\r\n * SVG icon markup displayed on toolbar buttons.\r\n */\r\n public static icon = Icon;\r\n\r\n /**\r\n * Caption background (fill) color.\r\n */\r\n protected fillColor = 'transparent';\r\n /**\r\n * Frame border color.\r\n */\r\n protected strokeColor = 'transparent';\r\n /**\r\n * Frame border line width.\r\n */\r\n protected strokeWidth = 0;\r\n /**\r\n * Frame border dash array.\r\n */\r\n protected strokeDasharray = '';\r\n /**\r\n * Caption font family.\r\n */\r\n protected fontFamily: string;\r\n /**\r\n * Caption text color.\r\n */\r\n protected textColor = 'transparent';\r\n /**\r\n * Caption font size.\r\n */\r\n protected fontSize = '1rem';\r\n\r\n /**\r\n * Frame stroke color toolbox panel.\r\n */\r\n protected strokePanel: ColorPickerPanel;\r\n /**\r\n * Caption background (fill) color toolbox panel.\r\n */\r\n protected fillPanel: ColorPickerPanel;\r\n /**\r\n * Frame stroke width toolbox panel.\r\n */\r\n protected strokeWidthPanel: LineWidthPanel;\r\n /**\r\n * Frame stroke style toolbox panel.\r\n */\r\n protected strokeStylePanel: LineStylePanel;\r\n /**\r\n * Text font family toolbox panel.\r\n */\r\n protected fontFamilyPanel: FontFamilyPanel;\r\n /**\r\n * Text color picker toolbox panel.\r\n */\r\n protected textColorPanel: ColorPickerPanel;\r\n /**\r\n * True if the marker has moved in the manipulation.\r\n */\r\n protected isMoved = false;\r\n private pointerDownPoint: IPoint;\r\n private pointerDownTimestamp: number;\r\n\r\n /**\r\n * Frame rectangle.\r\n */\r\n protected frame: SVGRectElement;\r\n /**\r\n * Caption background element.\r\n */\r\n protected captionBg: SVGRectElement;\r\n /**\r\n * Caption text element.\r\n */\r\n protected captionElement!: SVGTextElement;\r\n /**\r\n * Caption text.\r\n */\r\n protected captionText = 'Caption';\r\n\r\n /**\r\n * Creates a new marker.\r\n *\r\n * @param container - SVG container to hold marker's visual.\r\n * @param overlayContainer - overlay HTML container to hold additional overlay elements while editing.\r\n * @param settings - settings object containing default markers settings.\r\n */\r\n constructor(\r\n container: SVGGElement,\r\n overlayContainer: HTMLDivElement,\r\n settings: Settings\r\n ) {\r\n super(container, overlayContainer, settings);\r\n\r\n this.strokeColor = settings.defaultColor;\r\n this.strokeWidth = settings.defaultStrokeWidth;\r\n this.strokeDasharray = settings.defaultStrokeDasharray;\r\n this.fillColor = settings.defaultFillColor;\r\n this.textColor = settings.defaultStrokeColor;\r\n this.fontFamily = settings.defaultFontFamily;\r\n this.fontSize = settings.defaultCaptionFontSize;\r\n this.captionText = settings.defaultCaptionText;\r\n\r\n this.setStrokeColor = this.setStrokeColor.bind(this);\r\n this.setFillColor = this.setFillColor.bind(this);\r\n this.setStrokeWidth = this.setStrokeWidth.bind(this);\r\n this.setStrokeDasharray = this.setStrokeDasharray.bind(this);\r\n this.createVisual = this.createVisual.bind(this);\r\n this.sizeCaption = this.sizeCaption.bind(this);\r\n this.setCaptionText = this.setCaptionText.bind(this);\r\n this.showTextEditor = this.showTextEditor.bind(this);\r\n this.positionTextEditor = this.positionTextEditor.bind(this);\r\n this.finishTextEditing = this.finishTextEditing.bind(this);\r\n this.setFont = this.setFont.bind(this);\r\n this.setTextColor = this.setTextColor.bind(this);\r\n\r\n this.strokePanel = new ColorPickerPanel(\r\n 'Line color',\r\n [...settings.defaultColorSet, 'transparent'],\r\n this.strokeColor\r\n );\r\n this.strokePanel.onColorChanged = this.setStrokeColor;\r\n\r\n this.fillPanel = new ColorPickerPanel(\r\n 'Fill color',\r\n [...settings.defaultColorSet, 'transparent'],\r\n this.fillColor,\r\n FillColorIcon\r\n );\r\n this.fillPanel.onColorChanged = this.setFillColor;\r\n\r\n this.strokeWidthPanel = new LineWidthPanel(\r\n 'Line width',\r\n settings.defaultStrokeWidths,\r\n settings.defaultStrokeWidth\r\n );\r\n this.strokeWidthPanel.onWidthChanged = this.setStrokeWidth;\r\n\r\n this.strokeStylePanel = new LineStylePanel(\r\n 'Line style',\r\n settings.defaultStrokeDasharrays,\r\n settings.defaultStrokeDasharray\r\n );\r\n this.strokeStylePanel.onStyleChanged = this.setStrokeDasharray;\r\n\r\n this.fontFamilyPanel = new FontFamilyPanel(\r\n 'Font',\r\n settings.defaultFontFamilies,\r\n settings.defaultFontFamily\r\n );\r\n this.fontFamilyPanel.onFontChanged = this.setFont;\r\n\r\n this.textColorPanel = new ColorPickerPanel(\r\n 'Text color',\r\n settings.defaultColorSet,\r\n this.textColor,\r\n TextColorIcon\r\n );\r\n this.textColorPanel.onColorChanged = this.setTextColor;\r\n\r\n }\r\n\r\n /**\r\n * Returns true if passed SVG element belongs to the marker. False otherwise.\r\n *\r\n * @param el - target element.\r\n */\r\n public ownsTarget(el: EventTarget): boolean {\r\n if (\r\n super.ownsTarget(el) ||\r\n el === this.visual ||\r\n el === this.frame ||\r\n el === this.captionBg ||\r\n el === this.captionElement\r\n ) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Creates marker visual.\r\n */\r\n protected createVisual(): void {\r\n this.visual = SvgHelper.createGroup();\r\n this.addMarkerVisualToContainer(this.visual);\r\n\r\n this.captionBg = SvgHelper.createRect(1, 1, [['fill', this.fillColor]]);\r\n this.visual.appendChild(this.captionBg);\r\n\r\n this.captionElement = SvgHelper.createText([\r\n ['fill', this.textColor],\r\n ['font-family', this.fontFamily],\r\n ]);\r\n this.captionElement.style.fontSize = this.fontSize;\r\n this.captionElement.style.textAnchor = 'start';\r\n this.captionElement.style.dominantBaseline = 'text-before-edge';\r\n this.captionElement.textContent = this.captionText;\r\n this.visual.appendChild(this.captionElement);\r\n\r\n this.frame = SvgHelper.createRect(this.width, this.height, [\r\n ['fill', 'transparent'],\r\n ['stroke', this.strokeColor],\r\n ['stroke-width', this.strokeWidth.toString()],\r\n ['stroke-dasharray', this.strokeDasharray],\r\n ]);\r\n\r\n this.visual.appendChild(this.frame);\r\n this.sizeCaption();\r\n }\r\n\r\n /**\r\n * Sets caption text.\r\n * @param text - new caption text.\r\n */\r\n public setCaptionText(text: string): void {\r\n this.captionText = text;\r\n this.captionElement.textContent = this.captionText;\r\n this.sizeCaption();\r\n }\r\n\r\n /**\r\n * Handles pointer (mouse, touch, stylus, etc.) down event.\r\n *\r\n * @param point - event coordinates.\r\n * @param target - direct event target element.\r\n */\r\n public pointerDown(point: IPoint, target?: EventTarget): void {\r\n super.pointerDown(point, target);\r\n\r\n this.isMoved = false;\r\n this.pointerDownPoint = point;\r\n this.pointerDownTimestamp = Date.now();\r\n\r\n if (this.state === 'new') {\r\n this.createVisual();\r\n\r\n this.moveVisual(point);\r\n\r\n this._state = 'creating';\r\n }\r\n }\r\n\r\n /**\r\n * Handles marker manipulation (move, resize, rotate, etc.).\r\n *\r\n * @param point - event coordinates.\r\n */\r\n public manipulate(point: IPoint): void {\r\n super.manipulate(point);\r\n if (this.pointerDownPoint !== undefined) {\r\n this.isMoved =\r\n Math.abs(point.x - this.pointerDownPoint.x) > 5 ||\r\n Math.abs(point.y - this.pointerDownPoint.y) > 5;\r\n }\r\n }\r\n\r\n /**\r\n * Resize marker based on current pointer coordinates and context.\r\n * @param point\r\n */\r\n protected resize(point: IPoint): void {\r\n super.resize(point);\r\n this.setSize();\r\n }\r\n\r\n private readonly PADDING = 5;\r\n private captionBoxWidth = 0;\r\n private captionBoxHeight = 0;\r\n /**\r\n * Adjusts caption size and location.\r\n */\r\n protected sizeCaption(): void {\r\n const textBBox = this.captionElement.getBBox();\r\n if (this.captionText.trim() !== '') {\r\n this.captionBoxWidth = textBBox.width + this.PADDING * 2;\r\n this.captionBoxHeight = textBBox.height + this.PADDING * 2;\r\n } else {\r\n this.captionBoxWidth = 0;\r\n this.captionBoxHeight = 0;\r\n }\r\n\r\n SvgHelper.setAttributes(this.captionBg, [\r\n ['width', this.captionBoxWidth.toString()],\r\n ['height', this.captionBoxHeight.toString()],\r\n [\r\n 'clip-path',\r\n `path('M0,0 H${this.width} V${this.height} H${-this.width} Z')`,\r\n ],\r\n ]);\r\n SvgHelper.setAttributes(this.captionElement, [\r\n ['x', this.PADDING.toString()],\r\n ['y', this.PADDING.toString()],\r\n [\r\n 'clip-path',\r\n `path('M0,0 H${this.width - this.PADDING} V${this.height} H${\r\n -this.width - this.PADDING\r\n } Z')`,\r\n ],\r\n ]);\r\n }\r\n\r\n private textEditDiv: HTMLDivElement;\r\n private textEditBox: HTMLInputElement;\r\n\r\n private showTextEditor() {\r\n this._state = 'edit';\r\n this.overlayContainer.innerHTML = '';\r\n\r\n this.textEditDiv = document.createElement('div');\r\n this.textEditDiv.style.flexGrow = '2';\r\n this.textEditDiv.style.alignItems = 'center';\r\n this.textEditDiv.style.justifyContent = 'center';\r\n this.textEditDiv.style.pointerEvents = 'auto';\r\n this.textEditDiv.style.overflow = 'hidden';\r\n\r\n this.textEditBox = document.createElement('input');\r\n this.textEditBox.style.position = 'absolute';\r\n this.textEditBox.style.width = `${this.width}px`;\r\n if (this.captionBoxHeight > 0) {\r\n this.textEditBox.style.height = `${this.captionBoxHeight}px`;\r\n }\r\n this.textEditBox.style.fontSize = this.fontSize;\r\n this.textEditBox.style.fontFamily = this.fontFamily;\r\n this.textEditBox.style.backgroundColor = this.fillColor;\r\n this.textEditBox.style.color = this.textColor;\r\n this.textEditBox.style.borderWidth = '0';\r\n this.textEditBox.setAttribute('value', this.captionText);\r\n this.textEditBox.select();\r\n\r\n this.textEditDiv.appendChild(this.textEditBox);\r\n this.overlayContainer.appendChild(this.textEditDiv);\r\n\r\n this.textEditBox.addEventListener('pointerup', (ev) => {\r\n ev.stopPropagation();\r\n });\r\n this.textEditBox.addEventListener('keypress', (ev) => {\r\n if (ev.key === 'Enter') {\r\n this.finishTextEditing(this.textEditBox.value);\r\n }\r\n });\r\n this.textEditBox.addEventListener('keyup', (ev) => {\r\n ev.cancelBubble = true;\r\n });\r\n this.textEditBox.addEventListener('blur', () => {\r\n this.finishTextEditing(this.textEditBox.value);\r\n });\r\n this.textEditDiv.addEventListener('pointerup', () => {\r\n this.finishTextEditing(this.textEditBox.value);\r\n });\r\n\r\n this.positionTextEditor();\r\n this.textEditBox.focus();\r\n }\r\n\r\n private positionTextEditor() {\r\n if (this.state === 'edit') {\r\n if (this.textEditBox === undefined) {\r\n this.showTextEditor();\r\n } else {\r\n this.textEditBox.style.left = `${this.left}px`;\r\n this.textEditBox.style.top = `${this.top}px`;\r\n this.textEditBox.style.transform = `rotate(${this.rotationAngle}deg)`;\r\n this.textEditBox.style.transformOrigin = `${this.width / 2}px ${\r\n this.height / 2\r\n }px`;\r\n }\r\n }\r\n }\r\n\r\n private finishTextEditing(text: string) {\r\n this.setCaptionText(text.trim());\r\n this.overlayContainer.innerHTML = '';\r\n this.stateChanged();\r\n }\r\n\r\n /**\r\n * Sets font family.\r\n * @param font - new font family.\r\n */\r\n protected setFont(font: string): void {\r\n if (this.captionElement) {\r\n SvgHelper.setAttributes(this.captionElement, [['font-family', font]]);\r\n }\r\n this.fontFamily = font;\r\n if (this.textEditBox) {\r\n this.textEditBox.style.fontFamily = this.fontFamily;\r\n }\r\n this.sizeCaption();\r\n this.stateChanged();\r\n }\r\n\r\n /**\r\n * Sets text color.\r\n * @param color - new text color.\r\n */\r\n protected setTextColor(color: string): void {\r\n if (this.captionElement) {\r\n SvgHelper.setAttributes(this.captionElement, [['fill', color]]);\r\n }\r\n this.textColor = color;\r\n if (this.textEditBox) {\r\n this.textEditBox.style.color = this.textColor;\r\n }\r\n this.stateChanged();\r\n }\r\n\r\n /**\r\n * Sets marker's visual size after manipulation.\r\n */\r\n protected setSize(): void {\r\n super.setSize();\r\n SvgHelper.setAttributes(this.frame, [\r\n ['width', this.width.toString()],\r\n ['height', this.height.toString()],\r\n ]);\r\n this.sizeCaption();\r\n }\r\n\r\n /**\r\n * Handles pointer (mouse, touch, stylus, etc.) up event.\r\n *\r\n * @param point - event coordinates.\r\n */\r\n public pointerUp(point: IPoint): void {\r\n super.pointerUp(point);\r\n this.setSize();\r\n\r\n if (!this.isMoved && Date.now() - this.pointerDownTimestamp > 500) {\r\n this.showTextEditor();\r\n }\r\n this.pointerDownPoint = undefined;\r\n }\r\n\r\n /**\r\n * Opens text editor on double-click.\r\n * @param point\r\n * @param target\r\n */\r\n public dblClick(point: IPoint, target?: EventTarget): void {\r\n super.dblClick(point, target);\r\n\r\n this.showTextEditor();\r\n }\r\n\r\n /**\r\n * Sets marker's line color.\r\n * @param color - new line color.\r\n */\r\n protected setStrokeColor(color: string): void {\r\n this.strokeColor = color;\r\n if (this.frame) {\r\n SvgHelper.setAttributes(this.frame, [['stroke', this.strokeColor]]);\r\n }\r\n this.colorChanged(color);\r\n this.stateChanged();\r\n }\r\n /**\r\n * Sets marker's fill (background) color.\r\n * @param color - new fill color.\r\n */\r\n protected setFillColor(color: string): void {\r\n this.fillColor = color;\r\n if (this.captionBg) {\r\n SvgHelper.setAttributes(this.captionBg, [['fill', this.fillColor]]);\r\n }\r\n this.fillColorChanged(color);\r\n this.stateChanged();\r\n }\r\n /**\r\n * Sets marker's line width.\r\n * @param width - new line width\r\n */\r\n protected setStrokeWidth(width: number): void {\r\n this.strokeWidth = width;\r\n if (this.frame) {\r\n SvgHelper.setAttributes(this.frame, [\r\n ['stroke-width', this.strokeWidth.toString()],\r\n ]);\r\n }\r\n this.stateChanged();\r\n }\r\n /**\r\n * Sets marker's border dash array.\r\n * @param dashes - new dash array.\r\n */\r\n protected setStrokeDasharray(dashes: string): void {\r\n this.strokeDasharray = dashes;\r\n if (this.frame) {\r\n SvgHelper.setAttributes(this.frame, [\r\n ['stroke-dasharray', this.strokeDasharray],\r\n ]);\r\n }\r\n this.stateChanged();\r\n }\r\n\r\n /**\r\n * Returns the list of toolbox panels for this marker type.\r\n */\r\n public get toolboxPanels(): ToolboxPanel[] {\r\n return [\r\n this.strokePanel,\r\n this.fillPanel,\r\n this.strokeWidthPanel,\r\n this.strokeStylePanel,\r\n this.fontFamilyPanel,\r\n this.textColorPanel,\r\n ];\r\n }\r\n\r\n /**\r\n * Returns current marker state that can be restored in the future.\r\n */\r\n public getState(): CaptionFrameMarkerState {\r\n const result: CaptionFrameMarkerState = Object.assign(\r\n {\r\n fillColor: this.fillColor,\r\n strokeColor: this.strokeColor,\r\n strokeWidth: this.strokeWidth,\r\n strokeDasharray: this.strokeDasharray,\r\n opacity: 1,\r\n textColor: this.textColor,\r\n fontFamily: this.fontFamily,\r\n fontSize: this.fontSize,\r\n captionText: this.captionText\r\n },\r\n super.getState()\r\n );\r\n result.typeName = this.typeName;\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Restores previously saved marker state.\r\n *\r\n * @param state - previously saved state.\r\n */\r\n public restoreState(state: MarkerBaseState): void {\r\n const frState = state as CaptionFrameMarkerState;\r\n this.fillColor = frState.fillColor;\r\n this.strokeColor = frState.strokeColor;\r\n this.strokeWidth = frState.strokeWidth;\r\n this.strokeDasharray = frState.strokeDasharray;\r\n this.textColor = frState.textColor;\r\n this.fontFamily = frState.fontFamily;\r\n this.captionText = frState.captionText;\r\n this.fontSize = frState.fontSize;\r\n\r\n this.createVisual();\r\n super.restoreState(state);\r\n this.setSize();\r\n }\r\n\r\n /**\r\n * Scales marker. Used after the image resize.\r\n *\r\n * @param scaleX - horizontal scale\r\n * @param scaleY - vertical scale\r\n */\r\n public scale(scaleX: number, scaleY: number): void {\r\n super.scale(scaleX, scaleY);\r\n\r\n this.setSize();\r\n }\r\n}\r\n","import { MarkerArea } from '../MarkerArea';\r\nimport { MarkerAreaState } from '../MarkerAreaState';\r\nimport { MarkerBase } from './MarkerBase';\r\n\r\nexport class MarkerAreaEvent {\r\n public markerArea: MarkerArea;\r\n public cancelable = false;\r\n\r\n private _defaultPrevented = false;\r\n public get defaultPrevented(): boolean {\r\n return this._defaultPrevented;\r\n }\r\n\r\n public preventDefault(): void {\r\n this._defaultPrevented = true;\r\n }\r\n\r\n constructor(markerArea: MarkerArea, cancelable = false) {\r\n this.markerArea = markerArea;\r\n this.cancelable = cancelable;\r\n }\r\n}\r\n\r\nexport class MarkerAreaRenderEvent extends MarkerAreaEvent {\r\n public dataUrl: string;\r\n public state: MarkerAreaState;\r\n\r\n constructor(markerArea: MarkerArea, dataUrl: string, state: MarkerAreaState) {\r\n super(markerArea, false);\r\n this.dataUrl = dataUrl;\r\n this.state = state;\r\n }\r\n}\r\n\r\n\r\nexport class MarkerEvent extends MarkerAreaEvent {\r\n public marker?: MarkerBase;\r\n\r\n constructor(markerArea: MarkerArea, marker?: MarkerBase, cancelable = false) {\r\n super(markerArea, cancelable);\r\n this.marker = marker;\r\n }\r\n}\r\n\r\n/**\r\n * General MarkerArea event handler type.\r\n */\r\nexport type MarkerAreaEventHandler = (event: MarkerAreaEvent) => void;\r\n\r\n/**\r\n * MarkerArea render event handler type.\r\n */\r\nexport type MarkerAreaRenderEventHandler = (event: MarkerAreaRenderEvent) => void;\r\n\r\n/**\r\n * Marker event handler type.\r\n */\r\nexport type MarkerEventHandler = (event: MarkerEvent) => void;\r\n\r\n/**\r\n * Describes a repository of MarkerArea event handlers.\r\n */\r\nexport interface IEventListenerRepository {\r\n /**\r\n * Event handlers for the `render` event.\r\n */\r\n render: MarkerAreaRenderEventHandler[];\r\n /**\r\n * Event handlers for the `beforeclose` event.\r\n */\r\n beforeclose: MarkerAreaEventHandler[];\r\n /**\r\n * Event handlers for the `close` event.\r\n */\r\n close: MarkerAreaEventHandler[];\r\n /**\r\n * Event handlers for the `show` event.\r\n */\r\n show: MarkerAreaEventHandler[];\r\n /**\r\n * Event handlers for the `restorestate` event.\r\n */\r\n restorestate: MarkerAreaEventHandler[];\r\n /**\r\n * Event handlers for the `statechange` event.\r\n * \r\n * @since 2.23.0\r\n */\r\n statechange: MarkerAreaEventHandler[];\r\n /**\r\n * Event handlers for the `markerselect` event.\r\n */\r\n markerselect: MarkerEventHandler[];\r\n /**\r\n * Event handlers for the `markerdeselect` event.\r\n */\r\n markerdeselect: MarkerEventHandler[];\r\n /**\r\n * Event handlers for the `markercreating` event.\r\n */\r\n markercreating: MarkerEventHandler[];\r\n /**\r\n * Event handlers for the `markercreated` event.\r\n */\r\n markercreate: MarkerEventHandler[];\r\n /**\r\n * Event handlers for the `markerbeforedelete` event.\r\n */\r\n markerbeforedelete: MarkerEventHandler[];\r\n /**\r\n * Event handlers for the `markerdelete` event.\r\n */\r\n markerdelete: MarkerEventHandler[];\r\n /**\r\n * Event handlers for the `markerchange` event.\r\n * \r\n * @since 2.23.0\r\n */\r\n markerchange: MarkerEventHandler[];\r\n /**\r\n * Event handlers for the `focus` event.\r\n * \r\n * @since 2.19.0\r\n */\r\n focus: MarkerAreaEventHandler[];\r\n /**\r\n * Event handlers for the `blur` event.\r\n * \r\n * @since 2.19.0\r\n */\r\n blur: MarkerAreaEventHandler[];\r\n}\r\n\r\n/**\r\n * Event handler type for a specific event type.\r\n */\r\nexport type EventHandler<\r\n T extends keyof IEventListenerRepository\r\n> = T extends 'markerselect'\r\n ? MarkerEventHandler\r\n : T extends 'markerdeselect'\r\n ? MarkerEventHandler\r\n : T extends 'markercreating'\r\n ? MarkerEventHandler\r\n : T extends 'markercreate'\r\n ? MarkerEventHandler\r\n : T extends 'markerbeforedelete'\r\n ? MarkerEventHandler\r\n : T extends 'markerdelete'\r\n ? MarkerEventHandler\r\n : T extends 'markerchange'\r\n ? MarkerEventHandler\r\n : T extends 'render'\r\n ? MarkerAreaRenderEventHandler\r\n : MarkerAreaEventHandler;\r\n\r\n/**\r\n * Event handler repository.\r\n */\r\nexport class EventListenerRepository implements IEventListenerRepository {\r\n /**\r\n * Event handlers for the `render` event.\r\n */\r\n render: MarkerAreaRenderEventHandler[] = [];\r\n /**\r\n * Event handlers for the `beforeclose` event.\r\n */\r\n beforeclose: MarkerAreaEventHandler[] = [];\r\n /**\r\n * Event handlers for the `close` event.\r\n */\r\n close: MarkerAreaEventHandler[] = [];\r\n /**\r\n * Event handlers for the `show` event.\r\n */\r\n show: MarkerAreaEventHandler[] = [];\r\n /**\r\n * Event handlers for the `restorestate` event.\r\n */\r\n restorestate: MarkerAreaEventHandler[] = [];\r\n /**\r\n * Event handlers for the `statechange` event.\r\n * \r\n * @since 2.23.0\r\n */\r\n statechange: MarkerAreaEventHandler[] = [];\r\n /**\r\n * Event handlers for the `markerselect` event.\r\n */\r\n markerselect: MarkerEventHandler[] = [];\r\n /**\r\n * Event handlers for the `markerdeselect` event.\r\n */\r\n markerdeselect: MarkerEventHandler[] = [];\r\n /**\r\n * Event handlers for the `markercreating` event.\r\n */\r\n markercreating: MarkerEventHandler[] = [];\r\n /**\r\n * Event handlers for the `markercreate` event.\r\n */\r\n markercreate: MarkerEventHandler[] = [];\r\n /**\r\n * Event handlers for the `markerbeforedelete` event.\r\n */\r\n markerbeforedelete: MarkerEventHandler[] = [];\r\n /**\r\n * Event handlers for the `markerdelete` event.\r\n */\r\n markerdelete: MarkerEventHandler[] = [];\r\n /**\r\n * Event handlers for the `markerchange` event.\r\n * \r\n * @since 2.23.0\r\n */\r\n markerchange: MarkerEventHandler[] = [];\r\n /**\r\n * Event handlers for the `focus` event.\r\n * \r\n * @since 2.19.0\r\n */\r\n focus: MarkerAreaEventHandler[] = [];\r\n /**\r\n * Event handlers for the `blur` event.\r\n * \r\n * @since 2.19.0\r\n */\r\n blur: MarkerAreaEventHandler[] = [];\r\n\r\n\r\n /**\r\n * Add an event handler for a specific event type.\r\n * @param eventType - event type.\r\n * @param handler - function to handle the event.\r\n */\r\n public addEventListener<T extends keyof IEventListenerRepository>(\r\n eventType: T,\r\n handler: EventHandler<T>\r\n ): void {\r\n (<Array<EventHandler<T>>>this[eventType]).push(handler);\r\n }\r\n\r\n /**\r\n * Remove an event handler for a specific event type.\r\n * @param eventType - event type.\r\n * @param handler - function currently handling the event.\r\n */\r\n public removeEventListener<T extends keyof IEventListenerRepository>(\r\n eventType: T,\r\n handler: EventHandler<T>\r\n ): void {\r\n const index = (<Array<EventHandler<T>>>this[eventType]).indexOf(handler);\r\n if (index > -1) {\r\n (<Array<EventHandler<T>>>this[eventType]).splice(index, 1);\r\n }\r\n }\r\n}\r\n","import { SvgHelper } from './core/SvgHelper';\r\nimport { Activator } from './core/Activator';\r\nimport { Renderer } from './core/Renderer';\r\n\r\nimport Logo from './assets/markerjs-logo-m.svg';\r\nimport { MarkerBase } from './core/MarkerBase';\r\nimport { Toolbar, ToolbarButtonType } from './ui/Toolbar';\r\nimport { Toolbox } from './ui/Toolbox';\r\nimport { FrameMarker } from './markers/frame-marker/FrameMarker';\r\nimport { Settings } from './core/Settings';\r\nimport { StyleManager, Style } from './core/Style';\r\nimport { LineMarker } from './markers/line-marker/LineMarker';\r\nimport { TextMarker } from './markers/text-marker/TextMarker';\r\nimport { FreehandMarker } from './markers/freehand-marker/FreehandMarker';\r\nimport { ArrowMarker } from './markers/arrow-marker/ArrowMarker';\r\nimport { CoverMarker } from './markers/cover-marker/CoverMarker';\r\nimport { HighlightMarker } from './markers/highlight-marker/HighlightMarker';\r\nimport { CalloutMarker } from './markers/callout-marker/CalloutMarker';\r\nimport { MarkerAreaState } from './MarkerAreaState';\r\nimport { EllipseMarker } from './markers/ellipse-marker/EllipseMarker';\r\nimport { IStyleSettings } from './core/IStyleSettings';\r\nimport { MeasurementMarker } from './markers/measurement-marker/MeasurementMarker';\r\nimport { IPoint } from './core/IPoint';\r\nimport { EllipseFrameMarker } from './markers/ellipse-frame-marker/EllipseFrameMarker';\r\nimport { UndoRedoManager } from './core/UndoRedoManager';\r\nimport { CurveMarker } from './markers/curve-marker/CurveMarker';\r\nimport { CaptionFrameMarker } from './markers/caption-frame-marker/CaptionFrameMarker';\r\nimport {\r\n EventHandler,\r\n EventListenerRepository,\r\n IEventListenerRepository,\r\n MarkerAreaEvent,\r\n MarkerAreaRenderEvent,\r\n MarkerEvent,\r\n} from './core/Events';\r\n\r\n/**\r\n * @ignore\r\n */\r\nexport type MarkerAreaMode = 'select' | 'create' | 'delete';\r\n\r\n/**\r\n * Identifier for marker type when setting {@linkcode availableMarkerTypes}.\r\n * Marker type can be set as either a string or a marker type reference.\r\n */\r\nexport type MarkerTypeIdentifier = string | typeof MarkerBase;\r\n\r\n/**\r\n * Event handler type for {@linkcode MarkerArea} `render` event.\r\n */\r\nexport type RenderEventHandler = (\r\n dataURL: string,\r\n state?: MarkerAreaState\r\n) => void;\r\n/**\r\n * Event handler type for {@linkcode MarkerArea} `close` event.\r\n */\r\nexport type CloseEventHandler = () => void;\r\n\r\n/**\r\n * MarkerArea is the main class of marker.js 2. It controls the behavior and appearance of the library.\r\n *\r\n * The simplest marker.js 2 usage scenario looks something like this:\r\n *\r\n * ```typescript\r\n * import * as markerjs2 from 'markerjs2';\r\n * // create an instance of MarkerArea and pass the target image reference as a parameter\r\n * let markerArea = new markerjs2.MarkerArea(document.getElementById('myimg'));\r\n *\r\n * // register an event listener for when user clicks OK/save in the marker.js UI\r\n * markerArea.addEventListener('render', event => {\r\n * // we are setting the markup result to replace our original image on the page\r\n * // but you can set a different image or upload it to your server\r\n * document.getElementById('myimg').src = event.dataUrl;\r\n * });\r\n *\r\n * // finally, call the show() method and marker.js UI opens\r\n * markerArea.show();\r\n * ```\r\n */\r\nexport class MarkerArea {\r\n private target: HTMLImageElement | HTMLElement;\r\n private targetObserver: ResizeObserver;\r\n\r\n private width: number;\r\n private height: number;\r\n private imageWidth: number;\r\n private imageHeight: number;\r\n private left: number;\r\n private top: number;\r\n private windowHeight: number;\r\n\r\n private markerImage: SVGSVGElement;\r\n private markerImageHolder: HTMLDivElement;\r\n private defs: SVGDefsElement;\r\n\r\n private coverDiv: HTMLDivElement;\r\n private uiDiv: HTMLDivElement;\r\n private contentDiv: HTMLDivElement;\r\n private editorCanvas: HTMLDivElement;\r\n private editingTarget: HTMLImageElement | HTMLCanvasElement;\r\n private overlayContainer: HTMLDivElement;\r\n\r\n private touchPoints = 0;\r\n\r\n private logoUI: HTMLElement;\r\n\r\n /**\r\n * `targetRoot` is used to set an alternative positioning root for the marker.js UI.\r\n *\r\n * This is useful in cases when your target image is positioned, say, inside a div with `position: relative;`\r\n *\r\n * ```typescript\r\n * // set targetRoot to a specific div instead of document.body\r\n * markerArea.targetRoot = document.getElementById('myRootElement');\r\n * ```\r\n *\r\n * @default document.body\r\n */\r\n public targetRoot: HTMLElement;\r\n\r\n /**\r\n * Returns a list of all built-in marker types for use with {@linkcode availableMarkerTypes}\r\n *\r\n * @readonly\r\n */\r\n public get ALL_MARKER_TYPES(): typeof MarkerBase[] {\r\n return [\r\n FrameMarker,\r\n FreehandMarker,\r\n ArrowMarker,\r\n TextMarker,\r\n EllipseFrameMarker,\r\n EllipseMarker,\r\n HighlightMarker,\r\n CalloutMarker,\r\n MeasurementMarker,\r\n CoverMarker,\r\n LineMarker,\r\n CurveMarker,\r\n CaptionFrameMarker,\r\n ];\r\n }\r\n\r\n /**\r\n * Returns a list of default set of built-in marker types.\r\n * Used when {@linkcode availableMarkerTypes} isn't set explicitly.\r\n *\r\n * @readonly\r\n */\r\n public get DEFAULT_MARKER_TYPES(): typeof MarkerBase[] {\r\n return [\r\n FrameMarker,\r\n FreehandMarker,\r\n ArrowMarker,\r\n TextMarker,\r\n EllipseMarker,\r\n HighlightMarker,\r\n CalloutMarker,\r\n ];\r\n }\r\n\r\n /**\r\n * Returns a short list of essential built-in marker types for use with {@linkcode availableMarkerTypes}\r\n *\r\n * @readonly\r\n */\r\n public get BASIC_MARKER_TYPES(): typeof MarkerBase[] {\r\n return [\r\n FrameMarker,\r\n FreehandMarker,\r\n ArrowMarker,\r\n TextMarker,\r\n HighlightMarker,\r\n ];\r\n }\r\n\r\n private _availableMarkerTypes: typeof MarkerBase[] = this\r\n .DEFAULT_MARKER_TYPES;\r\n\r\n /**\r\n * Gets or sets a list of marker types avaiable to the user in the toolbar.\r\n * The types can be passed as either type reference or a string type name.\r\n *\r\n * ```typescript\r\n * this.markerArea1.availableMarkerTypes = ['CalloutMarker', ...this.markerArea1.BASIC_MARKER_TYPES];\r\n * ```\r\n *\r\n * @default {@linkcode DEFAULT_MARKER_TYPES}\r\n */\r\n public get availableMarkerTypes(): MarkerTypeIdentifier[] {\r\n return this._availableMarkerTypes;\r\n }\r\n\r\n public set availableMarkerTypes(value: MarkerTypeIdentifier[]) {\r\n this._availableMarkerTypes.splice(0);\r\n value.forEach((mt) => {\r\n if (typeof mt === 'string') {\r\n const typeType = this.ALL_MARKER_TYPES.find(\r\n (allT) => allT.typeName === mt\r\n );\r\n if (typeType !== undefined) {\r\n this._availableMarkerTypes.push(typeType);\r\n }\r\n } else {\r\n this._availableMarkerTypes.push(mt);\r\n }\r\n });\r\n }\r\n\r\n private toolbar: Toolbar;\r\n private toolbox: Toolbox;\r\n\r\n private mode: MarkerAreaMode = 'select';\r\n\r\n private _currentMarker?: MarkerBase;\r\n /**\r\n * Gets currently selected marker\r\n *\r\n * @readonly\r\n * @since 2.27.0\r\n */\r\n public get currentMarker() : MarkerBase | undefined {\r\n return this._currentMarker;\r\n }\r\n private markers: MarkerBase[] = [];\r\n\r\n private isDragging = false;\r\n\r\n // for preserving orginal window state before opening the editor\r\n private bodyOverflowState: string;\r\n private scrollYState: number;\r\n private scrollXState: number;\r\n\r\n private renderEventListeners: RenderEventHandler[] = [];\r\n private closeEventListeners: CloseEventHandler[] = [];\r\n\r\n public settings: Settings = new Settings();\r\n public uiStyleSettings: IStyleSettings;\r\n\r\n private _isOpen = false;\r\n /**\r\n * Returns `true` when MarkerArea is open and `false` otherwise.\r\n *\r\n * @readonly\r\n */\r\n public get isOpen(): boolean {\r\n return this._isOpen;\r\n }\r\n\r\n private undoRedoManager: UndoRedoManager<\r\n MarkerAreaState\r\n > = new UndoRedoManager<MarkerAreaState>();\r\n\r\n /**\r\n * Returns true if undo operation can be performed (undo stack is not empty).\r\n * \r\n * @since 2.26.0\r\n */\r\n public get isUndoPossible(): boolean {\r\n if (this.undoRedoManager && this.undoRedoManager.isUndoPossible) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Returns true if redo operation can be performed (redo stack is not empty).\r\n * \r\n * @since 2.26.0\r\n */\r\n public get isRedoPossible(): boolean {\r\n if (this.undoRedoManager && this.undoRedoManager.isRedoPossible) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * When set to true resulting image will be rendered at the natural (original) resolution\r\n * of the target image. Otherwise (default), screen dimensions of the image are used.\r\n *\r\n * @default false (use screen dimensions)\r\n */\r\n public renderAtNaturalSize = false;\r\n /**\r\n * Type of image for the rendering result. Eg. `image/png` (default) or `image/jpeg`.\r\n *\r\n * @default `image/png`\r\n */\r\n public renderImageType = 'image/png';\r\n /**\r\n * When rendering engine/format supports it (jpeg, for exmample),\r\n * sets the rendering quality for the resulting image.\r\n *\r\n * In case of `image/jpeg` the value should be between 0 (worst quality) and 1 (best quality).\r\n */\r\n public renderImageQuality?: number;\r\n /**\r\n * When set to `true`, will render only the marker layer without the original image.\r\n * This could be useful when you want to non-destructively overlay markers on top of the original image.\r\n *\r\n * Note that in order for the markers layer to have a transparent background {@linkcode renderImageType}\r\n * should be set to a format supporting transparency, such as `image/png`.\r\n *\r\n * @default false\r\n */\r\n public renderMarkersOnly = false;\r\n\r\n /**\r\n * When set and {@linkcode renderAtNaturalSize} is `false` sets the width of the rendered image.\r\n *\r\n * Both `renderWidth` and `renderHeight` have to be set for this to take effect.\r\n */\r\n public renderWidth?: number;\r\n /**\r\n * When set and {@linkcode renderAtNaturalSize} is `false` sets the height of the rendered image.\r\n *\r\n * Both `renderWidth` and `renderHeight` have to be set for this to take effect.\r\n */\r\n public renderHeight?: number;\r\n\r\n /**\r\n * If a canvas is specified here, then marker.js will render the output to this canvas\r\n * in addition to generating an image.\r\n *\r\n * @since 2.14.0\r\n */\r\n public renderTarget?: HTMLCanvasElement;\r\n\r\n /**\r\n * Pressing zoom button iterates through values in this array.\r\n *\r\n * @since 2.12.0\r\n */\r\n public zoomSteps = [1, 1.5, 2, 4];\r\n private _zoomLevel = 1;\r\n /**\r\n * Gets current zoom level.\r\n *\r\n * @since 2.12.0\r\n */\r\n public get zoomLevel(): number {\r\n return this._zoomLevel;\r\n }\r\n /**\r\n * Sets current zoom level.\r\n *\r\n * @since 2.12.0\r\n */\r\n public set zoomLevel(value: number) {\r\n this._zoomLevel = value;\r\n if (this.editorCanvas && this.contentDiv) {\r\n this.editorCanvas.style.transform = `scale(${this._zoomLevel})`;\r\n this.contentDiv.scrollTo({\r\n left:\r\n (this.editorCanvas.clientWidth * this._zoomLevel -\r\n this.contentDiv.clientWidth) /\r\n 2,\r\n top:\r\n (this.editorCanvas.clientHeight * this._zoomLevel -\r\n this.contentDiv.clientHeight) /\r\n 2,\r\n });\r\n }\r\n }\r\n\r\n private static instanceCounter = 0;\r\n private _instanceNo: number;\r\n public get instanceNo(): number {\r\n return this._instanceNo;\r\n }\r\n\r\n /**\r\n * Manage style releated settings via the `styles` property.\r\n */\r\n public styles: StyleManager;\r\n\r\n /**\r\n * Creates a new MarkerArea for the specified target image.\r\n *\r\n * ```typescript\r\n * // create an instance of MarkerArea and pass the target image (or other HTML element) reference as a parameter\r\n * let markerArea = new markerjs2.MarkerArea(document.getElementById('myimg'));\r\n * ```\r\n *\r\n * When `target` is not an image object the output is limited to \"markers only\" (@linkcode renderMarkersOnly)\r\n * and \"popup\" mode won't work properly as the target object stays in it's original position and, unlike images,\r\n * is not copied.\r\n *\r\n * @param target image object to mark up.\r\n */\r\n constructor(target: HTMLImageElement | HTMLElement) {\r\n this._instanceNo = MarkerArea.instanceCounter++;\r\n\r\n this.styles = new StyleManager(this.instanceNo);\r\n\r\n this.uiStyleSettings = this.styles.settings;\r\n\r\n this.target = target;\r\n this.targetRoot = document.body;\r\n\r\n this.width = target.clientWidth;\r\n this.height = target.clientHeight;\r\n\r\n this.styles.removeStyleSheet();\r\n\r\n this.open = this.open.bind(this);\r\n this.setTopLeft = this.setTopLeft.bind(this);\r\n\r\n this.toolbarButtonClicked = this.toolbarButtonClicked.bind(this);\r\n this.createNewMarker = this.createNewMarker.bind(this);\r\n this.addNewMarker = this.addNewMarker.bind(this);\r\n this.markerCreated = this.markerCreated.bind(this);\r\n this.setCurrentMarker = this.setCurrentMarker.bind(this);\r\n this.onPointerDown = this.onPointerDown.bind(this);\r\n this.onDblClick = this.onDblClick.bind(this);\r\n this.onPointerMove = this.onPointerMove.bind(this);\r\n this.onPointerUp = this.onPointerUp.bind(this);\r\n this.onPointerOut = this.onPointerOut.bind(this);\r\n this.onKeyUp = this.onKeyUp.bind(this);\r\n this.overrideOverflow = this.overrideOverflow.bind(this);\r\n this.restoreOverflow = this.restoreOverflow.bind(this);\r\n this.close = this.close.bind(this);\r\n this.closeUI = this.closeUI.bind(this);\r\n this.addCloseEventListener = this.addCloseEventListener.bind(this);\r\n this.removeCloseEventListener = this.removeCloseEventListener.bind(this);\r\n this.addRenderEventListener = this.addRenderEventListener.bind(this);\r\n this.removeRenderEventListener = this.removeRenderEventListener.bind(this);\r\n this.clientToLocalCoordinates = this.clientToLocalCoordinates.bind(this);\r\n this.onWindowResize = this.onWindowResize.bind(this);\r\n this.deleteSelectedMarker = this.deleteSelectedMarker.bind(this);\r\n this.setWindowHeight = this.setWindowHeight.bind(this);\r\n this.removeMarker = this.removeMarker.bind(this);\r\n this.colorChanged = this.colorChanged.bind(this);\r\n this.fillColorChanged = this.fillColorChanged.bind(this);\r\n this.onPopupTargetResize = this.onPopupTargetResize.bind(this);\r\n this.showNotesEditor = this.showNotesEditor.bind(this);\r\n this.hideNotesEditor = this.hideNotesEditor.bind(this);\r\n this.stepZoom = this.stepZoom.bind(this);\r\n this.focus = this.focus.bind(this);\r\n this.blur = this.blur.bind(this);\r\n this.markerStateChanged = this.markerStateChanged.bind(this);\r\n this.switchToSelectMode = this.switchToSelectMode.bind(this);\r\n this.addDefs = this.addDefs.bind(this);\r\n this.addDefsToImage = this.addDefsToImage.bind(this);\r\n }\r\n\r\n private open(): void {\r\n this.setupResizeObserver();\r\n this.setEditingTarget();\r\n this.setTopLeft();\r\n this.initMarkerCanvas();\r\n this.initOverlay();\r\n this.attachEvents();\r\n if (this.settings.displayMode === 'popup') {\r\n this.onPopupTargetResize();\r\n }\r\n\r\n if (!Activator.isLicensed) {\r\n // NOTE:\r\n // before removing this call please consider supporting marker.js\r\n // by visiting https://markerjs.com/ for details\r\n // thank you!\r\n this.addLogo();\r\n }\r\n\r\n this._isOpen = true;\r\n this._isFocused = true;\r\n }\r\n\r\n /**\r\n * Initializes the MarkerArea and opens the UI.\r\n */\r\n public show(): void {\r\n // backwards compatibility with deprecated static Style class\r\n if (this.styles.styleSheetRoot === undefined && Style.styleSheetRoot !== undefined) {\r\n this.styles.styleSheetRoot = Style.styleSheetRoot;\r\n }\r\n\r\n // reset markers array\r\n this.markers.splice(0);\r\n\r\n this.setWindowHeight();\r\n this.showUI();\r\n this.open();\r\n this.eventListeners['show'].forEach((listener) =>\r\n listener(new MarkerAreaEvent(this))\r\n );\r\n }\r\n\r\n /**\r\n * Renders the annotation result.\r\n *\r\n * Normally, you should use {@linkcode addEventListener} method to set a listener for the `render` event\r\n * rather than calling this method directly.\r\n */\r\n public async render(): Promise<string> {\r\n this.setCurrentMarker();\r\n\r\n const renderer = new Renderer();\r\n renderer.naturalSize = this.renderAtNaturalSize;\r\n renderer.imageType = this.renderImageType;\r\n renderer.imageQuality = this.renderImageQuality;\r\n renderer.markersOnly = this.renderMarkersOnly;\r\n renderer.width = this.renderWidth;\r\n renderer.height = this.renderHeight;\r\n\r\n // workaround for an issue in Safari where FreeHand marker\r\n // is not rendered on the first try for some reason\r\n await renderer.rasterize(\r\n this.target instanceof HTMLImageElement ? this.target : null,\r\n this.markerImage,\r\n this.renderTarget\r\n );\r\n\r\n return await renderer.rasterize(\r\n this.target instanceof HTMLImageElement ? this.target : null,\r\n this.markerImage,\r\n this.renderTarget\r\n );\r\n }\r\n\r\n /**\r\n * Closes the MarkerArea UI.\r\n */\r\n public close(suppressBeforeClose = false): void {\r\n if (this.isOpen) {\r\n let cancel = false;\r\n\r\n if (!suppressBeforeClose) {\r\n this.eventListeners['beforeclose'].forEach((listener) => {\r\n const ev = new MarkerAreaEvent(this, true);\r\n listener(ev);\r\n if (ev.defaultPrevented) {\r\n cancel = true;\r\n }\r\n });\r\n }\r\n\r\n if (!cancel) {\r\n if (this.coverDiv) {\r\n this.closeUI();\r\n }\r\n if (this.targetObserver) {\r\n this.targetObserver.unobserve(this.target);\r\n this.targetObserver.unobserve(this.editorCanvas);\r\n }\r\n if (this.settings.displayMode === 'popup') {\r\n window.removeEventListener('resize', this.setWindowHeight);\r\n }\r\n //this.closeEventListeners.forEach((listener) => listener());\r\n this.eventListeners['close'].forEach((listener) =>\r\n listener(new MarkerAreaEvent(this))\r\n );\r\n this.detachEvents();\r\n this._isOpen = false;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Adds one or more markers to the toolbar.\r\n *\r\n * @param markers - one or more marker types to be added.\r\n */\r\n public addMarkersToToolbar(...markers: typeof MarkerBase[]): void {\r\n this._availableMarkerTypes.push(...markers);\r\n }\r\n\r\n /**\r\n * Add a `render` event listener which is called when user clicks on the OK/save button\r\n * in the toolbar.\r\n *\r\n * ```typescript\r\n * // register an event listener for when user clicks OK/save in the marker.js UI\r\n * markerArea.addRenderEventListener(dataUrl => {\r\n * // we are setting the markup result to replace our original image on the page\r\n * // but you can set a different image or upload it to your server\r\n * document.getElementById('myimg').src = dataUrl;\r\n * });\r\n * ```\r\n *\r\n * This is where you place your code to save a resulting image and/or MarkerAreaState.\r\n *\r\n * @param listener - a method handling rendering results\r\n *\r\n * @see {@link MarkerAreaState}\r\n * @deprecated use `addEventListener('render', ...)` instead.\r\n */\r\n public addRenderEventListener(listener: RenderEventHandler): void {\r\n //this.renderEventListeners.push(listener);\r\n this.addEventListener('render', (event: MarkerAreaRenderEvent) => {\r\n listener(event.dataUrl, event.state);\r\n });\r\n }\r\n\r\n /**\r\n * Remove a `render` event handler.\r\n *\r\n * @param listener - previously registered `render` event handler.\r\n * @deprecated use `removeEventListener('render', ...)` instead.\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n public removeRenderEventListener(listener: RenderEventHandler): void {\r\n // if (this.renderEventListeners.indexOf(listener) > -1) {\r\n // this.renderEventListeners.splice(\r\n // this.renderEventListeners.indexOf(listener),\r\n // 1\r\n // );\r\n // }\r\n }\r\n\r\n /**\r\n * Add a `close` event handler to perform actions in your code after the user\r\n * clicks on the close button (without saving).\r\n *\r\n * @param listener - close event listener\r\n * @deprecated use `addEventListener('close', ...)` instead.\r\n */\r\n public addCloseEventListener(listener: CloseEventHandler): void {\r\n //this.closeEventListeners.push(listener);\r\n this.addEventListener('close', () => {\r\n listener();\r\n });\r\n }\r\n\r\n /**\r\n * Remove a `close` event handler.\r\n *\r\n * @param listener - previously registered `close` event handler.\r\n * @deprecated use `removeEventListener('close', ...)` instead.\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n public removeCloseEventListener(listener: CloseEventHandler): void {\r\n // if (this.closeEventListeners.indexOf(listener) > -1) {\r\n // this.closeEventListeners.splice(\r\n // this.closeEventListeners.indexOf(listener),\r\n // 1\r\n // );\r\n // }\r\n }\r\n\r\n private setupResizeObserver() {\r\n if (this.settings.displayMode === 'inline') {\r\n if (window.ResizeObserver) {\r\n this.targetObserver = new ResizeObserver(() => {\r\n this.resize(this.target.clientWidth, this.target.clientHeight);\r\n });\r\n this.targetObserver.observe(this.target);\r\n }\r\n } else if (this.settings.displayMode === 'popup') {\r\n if (window.ResizeObserver) {\r\n this.targetObserver = new ResizeObserver(() =>\r\n this.onPopupTargetResize()\r\n );\r\n this.targetObserver.observe(this.editorCanvas);\r\n }\r\n window.addEventListener('resize', this.setWindowHeight);\r\n }\r\n }\r\n\r\n private onPopupTargetResize() {\r\n const ratio = (1.0 * this.target.clientWidth) / this.target.clientHeight;\r\n const newWidth =\r\n this.editorCanvas.clientWidth / ratio > this.editorCanvas.clientHeight\r\n ? this.editorCanvas.clientHeight * ratio\r\n : this.editorCanvas.clientWidth;\r\n const newHeight =\r\n newWidth < this.editorCanvas.clientWidth\r\n ? this.editorCanvas.clientHeight\r\n : this.editorCanvas.clientWidth / ratio;\r\n this.resize(newWidth, newHeight);\r\n }\r\n\r\n private setWindowHeight() {\r\n this.windowHeight = window.innerHeight;\r\n }\r\n\r\n private _isResizing = false;\r\n private resize(newWidth: number, newHeight: number) {\r\n this._isResizing = true;\r\n\r\n const scaleX = newWidth / this.imageWidth;\r\n const scaleY = newHeight / this.imageHeight;\r\n\r\n this.imageWidth = Math.round(newWidth);\r\n this.imageHeight = Math.round(newHeight);\r\n if (\r\n this.target instanceof HTMLImageElement &&\r\n this.editingTarget instanceof HTMLImageElement\r\n ) {\r\n this.editingTarget.src = this.target.src;\r\n }\r\n this.editingTarget.width = this.imageWidth;\r\n this.editingTarget.height = this.imageHeight;\r\n this.editingTarget.style.width = `${this.imageWidth}px`;\r\n this.editingTarget.style.height = `${this.imageHeight}px`;\r\n\r\n this.markerImage.setAttribute('width', this.imageWidth.toString());\r\n this.markerImage.setAttribute('height', this.imageHeight.toString());\r\n this.markerImage.setAttribute(\r\n 'viewBox',\r\n '0 0 ' + this.imageWidth.toString() + ' ' + this.imageHeight.toString()\r\n );\r\n\r\n this.markerImageHolder.style.width = `${this.imageWidth}px`;\r\n this.markerImageHolder.style.height = `${this.imageHeight}px`;\r\n\r\n this.overlayContainer.style.width = `${this.imageWidth}px`;\r\n this.overlayContainer.style.height = `${this.imageHeight}px`;\r\n\r\n if (this.settings.displayMode !== 'popup') {\r\n this.coverDiv.style.width = `${this.imageWidth.toString()}px`;\r\n } else {\r\n this.setTopLeft();\r\n this.positionMarkerImage();\r\n }\r\n\r\n if (this.toolbar !== undefined) {\r\n this.toolbar.adjustLayout();\r\n }\r\n\r\n this.positionLogo();\r\n\r\n this.scaleMarkers(scaleX, scaleY);\r\n\r\n this._isResizing = false;\r\n }\r\n\r\n private scaleMarkers(scaleX: number, scaleY: number) {\r\n let preScaleSelectedMarker: MarkerBase;\r\n if (!(this._currentMarker && this._currentMarker instanceof TextMarker)) {\r\n // can't unselect text marker as it would hide keyboard on mobile\r\n preScaleSelectedMarker = this._currentMarker;\r\n this.setCurrentMarker();\r\n } else {\r\n this._currentMarker.scale(scaleX, scaleY);\r\n }\r\n this.markers.forEach((marker) => {\r\n if (marker !== this._currentMarker) {\r\n marker.scale(scaleX, scaleY)\r\n }\r\n });\r\n if (preScaleSelectedMarker !== undefined) {\r\n this.setCurrentMarker(preScaleSelectedMarker);\r\n }\r\n }\r\n\r\n private setEditingTarget() {\r\n this.imageWidth = Math.round(this.target.clientWidth);\r\n this.imageHeight = Math.round(this.target.clientHeight);\r\n if (\r\n this.target instanceof HTMLImageElement &&\r\n this.editingTarget instanceof HTMLImageElement\r\n ) {\r\n this.editingTarget.src = this.target.src;\r\n }\r\n this.editingTarget.width = this.imageWidth;\r\n this.editingTarget.height = this.imageHeight;\r\n this.editingTarget.style.width = `${this.imageWidth}px`;\r\n this.editingTarget.style.height = `${this.imageHeight}px`;\r\n }\r\n\r\n private setTopLeft() {\r\n const targetRect = this.editingTarget.getBoundingClientRect();\r\n const bodyRect = this.editorCanvas.getBoundingClientRect();\r\n this.left = targetRect.left - bodyRect.left;\r\n this.top = targetRect.top - bodyRect.top;\r\n }\r\n\r\n private initMarkerCanvas(): void {\r\n this.markerImageHolder = document.createElement('div');\r\n this.markerImageHolder.style.setProperty('touch-action', 'pinch-zoom');\r\n\r\n this.markerImage = document.createElementNS(\r\n 'http://www.w3.org/2000/svg',\r\n 'svg'\r\n );\r\n this.markerImage.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\r\n this.markerImage.setAttribute('width', this.imageWidth.toString());\r\n this.markerImage.setAttribute('height', this.imageHeight.toString());\r\n this.markerImage.setAttribute(\r\n 'viewBox',\r\n '0 0 ' + this.imageWidth.toString() + ' ' + this.imageHeight.toString()\r\n );\r\n this.markerImage.style.pointerEvents = 'auto';\r\n\r\n this.markerImageHolder.style.position = 'absolute';\r\n this.markerImageHolder.style.width = `${this.imageWidth}px`;\r\n this.markerImageHolder.style.height = `${this.imageHeight}px`;\r\n this.markerImageHolder.style.transformOrigin = 'top left';\r\n this.positionMarkerImage();\r\n\r\n this.markerImageHolder.appendChild(this.markerImage);\r\n\r\n this.editorCanvas.appendChild(this.markerImageHolder);\r\n }\r\n\r\n /**\r\n * Adds \"defs\" element to the marker SVG element.\r\n * Useful for using custom fonts and potentially other scenarios.\r\n *\r\n * @param {(...(string | Node)[])} nodes\r\n * @see Documentation article on adding custom fonts for an example\r\n */\r\n public addDefs(...nodes: (string | Node)[]): void {\r\n this.defs = SvgHelper.createDefs();\r\n this.addDefsToImage();\r\n\r\n this.defs.append(...nodes);\r\n }\r\n\r\n private addDefsToImage() {\r\n if (this.defs) {\r\n this.markerImage.insertBefore(this.defs, this.markerImage.firstChild);\r\n }\r\n }\r\n\r\n private initOverlay(): void {\r\n this.overlayContainer = document.createElement('div');\r\n this.overlayContainer.style.position = 'absolute';\r\n this.overlayContainer.style.left = '0px';\r\n this.overlayContainer.style.top = '0px';\r\n this.overlayContainer.style.width = `${this.imageWidth}px`;\r\n this.overlayContainer.style.height = `${this.imageHeight}px`;\r\n this.overlayContainer.style.display = 'flex';\r\n this.markerImageHolder.appendChild(this.overlayContainer);\r\n }\r\n\r\n private positionMarkerImage() {\r\n this.markerImageHolder.style.top = this.top / this.zoomLevel + 'px';\r\n this.markerImageHolder.style.left = this.left / this.zoomLevel + 'px';\r\n }\r\n\r\n private attachEvents() {\r\n this.markerImage.addEventListener('pointerdown', this.onPointerDown);\r\n // workaround to prevent a bug with Apple Pencil\r\n // https://bugs.webkit.org/show_bug.cgi?id=217430\r\n this.markerImage.addEventListener('touchmove', ev => ev.preventDefault());\r\n \r\n this.markerImage.addEventListener('dblclick', this.onDblClick);\r\n this.attachWindowEvents();\r\n }\r\n\r\n private attachWindowEvents() {\r\n window.addEventListener('pointermove', this.onPointerMove);\r\n window.addEventListener('pointerup', this.onPointerUp);\r\n window.addEventListener('pointercancel', this.onPointerOut);\r\n window.addEventListener('pointerout', this.onPointerOut);\r\n window.addEventListener('pointerleave', this.onPointerUp);\r\n window.addEventListener('resize', this.onWindowResize);\r\n window.addEventListener('keyup', this.onKeyUp);\r\n }\r\n\r\n private detachEvents() {\r\n this.markerImage.removeEventListener('pointerdown', this.onPointerDown);\r\n this.markerImage.removeEventListener('dblclick', this.onDblClick);\r\n this.detachWindowEvents();\r\n }\r\n\r\n private detachWindowEvents() {\r\n window.removeEventListener('pointermove', this.onPointerMove);\r\n window.removeEventListener('pointerup', this.onPointerUp);\r\n window.removeEventListener('pointercancel', this.onPointerOut);\r\n window.removeEventListener('pointerout', this.onPointerOut);\r\n window.removeEventListener('pointerleave', this.onPointerUp);\r\n window.removeEventListener('resize', this.onWindowResize);\r\n window.removeEventListener('keyup', this.onKeyUp);\r\n }\r\n\r\n /**\r\n * NOTE:\r\n *\r\n * before removing or modifying this method please consider supporting marker.js\r\n * by visiting https://markerjs.com/#price for details\r\n *\r\n * thank you!\r\n */\r\n private addLogo() {\r\n this.logoUI = document.createElement('div');\r\n this.logoUI.style.display = 'inline-block';\r\n this.logoUI.style.margin = '0px';\r\n this.logoUI.style.padding = '0px';\r\n this.logoUI.style.fill = '#333333';\r\n\r\n const link = document.createElement('a');\r\n link.href = 'https://markerjs.com/';\r\n link.target = '_blank';\r\n link.innerHTML = Logo;\r\n link.title = 'Powered by marker.js';\r\n\r\n link.style.display = 'grid';\r\n link.style.alignItems = 'center';\r\n link.style.justifyItems = 'center';\r\n link.style.padding = '3px';\r\n link.style.width = '20px';\r\n link.style.height = '20px';\r\n\r\n this.logoUI.appendChild(link);\r\n\r\n this.editorCanvas.appendChild(this.logoUI);\r\n\r\n this.logoUI.style.position = 'absolute';\r\n this.logoUI.style.pointerEvents = 'all';\r\n this.positionLogo();\r\n }\r\n\r\n private positionLogo() {\r\n if (this.logoUI) {\r\n if (this.uiStyleSettings.logoPosition !== 'right') {\r\n this.logoUI.style.left = `${this.markerImageHolder.offsetLeft + 10}px`;\r\n } else {\r\n this.logoUI.style.left = `${\r\n this.markerImageHolder.offsetLeft +\r\n this.markerImageHolder.offsetWidth -\r\n this.logoUI.clientWidth -\r\n 10\r\n }px`;\r\n }\r\n this.logoUI.style.top = `${\r\n this.markerImageHolder.offsetTop +\r\n this.markerImageHolder.offsetHeight -\r\n this.logoUI.clientHeight -\r\n 10\r\n }px`;\r\n }\r\n }\r\n\r\n private overrideOverflow() {\r\n // backup current state of scrolling and overflow\r\n this.scrollXState = window.scrollX;\r\n this.scrollYState = window.scrollY;\r\n this.bodyOverflowState = document.body.style.overflow;\r\n\r\n window.scroll({ top: 0, left: 0 });\r\n document.body.style.overflow = 'hidden';\r\n }\r\n\r\n private restoreOverflow() {\r\n document.body.style.overflow = this.bodyOverflowState;\r\n window.scroll({ top: this.scrollYState, left: this.scrollXState });\r\n }\r\n\r\n private showUI(): void {\r\n if (this.settings.displayMode === 'popup') {\r\n this.overrideOverflow();\r\n }\r\n\r\n this.coverDiv = document.createElement('div');\r\n // prevent UI from blinking when just rendering state\r\n this.coverDiv.style.visibility = this._silentRenderMode\r\n ? 'hidden'\r\n : 'visible';\r\n this.coverDiv.className = `${this.styles.classNamePrefixBase} ${this.styles.classNamePrefix}`;\r\n // hardcode font size so nothing inside is affected by higher up settings\r\n this.coverDiv.style.fontSize = '16px';\r\n this.coverDiv.style.userSelect = 'none';\r\n\r\n switch (this.settings.displayMode) {\r\n case 'inline': {\r\n this.coverDiv.style.position = 'absolute';\r\n const coverTop = this.settings.uiOffsetTop !== undefined ? \r\n this.target.offsetTop + this.settings.uiOffsetTop :\r\n this.target.offsetTop > this.styles.settings.toolbarHeight\r\n ? this.target.offsetTop - this.styles.settings.toolbarHeight\r\n : 0;\r\n const coverLeft = this.target.offsetLeft + (this.settings.uiOffsetLeft ?? 0); \r\n this.coverDiv.style.top = `${coverTop}px`;\r\n this.coverDiv.style.left = `${coverLeft}px`;\r\n this.coverDiv.style.width = `${this.target.offsetWidth.toString()}px`;\r\n //this.coverDiv.style.height = `${this.target.offsetHeight.toString()}px`;\r\n this.coverDiv.style.zIndex =\r\n this.uiStyleSettings.zIndex !== undefined\r\n ? this.uiStyleSettings.zIndex\r\n : '5';\r\n // flex causes the ui to stretch when toolbox has wider nowrap panels\r\n //this.coverDiv.style.display = 'flex';\r\n break;\r\n }\r\n case 'popup': {\r\n this.coverDiv.style.position = 'fixed';\r\n // this.coverDiv.style.position = 'absolute';\r\n this.coverDiv.style.top = '0px';\r\n this.coverDiv.style.left = '0px';\r\n this.coverDiv.style.width = '100vw';\r\n this.coverDiv.style.height = `${window.innerHeight}px`;\r\n this.coverDiv.style.backgroundColor = 'rgba(0, 0, 0, 0.75)';\r\n this.coverDiv.style.zIndex =\r\n this.uiStyleSettings.zIndex !== undefined\r\n ? this.uiStyleSettings.zIndex\r\n : '1000';\r\n this.coverDiv.style.display = 'flex';\r\n // this.coverDiv.style.overflow = 'auto';\r\n }\r\n }\r\n this.targetRoot.appendChild(this.coverDiv);\r\n\r\n this.uiDiv = document.createElement('div');\r\n this.uiDiv.style.display = 'flex';\r\n this.uiDiv.style.flexDirection = 'column';\r\n this.uiDiv.style.flexGrow = '2';\r\n this.uiDiv.style.margin =\r\n this.settings.displayMode === 'popup'\r\n ? `${this.settings.popupMargin}px`\r\n : '0px';\r\n if (this.settings.displayMode === 'popup') {\r\n this.uiDiv.style.maxWidth = `calc(100vw - ${this.settings.popupMargin * 2}px`;\r\n }\r\n this.uiDiv.style.border = '0px';\r\n // this.uiDiv.style.overflow = 'hidden';\r\n //this.uiDiv.style.backgroundColor = '#ffffff';\r\n this.coverDiv.appendChild(this.uiDiv);\r\n\r\n this.toolbar = new Toolbar(\r\n this.uiDiv,\r\n this.settings.displayMode,\r\n this._availableMarkerTypes,\r\n this.uiStyleSettings,\r\n this.styles\r\n );\r\n this.toolbar.addButtonClickListener(this.toolbarButtonClicked);\r\n this.toolbar.show(\r\n this._silentRenderMode || this.uiStyleSettings.hideToolbar\r\n ? 'hidden'\r\n : 'visible'\r\n );\r\n\r\n this.contentDiv = document.createElement('div');\r\n this.contentDiv.style.display = 'flex';\r\n this.contentDiv.style.flexDirection = 'row';\r\n this.contentDiv.style.flexGrow = '2';\r\n this.contentDiv.style.flexShrink = '1';\r\n if (this.settings.displayMode === 'popup') {\r\n this.contentDiv.style.backgroundColor = this.uiStyleSettings.canvasBackgroundColor;\r\n this.contentDiv.style.maxHeight = `${\r\n this.windowHeight -\r\n this.settings.popupMargin * 2 -\r\n this.uiStyleSettings.toolbarHeight * 3.5\r\n }px`;\r\n // this.contentDiv.style.maxHeight = `calc(100vh - ${\r\n // this.settings.popupMargin * 2 + this.uiStyleSettings.toolbarHeight * 3.5}px)`;\r\n this.contentDiv.style.maxWidth = `calc(100vw - ${\r\n this.settings.popupMargin * 2\r\n }px)`;\r\n }\r\n this.contentDiv.style.overflow = 'auto';\r\n this.uiDiv.appendChild(this.contentDiv);\r\n\r\n this.editorCanvas = document.createElement('div');\r\n this.editorCanvas.style.flexGrow = '2';\r\n this.editorCanvas.style.flexShrink = '1';\r\n this.editorCanvas.style.position = 'relative';\r\n this.editorCanvas.style.overflow = 'hidden';\r\n this.editorCanvas.style.display = 'flex';\r\n if (this.settings.displayMode === 'popup') {\r\n this.editorCanvas.style.alignItems = 'center';\r\n this.editorCanvas.style.justifyContent = 'center';\r\n }\r\n this.editorCanvas.style.pointerEvents = 'none';\r\n this.editorCanvas.style.transformOrigin = 'left top';\r\n this.editorCanvas.style.transform = `scale(${this.zoomLevel})`;\r\n this.contentDiv.appendChild(this.editorCanvas);\r\n\r\n this.editingTarget =\r\n this.target instanceof HTMLImageElement\r\n ? document.createElement('img')\r\n : document.createElement('canvas');\r\n if (this.settings.displayMode === 'inline' \r\n && this.settings.uiOffsetTop === undefined \r\n && this.target.offsetTop < this.styles.settings.toolbarHeight) {\r\n this.editingTarget.style.marginTop = `${\r\n this.target.offsetTop - this.styles.settings.toolbarHeight\r\n }px`;\r\n }\r\n this.editorCanvas.appendChild(this.editingTarget);\r\n\r\n this.toolbox = new Toolbox(\r\n this.uiDiv,\r\n this.settings.displayMode,\r\n this.uiStyleSettings,\r\n this.styles\r\n );\r\n this.toolbox.show(\r\n this._silentRenderMode || this.uiStyleSettings.hideToolbox\r\n ? 'hidden'\r\n : 'visible'\r\n );\r\n }\r\n\r\n private closeUI() {\r\n if (this.settings.displayMode === 'popup') {\r\n this.restoreOverflow();\r\n }\r\n // @todo better cleanup\r\n this.targetRoot.removeChild(this.coverDiv);\r\n this.coverDiv.remove();\r\n this.coverDiv = null;\r\n }\r\n\r\n private removeMarker(marker: MarkerBase) {\r\n this.markerImage.removeChild(marker.container);\r\n if (this.markers.indexOf(marker) > -1) {\r\n this.markers.splice(this.markers.indexOf(marker), 1);\r\n }\r\n marker.dispose();\r\n }\r\n\r\n public switchToSelectMode(): void {\r\n this.mode = 'select';\r\n this.hideNotesEditor();\r\n if (this._currentMarker !== undefined) {\r\n if (this._currentMarker.state !== 'new') {\r\n this._currentMarker.select();\r\n } else {\r\n this.removeMarker(this._currentMarker);\r\n this.setCurrentMarker();\r\n this.markerImage.style.cursor = 'default';\r\n }\r\n this.addUndoStep();\r\n }\r\n }\r\n\r\n private toolbarButtonClicked(\r\n buttonType: ToolbarButtonType,\r\n value?: typeof MarkerBase | string\r\n ) {\r\n if (buttonType === 'marker' && value !== undefined) {\r\n this.createNewMarker(<typeof MarkerBase>value);\r\n } else if (buttonType === 'action') {\r\n switch (value) {\r\n case 'select': {\r\n this.switchToSelectMode();\r\n // workaround for text markers in continuos mode\r\n // otherwise it continues creation until clicked a second time\r\n this.switchToSelectMode();\r\n break;\r\n }\r\n case 'delete': {\r\n this.deleteSelectedMarker();\r\n break;\r\n }\r\n case 'clear': {\r\n this.clear();\r\n break;\r\n }\r\n case 'undo': {\r\n this.undo();\r\n break;\r\n }\r\n case 'redo': {\r\n this.redo();\r\n break;\r\n }\r\n case 'zoom': {\r\n this.stepZoom();\r\n break;\r\n }\r\n case 'zoom-out': {\r\n this.zoomLevel = 1;\r\n break;\r\n }\r\n case 'notes': {\r\n if (this.notesArea === undefined) {\r\n this.switchToSelectMode();\r\n this.zoomLevel = 1;\r\n this.showNotesEditor();\r\n } else {\r\n this.switchToSelectMode();\r\n }\r\n break;\r\n }\r\n case 'close': {\r\n this.close();\r\n break;\r\n }\r\n case 'render': {\r\n this.switchToSelectMode();\r\n this.startRenderAndClose();\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Removes currently selected marker.\r\n */\r\n public deleteSelectedMarker(): void {\r\n if (this._currentMarker !== undefined) {\r\n let cancel = false;\r\n\r\n this.eventListeners['markerbeforedelete'].forEach((listener) => {\r\n const ev = new MarkerEvent(this, this._currentMarker, true);\r\n listener(ev);\r\n if (ev.defaultPrevented) {\r\n cancel = true;\r\n }\r\n });\r\n\r\n if (!cancel) {\r\n const marker = this._currentMarker;\r\n this._currentMarker.dispose();\r\n this.markerImage.removeChild(this._currentMarker.container);\r\n this.markers.splice(this.markers.indexOf(this._currentMarker), 1);\r\n this.setCurrentMarker();\r\n this.addUndoStep();\r\n this.eventListeners['markerdelete'].forEach((listener) =>\r\n listener(new MarkerEvent(this, marker))\r\n );\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Removes all markers.\r\n *\r\n * @since 2.15.0\r\n */\r\n public clear(): void {\r\n let cancel = false;\r\n if (this.markers.length > 0) {\r\n this.eventListeners['markerbeforedelete'].forEach((listener) => {\r\n const ev = new MarkerEvent(this, undefined, true);\r\n listener(ev);\r\n if (ev.defaultPrevented) {\r\n cancel = true;\r\n }\r\n });\r\n if (!cancel) {\r\n this.setCurrentMarker();\r\n for (let i = this.markers.length - 1; i >= 0; i--) {\r\n const marker = this.markers[i];\r\n this.setCurrentMarker(this.markers[i]);\r\n this._currentMarker.dispose();\r\n this.markerImage.removeChild(this._currentMarker.container);\r\n this.markers.splice(this.markers.indexOf(this._currentMarker), 1);\r\n this.eventListeners['markerdelete'].forEach((listener) =>\r\n listener(new MarkerEvent(this, marker))\r\n );\r\n }\r\n this.addUndoStep();\r\n }\r\n }\r\n }\r\n\r\n private notesArea?: HTMLTextAreaElement;\r\n private get isNotesAreaOpen(): boolean {\r\n return this.notesArea !== undefined;\r\n }\r\n\r\n private showNotesEditor() {\r\n if (this._currentMarker !== undefined) {\r\n this.overlayContainer.innerHTML = '';\r\n this.notesArea = document.createElement('textarea');\r\n this.notesArea.className = this.uiStyleSettings.notesAreaStyleClassName;\r\n this.notesArea.style.pointerEvents = 'auto';\r\n this.notesArea.style.alignSelf = 'stretch';\r\n this.notesArea.style.width = '100%';\r\n this.notesArea.style.margin = `${\r\n this.uiStyleSettings.toolbarHeight / 4\r\n }px`;\r\n this.notesArea.value = this._currentMarker.notes ?? '';\r\n this.overlayContainer.appendChild(this.notesArea);\r\n }\r\n }\r\n private hideNotesEditor() {\r\n if (this.isNotesAreaOpen) {\r\n if (this._currentMarker !== undefined) {\r\n this._currentMarker.notes =\r\n this.notesArea.value.trim() !== '' ? this.notesArea.value : undefined;\r\n }\r\n this.overlayContainer.removeChild(this.notesArea);\r\n this.notesArea = undefined;\r\n }\r\n }\r\n\r\n private selectLastMarker() {\r\n if (this.markers.length > 0) {\r\n this.setCurrentMarker(this.markers[this.markers.length - 1]);\r\n } else {\r\n this.setCurrentMarker();\r\n }\r\n }\r\n\r\n private addUndoStep() {\r\n if (\r\n this._currentMarker === undefined ||\r\n this._currentMarker.state !== 'edit'\r\n ) {\r\n const currentState = this.getState();\r\n const lastUndoState = this.undoRedoManager.getLastUndoStep();\r\n if (\r\n lastUndoState &&\r\n (lastUndoState.width !== currentState.width ||\r\n lastUndoState.height !== currentState.height)\r\n ) {\r\n // if the size changed just replace the last step with a resized one\r\n this.undoRedoManager.replaceLastUndoStep(currentState);\r\n // @todo was sometimes fired on zoom events in popup mode\r\n // need to find the root cause before restoring statechange event here (if needed?)\r\n // this.eventListeners['statechange'].forEach((listener) =>\r\n // listener(new MarkerAreaEvent(this))\r\n // );\r\n } else {\r\n const beforeSteps = this.undoRedoManager.undoStepCount;\r\n this.undoRedoManager.addUndoStep(currentState);\r\n if (beforeSteps < this.undoRedoManager.undoStepCount) {\r\n this.eventListeners['statechange'].forEach((listener) =>\r\n listener(new MarkerAreaEvent(this))\r\n );\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Undo last action.\r\n *\r\n * @since 2.6.0\r\n */\r\n public undo(): void {\r\n this.switchToSelectMode();\r\n this.addUndoStep();\r\n this.undoStep();\r\n }\r\n\r\n private undoStep(): void {\r\n const stepData = this.undoRedoManager.undo();\r\n if (stepData !== undefined) {\r\n this.restoreState(stepData);\r\n this.addDefsToImage();\r\n this.selectLastMarker();\r\n this.eventListeners['statechange'].forEach((listener) =>\r\n listener(new MarkerAreaEvent(this))\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Redo previously undone action.\r\n *\r\n * @since 2.6.0\r\n */\r\n public redo(): void {\r\n this.switchToSelectMode();\r\n this.redoStep();\r\n }\r\n\r\n private redoStep(): void {\r\n const stepData = this.undoRedoManager.redo();\r\n if (stepData !== undefined) {\r\n this.restoreState(stepData);\r\n this.addDefsToImage();\r\n this.selectLastMarker();\r\n this.eventListeners['statechange'].forEach((listener) =>\r\n listener(new MarkerAreaEvent(this))\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Iterate zoom steps (@linkcode zoomSteps).\r\n * Next zoom level is selected or returns to the first zoom level restarting the sequence.\r\n *\r\n * @since 2.12.0\r\n */\r\n public stepZoom(): void {\r\n const zoomStepIndex = this.zoomSteps.indexOf(this.zoomLevel);\r\n this.zoomLevel =\r\n zoomStepIndex < this.zoomSteps.length - 1\r\n ? this.zoomSteps[zoomStepIndex + 1]\r\n : this.zoomSteps[0];\r\n }\r\n\r\n private prevPanPoint: IPoint = { x: 0, y: 0 };\r\n private panTo(point: IPoint) {\r\n this.contentDiv.scrollBy({\r\n left: this.prevPanPoint.x - point.x,\r\n top: this.prevPanPoint.y - point.y,\r\n });\r\n this.prevPanPoint = point;\r\n }\r\n\r\n /**\r\n * Initiates markup rendering.\r\n *\r\n * Get results by adding a render event listener via {@linkcode addRenderEventListener}.\r\n */\r\n public async startRenderAndClose(): Promise<void> {\r\n const result = await this.render();\r\n const state = this.getState();\r\n //this.renderEventListeners.forEach((listener) => listener(result, state));\r\n this.eventListeners['render'].forEach((listener) =>\r\n listener(new MarkerAreaRenderEvent(this, result, state))\r\n );\r\n this.close(true);\r\n }\r\n\r\n /**\r\n * Returns the complete state for the MarkerArea that can be preserved and used\r\n * to continue annotation next time.\r\n *\r\n * @param deselectCurrentMarker - when `true` is passed, currently selected marker will be deselected before getting the state.\r\n */\r\n public getState(deselectCurrentMarker?: boolean): MarkerAreaState {\r\n if (deselectCurrentMarker === true) {\r\n this.setCurrentMarker();\r\n }\r\n const result: MarkerAreaState = {\r\n width: this.imageWidth,\r\n height: this.imageHeight,\r\n markers: [],\r\n };\r\n this.markers.forEach((marker) => result.markers.push(marker.getState()));\r\n return result;\r\n }\r\n\r\n /**\r\n * Restores MarkerArea state to continue previous annotation session.\r\n *\r\n * **IMPORTANT**: call `restoreState()` __after__ you've opened the MarkerArea with {@linkcode show}.\r\n *\r\n * ```typescript\r\n * this.markerArea1.show();\r\n * if (this.currentState) {\r\n * this.markerArea1.restoreState(this.currentState);\r\n * }\r\n * ```\r\n *\r\n * @param state - previously saved state object.\r\n */\r\n public restoreState(state: MarkerAreaState): void {\r\n this.markers.splice(0);\r\n while (this.markerImage.lastChild) {\r\n this.markerImage.removeChild(this.markerImage.lastChild);\r\n }\r\n\r\n state.markers.forEach((markerState) => {\r\n const markerType = this._availableMarkerTypes.find(\r\n (mType) => mType.typeName === markerState.typeName\r\n );\r\n if (markerType !== undefined) {\r\n const marker = this.addNewMarker(markerType);\r\n marker.restoreState(markerState);\r\n this.markers.push(marker);\r\n }\r\n });\r\n if (\r\n state.width &&\r\n state.height &&\r\n (state.width !== this.imageWidth || state.height !== this.imageHeight)\r\n ) {\r\n this.scaleMarkers(\r\n this.imageWidth / state.width,\r\n this.imageHeight / state.height\r\n );\r\n }\r\n this.eventListeners['restorestate'].forEach((listener) =>\r\n listener(new MarkerAreaEvent(this))\r\n );\r\n }\r\n\r\n private addNewMarker(markerType: typeof MarkerBase): MarkerBase {\r\n const g = SvgHelper.createGroup();\r\n this.markerImage.appendChild(g);\r\n\r\n return new markerType(g, this.overlayContainer, this.settings);\r\n }\r\n\r\n /**\r\n * Initiate new marker creation.\r\n *\r\n * marker.js switches to marker creation mode for the marker type specified\r\n * and users can draw a new marker like they would by pressing a corresponding\r\n * toolbar button.\r\n *\r\n * This example initiates creation of a `FrameMarker`:\r\n * ```typescript\r\n * this.markerArea1.createNewMarker(FrameMarker);\r\n * ```\r\n *\r\n * @param markerType\r\n */\r\n public createNewMarker(markerType: typeof MarkerBase | string): void {\r\n let mType: typeof MarkerBase;\r\n\r\n if (typeof markerType === 'string') {\r\n mType = this._availableMarkerTypes.find(\r\n (mt) => mt.typeName === markerType\r\n );\r\n } else {\r\n mType = markerType;\r\n }\r\n\r\n if (mType) {\r\n this.setCurrentMarker();\r\n this.addUndoStep();\r\n this._currentMarker = this.addNewMarker(mType);\r\n this._currentMarker.onMarkerCreated = this.markerCreated;\r\n this._currentMarker.onColorChanged = this.colorChanged;\r\n this._currentMarker.onFillColorChanged = this.fillColorChanged;\r\n this._currentMarker.onStateChanged = this.markerStateChanged;\r\n this.markerImage.style.cursor = 'crosshair';\r\n this.toolbar.setActiveMarkerButton(mType.typeName);\r\n this.toolbox.setPanelButtons(this._currentMarker.toolboxPanels);\r\n this.eventListeners['markercreating'].forEach((listener) =>\r\n listener(new MarkerEvent(this, this._currentMarker))\r\n );\r\n }\r\n }\r\n\r\n private markerCreated(marker: MarkerBase) {\r\n this.mode = 'select';\r\n this.markerImage.style.cursor = 'default';\r\n this.markers.push(marker);\r\n this.setCurrentMarker(marker);\r\n if (\r\n marker instanceof FreehandMarker &&\r\n this.settings.newFreehandMarkerOnPointerUp\r\n ) {\r\n this.createNewMarker(FreehandMarker);\r\n } else {\r\n this.toolbar.setSelectMode();\r\n }\r\n this.addUndoStep();\r\n this.eventListeners['markercreate'].forEach((listener) =>\r\n listener(new MarkerEvent(this, marker))\r\n );\r\n }\r\n\r\n private colorChanged(color: string): void {\r\n if (this.settings.defaultColorsFollowCurrentColors) {\r\n this.settings.defaultColor = color;\r\n this.settings.defaultStrokeColor = color;\r\n }\r\n }\r\n private fillColorChanged(color: string): void {\r\n if (this.settings.defaultColorsFollowCurrentColors) {\r\n this.settings.defaultFillColor = color;\r\n }\r\n }\r\n\r\n private markerStateChanged(marker: MarkerBase): void {\r\n this.eventListeners['markerchange'].forEach((listener) =>\r\n listener(new MarkerEvent(this, marker))\r\n );\r\n }\r\n\r\n /**\r\n * Sets the currently selected marker or deselects it if no parameter passed.\r\n *\r\n * @param marker marker to select. Deselects current marker if undefined.\r\n */\r\n public setCurrentMarker(marker?: MarkerBase): void {\r\n if (this._currentMarker !== marker) {\r\n // no need to deselect if not changed\r\n if (this._currentMarker !== undefined) {\r\n this._currentMarker.deselect();\r\n this.toolbar.setCurrentMarker();\r\n this.toolbox.setPanelButtons([]);\r\n\r\n if (!this._isResizing) {\r\n this.eventListeners['markerdeselect'].forEach((listener) =>\r\n listener(new MarkerEvent(this, this._currentMarker))\r\n );\r\n }\r\n }\r\n }\r\n this._currentMarker = marker;\r\n if (this._currentMarker !== undefined && !this._currentMarker.isSelected) {\r\n if (this._currentMarker.state !== 'new') {\r\n this._currentMarker.select();\r\n }\r\n this.toolbar.setCurrentMarker(this._currentMarker);\r\n this.toolbox.setPanelButtons(this._currentMarker.toolboxPanels);\r\n\r\n if (!this._isResizing) {\r\n this.eventListeners['markerselect'].forEach((listener) =>\r\n listener(new MarkerEvent(this, this._currentMarker))\r\n );\r\n }\r\n }\r\n }\r\n\r\n private onPointerDown(ev: PointerEvent) {\r\n if (!this._isFocused) {\r\n this.focus();\r\n }\r\n\r\n this.touchPoints++;\r\n if (this.touchPoints === 1 || ev.pointerType !== 'touch') {\r\n if (\r\n this._currentMarker !== undefined &&\r\n (this._currentMarker.state === 'new' ||\r\n this._currentMarker.state === 'creating')\r\n ) {\r\n this.isDragging = true;\r\n this._currentMarker.pointerDown(\r\n this.clientToLocalCoordinates(ev.clientX, ev.clientY)\r\n );\r\n } else if (this.mode === 'select') {\r\n const hitMarker = this.markers.find((m) => m.ownsTarget(ev.target));\r\n if (hitMarker !== undefined) {\r\n this.setCurrentMarker(hitMarker);\r\n this.isDragging = true;\r\n this._currentMarker.pointerDown(\r\n this.clientToLocalCoordinates(ev.clientX, ev.clientY),\r\n ev.target\r\n );\r\n } else {\r\n this.setCurrentMarker();\r\n this.isDragging = true;\r\n this.prevPanPoint = { x: ev.clientX, y: ev.clientY };\r\n }\r\n }\r\n }\r\n }\r\n\r\n private onDblClick(ev: PointerEvent) {\r\n if (!this._isFocused) {\r\n this.focus();\r\n }\r\n\r\n if (this.mode === 'select') {\r\n const hitMarker = this.markers.find((m) => m.ownsTarget(ev.target));\r\n if (hitMarker !== undefined && hitMarker !== this._currentMarker) {\r\n this.setCurrentMarker(hitMarker);\r\n }\r\n if (this._currentMarker !== undefined) {\r\n this._currentMarker.dblClick(\r\n this.clientToLocalCoordinates(ev.clientX, ev.clientY),\r\n ev.target\r\n );\r\n } else {\r\n this.setCurrentMarker();\r\n }\r\n }\r\n }\r\n\r\n private onPointerMove(ev: PointerEvent) {\r\n if (this.touchPoints === 1 || ev.pointerType !== 'touch') {\r\n if (this._currentMarker !== undefined || this.isDragging) {\r\n // don't swallow the event when editing text markers\r\n if (\r\n this._currentMarker === undefined ||\r\n this._currentMarker.state !== 'edit'\r\n ) {\r\n ev.preventDefault();\r\n }\r\n\r\n if (this._currentMarker !== undefined) {\r\n this._currentMarker.manipulate(\r\n this.clientToLocalCoordinates(ev.clientX, ev.clientY)\r\n );\r\n } else if (this.zoomLevel > 1) {\r\n this.panTo({ x: ev.clientX, y: ev.clientY });\r\n }\r\n }\r\n }\r\n }\r\n private onPointerUp(ev: PointerEvent) {\r\n if (this.touchPoints > 0) {\r\n this.touchPoints--;\r\n }\r\n if (this.touchPoints === 0) {\r\n if (this.isDragging && this._currentMarker !== undefined) {\r\n this._currentMarker.pointerUp(\r\n this.clientToLocalCoordinates(ev.clientX, ev.clientY)\r\n );\r\n }\r\n }\r\n this.isDragging = false;\r\n this.addUndoStep();\r\n }\r\n\r\n private onPointerOut(/*ev: PointerEvent*/) {\r\n if (this.touchPoints > 0) {\r\n this.touchPoints--;\r\n }\r\n }\r\n\r\n private onKeyUp(ev: KeyboardEvent) {\r\n if (\r\n this._currentMarker !== undefined &&\r\n this.notesArea === undefined &&\r\n (ev.key === 'Delete' || ev.key === 'Backspace')\r\n ) {\r\n this.deleteSelectedMarker();\r\n // this.setCurrentMarker();\r\n // this.markerImage.style.cursor = 'default';\r\n // this.addUndoStep();\r\n }\r\n }\r\n\r\n private clientToLocalCoordinates(x: number, y: number): IPoint {\r\n const clientRect = this.markerImage.getBoundingClientRect();\r\n const scaleX = clientRect.width / this.imageWidth / this.zoomLevel;\r\n const scaleY = clientRect.height / this.imageHeight / this.zoomLevel;\r\n return {\r\n x: (x - clientRect.left) / this.zoomLevel / scaleX,\r\n y: (y - clientRect.top) / this.zoomLevel / scaleY,\r\n };\r\n }\r\n\r\n private onWindowResize() {\r\n this.positionUI();\r\n }\r\n\r\n private positionUI() {\r\n this.setTopLeft();\r\n switch (this.settings.displayMode) {\r\n case 'inline': {\r\n const rects = this.target.getClientRects();\r\n const coverTop =\r\n rects.length > 0 && rects.item(0) &&\r\n (rects.item(0).y > this.styles.settings.toolbarHeight)\r\n ? this.target.offsetTop - this.styles.settings.toolbarHeight\r\n : 0;\r\n this.coverDiv.style.top = `${coverTop}px`;\r\n this.coverDiv.style.left = `${this.target.offsetLeft.toString()}px`;\r\n break;\r\n }\r\n case 'popup': {\r\n this.coverDiv.style.top = '0px';\r\n this.coverDiv.style.left = '0px';\r\n this.coverDiv.style.width = '100vw';\r\n this.coverDiv.style.height = `${this.windowHeight}px`;\r\n this.contentDiv.style.maxHeight = `${\r\n this.windowHeight -\r\n this.settings.popupMargin * 2 -\r\n this.styles.settings.toolbarHeight * 3.5\r\n }px`;\r\n }\r\n }\r\n this.positionMarkerImage();\r\n this.positionLogo();\r\n }\r\n\r\n /**\r\n * Add license key.\r\n *\r\n * This is a proxy method for {@linkcode Activator.addKey()}.\r\n *\r\n * @param key - commercial license key.\r\n */\r\n public addLicenseKey(key: string): void {\r\n Activator.addKey(key);\r\n }\r\n\r\n private eventListeners = new EventListenerRepository();\r\n /**\r\n * Adds an event listener for one of the marker.js Live events.\r\n *\r\n * @param eventType - type of the event.\r\n * @param handler - function handling the event.\r\n *\r\n * @since 2.16.0\r\n */\r\n public addEventListener<T extends keyof IEventListenerRepository>(\r\n eventType: T,\r\n handler: EventHandler<T>\r\n ): void {\r\n this.eventListeners.addEventListener(eventType, handler);\r\n }\r\n\r\n /**\r\n * Removes an event listener for one of the marker.js Live events.\r\n *\r\n * @param eventType - type of the event.\r\n * @param handler - function currently handling the event.\r\n *\r\n * @since 2.16.0\r\n */\r\n public removeEventListener<T extends keyof IEventListenerRepository>(\r\n eventType: T,\r\n handler: EventHandler<T>\r\n ): void {\r\n this.eventListeners.removeEventListener(eventType, handler);\r\n }\r\n\r\n private _silentRenderMode = false;\r\n /**\r\n * Renders previously saved state without user intervention.\r\n *\r\n * The rendered image is returned to the `render` event handlers (as in the regular interactive process).\r\n * Rendering options set on `MarkerArea` are respected.\r\n *\r\n * @param state state to render\r\n *\r\n * @since 2.17.0\r\n */\r\n public renderState(state: MarkerAreaState): void {\r\n this._silentRenderMode = true;\r\n this.settings.displayMode = 'inline';\r\n if (!this.isOpen) {\r\n this.show();\r\n }\r\n this.restoreState(state);\r\n this.startRenderAndClose();\r\n this._silentRenderMode = false;\r\n }\r\n\r\n private _isFocused = false;\r\n /**\r\n * Returns true when this MarkerArea is focused.\r\n *\r\n * @since 2.19.0\r\n */\r\n public get isFocused(): boolean {\r\n return this._isFocused;\r\n }\r\n\r\n private _previousCurrentMarker?: MarkerBase;\r\n\r\n /**\r\n * Focuses the MarkerArea to receive all input from the window.\r\n *\r\n * Is called automatically when user clicks inside of the marker area. Call manually to set focus explicitly.\r\n *\r\n * @since 2.19.0\r\n */\r\n public focus(): void {\r\n if (!this._isFocused) {\r\n this.attachWindowEvents();\r\n this._isFocused = true;\r\n if (this._previousCurrentMarker !== undefined) {\r\n this.setCurrentMarker(this._previousCurrentMarker);\r\n }\r\n this.eventListeners['focus'].forEach((listener) =>\r\n listener(new MarkerAreaEvent(this))\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Tells MarkerArea to stop reacting to input outside of the immediate marker image.\r\n *\r\n * Call `focus()` to re-enable.\r\n *\r\n * @since 2.19.0\r\n */\r\n public blur(): void {\r\n if (this._isFocused) {\r\n this.detachWindowEvents();\r\n this._isFocused = false;\r\n this._previousCurrentMarker = this._currentMarker;\r\n this.setCurrentMarker();\r\n this.eventListeners['blur'].forEach((listener) =>\r\n listener(new MarkerAreaEvent(this))\r\n );\r\n }\r\n }\r\n}\r\n"],"names":["extendStatics","d","b","Object","setPrototypeOf","__proto__","Array","p","prototype","hasOwnProperty","call","__extends","__","this","constructor","create","__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","value","step","next","e","rejected","result","done","then","apply","__generator","body","f","y","t","g","_","label","sent","trys","ops","verb","throw","return","Symbol","iterator","n","v","op","TypeError","pop","length","push","__spreadArrays","s","i","il","arguments","r","k","a","j","jl","SvgHelper","document","createElementNS","el","attributes","attributes_1","_i","_a","attr","setAttribute","width","height","rect","toString","setAttributes","x1","y1","x2","y2","line","points","polygon","radius","circle","rx","ry","ellipse","createSVGTransform","id","orient","markerWidth","markerHeight","refX","refY","markerElement","marker","appendChild","text","tspan","textContent","image","x","svgPoint","createSVGPoint","path","Activator","key","RegExp","test","Renderer","target","markerImage","targetCanvas","canvas","undefined","createElement","_this","markersOnly","naturalSize","markerImageCopy","baseVal","valueAsString","viewBox","innerHTML","naturalWidth","naturalHeight","data","outerHTML","ctx","getContext","drawImage","DOMURL","window","URL","img","Image","blob","Blob","type","url","createObjectURL","onload","revokeObjectURL","toDataURL","imageType","imageQuality","src","instanceNo","defaultSettings","_classNamePrefix","_classNamePrefixBase","StyleManager","canvasBackgroundColor","toolbarBackgroundColor","toolbarBackgroundHoverColor","toolbarColor","toolbarHeight","toolboxColor","toolboxAccentColor","undoButtonVisible","redoButtonVisible","zoomButtonVisible","zoomOutButtonVisible","clearButtonVisible","resultButtonBlockVisible","logoPosition","classNamePrefix","styleClass","styleSheet","addStyleSheet","name","localName","classes","sheet","insertRule","style","cssRules","styleRule","rules","selector","styleSheetRoot","head","addRule","StyleRule","addClass","StyleClass","removeChild","markerjsContainer","displayMode","markerItems","uiStyleSettings","styles","addStyles","adjustLayout","bind","overflowButtonClicked","setCurrentMarker","Toolbar","visiblity","uiContainer","visibility","className","toolbarStyleClass","fadeInAnimationClassName","toolbarStyleColorsClassName","toolbarStyleColorsClass","actionButtonBlock","toolbarBlockStyleClass","whiteSpace","addActionButton","notesButtonVisible","markerButtonBlock","flexGrow","textAlign","markerButtonOverflowBlock","toolbarOverflowBlockStyleClass","toolbarOverflowBlockStyleColorsClassName","toolbarOverflowBlockStyleColorsClass","display","forEach","mi","buttonContainer","toolbarButtonStyleClass","typeName","title","icon","addEventListener","markerToolbarButtonClicked","buttons","markerButtons","overflowButton","toolbarButtonStyleColorsClassName","toolbarButtonStyleColorsClass","resultButtonBlock","setSelectMode","listener","buttonClickListeners","indexOf","splice","resetButtonStyles","setActiveButton","numberToFit","Math","floor","clientWidth","buttonIndex","replace","top","offsetTop","offsetHeight","right","offsetWidth","offsetLeft","button","trim","toolbarActiveButtonStyleColorsClassName","toolbarActiveButtonStyleColorsClass","container","actionButton","actionToolbarButtonClicked","fill","selectButtonColor","deleteButtonColor","okButtonColor","closeButtonColor","round","buttonPadding","markerType","action","activeBtn","find","btn","getAttribute","currentMarker","filter","fillOpacity","pointerEvents","panelButtonClick","Toolbox","toolboxStyleClass","toolboxStyleColorsClass","toolboxButtonRowStyleClass","toolboxButtonRowStyleColorsClass","toolboxPanelRowStyleClass","toolboxPanelRowStyleColorsClass","toolboxBackgroundColor","toolboxButtonStyleClass","toolboxButtonStyleColorsClass","toolboxActiveButtonStyleColorsClass","toolboxStyleColorsClassName","panels","panelRow","toolboxPanelRowStyleColorsClassName","buttonRow","toolboxButtonRowStyleColorsClassName","panelButtons","panel","panelBtnDiv","toolboxButtonStyleColorsClassName","panelIndex","activePanel","panelUI","getUi","margin","fadeOutAnimationClassName","setTimeout","pb","index","toolboxActiveButtonStyleColorsClassName","ToolboxPanel","_id","colors","currentColor","_super","setCurrentColor","getColorBox","ColorPickerPanel","panelDiv","overflow","overflowX","color","colorBoxContainer","colorBoxes","buttonHeight","boxSizing","padding","marginRight","marginBottom","borderWidth","borderStyle","borderRadius","borderColor","colorBox","backgroundColor","box","onColorChanged","overlayContainer","settings","_container","_overlayContainer","globalSettings","stateChanged","colorChanged","fillColorChanged","MarkerBase","getPrototypeOf","_state","_isSelected","cursor","manipulationStartState","getState","point","element","childNodes","insertBefore","state","notes","scaleX","scaleY","onFillColorChanged","onStateChanged","currentState","JSON","stringify","findGripByVisual","RectangularBoxMarkerGrips","gripVisual","topLeft","ownsTarget","topCenter","topRight","centerLeft","centerRight","bottomLeft","bottomCenter","bottomRight","visual","createGroup","createCircle","GRIP_SIZE","ResizeGrip","TransformMatrix","matrix","c","currentMatrix","newMatrix","transform","appendItem","createTransform","setupControlBox","RectangularBoxMarkerBase","left","_visual","translate","controlGrips","rotatorGrip","pointerDown","manipulationStartLeft","manipulationStartTop","manipulationStartWidth","manipulationStartHeight","rotatedPoint","unrotatePoint","manipulationStartX","manipulationStartY","offsetX","offsetY","select","activeGrip","rotatedCenter","rotatePoint","centerX","centerY","moveVisual","rotate","getItem","setRotate","rotationAngle","replaceItem","adjustControlBox","inState","pointerUp","defaultSize","manipulate","onMarkerCreated","_suppressMarkerCreateEvent","resize","newX","newWidth","newY","newHeight","setSize","abs","sign","atan","PI","applyRotation","getCTM","createPoint","matrixTransform","inverse","controlBox","deselect","setTranslate","CB_DISTANCE","controlRect","createRect","disableRotation","rotatorGripLine","createLine","addControlGrips","positionGrips","createGrip","grip","gripSize","cx","cy","bottom","positionGrip","assign","visualTransformMatrix","toITransformMatrix","containerTransformMatrix","restoreState","rbmState","setMatrix","toSVGMatrix","scale","rPoint","setStrokeColor","setFillColor","setStrokeWidth","setStrokeDasharray","createVisual","RectangleMarker","fillColor","strokeColor","strokeWidth","strokeDasharray","opacity","addMarkerVisualToContainer","dashes","rectState","widths","currentWidth","setCurrentWidth","LineWidthPanel","lineWidth","widthBoxContainer","alignItems","justifyContent","innerText","widthBox","minHeight","hr","minWidth","border","borderTop","widthBoxes","onWidthChanged","currentStyle","setCurrentStyle","LineStylePanel","lineStyle","styleBoxContainer","maxWidth","styleBox","styleSample","styleBoxes","newStyle","onStyleChanged","defaultColor","defaultStrokeWidth","defaultStrokeDasharray","strokePanel","defaultColorSet","strokeWidthPanel","defaultStrokeWidths","strokeStylePanel","defaultStrokeDasharrays","FrameMarker","LinearMarkerBase","grip1","grip2","manipulationStartX1","manipulationStartY1","manipulationStartX2","manipulationStartY2","defaultLength","adjustVisual","lmbState","LineMarker","selectorLine","visibleLine","lmState","fonts","currentFont","setCurrentFont","FontFamilyPanel","font","fontBoxContainer","fontBox","fontFamily","fontLabel","textOverflow","fontBoxes","newFont","onFontChanged","DEFAULT_TEXT","defaultFontFamily","setColor","setFont","renderText","sizeText","textEditDivClicked","showTextEditor","positionTextEditor","wrapText","colorPanel","fontFamilyPanel","defaultFontFamilies","TextMarker","textElement","bgRectangle","found_1","span","createText","isMoved","pointerDownPoint","pointerDownTimestamp","Date","now","getTextAspectRatio","textLines","longestLineChars","lines","split","boxAspectRatio","processedLines_1","textAspectRatio","maxLineLength_1","Number","MAX_VALUE","longestLine","lastIndexOf","reminderLine","maxEnd","substring","join","lastChild","createTSpan","textSize","getBBox","xScale","yScale","min","xSign","getComputedStyle","direction","textBBox","getTextScale","position","getTextPosition","navigator","userAgent","setScale","textEditDiv","textEditor","lineHeight","contentEditable","ev","stopPropagation","fontSize","parseFloat","parseInt","max","cancelBubble","clipboardData","content","getData","selection","getSelection","rangeCount","deleteFromDocument","getRangeAt","insertNode","createTextNode","preventDefault","hideVisual","focus","execCommand","maxHeight","textScale","rPosition","rWH","showVisual","dblClick","hideControlBox","showControlBox","textState","pixelRatio","freehandPixelRatio","addCanvas","finishCreation","setLineWidth","lineWidthPanel","FreehandMarker","drawingImage","createImage","canvasContext","strokeStyle","beginPath","moveTo","drawing","lineTo","stroke","closePath","newFreehandMarkerOnPointerUp","canvasElement","clientHeight","imgData","getImageData","startX","startY","endX","endY","containsData","row","col","tmpCanvas","putImageData","drawingImgUrl","setDrawingImage","currentType","setCurrentType","ArrowTypePanel","ti","arrowType","typeBoxContainer","this_1","leftTip","marginLeft","lineBox","rightTip","typeBoxes","newType","onArrowTypeChanged","getArrowPoints","setArrowType","arrowTypePanel","ArrowMarker","arrow1","arrow2","arrowBaseWidth","arrowBaseHeight","createPolygon","createTips","lineAngle1","a1transform","a2transform","amState","defaultFillColor","fillPanel","CoverMarker","opacities","currentOpacity","setCurrentOpacity","OpacityPanel","opacityBoxContainer","opacityBoxes","onOpacityChanged","setOpacity","defaultHighlightColor","defaultHighlightOpacity","opacityPanel","defaultOpacitySteps","HighlightMarker","defaultStrokeColor","bgColor","setBgColor","getTipPoints","positionTip","setTipPoints","TextColorIcon","bgColorPanel","FillColorIcon","tipGrip","CalloutMarker","tip","createTip","tipMoving","isCreating","tipPosition","tipBase1Position","tipBase2Position","offset","baseWidth","cornerAngle","calloutState","EllipseMarker","createEllipse","MeasurementMarker","tip1","tip2","tipLength","EllipseFrameMarker","UndoRedoManager","undoStack","redoStack","stepData","lastRedoStep","lastStep","CurveMarker","selectorCurve","visibleCurve","curveGrip","curveX","curveY","createPath","getPathD","manipulationStartCurveX","manipulationStartCurveY","curveControlLine1","curveControlLine2","firstChild","textColor","defaultCaptionFontSize","captionText","defaultCaptionText","sizeCaption","setCaptionText","finishTextEditing","setTextColor","textColorPanel","CaptionFrameMarker","frame","captionBg","captionElement","textAnchor","dominantBaseline","captionBoxWidth","PADDING","captionBoxHeight","textEditBox","transformOrigin","frState","markerArea","cancelable","MarkerAreaEvent","_defaultPrevented","dataUrl","EventListenerRepository","eventType","handler","DEFAULT_MARKER_TYPES","Settings","_instanceNo","MarkerArea","instanceCounter","targetRoot","removeStyleSheet","open","setTopLeft","toolbarButtonClicked","createNewMarker","addNewMarker","markerCreated","onPointerDown","onDblClick","onPointerMove","onPointerUp","onPointerOut","onKeyUp","overrideOverflow","restoreOverflow","close","closeUI","addCloseEventListener","removeCloseEventListener","addRenderEventListener","removeRenderEventListener","clientToLocalCoordinates","onWindowResize","deleteSelectedMarker","setWindowHeight","removeMarker","onPopupTargetResize","showNotesEditor","hideNotesEditor","stepZoom","blur","markerStateChanged","switchToSelectMode","addDefs","addDefsToImage","_availableMarkerTypes","mt","typeType","ALL_MARKER_TYPES","allT","_currentMarker","_isOpen","undoRedoManager","isUndoPossible","isRedoPossible","_zoomLevel","editorCanvas","contentDiv","scrollTo","setupResizeObserver","setEditingTarget","initMarkerCanvas","initOverlay","attachEvents","isLicensed","addLogo","_isFocused","Style","markers","showUI","eventListeners","renderer","renderAtNaturalSize","renderImageType","renderImageQuality","renderMarkersOnly","renderWidth","renderHeight","rasterize","HTMLImageElement","renderTarget","suppressBeforeClose","isOpen","cancel_1","defaultPrevented","coverDiv","targetObserver","unobserve","removeEventListener","detachEvents","event","ResizeObserver","observe","ratio","windowHeight","innerHeight","_isResizing","imageWidth","imageHeight","editingTarget","markerImageHolder","positionMarkerImage","toolbar","positionLogo","scaleMarkers","preScaleSelectedMarker","targetRect","getBoundingClientRect","bodyRect","setProperty","nodes","defs","createDefs","append","zoomLevel","attachWindowEvents","detachWindowEvents","logoUI","link","href","justifyItems","scrollXState","scrollX","scrollYState","scrollY","bodyOverflowState","scroll","_silentRenderMode","classNamePrefixBase","userSelect","coverTop","uiOffsetTop","coverLeft","uiOffsetLeft","zIndex","uiDiv","flexDirection","popupMargin","addButtonClickListener","show","hideToolbar","flexShrink","marginTop","toolbox","hideToolbox","remove","dispose","mode","addUndoStep","buttonType","clear","undo","redo","notesArea","startRenderAndClose","cancel_2","MarkerEvent","marker_1","cancel","notesAreaStyleClassName","alignSelf","isNotesAreaOpen","lastUndoState","getLastUndoStep","beforeSteps","undoStepCount","replaceLastUndoStep","undoStep","selectLastMarker","redoStep","zoomStepIndex","zoomSteps","scrollBy","prevPanPoint","render","MarkerAreaRenderEvent","deselectCurrentMarker","markerState","mType","setActiveMarkerButton","setPanelButtons","toolboxPanels","defaultColorsFollowCurrentColors","isSelected","touchPoints","pointerType","hitMarker","m","isDragging","clientX","clientY","panTo","clientRect","positionUI","rects","getClientRects","item","addKey","_previousCurrentMarker"],"mappings":"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"}