From 19403a275550dd7ebc2f62359de5094728ec4511 Mon Sep 17 00:00:00 2001 From: olekhshch <96601180+olekhshch@users.noreply.github.com> Date: Thu, 28 Dec 2023 11:20:26 +0100 Subject: [PATCH] Panning, modeChange Event, minor changes (#939) * mode event, panning cursor * Panning shortcuts(space,wheel), undo shortcut * Undo/redo shortcuts, svgcanvas changes added to the main file * minor refactoring --- packages/svgcanvas/svgcanvas.js | 16 ++++ src/editor/Editor.js | 4 +- src/editor/EditorStartup.js | 60 ++++++++++++- .../extensions/ext-panning/ext-panning.js | 2 +- src/editor/panels/LeftPanel.js | 2 +- src/editor/panels/TopPanel.html | 90 ++++++++++--------- src/editor/svgedit.css | 44 +++++---- 7 files changed, 156 insertions(+), 62 deletions(-) diff --git a/packages/svgcanvas/svgcanvas.js b/packages/svgcanvas/svgcanvas.js index 17be102b..5c4a6377 100644 --- a/packages/svgcanvas/svgcanvas.js +++ b/packages/svgcanvas/svgcanvas.js @@ -308,6 +308,9 @@ class SvgCanvas { this.contentW = this.getResolution().w this.contentH = this.getResolution().h this.clear() + + // creates custom modeEvent for editor + this.modeChangeEvent() } // End constructor getSvgOption () { @@ -827,6 +830,11 @@ class SvgCanvas { ? this.curText : this.curShape this.currentMode = name + + // fires modeChange event for the editor + if (this.modeEvent) { + document.dispatchEvent(this.modeEvent) + } } /** @@ -1328,6 +1336,14 @@ class SvgCanvas { this.decode64 = decode64 this.mergeDeep = mergeDeep } + + /** + * Creates modeChange event, adds it as an svgCanvas property + * **/ + modeChangeEvent () { + const modeEvent = new CustomEvent('modeChange', { detail: { getMode: () => this.getMode() } }) + this.modeEvent = modeEvent + } } // End class // attach utilities function to the class that are used by SvgEdit so diff --git a/src/editor/Editor.js b/src/editor/Editor.js index 17978aca..e35c0334 100644 --- a/src/editor/Editor.js +++ b/src/editor/Editor.js @@ -388,8 +388,10 @@ class Editor extends EditorStartup { this.svgCanvas.randomizeIds(arg) } - /** @lends module:SVGEditor~Actions */ /** + * @lends module:SVGEditor~Actions */ + /** + * editor shortcuts init * @returns {void} */ setAll () { diff --git a/src/editor/EditorStartup.js b/src/editor/EditorStartup.js index 1ea9224b..20b9aaa3 100644 --- a/src/editor/EditorStartup.js +++ b/src/editor/EditorStartup.js @@ -118,6 +118,10 @@ class EditorStartup { this.configObj.curConfig ) + // once svgCanvas is init - adding listener to the changes of the current mode + this.modeEvent = this.svgCanvas.modeEvent + document.addEventListener('modeChange', (evt) => this.modeListener(evt)) + this.leftPanel.init() this.bottomPanel.init() this.topPanel.init() @@ -278,6 +282,7 @@ class EditorStartup { let lastX = null; let lastY = null let panning = false; let keypan = false + let previousMode = 'select' $id('svgcanvas').addEventListener('mouseup', (evt) => { if (panning === false) { return true } @@ -305,7 +310,12 @@ class EditorStartup { }) $id('svgcanvas').addEventListener('mousedown', (evt) => { if (evt.button === 1 || keypan === true) { + // prDefault to avoid firing of browser's panning on mousewheel + evt.preventDefault() panning = true + previousMode = this.svgCanvas.getMode() + this.svgCanvas.setMode('ext-panning') + this.workarea.style.cursor = 'grab' lastX = evt.clientX lastY = evt.clientY return false @@ -313,10 +323,27 @@ class EditorStartup { return true }) - window.addEventListener('mouseup', () => { + // preventing browser's scaling with Ctrl+wheel + this.$container.addEventListener('wheel', (e) => { + if (e.ctrlKey) { + e.preventDefault() + } + }) + + window.addEventListener('mouseup', (evt) => { + if (evt.button === 1) { + this.svgCanvas.setMode(previousMode ?? 'select') + } panning = false }) + // Allows quick change to the select mode while panning mode is active + this.workarea.addEventListener('dblclick', (evt) => { + if (this.svgCanvas.getMode() === 'ext-panning') { + this.leftPanel.clickSelect() + } + }) + document.addEventListener('keydown', (e) => { if (e.target.nodeName !== 'BODY') return if (e.code.toLowerCase() === 'space') { @@ -332,6 +359,7 @@ class EditorStartup { if (e.target.nodeName !== 'BODY') return if (e.code.toLowerCase() === 'space') { this.svgCanvas.spaceKey = keypan = false + this.svgCanvas.setMode(previousMode === 'ext-panning' ? 'select' : previousMode ?? 'select') e.preventDefault() } else if ((e.key.toLowerCase() === 'shift') && (this.svgCanvas.getMode() === 'zoom')) { this.workarea.style.cursor = zoomInIcon @@ -695,6 +723,36 @@ class EditorStartup { console.error(err) } } + + /** + * Listens to the mode change, listener is to be added on document +* @param {Event} evt custom modeChange event +*/ + modeListener (evt) { + const mode = this.svgCanvas.getMode() + + this.setCursorStyle(mode) + } + + /** + * sets cursor styling for workarea depending on the current mode + * @param {string} mode + */ + setCursorStyle (mode) { + let cs = 'auto' + switch (mode) { + case 'ext-panning': + cs = 'grab' + break + case 'zoom': + cs = 'crosshair' + break + default: + cs = 'auto' + } + + this.workarea.style.cursor = cs + } } export default EditorStartup diff --git a/src/editor/extensions/ext-panning/ext-panning.js b/src/editor/extensions/ext-panning/ext-panning.js index df106630..ce9fe264 100644 --- a/src/editor/extensions/ext-panning/ext-panning.js +++ b/src/editor/extensions/ext-panning/ext-panning.js @@ -39,7 +39,7 @@ export default { return { name: svgEditor.i18next.t(`${name}:name`), callback () { - const btitle = `${name}:buttons.0.title` + const btitle = `${name} [Space / mouse wheel + drag]` // Add the button and its handler(s) const buttonTemplate = document.createElement('template') buttonTemplate.innerHTML = ` diff --git a/src/editor/panels/LeftPanel.js b/src/editor/panels/LeftPanel.js index 0a497fa7..8a301278 100644 --- a/src/editor/panels/LeftPanel.js +++ b/src/editor/panels/LeftPanel.js @@ -45,7 +45,7 @@ class LeftPanel { */ clickSelect () { if (this.updateLeftPanel('tool_select')) { - this.editor.workarea.style.cursor = 'auto' + // this.editor.workarea.style.cursor = 'auto' this.editor.svgCanvas.setMode('select') } } diff --git a/src/editor/panels/TopPanel.html b/src/editor/panels/TopPanel.html index d3f60af4..9cdd976a 100644 --- a/src/editor/panels/TopPanel.html +++ b/src/editor/panels/TopPanel.html @@ -9,8 +9,8 @@
- - + +
@@ -43,27 +43,27 @@ + img-height="22px"> + img-height="22px"> + img-height="22px"> + img-height="22px"> + img-height="22px"> + img-height="22px">
+ title="properties.pos_x"> + title="properties.pos_y">
@@ -83,27 +83,29 @@ - - + + + options="tools.selected_objects,tools.largest_object,tools.smallest_object,tools.page" + values="selected::largest::smallest::page">
+ title="properties.rect_width"> + title="properties.rect_height"> + data-attr="Corner Radius" src="c_radius.svg">
+ title="properties.image_width"> + title="properties.image_height">
@@ -117,15 +119,15 @@
+ label="properties.cx_label"> + label="properties.cy_label">
+ label="properties.rx_label"> + label="properties.ry_label">
@@ -141,43 +143,49 @@ - - - + + + + options="properties.serif,properties.sans_serif,properties.cursive,properties.fantasy,properties.monospace,properties.courier,properties.helvetica,properties.times" + values="Serif::Sans-serif::Cursive::Fantasy::Monospace::Courier::Helvetica::Times"> + src="fontsize.svg"> - - - + + + + src="letter_spacing.svg"> + src="word_spacing.svg"> + src="text_length.svg"> + options="properties.text_length_adjust_spacing,properties.text_length_adjust_spacing_and_glyphs" + values="spacing::spacingAndGlyphs">
- +
@@ -192,7 +200,7 @@
@@ -204,11 +212,11 @@ + options="properties.straight_segments,properties.curve_segments" values="4::6">
-
+ \ No newline at end of file diff --git a/src/editor/svgedit.css b/src/editor/svgedit.css index 8bf49bf2..e1b62984 100644 --- a/src/editor/svgedit.css +++ b/src/editor/svgedit.css @@ -19,7 +19,7 @@ display: grid; grid-template-rows: auto 15px 1fr 40px; grid-template-columns: 40px 15px 50px 1fr 15px; - grid-template-areas: + grid-template-areas: "main main main top top" "left corner rulerX rulerX side" "left rulerY workarea workarea side" @@ -33,7 +33,7 @@ height: 100%; } -#title_panel > p { +#title_panel>p { color: white; padding-left: 5px; padding-right: 3px; @@ -86,7 +86,7 @@ color: white; position: absolute; cursor: pointer; - top:50%; + top: 50%; } .svg_editor:not(.open) #sidepanel_content { @@ -272,7 +272,8 @@ hr { top: -9px; } -#main_menu ul, #main_menu li { +#main_menu ul, +#main_menu li { list-style: none; margin: 0; padding: 0; @@ -327,15 +328,18 @@ hr { overflow-y: hidden; display: flex; align-items: center; - scrollbar-width: thin; /* Firefox */ + scrollbar-width: thin; + /* Firefox */ } -#tools_bottom::-webkit-scrollbar { /* Chrome, Edge, and Safari */ +#tools_bottom::-webkit-scrollbar { + /* Chrome, Edge, and Safari */ width: 3px; height: 3px; } -#tools_bottom se-list, #tools_bottom se-select { +#tools_bottom se-list, +#tools_bottom se-select { margin-bottom: 8px; } @@ -353,19 +357,24 @@ hr { margin-left: auto; margin-right: auto; overflow-y: scroll; - scrollbar-width: none; /* Firefox */ + scrollbar-width: none; + /* Firefox */ + user-select: none; } -#tools_left::-webkit-scrollbar { /* Chrome, Edge, and Safari */ +#tools_left::-webkit-scrollbar { + /* Chrome, Edge, and Safari */ width: 3px; } -#tools_left::-webkit-scrollbar-track, #tools_bottom::-webkit-scrollbar-track{ +#tools_left::-webkit-scrollbar-track, +#tools_bottom::-webkit-scrollbar-track { background: transparent; } -#tools_left::-webkit-scrollbar-thumb, #tools_bottom::-webkit-scrollbar-thumb { - background-color:rgb(70, 70, 70); +#tools_left::-webkit-scrollbar-thumb, +#tools_bottom::-webkit-scrollbar-thumb { + background-color: rgb(70, 70, 70); } /* End scrollbar styling */ @@ -486,7 +495,8 @@ input[type=text] { margin-right: 0; } -#main_menu li#tool_open, #main_menu li#tool_import { +#main_menu li#tool_open, +#main_menu li#tool_import { position: relative; overflow: hidden; } @@ -495,7 +505,9 @@ input[type=text] { overflow: hidden; } -#tool_open input, #tool_import input, #tool_image input { +#tool_open input, +#tool_import input, +#tool_image input { position: absolute; opacity: 0; font-size: 10em; @@ -615,6 +627,4 @@ ul li.current { .dropdown li.tool_button { width: 24px; -} - - +} \ No newline at end of file