UNPKG

svgedit

Version:

Powerful SVG-Editor for your browser

983 lines (883 loc) 44.2 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JSDoc: Source: svgcanvas/elem-get-set.js</title> <script src="scripts/prettify/prettify.js"> </script> <script src="scripts/prettify/lang-css.js"> </script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <div id="main"> <h1 class="page-title">Source: svgcanvas/elem-get-set.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>/** * @module elem-get-set get and set methods. * @license MIT * @copyright 2011 Jeff Schiller */ import { jGraduate } from '../editor/components/jgraduate/jQuery.jGraduate.js'; import * as hstry from './history.js'; import { NS } from './namespaces.js'; import { getVisibleElements, getStrokedBBoxDefaultVisible, findDefs, walkTree, isNullish, getHref, setHref, getElem } from './utilities.js'; import { convertToNum } from '../common/units.js'; import { getParents } from '../editor/components/jgraduate/Util.js'; const { InsertElementCommand, RemoveElementCommand, ChangeElementCommand, BatchCommand } = hstry; let elemContext_ = null; /** * @function module:elem-get-set.init * @param {module:elem-get-set.elemContext} elemContext * @returns {void} */ export const init = function (elemContext) { elemContext_ = elemContext; }; /** * @function module:elem-get-set.SvgCanvas#getResolution * @returns {DimensionsAndZoom} The current dimensions and zoom level in an object */ export const getResolutionMethod = function () { const currentZoom = elemContext_.getCurrentZoom(); const w = elemContext_.getSVGContent().getAttribute('width') / currentZoom; const h = elemContext_.getSVGContent().getAttribute('height') / currentZoom; return { w, h, zoom: currentZoom }; }; /** * @function module:elem-get-set.SvgCanvas#getTitle * @param {Element} [elem] * @returns {string|void} the current group/SVG's title contents or * `undefined` if no element is passed nd there are no selected elements. */ export const getTitleMethod = function (elem) { const selectedElements = elemContext_.getSelectedElements(); const dataStorage = elemContext_.getDataStorage(); elem = elem || selectedElements[0]; if (!elem) { return undefined; } if (dataStorage.has(elem, 'gsvg')) { elem = dataStorage.get(elem, 'gsvg'); } else if (dataStorage.has(elem, 'symbol')) { elem = dataStorage.get(elem, 'symbol'); } const childs = elem.childNodes; for (const child of childs) { if (child.nodeName === 'title') { return child.textContent; } } return ''; }; /** * Sets the group/SVG's title content. * @function module:elem-get-set.SvgCanvas#setGroupTitle * @param {string} val * @todo Combine this with `setDocumentTitle` * @returns {void} */ export const setGroupTitleMethod = function (val) { const selectedElements = elemContext_.getSelectedElements(); const dataStorage = elemContext_.getDataStorage(); let elem = selectedElements[0]; if (dataStorage.has(elem, 'gsvg')) { elem = dataStorage.get(elem, 'gsvg'); } const ts = elem.querySelectorAll('title'); const batchCmd = new BatchCommand('Set Label'); let title; if (!val.length) { // Remove title element const tsNextSibling = ts.nextSibling; batchCmd.addSubCommand(new RemoveElementCommand(ts[0], tsNextSibling, elem)); ts.remove(); } else if (ts.length) { // Change title contents title = ts[0]; batchCmd.addSubCommand(new ChangeElementCommand(title, { '#text': title.textContent })); title.textContent = val; } else { // Add title element title = elemContext_.getDOMDocument().createElementNS(NS.SVG, 'title'); title.textContent = val; elem.insertBefore(title, elem.firstChild); batchCmd.addSubCommand(new InsertElementCommand(title)); } elemContext_.addCommandToHistory(batchCmd); }; /** * Adds/updates a title element for the document with the given name. * This is an undoable action. * @function module:elem-get-set.SvgCanvas#setDocumentTitle * @param {string} newTitle - String with the new title * @returns {void} */ export const setDocumentTitleMethod = function (newTitle) { const childs = elemContext_.getSVGContent().childNodes; let docTitle = false; let oldTitle = ''; const batchCmd = new BatchCommand('Change Image Title'); for (const child of childs) { if (child.nodeName === 'title') { docTitle = child; oldTitle = docTitle.textContent; break; } } if (!docTitle) { docTitle = elemContext_.getDOMDocument().createElementNS(NS.SVG, 'title'); elemContext_.getSVGContent().insertBefore(docTitle, elemContext_.getSVGContent().firstChild); // svgcontent.firstChild.before(docTitle); // Ok to replace above with this? } if (newTitle.length) { docTitle.textContent = newTitle; } else { // No title given, so element is not necessary docTitle.remove(); } batchCmd.addSubCommand(new ChangeElementCommand(docTitle, { '#text': oldTitle })); elemContext_.addCommandToHistory(batchCmd); }; /** * Changes the document's dimensions to the given size. * @function module:elem-get-set.SvgCanvas#setResolution * @param {Float|"fit"} x - Number with the width of the new dimensions in user units. * Can also be the string "fit" to indicate "fit to content". * @param {Float} y - Number with the height of the new dimensions in user units. * @fires module:elem-get-set.SvgCanvas#event:changed * @returns {boolean} Indicates if resolution change was successful. * It will fail on "fit to content" option with no content to fit to. */ export const setResolutionMethod = function (x, y) { const currentZoom = elemContext_.getCurrentZoom(); const res = elemContext_.getCanvas().getResolution(); const { w, h } = res; let batchCmd; if (x === 'fit') { // Get bounding box const bbox = getStrokedBBoxDefaultVisible(); if (bbox) { batchCmd = new BatchCommand('Fit Canvas to Content'); const visEls = getVisibleElements(); elemContext_.getCanvas().addToSelection(visEls); const dx = []; const dy = []; visEls.forEach(function(_item, _i){ dx.push(bbox.x * -1); dy.push(bbox.y * -1); }); const cmd = elemContext_.getCanvas().moveSelectedElements(dx, dy, true); batchCmd.addSubCommand(cmd); elemContext_.getCanvas().clearSelection(); x = Math.round(bbox.width); y = Math.round(bbox.height); } else { return false; } } if (x !== w || y !== h) { if (!batchCmd) { batchCmd = new BatchCommand('Change Image Dimensions'); } x = convertToNum('width', x); y = convertToNum('height', y); elemContext_.getSVGContent().setAttribute('width', x); elemContext_.getSVGContent().setAttribute('height', y); this.contentW = x; this.contentH = y; batchCmd.addSubCommand(new ChangeElementCommand(elemContext_.getSVGContent(), { width: w, height: h })); elemContext_.getSVGContent().setAttribute('viewBox', [ 0, 0, x / currentZoom, y / currentZoom ].join(' ')); batchCmd.addSubCommand(new ChangeElementCommand(elemContext_.getSVGContent(), { viewBox: [ '0 0', w, h ].join(' ') })); elemContext_.addCommandToHistory(batchCmd); elemContext_.call('changed', [ elemContext_.getSVGContent() ]); } return true; }; /** * Returns the editor's namespace URL, optionally adding it to the root element. * @function module:elem-get-set.SvgCanvas#getEditorNS * @param {boolean} [add] - Indicates whether or not to add the namespace value * @returns {string} The editor's namespace URL */ export const getEditorNSMethod = function (add) { if (add) { elemContext_.getSVGContent().setAttribute('xmlns:se', NS.SE); } return NS.SE; }; /** * @typedef {PlainObject} module:elem-get-set.ZoomAndBBox * @property {Float} zoom * @property {module:utilities.BBoxObject} bbox */ /** * Sets the zoom level on the canvas-side based on the given value. * @function module:elem-get-set.SvgCanvas#setBBoxZoom * @param {"selection"|"canvas"|"content"|"layer"|module:SVGEditor.BBoxObjectWithFactor} val - Bounding box object to zoom to or string indicating zoom option. Note: the object value type is defined in `svg-editor.js` * @param {Integer} editorW - The editor's workarea box's width * @param {Integer} editorH - The editor's workarea box's height * @returns {module:elem-get-set.ZoomAndBBox|void} */ export const setBBoxZoomMethod = function (val, editorW, editorH) { const currentZoom = elemContext_.getCurrentZoom(); const selectedElements = elemContext_.getSelectedElements(); let spacer = 0.85; let bb; const calcZoom = function (bb) { if (!bb) { return false; } const wZoom = Math.round((editorW / bb.width) * 100 * spacer) / 100; const hZoom = Math.round((editorH / bb.height) * 100 * spacer) / 100; const zoom = Math.min(wZoom, hZoom); elemContext_.getCanvas().setZoom(zoom); return { zoom, bbox: bb }; }; if (typeof val === 'object') { bb = val; if (bb.width === 0 || bb.height === 0) { const newzoom = bb.zoom ? bb.zoom : currentZoom * bb.factor; elemContext_.getCanvas().setZoom(newzoom); return { zoom: currentZoom, bbox: bb }; } return calcZoom(bb); } switch (val) { case 'selection': { if (!selectedElements[0]) { return undefined; } const selectedElems = selectedElements.map(function (n, _) { if (n) { return n; } return undefined; }); bb = getStrokedBBoxDefaultVisible(selectedElems); break; } case 'canvas': { const res = elemContext_.getCanvas().getResolution(); spacer = 0.95; bb = { width: res.w, height: res.h, x: 0, y: 0 }; break; } case 'content': bb = getStrokedBBoxDefaultVisible(); break; case 'layer': bb = getStrokedBBoxDefaultVisible(getVisibleElements(elemContext_.getCanvas().getCurrentDrawing().getCurrentLayer())); break; default: return undefined; } return calcZoom(bb); }; /** * Sets the zoom to the given level. * @function module:elem-get-set.SvgCanvas#setZoom * @param {Float} zoomLevel - Float indicating the zoom level to change to * @fires module:elem-get-set.SvgCanvas#event:ext_zoomChanged * @returns {void} */ export const setZoomMethod = function (zoomLevel) { const selectedElements = elemContext_.getSelectedElements(); const res = elemContext_.getCanvas().getResolution(); elemContext_.getSVGContent().setAttribute('viewBox', '0 0 ' + res.w / zoomLevel + ' ' + res.h / zoomLevel); elemContext_.setCurrentZoom(zoomLevel); selectedElements.forEach(function(elem){ if (!elem) { return; } elemContext_.getCanvas().selectorManager.requestSelector(elem).resize(); }); elemContext_.getCanvas().pathActions.zoomChange(); elemContext_.getCanvas().runExtensions('zoomChanged', zoomLevel); }; /** * Change the current stroke/fill color/gradient value. * @function module:elem-get-set.SvgCanvas#setColor * @param {string} type - String indicating fill or stroke * @param {string} val - The value to set the stroke attribute to * @param {boolean} preventUndo - Boolean indicating whether or not this should be an undoable option * @fires module:elem-get-set.SvgCanvas#event:changed * @returns {void} */ export const setColorMethod = function (type, val, preventUndo) { const selectedElements = elemContext_.getSelectedElements(); elemContext_.setCurShape(type, val); elemContext_.setCurProperties(type + '_paint', { type: 'solidColor' }); const elems = []; /** * * @param {Element} e * @returns {void} */ function addNonG(e) { if (e.nodeName !== 'g') { elems.push(e); } } let i = selectedElements.length; while (i--) { const elem = selectedElements[i]; if (elem) { if (elem.tagName === 'g') { walkTree(elem, addNonG); } else if (type === 'fill') { if (elem.tagName !== 'polyline' &amp;&amp; elem.tagName !== 'line') { elems.push(elem); } } else { elems.push(elem); } } } if (elems.length > 0) { if (!preventUndo) { elemContext_.getCanvas().changeSelectedAttribute(type, val, elems); elemContext_.call('changed', elems); } else { elemContext_.changeSelectedAttributeNoUndoMethod(type, val, elems); } } }; /** * Apply the current gradient to selected element's fill or stroke. * @function module:elem-get-set.SvgCanvas#setGradient * @param {"fill"|"stroke"} type - String indicating "fill" or "stroke" to apply to an element * @returns {void} */ export const setGradientMethod = function (type) { if (!elemContext_.getCurProperties(type + '_paint') || elemContext_.getCurProperties(type + '_paint').type === 'solidColor') { return; } const canvas = elemContext_.getCanvas(); let grad = canvas[type + 'Grad']; // find out if there is a duplicate gradient already in the defs const duplicateGrad = findDuplicateGradient(grad); const defs = findDefs(); // no duplicate found, so import gradient into defs if (!duplicateGrad) { // const origGrad = grad; grad = elemContext_.getDOMDocument().importNode(grad, true); defs.append(grad); // get next id and set it on the grad grad.id = elemContext_.getCanvas().getNextId(); } else { // use existing gradient grad = duplicateGrad; } elemContext_.getCanvas().setColor(type, 'url(#' + grad.id + ')'); }; /** * Check if exact gradient already exists. * @function module:svgcanvas~findDuplicateGradient * @param {SVGGradientElement} grad - The gradient DOM element to compare to others * @returns {SVGGradientElement} The existing gradient if found, `null` if not */ export const findDuplicateGradient = function (grad) { const defs = findDefs(); const existingGrads = defs.querySelectorAll('linearGradient, radialGradient'); let i = existingGrads.length; const radAttrs = [ 'r', 'cx', 'cy', 'fx', 'fy' ]; while (i--) { const og = existingGrads[i]; if (grad.tagName === 'linearGradient') { if (grad.getAttribute('x1') !== og.getAttribute('x1') || grad.getAttribute('y1') !== og.getAttribute('y1') || grad.getAttribute('x2') !== og.getAttribute('x2') || grad.getAttribute('y2') !== og.getAttribute('y2') ) { continue; } } else { const gradAttrs = { r: Number(grad.getAttribute('r')), cx: Number(grad.getAttribute('cx')), cy: Number(grad.getAttribute('cy')), fx: Number(grad.getAttribute('fx')), fy: Number(grad.getAttribute('fy')) }; const ogAttrs = { r: Number(og.getAttribute('r')), cx: Number(og.getAttribute('cx')), cy: Number(og.getAttribute('cy')), fx: Number(og.getAttribute('fx')), fy: Number(og.getAttribute('fy')) }; let diff = false; radAttrs.forEach(function (attr) { if (gradAttrs[attr] !== ogAttrs[attr]) { diff = true; } }); if (diff) { continue; } } // else could be a duplicate, iterate through stops const stops = grad.getElementsByTagNameNS(NS.SVG, 'stop'); const ostops = og.getElementsByTagNameNS(NS.SVG, 'stop'); if (stops.length !== ostops.length) { continue; } let j = stops.length; while (j--) { const stop = stops[j]; const ostop = ostops[j]; if (stop.getAttribute('offset') !== ostop.getAttribute('offset') || stop.getAttribute('stop-opacity') !== ostop.getAttribute('stop-opacity') || stop.getAttribute('stop-color') !== ostop.getAttribute('stop-color')) { break; } } if (j === -1) { return og; } } // for each gradient in defs return null; }; /** * Set a color/gradient to a fill/stroke. * @function module:elem-get-set.SvgCanvas#setPaint * @param {"fill"|"stroke"} type - String with "fill" or "stroke" * @param {module:jGraduate.jGraduatePaintOptions} paint - The jGraduate paint object to apply * @returns {void} */ export const setPaintMethod = function (type, paint) { // make a copy const p = new jGraduate.Paint(paint); this.setPaintOpacity(type, p.alpha / 100, true); // now set the current paint object elemContext_.setCurProperties(type + '_paint', p); switch (p.type) { case 'solidColor': this.setColor(type, p.solidColor !== 'none' ? '#' + p.solidColor : 'none'); break; case 'linearGradient': case 'radialGradient': elemContext_.setCanvas(type + 'Grad', p[p.type]); elemContext_.getCanvas().setGradient(type); break; } }; /** * Sets the stroke width for the current selected elements. * When attempting to set a line's width to 0, this changes it to 1 instead. * @function module:elem-get-set.SvgCanvas#setStrokeWidth * @param {Float} val - A Float indicating the new stroke width value * @fires module:elem-get-set.SvgCanvas#event:changed * @returns {void} */ export const setStrokeWidthMethod = function (val) { const selectedElements = elemContext_.getSelectedElements(); if (val === 0 &amp;&amp; [ 'line', 'path' ].includes(elemContext_.getCanvas().getMode())) { elemContext_.getCanvas().setStrokeWidth(1); return; } elemContext_.setCurProperties('stroke_width', val); const elems = []; /** * * @param {Element} e * @returns {void} */ function addNonG(e) { if (e.nodeName !== 'g') { elems.push(e); } } let i = selectedElements.length; while (i--) { const elem = selectedElements[i]; if (elem) { if (elem.tagName === 'g') { walkTree(elem, addNonG); } else { elems.push(elem); } } } if (elems.length > 0) { elemContext_.getCanvas().changeSelectedAttribute('stroke-width', val, elems); elemContext_.call('changed', selectedElements); } }; /** * Set the given stroke-related attribute the given value for selected elements. * @function module:elem-get-set.SvgCanvas#setStrokeAttr * @param {string} attr - String with the attribute name * @param {string|Float} val - String or number with the attribute value * @fires module:elem-get-set.SvgCanvas#event:changed * @returns {void} */ export const setStrokeAttrMethod = function (attr, val) { const selectedElements = elemContext_.getSelectedElements(); elemContext_.setCurShape(attr.replace('-', '_'), val); const elems = []; let i = selectedElements.length; while (i--) { const elem = selectedElements[i]; if (elem) { if (elem.tagName === 'g') { walkTree(elem, function (e) { if (e.nodeName !== 'g') { elems.push(e); } }); } else { elems.push(elem); } } } if (elems.length > 0) { elemContext_.getCanvas().changeSelectedAttribute(attr, val, elems); elemContext_.call('changed', selectedElements); } }; /** * Check whether selected element is bold or not. * @function module:svgcanvas.SvgCanvas#getBold * @returns {boolean} Indicates whether or not element is bold */ export const getBoldMethod = function () { const selectedElements = elemContext_.getSelectedElements(); // should only have one element selected const selected = selectedElements[0]; if (!isNullish(selected) &amp;&amp; selected.tagName === 'text' &amp;&amp; isNullish(selectedElements[1])) { return (selected.getAttribute('font-weight') === 'bold'); } return false; }; /** * Make the selected element bold or normal. * @function module:svgcanvas.SvgCanvas#setBold * @param {boolean} b - Indicates bold (`true`) or normal (`false`) * @returns {void} */ export const setBoldMethod = function (b) { const selectedElements = elemContext_.getSelectedElements(); const selected = selectedElements[0]; if (!isNullish(selected) &amp;&amp; selected.tagName === 'text' &amp;&amp; isNullish(selectedElements[1])) { elemContext_.getCanvas().changeSelectedAttribute('font-weight', b ? 'bold' : 'normal'); } if (!selectedElements[0].textContent) { elemContext_.getCanvas().textActions.setCursor(); } }; /** * Check whether selected element is in italics or not. * @function module:svgcanvas.SvgCanvas#getItalic * @returns {boolean} Indicates whether or not element is italic */ export const getItalicMethod = function () { const selectedElements = elemContext_.getSelectedElements(); const selected = selectedElements[0]; if (!isNullish(selected) &amp;&amp; selected.tagName === 'text' &amp;&amp; isNullish(selectedElements[1])) { return (selected.getAttribute('font-style') === 'italic'); } return false; }; /** * Make the selected element italic or normal. * @function module:svgcanvas.SvgCanvas#setItalic * @param {boolean} i - Indicates italic (`true`) or normal (`false`) * @returns {void} */ export const setItalicMethod = function (i) { const selectedElements = elemContext_.getSelectedElements(); const selected = selectedElements[0]; if (!isNullish(selected) &amp;&amp; selected.tagName === 'text' &amp;&amp; isNullish(selectedElements[1])) { elemContext_.getCanvas().changeSelectedAttribute('font-style', i ? 'italic' : 'normal'); } if (!selectedElements[0].textContent) { elemContext_.getCanvas().textActions.setCursor(); } }; /** * @function module:svgcanvas.SvgCanvas#setTextAnchorMethod Set the new text anchor * @param {string} value - The text anchor value (start, middle or end) * @returns {void} */ export const setTextAnchorMethod = function (value) { const selectedElements = elemContext_.getSelectedElements(); const selected = selectedElements[0]; if (!isNullish(selected) &amp;&amp; selected.tagName === 'text' &amp;&amp; isNullish(selectedElements[1])) { elemContext_.getCanvas().changeSelectedAttribute('text-anchor', value); } if (!selectedElements[0].textContent) { elemContext_.getCanvas().textActions.setCursor(); } }; /** * @function module:svgcanvas.SvgCanvas#getFontFamily * @returns {string} The current font family */ export const getFontFamilyMethod = function () { return elemContext_.getCurText('font_family'); }; /** * Set the new font family. * @function module:svgcanvas.SvgCanvas#setFontFamily * @param {string} val - String with the new font family * @returns {void} */ export const setFontFamilyMethod = function (val) { const selectedElements = elemContext_.getSelectedElements(); elemContext_.setCurText('font_family', val); elemContext_.getCanvas().changeSelectedAttribute('font-family', val); if (selectedElements[0] &amp;&amp; !selectedElements[0].textContent) { elemContext_.getCanvas().textActions.setCursor(); } }; /** * Set the new font color. * @function module:svgcanvas.SvgCanvas#setFontColor * @param {string} val - String with the new font color * @returns {void} */ export const setFontColorMethod = function (val) { elemContext_.setCurText('fill', val); elemContext_.getCanvas().changeSelectedAttribute('fill', val); }; /** * @function module:svgcanvas.SvgCanvas#getFontColor * @returns {string} The current font color */ export const getFontColorMethod = function () { return elemContext_.getCurText('fill'); }; /** * @function module:svgcanvas.SvgCanvas#getFontSize * @returns {Float} The current font size */ export const getFontSizeMethod = function () { return elemContext_.getCurText('font_size'); }; /** * Applies the given font size to the selected element. * @function module:svgcanvas.SvgCanvas#setFontSize * @param {Float} val - Float with the new font size * @returns {void} */ export const setFontSizeMethod = function (val) { const selectedElements = elemContext_.getSelectedElements(); elemContext_.setCurText('font_size', val); elemContext_.getCanvas().changeSelectedAttribute('font-size', val); if (!selectedElements[0].textContent) { elemContext_.getCanvas().textActions.setCursor(); } }; /** * @function module:svgcanvas.SvgCanvas#getText * @returns {string} The current text (`textContent`) of the selected element */ export const getTextMethod = function () { const selectedElements = elemContext_.getSelectedElements(); const selected = selectedElements[0]; if (isNullish(selected)) { return ''; } return (selected) ? selected.textContent : ''; }; /** * Updates the text element with the given string. * @function module:svgcanvas.SvgCanvas#setTextContent * @param {string} val - String with the new text * @returns {void} */ export const setTextContentMethod = function (val) { elemContext_.getCanvas().changeSelectedAttribute('#text', val); elemContext_.getCanvas().textActions.init(val); elemContext_.getCanvas().textActions.setCursor(); }; /** * Sets the new image URL for the selected image element. Updates its size if * a new URL is given. * @function module:svgcanvas.SvgCanvas#setImageURL * @param {string} val - String with the image URL/path * @fires module:svgcanvas.SvgCanvas#event:changed * @returns {void} */ export const setImageURLMethod = function (val) { const selectedElements = elemContext_.getSelectedElements(); const elem = selectedElements[0]; if (!elem) { return; } const attrs = { width: elem.getAttribute('width'), height: elem.getAttribute('height') }; const setsize = (!attrs.width || !attrs.height); const curHref = getHref(elem); // Do nothing if no URL change or size change if (curHref === val &amp;&amp; !setsize) { return; } const batchCmd = new BatchCommand('Change Image URL'); setHref(elem, val); batchCmd.addSubCommand(new ChangeElementCommand(elem, { '#href': curHref })); const img = new Image(); img.onload = function () { const changes = { width: elem.getAttribute('width'), height: elem.getAttribute('height') }; elem.setAttribute('width', this.width); elem.setAttribute('height', this.height); elemContext_.getCanvas().selectorManager.requestSelector(elem).resize(); batchCmd.addSubCommand(new ChangeElementCommand(elem, changes)); elemContext_.addCommandToHistory(batchCmd); elemContext_.call('changed', [ elem ]); }; img.src = val; }; /** * Sets the new link URL for the selected anchor element. * @function module:svgcanvas.SvgCanvas#setLinkURL * @param {string} val - String with the link URL/path * @returns {void} */ export const setLinkURLMethod = function (val) { const selectedElements = elemContext_.getSelectedElements(); let elem = selectedElements[0]; if (!elem) { return; } if (elem.tagName !== 'a') { // See if parent is an anchor const parentsA = getParents(elem.parentNode, 'a'); if (parentsA?.length) { elem = parentsA[0]; } else { return; } } const curHref = getHref(elem); if (curHref === val) { return; } const batchCmd = new BatchCommand('Change Link URL'); setHref(elem, val); batchCmd.addSubCommand(new ChangeElementCommand(elem, { '#href': curHref })); elemContext_.addCommandToHistory(batchCmd); }; /** * Sets the `rx` and `ry` values to the selected `rect` element * to change its corner radius. * @function module:svgcanvas.SvgCanvas#setRectRadius * @param {string|Float} val - The new radius * @fires module:svgcanvas.SvgCanvas#event:changed * @returns {void} */ export const setRectRadiusMethod = function (val) { const selectedElements = elemContext_.getSelectedElements(); const selected = selectedElements[0]; if (!isNullish(selected) &amp;&amp; selected.tagName === 'rect') { const r = Number(selected.getAttribute('rx')); if (r !== val) { selected.setAttribute('rx', val); selected.setAttribute('ry', val); elemContext_.addCommandToHistory(new ChangeElementCommand(selected, { rx: r, ry: r }, 'Radius')); elemContext_.call('changed', [ selected ]); } } }; /** * Wraps the selected element(s) in an anchor element or converts group to one. * @function module:svgcanvas.SvgCanvas#makeHyperlink * @param {string} url * @returns {void} */ export const makeHyperlinkMethod = function (url) { elemContext_.getCanvas().groupSelectedElements('a', url); // TODO: If element is a single "g", convert to "a" // if (selectedElements.length > 1 &amp;&amp; selectedElements[1]) { }; /** * @function module:svgcanvas.SvgCanvas#removeHyperlink * @returns {void} */ export const removeHyperlinkMethod = function () { elemContext_.getCanvas().ungroupSelectedElement(); }; /** * Group: Element manipulation. */ /** * Sets the new segment type to the selected segment(s). * @function module:svgcanvas.SvgCanvas#setSegType * @param {Integer} newType - New segment type. See {@link https://www.w3.org/TR/SVG/paths.html#InterfaceSVGPathSeg} for list * @returns {void} */ export const setSegTypeMethod = function (newType) { elemContext_.getCanvas().pathActions.setSegType(newType); }; /** * Set the background of the editor (NOT the actual document). * @function module:svgcanvas.SvgCanvas#setBackground * @param {string} color - String with fill color to apply * @param {string} url - URL or path to image to use * @returns {void} */ export const setBackgroundMethod = function (color, url) { const bg = getElem('canvasBackground'); const border = bg.querySelector('rect'); let bgImg = getElem('background_image'); let bgPattern = getElem('background_pattern'); border.setAttribute('fill', color === 'chessboard' ? '#fff' : color); if (color === 'chessboard') { if (!bgPattern) { bgPattern = elemContext_.getDOMDocument().createElementNS(NS.SVG, 'foreignObject'); elemContext_.getCanvas().assignAttributes(bgPattern, { id: 'background_pattern', width: '100%', height: '100%', preserveAspectRatio: 'xMinYMin', style: 'pointer-events:none' }); const div = document.createElement('div'); elemContext_.getCanvas().assignAttributes(div, { style: 'pointer-events:none;width:100%;height:100%;' + 'background-image:url(data:image/gif;base64,' + 'R0lGODlhEAAQAIAAAP///9bW1iH5BAAAAAAALAAAAAAQABAAAAIfjG+' + 'gq4jM3IFLJgpswNly/XkcBpIiVaInlLJr9FZWAQA7);' }); bgPattern.append(div); bg.append(bgPattern); } } else if (bgPattern) { bgPattern.remove(); } if (url) { if (!bgImg) { bgImg = elemContext_.getDOMDocument().createElementNS(NS.SVG, 'image'); elemContext_.getCanvas().assignAttributes(bgImg, { id: 'background_image', width: '100%', height: '100%', preserveAspectRatio: 'xMinYMin', style: 'pointer-events:none' }); } setHref(bgImg, url); bg.append(bgImg); } else if (bgImg) { bgImg.remove(); } }; </code></pre> </article> </section> </div> <nav> <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-blur.html">blur</a></li><li><a href="module-browser.html">browser</a></li><li><a href="module-clear.html">clear</a></li><li><a href="module-contextmenu.html">contextmenu</a></li><li><a href="module-coords.html">coords</a></li><li><a href="module-draw.html">draw</a></li><li><a href="module-elem-get-set%2520get%2520and%2520set%2520methods..html">elem-get-set get and set methods.</a></li><li><a href="module-event.html">event</a></li><li><a href="module-history.html">history</a></li><li><a href="module-jGraduate.html">jGraduate</a></li><li><a href="module-jPicker.html">jPicker</a></li><li><a href="module-jQueryAttr.html">jQueryAttr</a></li><li><a href="module-layer.html">layer</a></li><li><a href="module-locale.html">locale</a></li><li><a href="module-math.html">math</a></li><li><a href="module-namespaces.html">namespaces</a></li><li><a href="module-path.html">path</a></li><li><a href="module-recalculate.html">recalculate</a></li><li><a href="module-sanitize.html">sanitize</a></li><li><a href="module-select.html">select</a></li><li><a href="module-selected-elem.html">selected-elem</a></li><li><a href="module-selection.html">selection</a></li><li><a href="module-svg.html">svg</a></li><li><a href="module-svgcanvas.html">svgcanvas</a></li><li><a href="module-SVGEditor.html">SVGEditor</a></li><li><a href="module-text-actions%2520Tools%2520for%2520Text%2520edit%2520functions.html">text-actions Tools for Text edit functions</a></li><li><a href="module-undo.html">undo</a></li><li><a href="module-units.html">units</a></li><li><a href="module-utilities.html">utilities</a></li></ul><h3>Externals</h3><ul><li><a href="external-JamilihArray.html">JamilihArray</a></li><li><a href="external-jQuery.html">jQuery</a></li><li><a href="external-Math.html">Math</a></li><li><a href="external-MouseEvent.html">MouseEvent</a></li><li><a href="external-Window.html">Window</a></li></ul><h3>Namespaces</h3><ul><li><a href="external-jQuery.fn.html">fn</a></li><li><a href="external-jQuery.fn.$.fn.jPicker.defaults.html">defaults</a></li><li><a href="external-jQuery.fn.exports.jPickerMethod.html">exports.jPickerMethod</a></li><li><a href="external-jQuery.fn.jGraduateDefaults.html">jGraduateDefaults</a></li><li><a href="external-jQuery.fn.jGraduateDefaults.images.html">images</a></li><li><a href="external-jQuery.fn.jGraduateDefaults.window.html">window</a></li><li><a href="external-jQuery.jGraduate.html">jGraduate</a></li><li><a href="external-jQuery.jPicker.html">jPicker</a></li><li><a href="external-jQuery.jPicker.ColorMethods.html">ColorMethods</a></li><li><a href="module-path.html#.pathActions">pathActions</a></li><li><a href="module-svgcanvas.SvgCanvas_pathActions.html">pathActions</a></li><li><a href="module-svgcanvas.SvgCanvas_textActions.html">textActions</a></li></ul><h3>Classes</h3><ul><li><a href="BottomPanel.html">BottomPanel</a></li><li><a href="configObj.html">configObj</a></li><li><a href="Dropdown.html">Dropdown</a></li><li><a href="EditorStartup.html">EditorStartup</a></li><li><a href="ElixMenuButton.html">ElixMenuButton</a></li><li><a href="ElixNumberSpinBox.html">ElixNumberSpinBox</a></li><li><a href="ExplorerButton.html">ExplorerButton</a></li><li><a href="external-jQuery.jGraduate.Paint.html">Paint</a></li><li><a href="external-jQuery.jPicker.Color.html">Color</a></li><li><a href="FlyingButton.html">FlyingButton</a></li><li><a href="LayersPanel.html">LayersPanel</a></li><li><a href="LeftPanel.html">LeftPanel</a></li><li><a href="MainMenu.html">MainMenu</a></li><li><a href="module.exports.html">exports</a></li><li><a href="module.exports_module.exports.html">exports</a></li><li><a href="module-draw.Drawing.html">Drawing</a></li><li><a href="module-draw.Layer.html">Layer</a></li><li><a href="module-history.BatchCommand.html">BatchCommand</a></li><li><a href="module-history.ChangeElementCommand.html">ChangeElementCommand</a></li><li><a href="module-history.Command.html">Command</a></li><li><a href="module-history.HistoryRecordingService.html">HistoryRecordingService</a></li><li><a href="module-history.InsertElementCommand.html">InsertElementCommand</a></li><li><a href="module-history.MoveElementCommand.html">MoveElementCommand</a></li><li><a href="module-history.RemoveElementCommand.html">RemoveElementCommand</a></li><li><a href="module-history.UndoManager.html">UndoManager</a></li><li><a href="module-jPicker.module.exports.html">module.exports</a></li><li><a href="module-layer.Layer.html">Layer</a></li><li><a href="module-path.Path.html">Path</a></li><li><a href="module-path.Segment.html">Segment</a></li><li><a href="module-select.Selector.html">Selector</a></li><li><a href="module-select.SelectorManager.html">SelectorManager</a></li><li><a href="module-svgcanvas.SvgCanvas.html">SvgCanvas</a></li><li><a href="module-SVGEditor-Editor.html">Editor</a></li><li><a href="NumberSpinBox.html">NumberSpinBox</a></li><li><a href="PaintBox.html">PaintBox</a></li><li><a href="PlainNumberSpinBox.html">PlainNumberSpinBox</a></li><li><a href="Rulers.html">Rulers</a></li><li><a href="SeCMenuDialog.html">SeCMenuDialog</a></li><li><a href="SeCMenuLayerDialog.html">SeCMenuLayerDialog</a></li><li><a href="SeColorPicker.html">SeColorPicker</a></li><li><a href="SeEditPrefsDialog.html">SeEditPrefsDialog</a></li><li><a href="SeExportDialog.html">SeExportDialog</a></li><li><a href="SeImgPropDialog.html">SeImgPropDialog</a></li><li><a href="SEInput.html">SEInput</a></li><li><a href="SeList.html">SeList</a></li><li><a href="SeMenu.html">SeMenu</a></li><li><a href="SeMenuItem.html">SeMenuItem</a></li><li><a href="SEPalette.html">SEPalette</a></li><li><a href="SePlainAlertDialog.html">SePlainAlertDialog</a></li><li><a href="SePlainBorderButton.html">SePlainBorderButton</a></li><li><a href="SePromptDialog.html">SePromptDialog</a></li><li><a href="SESpinInput.html">SESpinInput</a></li><li><a href="SeStorageDialog.html">SeStorageDialog</a></li><li><a href="SeSvgSourceEditorDialog.html">SeSvgSourceEditorDialog</a></li><li><a href="SeText.html">SeText</a></li><li><a href="ToolButton.html">ToolButton</a></li><li><a href="TopPanel.html">TopPanel</a></li></ul><h3>Interfaces</h3><ul><li><a href="module-coords.EditorContext.html">EditorContext</a></li><li><a href="module-draw.DrawCanvasInit.html">DrawCanvasInit</a></li><li><a href="module-history.HistoryCommand.html">HistoryCommand</a></li><li><a href="module-history.HistoryEventHandler.html">HistoryEventHandler</a></li><li><a href="module-locale.LocaleEditorInit.html">LocaleEditorInit</a></li><li><a href="module-path.EditorContext.html">EditorContext</a></li><li><a href="module-recalculate.EditorContext.html">EditorContext</a></li><li><a href="module-select.SVGFactory.html">SVGFactory</a></li><li><a href="module-svgcanvas.PrivateMethods.html">PrivateMethods</a></li><li><a href="module-SVGEditor.Config.html">Config</a></li><li><a href="module-SVGEditor.Prefs.html">Prefs</a></li><li><a href="module-SVGthis.CustomHandler.html">CustomHandler</a></li><li><a href="module-units.ElementContainer.html">ElementContainer</a></li><li><a href="module-utilities.EditorContext.html">EditorContext</a></li></ul><h3>Events</h3><ul><li><a href="module-history-Command.html#event:event:history">history</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:changed">changed</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:cleared">cleared</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:contextset">contextset</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:exported">exported</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:exportedPDF">exportedPDF</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_addLangData">ext_addLangData</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_callback">ext_callback</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_canvasUpdated">ext_canvasUpdated</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_elementChanged">ext_elementChanged</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_elementTransition">ext_elementTransition</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_IDsUpdated">ext_IDsUpdated</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_langChanged">ext_langChanged</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_langReady">ext_langReady</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_mouseDown">ext_mouseDown</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_mouseMove">ext_mouseMove</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_mouseUp">ext_mouseUp</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_onNewDocument">ext_onNewDocument</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_selectedChanged">ext_selectedChanged</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_toolButtonStateUpdate">ext_toolButtonStateUpdate</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_workareaResized">ext_workareaResized</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:ext_zoomChanged">ext_zoomChanged</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:extension_added">extension_added</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:extensions_added">extensions_added</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:GenericCanvasEvent">GenericCanvasEvent</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:message">message</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:pointsAdded">pointsAdded</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:saved">saved</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:selected">selected</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:setnonce">setnonce</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:transition">transition</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:unsetnonce">unsetnonce</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:updateCanvas">updateCanvas</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:zoomDone">zoomDone</a></li><li><a href="module-svgcanvas.SvgCanvas.html#event:event:zoomed">zoomed</a></li><li><a href="module-SVGEditor.html#event:event:svgEditorReadyEvent">svgEditorReadyEvent</a></li></ul><h3>Tutorials</h3><ul><li><a href="tutorial-CanvasAPI.html">CanvasAPI</a></li><li><a href="tutorial-Editor.html">Editor</a></li><li><a href="tutorial-EditorAPI.html">EditorAPI</a></li><li><a href="tutorial-Events.html">Events</a></li><li><a href="tutorial-FrequentlyAskedQuestions.html">Frequently Asked Questions (FAQ)</a></li></ul><h3>Global</h3><ul><li><a href="global.html#attributeChangedCallback">attributeChangedCallback</a></li><li><a href="global.html#connectedCallback">connectedCallback</a></li><li><a href="global.html#constructor">constructor</a></li><li><a href="global.html#expireCookie">expireCookie</a></li><li><a href="global.html#findPos">findPos</a></li><li><a href="global.html#formatValueFormatthenumericvalueasastring.Thisisusedafterincrementing/decrementingthevaluetoreformatthevalueasastring.">formatValue Format the numeric value as a string. This is used after incrementing/decrementing the value to reformat the value as a string.</a></li><li><a href="global.html#get">get</a></li><li><a href="global.html#getClosest">getClosest</a></li><li><a href="global.html#getParents">getParents</a></li><li><a href="global.html#init">init</a></li><li><a href="global.html#inputsize">inputsize</a></li><li><a href="global.html#isNullish">isNullish</a></li><li><a href="global.html#loadloadConfig">load load Config</a></li><li><a href="global.html#loadFromURLLoadconfig/datafromURLifgiven">loadFromURL Load config/data from URL if given</a></li><li><a href="global.html#name">name</a></li><li><a href="global.html#observedAttributes">observedAttributes</a></li><li><a href="global.html#parseValue">parseValue</a></li><li><a href="global.html#pref">pref</a></li><li><a href="global.html#processResults">processResults</a></li><li><a href="global.html#readySignal">readySignal</a></li><li><a href="global.html#regexEscape">regexEscape</a></li><li><a href="global.html#removeStoragePrefCookie">removeStoragePrefCookie</a></li><li><a href="global.html#replaceStoragePrompt">replaceStoragePrompt</a></li><li><a href="global.html#set">set</a></li><li><a href="global.html#setupCurConfig">setupCurConfig</a></li><li><a href="global.html#setupCurPrefs">setupCurPrefs</a></li><li><a href="global.html#src">src</a></li><li><a href="global.html#stateEffects">stateEffects</a></li><li><a href="global.html#stepDown">stepDown</a></li><li><a href="global.html#stepUp">stepUp</a></li><li><a href="global.html#touchHandler">touchHandler</a></li><li><a href="global.html#updateLib">updateLib</a></li><li><a href="global.html#value">value</a></li></ul> </nav> <br class="clear"> <footer> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 3.6.7</a> on Mon Nov 08 2021 09:47:00 GMT+0100 (Central European Standard Time) </footer> <script> prettyPrint(); </script> <script src="scripts/linenumber.js"> </script> </body> </html>