From 83d54ff40ddf82eebc53cf0d8df9cf1743033f65 Mon Sep 17 00:00:00 2001 From: olekhshch Date: Thu, 21 Dec 2023 23:01:53 +0100 Subject: [PATCH 1/2] Bottom panel styling, palette is more adaptive to screenwidth, popup palette --- src/editor/Editor.js | 300 ++++++++++++++++++++----- src/editor/components/seColorPicker.js | 6 +- src/editor/components/sePalette.js | 145 ++++++++++-- src/editor/panels/BottomPanel.js | 161 ++++++++----- src/editor/svgedit.css | 13 +- 5 files changed, 491 insertions(+), 134 deletions(-) diff --git a/src/editor/Editor.js b/src/editor/Editor.js index cc314893b..17978aca7 100644 --- a/src/editor/Editor.js +++ b/src/editor/Editor.js @@ -71,49 +71,240 @@ class Editor extends EditorStartup { this.docprops = false this.configObj.preferences = false this.canvMenu = null - this.goodLangs = ['ar', 'cs', 'de', 'en', 'es', 'fa', 'fr', 'fy', 'hi', 'it', 'ja', 'nl', 'pl', 'pt-BR', 'ro', 'ru', 'sk', 'sl', 'sv', 'tr', 'uk', 'zh-CN', 'zh-TW'] - const modKey = (isMac() ? 'meta+' : 'ctrl+') + this.goodLangs = [ + 'ar', + 'cs', + 'de', + 'en', + 'es', + 'fa', + 'fr', + 'fy', + 'hi', + 'it', + 'ja', + 'nl', + 'pl', + 'pt-BR', + 'ro', + 'ru', + 'sk', + 'sl', + 'sv', + 'tr', + 'uk', + 'zh-CN', + 'zh-TW' + ] + const modKey = isMac() ? 'meta+' : 'ctrl+' this.shortcuts = [ // Shortcuts not associated with buttons - { key: 'ctrl+arrowleft', fn: () => { this.rotateSelected(0, 1) } }, - { key: 'ctrl+arrowright', fn: () => { this.rotateSelected(1, 1) } }, - { key: 'ctrl+shift+arrowleft', fn: () => { this.rotateSelected(0, 5) } }, - { key: 'ctrl+shift+arrowright', fn: () => { this.rotateSelected(1, 5) } }, - { key: 'shift+o', fn: () => { this.svgCanvas.cycleElement(0) } }, - { key: 'shift+p', fn: () => { this.svgCanvas.cycleElement(1) } }, - { key: 'tab', fn: () => { this.svgCanvas.cycleElement(0) } }, - { key: 'shift+tab', fn: () => { this.svgCanvas.cycleElement(1) } }, - { key: [modKey + 'arrowup', true], fn: () => { this.zoomImage(2) } }, - { key: [modKey + 'arrowdown', true], fn: () => { this.zoomImage(0.5) } }, - { key: [modKey + ']', true], fn: () => { this.moveUpDownSelected('Up') } }, - { key: [modKey + '[', true], fn: () => { this.moveUpDownSelected('Down') } }, - { key: ['arrowup', true], fn: () => { this.moveSelected(0, -1) } }, - { key: ['arrowdown', true], fn: () => { this.moveSelected(0, 1) } }, - { key: ['arrowleft', true], fn: () => { this.moveSelected(-1, 0) } }, - { key: ['arrowright', true], fn: () => { this.moveSelected(1, 0) } }, - { key: 'shift+arrowup', fn: () => { this.moveSelected(0, -10) } }, - { key: 'shift+arrowdown', fn: () => { this.moveSelected(0, 10) } }, - { key: 'shift+arrowleft', fn: () => { this.moveSelected(-10, 0) } }, - { key: 'shift+arrowright', fn: () => { this.moveSelected(10, 0) } }, - { key: ['alt+arrowup', true], fn: () => { this.svgCanvas.cloneSelectedElements(0, -1) } }, - { key: ['alt+arrowdown', true], fn: () => { this.svgCanvas.cloneSelectedElements(0, 1) } }, - { key: ['alt+arrowleft', true], fn: () => { this.svgCanvas.cloneSelectedElements(-1, 0) } }, - { key: ['alt+arrowright', true], fn: () => { this.svgCanvas.cloneSelectedElements(1, 0) } }, - { key: ['alt+shift+arrowup', true], fn: () => { this.svgCanvas.cloneSelectedElements(0, -10) } }, - { key: ['alt+shift+arrowdown', true], fn: () => { this.svgCanvas.cloneSelectedElements(0, 10) } }, - { key: ['alt+shift+arrowleft', true], fn: () => { this.svgCanvas.cloneSelectedElements(-10, 0) } }, - { key: ['alt+shift+arrowright', true], fn: () => { this.svgCanvas.cloneSelectedElements(10, 0) } }, + { + key: ['ctrl+arrowleft', true], + fn: () => { + this.rotateSelected(0, 1) + } + }, + { + key: 'ctrl+arrowright', + fn: () => { + this.rotateSelected(1, 1) + } + }, + { + key: ['ctrl+shift+arrowleft', true], + fn: () => { + this.rotateSelected(0, 5) + } + }, + { + key: 'ctrl+shift+arrowright', + fn: () => { + this.rotateSelected(1, 5) + } + }, + { + key: 'shift+o', + fn: () => { + this.svgCanvas.cycleElement(0) + } + }, + { + key: 'shift+p', + fn: () => { + this.svgCanvas.cycleElement(1) + } + }, + { + key: 'tab', + fn: () => { + this.svgCanvas.cycleElement(0) + } + }, + { + key: 'shift+tab', + fn: () => { + this.svgCanvas.cycleElement(1) + } + }, + { + key: [modKey + 'arrowup', true], + fn: () => { + this.zoomImage(2) + } + }, + { + key: [modKey + 'arrowdown', true], + fn: () => { + this.zoomImage(0.5) + } + }, + { + key: [modKey + ']', true], + fn: () => { + this.moveUpDownSelected('Up') + } + }, + { + key: [modKey + '[', true], + fn: () => { + this.moveUpDownSelected('Down') + } + }, + { + key: ['arrowup', true], + fn: () => { + this.moveSelected(0, -1) + } + }, + { + key: ['arrowdown', true], + fn: () => { + this.moveSelected(0, 1) + } + }, + { + key: ['arrowleft', true], + fn: () => { + this.moveSelected(-1, 0) + } + }, + { + key: ['arrowright', true], + fn: () => { + this.moveSelected(1, 0) + } + }, + { + key: 'shift+arrowup', + fn: () => { + this.moveSelected(0, -10) + } + }, + { + key: 'shift+arrowdown', + fn: () => { + this.moveSelected(0, 10) + } + }, + { + key: 'shift+arrowleft', + fn: () => { + this.moveSelected(-10, 0) + } + }, + { + key: 'shift+arrowright', + fn: () => { + this.moveSelected(10, 0) + } + }, + { + key: ['alt+arrowup', true], + fn: () => { + this.svgCanvas.cloneSelectedElements(0, -1) + } + }, + { + key: ['alt+arrowdown', true], + fn: () => { + this.svgCanvas.cloneSelectedElements(0, 1) + } + }, + { + key: ['alt+arrowleft', true], + fn: () => { + this.svgCanvas.cloneSelectedElements(-1, 0) + } + }, + { + key: ['alt+arrowright', true], + fn: () => { + this.svgCanvas.cloneSelectedElements(1, 0) + } + }, + { + key: ['alt+shift+arrowup', true], + fn: () => { + this.svgCanvas.cloneSelectedElements(0, -10) + } + }, + { + key: ['alt+shift+arrowdown', true], + fn: () => { + this.svgCanvas.cloneSelectedElements(0, 10) + } + }, + { + key: ['alt+shift+arrowleft', true], + fn: () => { + this.svgCanvas.cloneSelectedElements(-10, 0) + } + }, + { + key: ['alt+shift+arrowright', true], + fn: () => { + this.svgCanvas.cloneSelectedElements(10, 0) + } + }, { key: ['delete/backspace', true], fn: () => { - if (this.selectedElement || this.multiselected) { this.svgCanvas.deleteSelectedElements() } + if (this.selectedElement || this.multiselected) { + this.svgCanvas.deleteSelectedElements() + } + } + }, + { + key: 'a', + fn: () => { + this.svgCanvas.selectAllInCurrentLayer() + } + }, + { + key: [modKey + 'a', true], + fn: () => { + this.svgCanvas.selectAllInCurrentLayer() } }, - { key: 'a', fn: () => { this.svgCanvas.selectAllInCurrentLayer() } }, - { key: modKey + 'a', fn: () => { this.svgCanvas.selectAllInCurrentLayer() } }, - { key: modKey + 'x', fn: () => { this.cutSelected() } }, - { key: modKey + 'c', fn: () => { this.copySelected() } }, - { key: modKey + 'v', fn: () => { this.pasteInCenter() } } + { + key: modKey + 'x', + fn: () => { + this.cutSelected() + } + }, + { + key: modKey + 'c', + fn: () => { + this.copySelected() + } + }, + { + key: modKey + 'v', + fn: () => { + this.pasteInCenter() + } + } ] this.leftPanel = new LeftPanel(this) this.bottomPanel = new BottomPanel(this) @@ -204,7 +395,7 @@ class Editor extends EditorStartup { setAll () { const keyHandler = {} // will contain the action for each pressed key - this.shortcuts.forEach(shortcut => { + this.shortcuts.forEach((shortcut) => { // Bind function to shortcut key if (shortcut.key) { // Set shortcut based on options @@ -218,14 +409,14 @@ class Editor extends EditorStartup { } keyval = String(keyval) const { fn } = shortcut - keyval.split('/').forEach(key => { + keyval.split('/').forEach((key) => { keyHandler[key] = { fn, pd } }) } return true }) // register the keydown event - document.addEventListener('keydown', e => { + document.addEventListener('keydown', (e) => { // only track keyboard shortcuts for the body containing the SVG-Editor if (e.target.nodeName !== 'BODY') return // normalize key @@ -282,7 +473,7 @@ class Editor extends EditorStartup { * @returns {module:SVGthis.ToolButton} */ getButtonData (sel) { - return Object.values(this.shortcuts).find(btn => { + return Object.values(this.shortcuts).find((btn) => { return btn.sel === sel }) } @@ -350,7 +541,9 @@ class Editor extends EditorStartup { const { workarea } = this const cnvs = $id('svgcanvas') - let w = parseFloat(getComputedStyle(workarea, null).width.replace('px', '')) + let w = parseFloat( + getComputedStyle(workarea, null).width.replace('px', '') + ) let h = parseFloat( getComputedStyle(workarea, null).height.replace('px', '') ) @@ -444,9 +637,8 @@ class Editor extends EditorStartup { } ` if (document.querySelectorAll('#wireframe_rules').length > 0) { - document.querySelector( - '#wireframe_rules' - ).textContent = this.workarea.classList.contains('wireframe') ? rule : '' + document.querySelector('#wireframe_rules').textContent = + this.workarea.classList.contains('wireframe') ? rule : '' } } @@ -538,7 +730,7 @@ class Editor extends EditorStartup { this.leftPanel.clickSelect() } - elems.forEach(elem => { + elems.forEach((elem) => { const isSvgElem = elem?.tagName === 'svg' if (isSvgElem || this.svgCanvas.isLayer(elem)) { this.layersPanel.populateLayers() @@ -593,18 +785,14 @@ class Editor extends EditorStartup { * @returns {void} */ afterClear (win) { - this.svgCanvas.runExtensions( - 'afterClear' - ) + this.svgCanvas.runExtensions('afterClear') } /** * @returns {void} */ beforeClear (win) { - this.svgCanvas.runExtensions( - 'beforeClear' - ) + this.svgCanvas.runExtensions('beforeClear') } /** @@ -1135,7 +1323,7 @@ class Editor extends EditorStartup { return this.ready(() => { return new Promise((resolve, reject) => { fetch(url, { cache: cache ? 'force-cache' : 'no-cache' }) - .then(response => { + .then((response) => { if (!response.ok) { if (noAlert) { reject(new Error('URLLoadFail')) @@ -1146,16 +1334,18 @@ class Editor extends EditorStartup { } return response.text() }) - .then(str => { + .then((str) => { this.loadSvgString(str, { noAlert }) return str }) - .catch(error => { + .catch((error) => { if (noAlert) { reject(new Error('URLLoadFail')) return } - seAlert(this.i18next.t('notification.URLLoadFail') + ': \n' + error) + seAlert( + this.i18next.t('notification.URLLoadFail') + ': \n' + error + ) resolve() }) }) diff --git a/src/editor/components/seColorPicker.js b/src/editor/components/seColorPicker.js index 72b77d3db..8231be4e1 100644 --- a/src/editor/components/seColorPicker.js +++ b/src/editor/components/seColorPicker.js @@ -634,7 +634,7 @@ div.jGraduate_Slider img { } #color_picker { z-index: 1000; - top: 60%; + bottom: 0; }
@@ -651,8 +651,8 @@ div.jGraduate_Slider img { */ export class SeColorPicker extends HTMLElement { /** - * @function constructor - */ + * @function constructor + */ constructor () { super() // create the shadowDom and insert the template diff --git a/src/editor/components/sePalette.js b/src/editor/components/sePalette.js index e7a63e092..5ab3def5d 100644 --- a/src/editor/components/sePalette.js +++ b/src/editor/components/sePalette.js @@ -2,16 +2,48 @@ /* eslint-disable max-len */ const palette = [ // Todo: Make into configuration item? - 'none', '#000000', '#3f3f3f', '#7f7f7f', '#bfbfbf', '#ffffff', - '#ff0000', '#ff7f00', '#ffff00', '#7fff00', - '#00ff00', '#00ff7f', '#00ffff', '#007fff', - '#0000ff', '#7f00ff', '#ff00ff', '#ff007f', - '#7f0000', '#7f3f00', '#7f7f00', '#3f7f00', - '#007f00', '#007f3f', '#007f7f', '#003f7f', - '#00007f', '#3f007f', '#7f007f', '#7f003f', - '#ffaaaa', '#ffd4aa', '#ffffaa', '#d4ffaa', - '#aaffaa', '#aaffd4', '#aaffff', '#aad4ff', - '#aaaaff', '#d4aaff', '#ffaaff', '#ffaad4' + 'none', + '#000000', + '#3f3f3f', + '#7f7f7f', + '#bfbfbf', + '#ffffff', + '#ff0000', + '#ff7f00', + '#ffff00', + '#7fff00', + '#00ff00', + '#00ff7f', + '#00ffff', + '#007fff', + '#0000ff', + '#7f00ff', + '#ff00ff', + '#ff007f', + '#7f0000', + '#7f3f00', + '#7f7f00', + '#3f7f00', + '#007f00', + '#007f3f', + '#007f7f', + '#003f7f', + '#00007f', + '#3f007f', + '#7f007f', + '#7f003f', + '#ffaaaa', + '#ffd4aa', + '#ffffaa', + '#d4ffaa', + '#aaffaa', + '#aaffd4', + '#aaffff', + '#aad4ff', + '#aaaaff', + '#d4aaff', + '#ffaaff', + '#ffaad4' ] const template = document.createElement('template') @@ -32,8 +64,9 @@ template.innerHTML = ` #js-se-palette { float: left; - width: 632px; - height: 16px; + min-width: 30px; + height: 15px; + overflow: hidden; } div.palette_item { @@ -45,12 +78,40 @@ template.innerHTML = ` div.palette_item:first-child { background: white; } + + .palette_expand_btn { + background: none; + border: none; + width: 14px; + height: 14px; + font-size: 12px; + cursor: pointer; + user-select:none; + } + + #palette_popup { + padding: 4px; + margin-left: 24px; + background: white; + min-width: 180px; + max-width: 360px; + min-height: 14px; + flex-wrap: wrap; + border-radius: 4px; + + position: absolute; + bottom: 36px; + right: 30px; + }
+ + +