UNPKG

svgedit

Version:

Powerful SVG-Editor for your browser

460 lines (401 loc) 17.7 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JSDoc: Source: components/seZoom.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: components/seZoom.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>/* globals svgEditor */ const template = document.createElement('template') template.innerHTML = ` &lt;style> input{ border:unset; background-color:var(--input-color); min-width:unset; width:40px; height:23px; padding:1px 2px; border:2px; font: inherit; margin: 2px 1px 0px 2px; box-sizing:border-box; text-align: center; border-radius: 3px 0px 0px 3px; } #tool-wrapper{ height:20px; display:flex; align-items:center; } #icon{ margin-bottom:1px } #spinner{ display:flex; flex-direction:column; } #spinner > div { height: 11px; width: 7px; display: flex; align-items: center; justify-content: center; font-size: 7px; border-left:solid 1px transparent; border-right:solid 1px transparent; background-color:var(--input-color); } #arrow-up{ height:9px; margin-top: 2px; margin-bottom: 1px; } #arrow-up, #arrow-down { user-select: none; } @keyframes hover-arrows { from { background: transparent; color: var(--icon-bg-color-hover); } to { background: var(--icon-bg-color-hover); color: var(--orange-color); } } #arrow-up:hover, #arrow-down:hover { animation: hover-arrows 0.2s forwards; } #down{ width:18px; height:23px; display: flex; align-items: center; justify-content: center; background-color:var(--input-color); border-radius: 0px 3px 3px 0px; margin: 2px 5px 0px 1px; } #down > img { margin-top: 2px; } #options-container { position:fixed display:flex; flex-direction:column; background-color:var(--icon-bg-color); border:solid 1px white; box-shadow:0 0px 10px rgb(0 0 0 / 50%); } ::slotted(*) { margin:2px; padding:3px; color:white; } ::slotted(*:hover) { background-color: rgb(43, 60, 69); } &lt;/style> &lt;div id="tool-wrapper"> &lt;img id="icon" alt="icon" width="18" height="18"/> &lt;input/> &lt;div id="spinner"> &lt;div id="arrow-up">▲&lt;/div> &lt;div id="arrow-down">▼&lt;/div> &lt;/div> &lt;div id="down"> &lt;img width="16" height="8" src="arrow_down.svg" alt="Zoom dropdown"/> &lt;/div> &lt;/div> &lt;div id="options-container" style="display:none"> &lt;slot>&lt;/slot> &lt;/div> ` class SeZoom extends HTMLElement { constructor () { super() this.handleMouseDown = this.handleMouseDown.bind(this) this.handleMouseUp = this.handleMouseUp.bind(this) this.handleKeyDown = this.handleKeyDown.bind(this) this.initPopup = this.initPopup.bind(this) this.handleInput = this.handleInput.bind(this) // create the shadowDom and insert the template this._shadowRoot = this.attachShadow({ mode: 'open' }) // locate the component this._shadowRoot.append(template.content.cloneNode(true)) // prepare the slot element this.slotElement = this._shadowRoot.querySelector('slot') this.slotElement.addEventListener( 'slotchange', this.handleOptionsChange.bind(this) ) // hookup events for the input box this.inputElement = this._shadowRoot.querySelector('input') this.inputElement.addEventListener('click', this.handleClick.bind(this)) this.inputElement.addEventListener('change', this.handleInput) this.inputElement.addEventListener('keydown', this.handleKeyDown) this.clickArea = this._shadowRoot.querySelector('#down') this.clickArea.addEventListener('click', this.handleClick.bind(this)) this.imgPath = svgEditor.configObj.curConfig.imgPath this.downImageElement = this.clickArea.querySelector('img') this.downImageElement.setAttribute( 'src', (this.imgPath + '/' + this.downImageElement.getAttribute('src')) ) // set src for imageElement this.imageElement = this._shadowRoot.querySelector('img') this.imageElement.setAttribute( 'src', (this.imgPath + '/' + this.getAttribute('src')) ) // hookup events for arrow buttons this.arrowUp = this._shadowRoot.querySelector('#arrow-up') this.arrowUp.addEventListener('click', this.increment.bind(this)) this.arrowUp.addEventListener('mousedown', e => this.handleMouseDown('up', true) ) this.arrowUp.addEventListener('mouseleave', e => this.handleMouseUp('up')) this.arrowUp.addEventListener('mouseup', e => this.handleMouseUp('up')) this.arrowDown = this._shadowRoot.querySelector('#arrow-down') this.arrowDown.addEventListener('click', this.decrement.bind(this)) this.arrowDown.addEventListener('mousedown', e => this.handleMouseDown('down', true) ) this.arrowDown.addEventListener('mouseleave', e => this.handleMouseUp('down') ) this.arrowDown.addEventListener('mouseup', e => this.handleMouseUp('down')) this.optionsContainer = this._shadowRoot.querySelector( '#options-container' ) // add an event listener to close the popup document.addEventListener('click', e => this.handleClose(e)) this.changedTimeout = null } static get observedAttributes () { return ['value'] } /** * @function get * @returns {any} */ get value () { return this.getAttribute('value') } /** * @function set * @returns {void} */ set value (value) { this.setAttribute('value', value) } /** * @function attributeChangedCallback * @param {string} name * @param {string} oldValue * @param {string} newValue * @returns {void} */ attributeChangedCallback (name, oldValue, newValue) { if (oldValue === newValue) { switch (name) { case 'value': if (parseInt(this.inputElement.value) !== newValue) { this.inputElement.value = newValue } break } return } switch (name) { case 'value': this.inputElement.value = newValue this.dispatchEvent( new CustomEvent('change', { detail: { value: newValue } }) ) break } } /** * @function handleOptionsChange * @returns {void} */ handleOptionsChange () { if (this.slotElement.assignedElements().length > 0) { this.options = this.slotElement.assignedElements() this.selectedValue = this.options[0].textContent this.initPopup() this.options.forEach(option => { option.addEventListener('click', e => this.handleSelect(e)) }) } } /** * @function handleClick * @returns {void} */ handleClick () { this.optionsContainer.style.display = 'flex' this.inputElement.select() this.initPopup() } /** * @function handleSelect * @param {Event} e * @returns {void} */ handleSelect (e) { this.value = e.target.getAttribute('value') this.title = e.target.getAttribute('text') } /** * @function handleShow * @returns {void} * initialises the popup menu position */ initPopup () { const zoomPos = this.getBoundingClientRect() const popupPos = this.optionsContainer.getBoundingClientRect() const top = zoomPos.top - popupPos.height const left = zoomPos.left this.optionsContainer.style.position = 'fixed' this.optionsContainer.style.top = `${top}px` this.optionsContainer.style.left = `${left}px` } /** * @function handleClose * @param {Event} e * @returns {void} * Close the popup menu */ handleClose (e) { if (e.target !== this) { this.optionsContainer.style.display = 'none' this.inputElement.blur() } } /** * @function handleInput * @returns {void} */ handleInput () { if (this.changedTimeout) { clearTimeout(this.changedTimeout) } this.changedTimeout = setTimeout(this.triggerInputChanged.bind(this), 500) } /** * @function triggerInputChanged * @returns {void} */ triggerInputChanged () { const newValue = this.inputElement.value this.value = newValue } /** * @function increment * @returns {void} */ increment () { this.value = parseInt(this.value) + 10 } /** * @function decrement * @returns {void} */ decrement () { if (this.value - 10 &lt;= 0) { this.value = 10 } else { this.value = parseInt(this.value) - 10 } } /** * @function handleMouseDown * @param {string} dir * @param {boolean} isFirst * @returns {void} * Increment/Decrement on mouse held down, if its the first call add a delay before starting */ handleMouseDown (dir, isFirst) { if (dir === 'up') { this.incrementHold = true !isFirst &amp;&amp; this.increment() setTimeout( () => { if (this.incrementHold) { this.handleMouseDown(dir, false) } }, isFirst ? 500 : 50 ) } else if (dir === 'down') { this.decrementHold = true !isFirst &amp;&amp; this.decrement() setTimeout( () => { if (this.decrementHold) { this.handleMouseDown(dir, false) } }, isFirst ? 500 : 50 ) } } /** * @function handleMouseUp * @param {string} dir * @returns {void} */ handleMouseUp (dir) { if (dir === 'up') { this.incrementHold = false } else { this.decrementHold = false } } /** * @function handleKeyDown * @param {Event} e * @returns {void} */ handleKeyDown (e) { if (e.key === 'ArrowUp') { this.increment() } else if (e.key === 'ArrowDown') { this.decrement() } } } // Register customElements.define('se-zoom', SeZoom) </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>