mirror of
https://github.com/antos-rde/antosdk-apps.git
synced 2024-12-27 20:48:21 +01:00
1 line
18 KiB
Plaintext
1 line
18 KiB
Plaintext
{"version":3,"file":"ext-markers.js","sources":["../../../../src/editor/extensions/ext-markers/ext-markers.js"],"sourcesContent":["/**\n * @file ext-markers.js\n *\n * @license Apache-2.0\n *\n * @copyright 2010 Will Schleter based on ext-arrows.js by Copyright(c) 2010 Alexis Deveria\n * @copyright 2021 OptimistikSAS\n *\n * This extension provides for the addition of markers to the either end\n * or the middle of a line, polyline, path, polygon.\n *\n * Markers are graphics\n *\n * to simplify the coding and make the implementation as robust as possible,\n * markers are not shared - every object has its own set of markers.\n * this relationship is maintained by a naming convention between the\n * ids of the markers and the ids of the object\n *\n * The following restrictions exist for simplicty of use and programming\n * objects and their markers to have the same color\n * marker size is fixed\n * an application specific attribute - se_type - is added to each marker element\n * to store the type of marker\n *\n * @todo\n * remove some of the restrictions above\n *\n*/\n\nexport default {\n name: 'markers',\n async init () {\n const svgEditor = this\n const { svgCanvas } = svgEditor\n const { BatchCommand, RemoveElementCommand, InsertElementCommand } = svgCanvas.history\n const { $id, addSVGElementsFromJson: addElem } = svgCanvas\n const mtypes = ['start', 'mid', 'end']\n const markerElems = ['line', 'path', 'polyline', 'polygon']\n\n // note - to add additional marker types add them below with a unique id\n // and add the associated icon(s) to marker-icons.svg\n // the geometry is normalized to a 100x100 box with the origin at lower left\n // Safari did not like negative values for low left of viewBox\n // remember that the coordinate system has +y downward\n const markerTypes = {\n nomarker: {},\n leftarrow:\n { element: 'path', attr: { d: 'M0,50 L100,90 L70,50 L100,10 Z' } },\n rightarrow:\n { element: 'path', attr: { d: 'M100,50 L0,90 L30,50 L0,10 Z' } },\n box:\n { element: 'path', attr: { d: 'M20,20 L20,80 L80,80 L80,20 Z' } },\n mcircle:\n { element: 'circle', attr: { r: 30, cx: 50, cy: 50 } }\n };\n\n // duplicate shapes to support unfilled (open) marker types with an _o suffix\n ['leftarrow', 'rightarrow', 'box', 'mcircle'].forEach((v) => {\n markerTypes[v + '_o'] = markerTypes[v]\n })\n\n /**\n * @param {Element} elem - A graphic element will have an attribute like marker-start\n * @param {\"marker-start\"|\"marker-mid\"|\"marker-end\"} attr\n * @returns {Element} The marker element that is linked to the graphic element\n */\n const getLinked = (elem, attr) => {\n const str = elem.getAttribute(attr)\n if (!str) { return null }\n const m = str.match(/\\(#(.*)\\)/)\n // \"url(#mkr_end_svg_1)\" would give m[1] = \"mkr_end_svg_1\"\n if (!m || m.length !== 2) {\n return null\n }\n return svgCanvas.getElement(m[1])\n }\n\n /**\n * Toggles context tool panel off/on.\n * @param {boolean} on\n * @returns {void}\n */\n const showPanel = (on, elem) => {\n $id('marker_panel').style.display = (on) ? 'block' : 'none'\n if (on && elem) {\n mtypes.forEach((pos) => {\n const marker = getLinked(elem, 'marker-' + pos)\n if (marker?.attributes?.se_type) {\n $id(`${pos}_marker_list_opts`).setAttribute('value', marker.attributes.se_type.value)\n } else {\n $id(`${pos}_marker_list_opts`).setAttribute('value', 'nomarker')\n }\n })\n }\n }\n\n /**\n * @param {string} id\n * @param {\"\"|\"nomarker\"|\"nomarker\"|\"leftarrow\"|\"rightarrow\"|\"textmarker\"|\"forwardslash\"|\"reverseslash\"|\"verticalslash\"|\"box\"|\"star\"|\"xmark\"|\"triangle\"|\"mcircle\"} seType\n * @returns {SVGMarkerElement}\n */\n const addMarker = (id, seType) => {\n const selElems = svgCanvas.getSelectedElements()\n let marker = svgCanvas.getElement(id)\n if (marker) { return undefined }\n if (seType === '' || seType === 'nomarker') { return undefined }\n const el = selElems[0]\n const color = el.getAttribute('stroke')\n const strokeWidth = 10\n const refX = 50\n const refY = 50\n const viewBox = '0 0 100 100'\n const markerWidth = 5\n const markerHeight = 5\n\n if (!markerTypes[seType]) {\n console.error(`unknown marker type: ${seType}`)\n return undefined\n }\n\n // create a generic marker\n marker = addElem({\n element: 'marker',\n attr: {\n id,\n markerUnits: 'strokeWidth',\n orient: 'auto',\n style: 'pointer-events:none',\n se_type: seType\n }\n })\n\n const mel = addElem(markerTypes[seType])\n const fillcolor = (seType.substr(-2) === '_o')\n ? 'none'\n : color\n\n mel.setAttribute('fill', fillcolor)\n mel.setAttribute('stroke', color)\n mel.setAttribute('stroke-width', strokeWidth)\n marker.append(mel)\n\n marker.setAttribute('viewBox', viewBox)\n marker.setAttribute('markerWidth', markerWidth)\n marker.setAttribute('markerHeight', markerHeight)\n marker.setAttribute('refX', refX)\n marker.setAttribute('refY', refY)\n svgCanvas.findDefs().append(marker)\n\n return marker\n }\n\n /**\n * @param {Element} elem\n * @returns {SVGPolylineElement}\n */\n const convertline = (elem) => {\n // this routine came from the connectors extension\n // it is needed because midpoint markers don't work with line elements\n if (elem.tagName !== 'line') { return elem }\n\n // Convert to polyline to accept mid-arrow\n const x1 = Number(elem.getAttribute('x1'))\n const x2 = Number(elem.getAttribute('x2'))\n const y1 = Number(elem.getAttribute('y1'))\n const y2 = Number(elem.getAttribute('y2'))\n const { id } = elem\n\n const midPt = (' ' + ((x1 + x2) / 2) + ',' + ((y1 + y2) / 2) + ' ')\n const pline = addElem({\n element: 'polyline',\n attr: {\n points: (x1 + ',' + y1 + midPt + x2 + ',' + y2),\n stroke: elem.getAttribute('stroke'),\n 'stroke-width': elem.getAttribute('stroke-width'),\n fill: 'none',\n opacity: elem.getAttribute('opacity') || 1\n }\n })\n mtypes.forEach((pos) => { // get any existing marker definitions\n const nam = 'marker-' + pos\n const m = elem.getAttribute(nam)\n if (m) { pline.setAttribute(nam, elem.getAttribute(nam)) }\n })\n\n const batchCmd = new BatchCommand()\n batchCmd.addSubCommand(new RemoveElementCommand(elem, elem.parentNode))\n batchCmd.addSubCommand(new InsertElementCommand(pline))\n\n elem.insertAdjacentElement('afterend', pline)\n elem.remove()\n svgCanvas.clearSelection()\n pline.id = id\n svgCanvas.addToSelection([pline])\n svgCanvas.addCommandToHistory(batchCmd)\n return pline\n }\n\n /**\n *\n * @returns {void}\n */\n const setMarker = (pos, markerType) => {\n const selElems = svgCanvas.getSelectedElements()\n if (selElems.length === 0) return\n const markerName = 'marker-' + pos\n const el = selElems[0]\n const marker = getLinked(el, markerName)\n if (marker) { marker.remove() }\n el.removeAttribute(markerName)\n let val = markerType\n if (val === '') { val = 'nomarker' }\n if (val === 'nomarker') {\n svgCanvas.call('changed', selElems)\n return\n }\n // Set marker on element\n const id = 'mkr_' + pos + '_' + el.id\n addMarker(id, val)\n svgCanvas.changeSelectedAttribute(markerName, 'url(#' + id + ')')\n if (el.tagName === 'line' && pos === 'mid') {\n convertline(el)\n }\n svgCanvas.call('changed', selElems)\n }\n\n /**\n * Called when the main system modifies an object. This routine changes\n * the associated markers to be the same color.\n * @param {Element} elem\n * @returns {void}\n */\n const colorChanged = (elem) => {\n const color = elem.getAttribute('stroke')\n\n mtypes.forEach((pos) => {\n const marker = getLinked(elem, 'marker-' + pos)\n if (!marker) { return }\n if (!marker.attributes.se_type) { return } // not created by this extension\n const ch = marker.lastElementChild\n if (!ch) { return }\n const curfill = ch.getAttribute('fill')\n const curstroke = ch.getAttribute('stroke')\n if (curfill && curfill !== 'none') { ch.setAttribute('fill', color) }\n if (curstroke && curstroke !== 'none') { ch.setAttribute('stroke', color) }\n })\n }\n\n /**\n * Called when the main system creates or modifies an object.\n * Its primary purpose is to create new markers for cloned objects.\n * @param {Element} el\n * @returns {void}\n */\n const updateReferences = (el) => {\n const selElems = svgCanvas.getSelectedElements()\n mtypes.forEach((pos) => {\n const markerName = 'marker-' + pos\n const marker = getLinked(el, markerName)\n if (!marker || !marker.attributes.se_type) { return } // not created by this extension\n const url = el.getAttribute(markerName)\n if (url) {\n const len = el.id.length\n const linkid = url.substr(-len - 1, len)\n if (el.id !== linkid) {\n const newMarkerId = 'mkr_' + pos + '_' + el.id\n addMarker(newMarkerId, marker.attributes.se_type.value)\n svgCanvas.changeSelectedAttribute(markerName, 'url(#' + newMarkerId + ')')\n svgCanvas.call('changed', selElems)\n }\n }\n })\n }\n\n return {\n name: svgEditor.i18next.t(`${name}:name`),\n // The callback should be used to load the DOM with the appropriate UI items\n callback () {\n // Add the context panel and its handler(s)\n const panelTemplate = document.createElement('template')\n // create the marker panel\n let innerHTML = '<div id=\"marker_panel\">'\n mtypes.forEach((pos) => {\n innerHTML += `<se-list id=\"${pos}_marker_list_opts\" title=\"tools.${pos}_marker_list_opts\" label=\"\" width=\"22px\" height=\"22px\">`\n Object.entries(markerTypes).forEach(([marker, _mkr]) => {\n innerHTML += `<se-list-item id=\"mkr_${pos}_${marker}\" value=\"${marker}\" title=\"tools.mkr_${marker}\" src=\"${marker}.svg\" img-height=\"22px\"></se-list-item>`\n })\n innerHTML += '</se-list>'\n })\n innerHTML += '</div>'\n panelTemplate.innerHTML = innerHTML\n $id('tools_top').appendChild(panelTemplate.content.cloneNode(true))\n // don't display the panels on start\n showPanel(false)\n mtypes.forEach((pos) => {\n $id(`${pos}_marker_list_opts`).addEventListener('change', (evt) => {\n setMarker(pos, evt.detail.value)\n })\n })\n },\n selectedChanged (opts) {\n // Use this to update the current selected elements\n if (opts.elems.length === 0) showPanel(false)\n opts.elems.forEach((elem) => {\n if (elem && markerElems.includes(elem.tagName)) {\n if (opts.selectedElement && !opts.multiselected) {\n showPanel(true, elem)\n } else {\n showPanel(false)\n }\n } else {\n showPanel(false)\n }\n })\n },\n elementChanged (opts) {\n const elem = opts.elems[0]\n if (elem && (\n elem.getAttribute('marker-start') ||\n elem.getAttribute('marker-mid') ||\n elem.getAttribute('marker-end')\n )) {\n colorChanged(elem)\n updateReferences(elem)\n }\n }\n }\n }\n}\n"],"names":["extMarkers","name","async","svgCanvas","this","BatchCommand","RemoveElementCommand","InsertElementCommand","history","$id","addSVGElementsFromJson","addElem","mtypes","markerElems","markerTypes","nomarker","leftarrow","element","attr","d","rightarrow","box","mcircle","r","cx","cy","forEach","v","getLinked","elem","str","getAttribute","m","match","length","getElement","showPanel","on","style","display","pos","_marker$attributes","marker","attributes","se_type","setAttribute","value","concat","addMarker","id","seType","selElems","getSelectedElements","color","console","error","markerUnits","orient","mel","fillcolor","substr","append","findDefs","setMarker","markerType","markerName","el","remove","removeAttribute","val","call","changeSelectedAttribute","tagName","x1","Number","x2","y1","y2","pline","points","stroke","fill","opacity","nam","batchCmd","addSubCommand","parentNode","insertAdjacentElement","clearSelection","addToSelection","addCommandToHistory","convertline","i18next","t","callback","panelTemplate","document","createElement","innerHTML","Object","entries","_ref","_mkr","appendChild","content","cloneNode","addEventListener","evt","detail","selectedChanged","opts","elems","includes","selectedElement","multiselected","elementChanged","ch","lastElementChild","curfill","curstroke","colorChanged","url","len","linkid","newMarkerId","updateReferences"],"mappings":"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"} |