UNPKG

svgedit

Version:

Powerful SVG-Editor for your browser

1,110 lines (998 loc) 38.1 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JSDoc: Source: panels/TopPanel.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: panels/TopPanel.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>/* eslint-disable max-len */ /* globals seAlert */ import SvgCanvas from '@svgedit/svgcanvas' import topPanelHTML from './TopPanel.html' const { $qa, $id, $click, isValidUnit, getTypeMap, convertUnit } = SvgCanvas /* * register actions for left panel */ /** * */ class TopPanel { /** * @param {PlainObject} editor svgedit handler */ constructor (editor) { this.editor = editor } /** * @type {module} */ displayTool (className) { // default display is 'none' so removing the property will make the panel visible $qa(`.${className}`).map(el => el.style.removeProperty('display')) } /** * @type {module} */ hideTool (className) { $qa(`.${className}`).forEach(el => { el.style.display = 'none' }) } /** * @type {module} */ get selectedElement () { return this.editor.selectedElement } /** * @type {module} */ get multiselected () { return this.editor.multiselected } /** * @type {module} */ get path () { return this.editor.svgCanvas.pathActions } /** * * @param {Element} opt * @param {boolean} changeElem * @returns {void} */ setStrokeOpt (opt, changeElem) { const { id } = opt const bits = id.split('_') const [pre, val] = bits if (changeElem) { this.svgCanvas.setStrokeAttr('stroke-' + pre, val) } opt.classList.add('current') const elements = Array.prototype.filter.call( opt.parentNode.children, function (child) { return child !== opt } ) Array.from(elements).forEach(function (element) { element.classList.remove('current') }) } /** * Updates the toolbar (colors, opacity, etc) based on the selected element. * This function also updates the opacity and id elements that are in the * context panel. * @returns {void} */ update () { let i let len // set title $qa('#title_panel > p')[0].textContent = this.editor.title if (this.selectedElement) { switch (this.selectedElement.tagName) { case 'use': case 'image': case 'foreignObject': break case 'g': case 'a': { // Look for common styles const childs = this.selectedElement.getElementsByTagName('*') let gWidth = null for (i = 0, len = childs.length; i &lt; len; i++) { const swidth = childs[i].getAttribute('stroke-width') if (i === 0) { gWidth = swidth } else if (gWidth !== swidth) { gWidth = null } } $id('stroke_width').value = gWidth === null ? '' : gWidth this.editor.bottomPanel.updateColorpickers(false) break } default: { this.editor.bottomPanel.updateColorpickers(false) $id('stroke_width').value = this.selectedElement.getAttribute('stroke-width') || 1 $id('stroke_style').value = this.selectedElement.getAttribute('stroke-dasharray') || 'none' $id('stroke_style').setAttribute('value', $id('stroke_style').value) let attr = this.selectedElement.getAttribute('stroke-linejoin') || 'miter' if ($id('linejoin_' + attr)) { this.setStrokeOpt($id('linejoin_' + attr)) $id('stroke_linejoin').setAttribute('value', attr) } attr = this.selectedElement.getAttribute('stroke-linecap') || 'butt' if ($id('linecap_' + attr)) { this.setStrokeOpt($id('linecap_' + attr)) $id('stroke_linecap').setAttribute('value', attr) } } } } // All elements including image and group have opacity if (this.selectedElement) { const opacPerc = (this.selectedElement.getAttribute('opacity') || 1.0) * 100 $id('opacity').value = opacPerc $id('elem_id').value = this.selectedElement.id $id('elem_class').value = this.selectedElement.getAttribute('class') ?? '' } this.editor.bottomPanel.updateToolButtonState() } /** * @param {PlainObject} [opts={}] * @param {boolean} [opts.cancelDeletes=false] * @returns {void} Resolves to `undefined` */ promptImgURL ({ cancelDeletes = false } = {}) { let curhref = this.editor.svgCanvas.getHref(this.editor.selectedElement) curhref = curhref.startsWith('data:') ? '' : curhref const url = prompt( this.editor.i18next.t('notification.enterNewImgURL'), curhref ) if (url) { this.setImageURL(url) } else if (cancelDeletes) { this.editor.svgCanvas.deleteSelectedElements() } } /** * Updates the context panel tools based on the selected element. * @returns {void} */ updateContextPanel () { let elem = this.editor.selectedElement // If element has just been deleted, consider it null if (!elem?.parentNode) { elem = null } const currentLayerName = this.editor.svgCanvas .getCurrentDrawing() .getCurrentLayerName() const currentMode = this.editor.svgCanvas.getMode() const unit = this.editor.configObj.curConfig.baseUnit !== 'px' ? this.editor.configObj.curConfig.baseUnit : null const isNode = currentMode === 'pathedit' const menuItems = document.getElementById('se-cmenu_canvas') this.hideTool('selected_panel') this.hideTool('multiselected_panel') this.hideTool('g_panel') this.hideTool('rect_panel') this.hideTool('circle_panel') this.hideTool('ellipse_panel') this.hideTool('line_panel') this.hideTool('text_panel') this.hideTool('image_panel') this.hideTool('container_panel') this.hideTool('use_panel') this.hideTool('a_panel') this.hideTool('xy_panel') if (elem) { const elname = elem.nodeName const angle = this.editor.svgCanvas.getRotationAngle(elem) $id('angle').value = angle const blurval = this.editor.svgCanvas.getBlur(elem) * 10 $id('blur').value = blurval if ( this.editor.svgCanvas.addedNew &amp;&amp; elname === 'image' &amp;&amp; this.editor.svgCanvas.getMode() === 'image' &amp;&amp; !this.editor.svgCanvas.getHref(elem).startsWith('data:') ) { /* await */ this.promptImgURL({ cancelDeletes: true }) } if (!isNode &amp;&amp; currentMode !== 'pathedit') { this.displayTool('selected_panel') // Elements in this array already have coord fields if (['line', 'circle', 'ellipse', 'polygon'].includes(elname)) { this.hideTool('xy_panel') } else { let x let y // Get BBox vals for g, polyline and path if (['g', 'polyline', 'path'].includes(elname)) { const bb = this.editor.svgCanvas.getStrokedBBox([elem]) if (bb) { ;({ x, y } = bb) } } else { x = elem.getAttribute('x') y = elem.getAttribute('y') } if (unit) { x = convertUnit(x) y = convertUnit(y) } /** * Updates the value of an input field if needed * @param {string} id - The ID of the input element to be updated. * @param {number} newValue - The new numeric value to set in the input field. */ const updateValue = (id, newValue) => { const currentValue = $id(id).value // Get current value from the field // do nothing if nothing changed... if (parseFloat(currentValue) === newValue) { return } $id(id).value = newValue } updateValue('selected_x', x) updateValue('selected_y', y) this.displayTool('xy_panel') } // Elements in this array cannot be converted to a path if (['image', 'text', 'path', 'g', 'use'].includes(elname)) { this.hideTool('tool_topath') } else { this.displayTool('tool_topath') } if (elname === 'path') { this.displayTool('tool_reorient') } else { this.hideTool('tool_reorient') } $id('tool_reorient').disabled = angle === 0 } else { const point = this.path.getNodePoint() $id('tool_add_subpath').pressed = false !this.path.canDeleteNodes ? $id('tool_node_delete').classList.add('disabled') : $id('tool_node_delete').classList.remove('disabled') // Show open/close button based on selected point // setIcon('#tool_openclose_path', path.closed_subpath ? 'open_path' : 'close_path'); if (point) { const segType = $id('seg_type') if (unit) { point.x = convertUnit(point.x) point.y = convertUnit(point.y) } $id('path_node_x').value = point.x $id('path_node_y').value = point.y if (point.type) { segType.value = point.type segType.removeAttribute('disabled') } else { segType.value = 4 segType.setAttribute('disabled', 'disabled') } } return } // update contextual tools here const panels = { g: [], a: [], rect: ['rx', 'width', 'height'], image: ['width', 'height'], circle: ['cx', 'cy', 'r'], ellipse: ['cx', 'cy', 'rx', 'ry'], line: ['x1', 'y1', 'x2', 'y2'], text: [], use: [] } const { tagName } = elem let linkHref = null if (tagName === 'a') { linkHref = this.editor.svgCanvas.getHref(elem) this.displayTool('g_panel') } // siblings if (elem.parentNode) { const selements = Array.prototype.filter.call( elem.parentNode.children, function (child) { return child !== elem } ) if (elem.parentNode.tagName === 'a' &amp;&amp; !selements.length) { this.displayTool('a_panel') linkHref = this.editor.svgCanvas.getHref(elem.parentNode) } } // Hide/show the make_link buttons if (linkHref) { this.displayTool('tool_make_link') this.displayTool('tool_make_link_multi') $id('link_url').value = linkHref } else { this.hideTool('tool_make_link') this.hideTool('tool_make_link_multi') } if (panels[tagName]) { const curPanel = panels[tagName] this.displayTool(tagName + '_panel') curPanel.forEach(item => { let attrVal = elem.getAttribute(item) if (this.editor.configObj.curConfig.baseUnit !== 'px' &amp;&amp; elem[item]) { const bv = elem[item].baseVal.value attrVal = convertUnit(bv) } $id(`${tagName}_${item}`).value = attrVal || 0 }) if (tagName === 'text') { this.displayTool('text_panel') $id('tool_italic').pressed = this.editor.svgCanvas.getItalic() $id('tool_bold').pressed = this.editor.svgCanvas.getBold() $id('tool_text_decoration_underline').pressed = this.editor.svgCanvas.hasTextDecoration('underline') $id('tool_text_decoration_linethrough').pressed = this.editor.svgCanvas.hasTextDecoration('line-through') $id('tool_text_decoration_overline').pressed = this.editor.svgCanvas.hasTextDecoration('overline') $id('tool_font_family').value = elem.getAttribute('font-family') $id('tool_text_anchor').setAttribute( 'value', elem.getAttribute('text-anchor') ) $id('font_size').value = elem.getAttribute('font-size') $id('tool_letter_spacing').value = elem.getAttribute('letter-spacing') ?? 0 $id('tool_word_spacing').value = elem.getAttribute('word-spacing') ?? 0 $id('tool_text_length').value = elem.getAttribute('textLength') ?? 0 $id('tool_length_adjust').value = elem.getAttribute('lengthAdjust') ?? 0 $id('text').value = elem.textContent if (this.editor.svgCanvas.addedNew) { // Timeout needed for IE9 setTimeout(() => { $id('text').focus() $id('text').select() }, 100) } // text } else if ( tagName === 'image' &amp;&amp; this.editor.svgCanvas.getMode() === 'image' ) { this.editor.svgCanvas.setImageURL(this.editor.svgCanvas.getHref(elem)) // image } else if (tagName === 'g' || tagName === 'use') { this.displayTool('container_panel') const title = this.editor.svgCanvas.getTitle() const label = $id('g_title') label.value = title $id('g_title').disabled = tagName === 'use' } } menuItems.setAttribute( (tagName === 'g' ? 'en' : 'dis') + 'ablemenuitems', '#ungroup' ) menuItems.setAttribute( (tagName === 'g' || !this.multiselected ? 'dis' : 'en') + 'ablemenuitems', '#group' ) // if (elem) } else if (this.multiselected) { // Check if all selected elements are 'text' nodes, if yes enable text panel const selElems = this.editor.svgCanvas.getSelectedElements() if (selElems.every(elem => elem.tagName === 'text')) { this.displayTool('text_panel') } this.displayTool('multiselected_panel') menuItems.setAttribute('enablemenuitems', '#group') menuItems.setAttribute('disablemenuitems', '#ungroup') } else { menuItems.setAttribute( 'disablemenuitems', '#delete,#cut,#copy,#group,#ungroup,#move_front,#move_up,#move_down,#move_back' ) } // update history buttons $id('tool_undo').disabled = this.editor.svgCanvas.undoMgr.getUndoStackSize() === 0 $id('tool_redo').disabled = this.editor.svgCanvas.undoMgr.getRedoStackSize() === 0 this.editor.svgCanvas.addedNew = false if ((elem &amp;&amp; !isNode) || this.multiselected) { // update the selected elements' layer $id('selLayerNames').removeAttribute('disabled') $id('selLayerNames').value = currentLayerName $id('selLayerNames').setAttribute('value', currentLayerName) // Enable regular menu options const canCMenu = document.getElementById('se-cmenu_canvas') canCMenu.setAttribute( 'enablemenuitems', '#delete,#cut,#copy,#move_front,#move_up,#move_down,#move_back' ) } else { $id('selLayerNames').setAttribute('disabled', 'disabled') } } /** * @param {Event} [e] Not used. * @param {boolean} forSaving * @returns {void} */ showSourceEditor (e, forSaving) { const $editorDialog = document.getElementById('se-svg-editor-dialog') if ($editorDialog.getAttribute('dialog') === 'open') return const origSource = this.editor.svgCanvas.getSvgString() $editorDialog.setAttribute('dialog', 'open') $editorDialog.setAttribute('value', origSource) $editorDialog.setAttribute('copysec', Boolean(forSaving)) $editorDialog.setAttribute('applysec', !forSaving) } /** * * @returns {void} */ clickWireframe () { $id('tool_wireframe').pressed = !$id('tool_wireframe').pressed this.editor.workarea.classList.toggle('wireframe') const wfRules = $id('wireframe_rules') if (!wfRules) { const fcRules = document.createElement('style') fcRules.setAttribute('id', 'wireframe_rules') document.getElementsByTagName('head')[0].appendChild(fcRules) } else { while (wfRules.firstChild) { wfRules.removeChild(wfRules.firstChild) } } this.editor.updateWireFrame() } /** * * @returns {void} */ clickUndo () { const { undoMgr, textActions } = this.editor.svgCanvas if (undoMgr.getUndoStackSize() > 0) { undoMgr.undo() this.editor.layersPanel.populateLayers() if (this.editor.svgCanvas.getMode() === 'textedit') { textActions.clear() } } } /** * * @returns {void} */ clickRedo () { const { undoMgr } = this.editor.svgCanvas if (undoMgr.getRedoStackSize() > 0) { undoMgr.redo() this.editor.layersPanel.populateLayers() } } /** * @type {module} */ changeRectRadius (e) { this.editor.svgCanvas.setRectRadius(e.target.value) } /** * @type {module} */ changeFontSize (e) { this.editor.svgCanvas.setFontSize(e.target.value) } /** * @type {module} */ changeRotationAngle (e) { this.editor.svgCanvas.setRotationAngle(e.target.value) if (Number.parseInt(e.target.value) === 0) { $id('tool_reorient').classList.add('disabled') } else { $id('tool_reorient').classList.remove('disabled') } } /** * @param {PlainObject} e * @returns {void} */ changeBlur (e) { this.editor.svgCanvas.setBlur(e.target.value / 10, true) } /** * * @returns {void} */ clickGroup () { // group if (this.editor.multiselected) { this.editor.svgCanvas.groupSelectedElements() // ungroup } else if (this.editor.selectedElement) { this.editor.svgCanvas.ungroupSelectedElement() } } /** * * @returns {void} */ clickClone () { this.editor.svgCanvas.cloneSelectedElements(20, 20) } /** * @param {PlainObject} evt * @returns {void} */ clickAlignEle (evt) { this.editor.svgCanvas.alignSelectedElements(evt.detail.value, 'page') } /** * @param {string} pos indicate the alignment relative to top, bottom, middle etc.. * @returns {void} */ clickAlign (pos) { let value = $id('tool_align_relative').value if (value === '') { value = 'selected' } this.editor.svgCanvas.alignSelectedElements(pos, value) } /** * * @type {module} */ attrChanger (e) { const attr = e.target.getAttribute('data-attr') let val = e.target.value const valid = isValidUnit(attr, val, this.selectedElement) if (!valid) { e.target.value = this.selectedElement.getAttribute(attr) alert(this.editor.i18next.t('notification.invalidAttrValGiven')) return false } if (attr !== 'id' &amp;&amp; attr !== 'class') { if (isNaN(val)) { val = this.editor.svgCanvas.convertToNum(attr, val) } else if (this.editor.configObj.curConfig.baseUnit !== 'px') { // Convert unitless value to one with given unit const unitData = getTypeMap() if ( this.editor.selectedElement[attr] || this.editor.svgCanvas.getMode() === 'pathedit' || attr === 'x' || attr === 'y' ) { val *= unitData[this.editor.configObj.curConfig.baseUnit] } } } this.editor.svgCanvas.changeSelectedAttribute(attr, val) return true } /** * * @returns {void} */ convertToPath () { if (this.editor.selectedElement) { this.editor.svgCanvas.convertToPath() } } /** * * @returns {void} */ reorientPath () { if (this.editor.selectedElement) { this.path.reorient() } } /** * * @returns {void} Resolves to `undefined` */ makeHyperlink () { if (this.editor.selectedElement || this.multiselected) { const url = prompt( this.editor.i18next.t('notification.enterNewLinkURL'), 'http://' ) if (url) { this.editor.svgCanvas.makeHyperlink(url) } } } /** * * @returns {void} */ linkControlPoints () { $id('tool_node_link').pressed = !$id('tool_node_link').pressed const linked = !!$id('tool_node_link').pressed this.path.linkControlPoints(linked) } /** * * @returns {void} */ clonePathNode () { if (this.path.getNodePoint()) { this.path.clonePathNode() } } /** * * @returns {void} */ deletePathNode () { if (this.path.getNodePoint()) { this.path.deletePathNode() } } /** * * @returns {void} */ addSubPath () { const button = $id('tool_add_subpath') const sp = !button.classList.contains('pressed') button.pressed = sp // button.toggleClass('push_button_pressed tool_button'); this.path.addSubPath(sp) } /** * * @returns {void} */ opencloseSubPath () { this.path.opencloseSubPath() } /** * Delete is a contextual tool that only appears in the ribbon if * an element has been selected. * @returns {void} */ deleteSelected () { if (this.editor.selectedElement || this.editor.multiselected) { this.editor.svgCanvas.deleteSelectedElements() } } /** * * @returns {void} */ moveToTopSelected () { if (this.editor.selectedElement) { this.editor.svgCanvas.moveToTopSelectedElement() } } /** * * @returns {void} */ moveToBottomSelected () { if (this.editor.selectedElement) { this.editor.svgCanvas.moveToBottomSelectedElement() } } /** * Checks if there are currently selected text elements to avoid firing of bold,italic when no text selected * @returns {boolean} */ get anyTextSelected () { const selected = this.editor.svgCanvas.getSelectedElements() return selected.filter(el => el.tagName === 'text').length > 0 } /** * * @returns {false} */ clickBold () { if (this.anyTextSelected) { this.editor.svgCanvas.setBold(!this.editor.svgCanvas.getBold()) this.updateContextPanel() return false } } /** * * @returns {false} */ clickItalic () { if (this.anyTextSelected) { this.editor.svgCanvas.setItalic(!this.editor.svgCanvas.getItalic()) this.updateContextPanel() return false } } /** * Handles the click on the text decoration buttons * * @param value The text decoration value * @returns {boolean} false */ clickTextDecoration (value) { if (this.editor.svgCanvas.hasTextDecoration(value)) { this.editor.svgCanvas.removeTextDecoration(value) } else { this.editor.svgCanvas.addTextDecoration(value) } this.updateContextPanel() return false } /** * Sets the text anchor value * * @returns {false} */ clickTextAnchor (evt) { this.editor.svgCanvas.setTextAnchor(evt.detail.value) return false } /** * @type {module} */ changeLetterSpacing (e) { this.editor.svgCanvas.setLetterSpacing(e.target.value) } /** * @type {module} */ changeWordSpacing (e) { this.editor.svgCanvas.setWordSpacing(e.target.value) } /** * @type {module} */ changeTextLength (e) { this.editor.svgCanvas.setTextLength(e.target.value) } /** * @type {module} */ changeLengthAdjust (evt) { this.editor.svgCanvas.setLengthAdjust(evt.detail.value) } /** * Set a selected image's URL. * @function module:SVGthis.setImageURL * @param {string} url * @returns {void} */ setImageURL (url) { const { editor } = this if (!url) { url = editor.defaultImageURL } editor.svgCanvas.setImageURL(url) $id('image_url').value = url if (url.startsWith('data:')) { // data URI found this.hideTool('image_url') } else { // regular URL const promised = editor.svgCanvas.embedImage(url) // eslint-disable-next-line promise/catch-or-return promised // eslint-disable-next-line promise/always-return .then( () => { // switch into "select" mode if we've clicked on an element editor.svgCanvas.setMode('select') editor.svgCanvas.selectOnly( editor.svgCanvas.getSelectedElements(), true ) }, error => { console.error('error =', error) seAlert(editor.i18next.t('tools.no_embed')) editor.svgCanvas.deleteSelectedElements() } ) this.displayTool('image_url') } } /** * */ updateTitle (title) { if (title) this.editor.title = title const titleElement = $qa('#title_panel > p')[0] if (titleElement) titleElement.textContent = this.editor.title } /** * @param {boolean} editmode * @param {module:svgcanvas.SvgCanvas#event:selected} elems * @returns {void} */ togglePathEditMode (editMode, elems) { if (editMode) { this.displayTool('path_node_panel') } else { this.hideTool('path_node_panel') } if (editMode) { // Change select icon $id('tool_path').pressed = false $id('tool_select').pressed = true $id('tool_select').setAttribute('src', 'select_node.svg') this.editor.multiselected = false if (elems.length) { this.editor.selectedElement = elems[0] } } else { setTimeout(() => { $id('tool_select').setAttribute('src', 'select.svg') }, 1000) } } /** * @type {module} */ init () { // add Top panel const template = document.createElement('template') const { i18next } = this.editor template.innerHTML = topPanelHTML this.editor.$svgEditor.append(template.content.cloneNode(true)) // svg editor source dialoag added to DOM const newSeEditorDialog = document.createElement( 'se-svg-source-editor-dialog' ) newSeEditorDialog.setAttribute('id', 'se-svg-editor-dialog') this.editor.$container.append(newSeEditorDialog) this.updateTitle() newSeEditorDialog.init(i18next) $id('tool_link_url').setAttribute('title', i18next.t('tools.set_link_url')) // register action to top panel buttons $click($id('tool_source'), this.showSourceEditor.bind(this)) $click($id('tool_wireframe'), this.clickWireframe.bind(this)) $click($id('tool_undo'), this.clickUndo.bind(this)) $click($id('tool_redo'), this.clickRedo.bind(this)) $click($id('tool_clone'), this.clickClone.bind(this)) $click($id('tool_clone_multi'), this.clickClone.bind(this)) $click($id('tool_delete'), this.deleteSelected.bind(this)) $click($id('tool_delete_multi'), this.deleteSelected.bind(this)) $click($id('tool_move_top'), this.moveToTopSelected.bind(this)) $click($id('tool_move_bottom'), this.moveToBottomSelected.bind(this)) $click($id('tool_topath'), this.convertToPath.bind(this)) $click($id('tool_make_link'), this.makeHyperlink.bind(this)) $click($id('tool_make_link_multi'), this.makeHyperlink.bind(this)) $click($id('tool_reorient'), this.reorientPath.bind(this)) $click($id('tool_group_elements'), this.clickGroup.bind(this)) $id('tool_position').addEventListener('change', evt => this.clickAlignEle.bind(this)(evt) ) $click($id('tool_align_left'), () => this.clickAlign.bind(this)('left')) $click($id('tool_align_right'), () => this.clickAlign.bind(this)('right')) $click($id('tool_align_center'), () => this.clickAlign.bind(this)('center')) $click($id('tool_align_top'), () => this.clickAlign.bind(this)('top')) $click($id('tool_align_bottom'), () => this.clickAlign.bind(this)('bottom')) $click($id('tool_align_middle'), () => this.clickAlign.bind(this)('middle')) $click($id('tool_align_distrib_horiz'), () => this.clickAlign.bind(this)('distrib_horiz') ) $click($id('tool_align_distrib_verti'), () => this.clickAlign.bind(this)('distrib_verti') ) $click($id('tool_node_clone'), this.clonePathNode.bind(this)) $click($id('tool_node_delete'), this.deletePathNode.bind(this)) $click($id('tool_openclose_path'), this.opencloseSubPath.bind(this)) $click($id('tool_add_subpath'), this.addSubPath.bind(this)) $click($id('tool_node_link'), this.linkControlPoints.bind(this)) $id('angle').addEventListener('change', this.changeRotationAngle.bind(this)) $id('blur').addEventListener('change', this.changeBlur.bind(this)) $id('rect_rx').addEventListener('change', this.changeRectRadius.bind(this)) $id('font_size').addEventListener('change', this.changeFontSize.bind(this)) $click($id('tool_ungroup'), this.clickGroup.bind(this)) $click($id('tool_bold'), this.clickBold.bind(this)) $click($id('tool_italic'), this.clickItalic.bind(this)) $click($id('tool_text_decoration_underline'), () => this.clickTextDecoration.bind(this)('underline') ) $click($id('tool_text_decoration_linethrough'), () => this.clickTextDecoration.bind(this)('line-through') ) $click($id('tool_text_decoration_overline'), () => this.clickTextDecoration.bind(this)('overline') ) $id('tool_text_anchor').addEventListener('change', evt => this.clickTextAnchor.bind(this)(evt) ) $id('tool_letter_spacing').addEventListener( 'change', this.changeLetterSpacing.bind(this) ) $id('tool_word_spacing').addEventListener( 'change', this.changeWordSpacing.bind(this) ) $id('tool_text_length').addEventListener( 'change', this.changeTextLength.bind(this) ) $id('tool_length_adjust').addEventListener('change', evt => this.changeLengthAdjust.bind(this)(evt) ) $click($id('tool_unlink_use'), this.clickGroup.bind(this)) $id('image_url').addEventListener('change', evt => { this.setImageURL(evt.currentTarget.value) }) // all top panel attributes ;[ 'elem_id', 'elem_class', 'circle_cx', 'circle_cy', 'circle_r', 'ellipse_cx', 'ellipse_cy', 'ellipse_rx', 'ellipse_ry', 'selected_x', 'selected_y', 'rect_width', 'rect_height', 'line_x1', 'line_x2', 'line_y1', 'line_y2', 'image_width', 'image_height', 'path_node_x', 'path_node_y' ].forEach(attrId => $id(attrId).addEventListener('change', this.attrChanger.bind(this)) ) } } export default TopPanel </code></pre> </article> </section> </div> <nav> <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-SVGEditor.html">SVGEditor</a></li><li><a href="module-contextmenu.html">contextmenu</a></li><li><a href="module-jGraduate.html">jGraduate</a></li><li><a href="module-jPicker.html">jPicker</a></li><li><a href="module-locale.html">locale</a></li></ul><h3>Externals</h3><ul><li><a href="external-JamilihArray.html">JamilihArray</a></li><li><a href="external-Math.html">Math</a></li><li><a href="external-Window.html">Window</a></li><li><a href="external-jQuery.html">jQuery</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></ul><h3>Classes</h3><ul><li><a href="BottomPanel.html">BottomPanel</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="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="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="SEInput.html">SEInput</a></li><li><a href="SEPalette.html">SEPalette</a></li><li><a href="SESpinInput.html">SESpinInput</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="SeList.html">SeList</a></li><li><a href="SeMenu.html">SeMenu</a></li><li><a href="SeMenuItem.html">SeMenuItem</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="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><li><a href="configObj.html">configObj</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="module.exports.html">exports</a></li><li><a href="module.exports_module.exports.html">exports</a></li><li><a href="module-SVGEditor-Editor.html">Editor</a></li><li><a href="module-jPicker.module.exports.html">module.exports</a></li></ul><h3>Interfaces</h3><ul><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-locale.LocaleEditorInit.html">LocaleEditorInit</a></li></ul><h3>Events</h3><ul><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#createTemplate">createTemplate</a></li><li><a href="global.html#decrement">decrement</a></li><li><a href="global.html#expireCookie">expireCookie</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#handleClick">handleClick</a></li><li><a href="global.html#handleClose">handleClose</a></li><li><a href="global.html#handleInput">handleInput</a></li><li><a href="global.html#handleKeyDown">handleKeyDown</a></li><li><a href="global.html#handleMouseDown">handleMouseDown</a></li><li><a href="global.html#handleMouseUp">handleMouseUp</a></li><li><a href="global.html#handleOptionsChange">handleOptionsChange</a></li><li><a href="global.html#handleSelect">handleSelect</a></li><li><a href="global.html#handleShow">handleShow</a></li><li><a href="global.html#increment">increment</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#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#triggerInputChanged">triggerInputChanged</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 4.0.4</a> on Mon Jun 09 2025 17:03:26 GMT+0200 (Central European Summer Time) </footer> <script> prettyPrint(); </script> <script src="scripts/linenumber.js"> </script> </body> </html>