Bottom panel styling, more adaptive palette, shortcuts (#937)
This commit is contained in:
3
.github/workflows/onpullrequest.yml
vendored
3
.github/workflows/onpullrequest.yml
vendored
@@ -1,6 +1,9 @@
|
|||||||
name: Node CI
|
name: Node CI
|
||||||
|
|
||||||
on: [pull_request]
|
on: [pull_request]
|
||||||
|
# To be able to write in the PR, we need write permission.
|
||||||
|
permissions:
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|||||||
@@ -71,49 +71,240 @@ class Editor extends EditorStartup {
|
|||||||
this.docprops = false
|
this.docprops = false
|
||||||
this.configObj.preferences = false
|
this.configObj.preferences = false
|
||||||
this.canvMenu = null
|
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']
|
this.goodLangs = [
|
||||||
const modKey = (isMac() ? 'meta+' : 'ctrl+')
|
'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 = [
|
this.shortcuts = [
|
||||||
// Shortcuts not associated with buttons
|
// Shortcuts not associated with buttons
|
||||||
{ key: 'ctrl+arrowleft', fn: () => { this.rotateSelected(0, 1) } },
|
{
|
||||||
{ key: 'ctrl+arrowright', fn: () => { this.rotateSelected(1, 1) } },
|
key: ['ctrl+arrowleft', true],
|
||||||
{ key: 'ctrl+shift+arrowleft', fn: () => { this.rotateSelected(0, 5) } },
|
fn: () => {
|
||||||
{ key: 'ctrl+shift+arrowright', fn: () => { this.rotateSelected(1, 5) } },
|
this.rotateSelected(0, 1)
|
||||||
{ 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: 'ctrl+arrowright',
|
||||||
{ key: [modKey + 'arrowup', true], fn: () => { this.zoomImage(2) } },
|
fn: () => {
|
||||||
{ key: [modKey + 'arrowdown', true], fn: () => { this.zoomImage(0.5) } },
|
this.rotateSelected(1, 1)
|
||||||
{ 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: ['ctrl+shift+arrowleft', true],
|
||||||
{ key: ['arrowleft', true], fn: () => { this.moveSelected(-1, 0) } },
|
fn: () => {
|
||||||
{ key: ['arrowright', true], fn: () => { this.moveSelected(1, 0) } },
|
this.rotateSelected(0, 5)
|
||||||
{ 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: 'ctrl+shift+arrowright',
|
||||||
{ key: ['alt+arrowup', true], fn: () => { this.svgCanvas.cloneSelectedElements(0, -1) } },
|
fn: () => {
|
||||||
{ key: ['alt+arrowdown', true], fn: () => { this.svgCanvas.cloneSelectedElements(0, 1) } },
|
this.rotateSelected(1, 5)
|
||||||
{ 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: 'shift+o',
|
||||||
{ key: ['alt+shift+arrowleft', true], fn: () => { this.svgCanvas.cloneSelectedElements(-10, 0) } },
|
fn: () => {
|
||||||
{ key: ['alt+shift+arrowright', true], fn: () => { this.svgCanvas.cloneSelectedElements(10, 0) } },
|
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],
|
key: ['delete/backspace', true],
|
||||||
fn: () => {
|
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', fn: () => { this.svgCanvas.selectAllInCurrentLayer() } },
|
key: 'a',
|
||||||
{ key: modKey + 'x', fn: () => { this.cutSelected() } },
|
fn: () => {
|
||||||
{ key: modKey + 'c', fn: () => { this.copySelected() } },
|
this.svgCanvas.selectAllInCurrentLayer()
|
||||||
{ key: modKey + 'v', fn: () => { this.pasteInCenter() } }
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: [modKey + 'a', true],
|
||||||
|
fn: () => {
|
||||||
|
this.svgCanvas.selectAllInCurrentLayer()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: modKey + 'x',
|
||||||
|
fn: () => {
|
||||||
|
this.cutSelected()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: modKey + 'c',
|
||||||
|
fn: () => {
|
||||||
|
this.copySelected()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: modKey + 'v',
|
||||||
|
fn: () => {
|
||||||
|
this.pasteInCenter()
|
||||||
|
}
|
||||||
|
}
|
||||||
]
|
]
|
||||||
this.leftPanel = new LeftPanel(this)
|
this.leftPanel = new LeftPanel(this)
|
||||||
this.bottomPanel = new BottomPanel(this)
|
this.bottomPanel = new BottomPanel(this)
|
||||||
@@ -204,7 +395,7 @@ class Editor extends EditorStartup {
|
|||||||
setAll () {
|
setAll () {
|
||||||
const keyHandler = {} // will contain the action for each pressed key
|
const keyHandler = {} // will contain the action for each pressed key
|
||||||
|
|
||||||
this.shortcuts.forEach(shortcut => {
|
this.shortcuts.forEach((shortcut) => {
|
||||||
// Bind function to shortcut key
|
// Bind function to shortcut key
|
||||||
if (shortcut.key) {
|
if (shortcut.key) {
|
||||||
// Set shortcut based on options
|
// Set shortcut based on options
|
||||||
@@ -218,14 +409,14 @@ class Editor extends EditorStartup {
|
|||||||
}
|
}
|
||||||
keyval = String(keyval)
|
keyval = String(keyval)
|
||||||
const { fn } = shortcut
|
const { fn } = shortcut
|
||||||
keyval.split('/').forEach(key => {
|
keyval.split('/').forEach((key) => {
|
||||||
keyHandler[key] = { fn, pd }
|
keyHandler[key] = { fn, pd }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
// register the keydown event
|
// register the keydown event
|
||||||
document.addEventListener('keydown', e => {
|
document.addEventListener('keydown', (e) => {
|
||||||
// only track keyboard shortcuts for the body containing the SVG-Editor
|
// only track keyboard shortcuts for the body containing the SVG-Editor
|
||||||
if (e.target.nodeName !== 'BODY') return
|
if (e.target.nodeName !== 'BODY') return
|
||||||
// normalize key
|
// normalize key
|
||||||
@@ -282,7 +473,7 @@ class Editor extends EditorStartup {
|
|||||||
* @returns {module:SVGthis.ToolButton}
|
* @returns {module:SVGthis.ToolButton}
|
||||||
*/
|
*/
|
||||||
getButtonData (sel) {
|
getButtonData (sel) {
|
||||||
return Object.values(this.shortcuts).find(btn => {
|
return Object.values(this.shortcuts).find((btn) => {
|
||||||
return btn.sel === sel
|
return btn.sel === sel
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -350,7 +541,9 @@ class Editor extends EditorStartup {
|
|||||||
const { workarea } = this
|
const { workarea } = this
|
||||||
const cnvs = $id('svgcanvas')
|
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(
|
let h = parseFloat(
|
||||||
getComputedStyle(workarea, null).height.replace('px', '')
|
getComputedStyle(workarea, null).height.replace('px', '')
|
||||||
)
|
)
|
||||||
@@ -444,9 +637,8 @@ class Editor extends EditorStartup {
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
if (document.querySelectorAll('#wireframe_rules').length > 0) {
|
if (document.querySelectorAll('#wireframe_rules').length > 0) {
|
||||||
document.querySelector(
|
document.querySelector('#wireframe_rules').textContent =
|
||||||
'#wireframe_rules'
|
this.workarea.classList.contains('wireframe') ? rule : ''
|
||||||
).textContent = this.workarea.classList.contains('wireframe') ? rule : ''
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -538,7 +730,7 @@ class Editor extends EditorStartup {
|
|||||||
this.leftPanel.clickSelect()
|
this.leftPanel.clickSelect()
|
||||||
}
|
}
|
||||||
|
|
||||||
elems.forEach(elem => {
|
elems.forEach((elem) => {
|
||||||
const isSvgElem = elem?.tagName === 'svg'
|
const isSvgElem = elem?.tagName === 'svg'
|
||||||
if (isSvgElem || this.svgCanvas.isLayer(elem)) {
|
if (isSvgElem || this.svgCanvas.isLayer(elem)) {
|
||||||
this.layersPanel.populateLayers()
|
this.layersPanel.populateLayers()
|
||||||
@@ -593,18 +785,14 @@ class Editor extends EditorStartup {
|
|||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
afterClear (win) {
|
afterClear (win) {
|
||||||
this.svgCanvas.runExtensions(
|
this.svgCanvas.runExtensions('afterClear')
|
||||||
'afterClear'
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
beforeClear (win) {
|
beforeClear (win) {
|
||||||
this.svgCanvas.runExtensions(
|
this.svgCanvas.runExtensions('beforeClear')
|
||||||
'beforeClear'
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1135,7 +1323,7 @@ class Editor extends EditorStartup {
|
|||||||
return this.ready(() => {
|
return this.ready(() => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
fetch(url, { cache: cache ? 'force-cache' : 'no-cache' })
|
fetch(url, { cache: cache ? 'force-cache' : 'no-cache' })
|
||||||
.then(response => {
|
.then((response) => {
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
if (noAlert) {
|
if (noAlert) {
|
||||||
reject(new Error('URLLoadFail'))
|
reject(new Error('URLLoadFail'))
|
||||||
@@ -1146,16 +1334,18 @@ class Editor extends EditorStartup {
|
|||||||
}
|
}
|
||||||
return response.text()
|
return response.text()
|
||||||
})
|
})
|
||||||
.then(str => {
|
.then((str) => {
|
||||||
this.loadSvgString(str, { noAlert })
|
this.loadSvgString(str, { noAlert })
|
||||||
return str
|
return str
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
if (noAlert) {
|
if (noAlert) {
|
||||||
reject(new Error('URLLoadFail'))
|
reject(new Error('URLLoadFail'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
seAlert(this.i18next.t('notification.URLLoadFail') + ': \n' + error)
|
seAlert(
|
||||||
|
this.i18next.t('notification.URLLoadFail') + ': \n' + error
|
||||||
|
)
|
||||||
resolve()
|
resolve()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -634,7 +634,7 @@ div.jGraduate_Slider img {
|
|||||||
}
|
}
|
||||||
#color_picker {
|
#color_picker {
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
top: 60%;
|
bottom: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<div id="picker">
|
<div id="picker">
|
||||||
@@ -651,8 +651,8 @@ div.jGraduate_Slider img {
|
|||||||
*/
|
*/
|
||||||
export class SeColorPicker extends HTMLElement {
|
export class SeColorPicker extends HTMLElement {
|
||||||
/**
|
/**
|
||||||
* @function constructor
|
* @function constructor
|
||||||
*/
|
*/
|
||||||
constructor () {
|
constructor () {
|
||||||
super()
|
super()
|
||||||
// create the shadowDom and insert the template
|
// create the shadowDom and insert the template
|
||||||
|
|||||||
@@ -2,16 +2,48 @@
|
|||||||
/* eslint-disable max-len */
|
/* eslint-disable max-len */
|
||||||
const palette = [
|
const palette = [
|
||||||
// Todo: Make into configuration item?
|
// Todo: Make into configuration item?
|
||||||
'none', '#000000', '#3f3f3f', '#7f7f7f', '#bfbfbf', '#ffffff',
|
'none',
|
||||||
'#ff0000', '#ff7f00', '#ffff00', '#7fff00',
|
'#000000',
|
||||||
'#00ff00', '#00ff7f', '#00ffff', '#007fff',
|
'#3f3f3f',
|
||||||
'#0000ff', '#7f00ff', '#ff00ff', '#ff007f',
|
'#7f7f7f',
|
||||||
'#7f0000', '#7f3f00', '#7f7f00', '#3f7f00',
|
'#bfbfbf',
|
||||||
'#007f00', '#007f3f', '#007f7f', '#003f7f',
|
'#ffffff',
|
||||||
'#00007f', '#3f007f', '#7f007f', '#7f003f',
|
'#ff0000',
|
||||||
'#ffaaaa', '#ffd4aa', '#ffffaa', '#d4ffaa',
|
'#ff7f00',
|
||||||
'#aaffaa', '#aaffd4', '#aaffff', '#aad4ff',
|
'#ffff00',
|
||||||
'#aaaaff', '#d4aaff', '#ffaaff', '#ffaad4'
|
'#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')
|
const template = document.createElement('template')
|
||||||
@@ -32,8 +64,9 @@ template.innerHTML = `
|
|||||||
|
|
||||||
#js-se-palette {
|
#js-se-palette {
|
||||||
float: left;
|
float: left;
|
||||||
width: 632px;
|
min-width: 30px;
|
||||||
height: 16px;
|
height: 15px;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.palette_item {
|
div.palette_item {
|
||||||
@@ -46,11 +79,39 @@ template.innerHTML = `
|
|||||||
background: white;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
<div id="palette_holder" title="">
|
<div id="palette_holder" title="">
|
||||||
<div id="js-se-palette">
|
<div id="js-se-palette">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<button class="palette_expand_btn" title="Show whole palette">▼</button>
|
||||||
|
<!-- hidden div -->
|
||||||
|
<div id="palette_popup" style="display:none"/>
|
||||||
`
|
`
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,20 +119,38 @@ template.innerHTML = `
|
|||||||
*/
|
*/
|
||||||
export class SEPalette extends HTMLElement {
|
export class SEPalette extends HTMLElement {
|
||||||
/**
|
/**
|
||||||
* @function constructor
|
* @function constructor
|
||||||
*/
|
*/
|
||||||
constructor () {
|
constructor () {
|
||||||
super()
|
super()
|
||||||
// create the shadowDom and insert the template
|
// create the shadowDom and insert the template
|
||||||
this._shadowRoot = this.attachShadow({ mode: 'open' })
|
this._shadowRoot = this.attachShadow({ mode: 'open' })
|
||||||
this._shadowRoot.append(template.content.cloneNode(true))
|
this._shadowRoot.append(template.content.cloneNode(true))
|
||||||
this.$strip = this._shadowRoot.querySelector('#js-se-palette')
|
this.$strip = this._shadowRoot.querySelector('#js-se-palette')
|
||||||
|
this.expand_btn = this._shadowRoot.querySelector(
|
||||||
|
'button.palette_expand_btn'
|
||||||
|
)
|
||||||
|
this.popUp = this._shadowRoot.getElementById('palette_popup')
|
||||||
|
svgEditor.$click(this.expand_btn, (e) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
const { display } = this.popUp.style
|
||||||
|
if (display === 'none') {
|
||||||
|
this.showPopUp()
|
||||||
|
} else {
|
||||||
|
this.hidePopUp()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
svgEditor.svgCanvas.container.addEventListener('click', () =>
|
||||||
|
this.hidePopUp()
|
||||||
|
)
|
||||||
|
|
||||||
palette.forEach((rgb) => {
|
palette.forEach((rgb) => {
|
||||||
const newDiv = document.createElement('div')
|
const newDiv = document.createElement('div')
|
||||||
newDiv.classList.add('square')
|
newDiv.classList.add('square')
|
||||||
if (rgb === 'none') {
|
if (rgb === 'none') {
|
||||||
const img = document.createElement('img')
|
const img = document.createElement('img')
|
||||||
img.src = 'data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgY2xhc3M9InN2Z19pY29uIj48c3ZnIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+CiAgICA8bGluZSBmaWxsPSJub25lIiBzdHJva2U9IiNkNDAwMDAiIGlkPSJzdmdfOTAiIHkyPSIyNCIgeDI9IjI0IiB5MT0iMCIgeDE9IjAiLz4KICAgIDxsaW5lIGlkPSJzdmdfOTIiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2Q0MDAwMCIgeTI9IjI0IiB4Mj0iMCIgeTE9IjAiIHgxPSIyNCIvPgogIDwvc3ZnPjwvc3ZnPg=='
|
img.src =
|
||||||
|
'data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgY2xhc3M9InN2Z19pY29uIj48c3ZnIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+CiAgICA8bGluZSBmaWxsPSJub25lIiBzdHJva2U9IiNkNDAwMDAiIGlkPSJzdmdfOTAiIHkyPSIyNCIgeDI9IjI0IiB5MT0iMCIgeDE9IjAiLz4KICAgIDxsaW5lIGlkPSJzdmdfOTIiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2Q0MDAwMCIgeTI9IjI0IiB4Mj0iMCIgeTE9IjAiIHgxPSIyNCIvPgogIDwvc3ZnPjwvc3ZnPg=='
|
||||||
img.style.width = '15px'
|
img.style.width = '15px'
|
||||||
img.style.height = '15px'
|
img.style.height = '15px'
|
||||||
newDiv.append(img)
|
newDiv.append(img)
|
||||||
@@ -79,19 +158,31 @@ export class SEPalette extends HTMLElement {
|
|||||||
newDiv.style.backgroundColor = rgb
|
newDiv.style.backgroundColor = rgb
|
||||||
}
|
}
|
||||||
newDiv.dataset.rgb = rgb
|
newDiv.dataset.rgb = rgb
|
||||||
svgEditor.$click(newDiv, (evt) => {
|
const clickCb = (evt) => {
|
||||||
evt.preventDefault()
|
evt.preventDefault()
|
||||||
// shift key or right click for stroke
|
// shift key or right click for stroke
|
||||||
const picker = evt.shiftKey || evt.button === 2 ? 'stroke' : 'fill'
|
const picker = evt.shiftKey || evt.button === 2 ? 'stroke' : 'fill'
|
||||||
let color = newDiv.dataset.rgb
|
let color = newDiv.dataset.rgb
|
||||||
// Webkit-based browsers returned 'initial' here for no stroke
|
// Webkit-based browsers returned 'initial' here for no stroke
|
||||||
if (color === 'none' || color === 'transparent' || color === 'initial') {
|
if (
|
||||||
|
color === 'none' ||
|
||||||
|
color === 'transparent' ||
|
||||||
|
color === 'initial'
|
||||||
|
) {
|
||||||
color = 'none'
|
color = 'none'
|
||||||
}
|
}
|
||||||
const paletteEvent = new CustomEvent('change', { detail: { picker, color }, bubbles: false })
|
const paletteEvent = new CustomEvent('change', {
|
||||||
|
detail: { picker, color },
|
||||||
|
bubbles: false
|
||||||
|
})
|
||||||
this.dispatchEvent(paletteEvent)
|
this.dispatchEvent(paletteEvent)
|
||||||
})
|
}
|
||||||
|
svgEditor.$click(newDiv, clickCb)
|
||||||
this.$strip.append(newDiv)
|
this.$strip.append(newDiv)
|
||||||
|
|
||||||
|
const divDialog = newDiv.cloneNode(true)
|
||||||
|
svgEditor.$click(divDialog, clickCb)
|
||||||
|
this.popUp.append(divDialog)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +222,21 @@ export class SEPalette extends HTMLElement {
|
|||||||
* @function connectedCallback
|
* @function connectedCallback
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
connectedCallback () {
|
connectedCallback () {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows popUp window with the whole palette
|
||||||
|
*/
|
||||||
|
showPopUp () {
|
||||||
|
this.popUp.style.display = 'flex'
|
||||||
|
this.expand_btn.textContent = '▲'
|
||||||
|
this.expand_btn.setAttribute('title', 'Hide palette window')
|
||||||
|
}
|
||||||
|
|
||||||
|
hidePopUp () {
|
||||||
|
this.popUp.style.display = 'none'
|
||||||
|
this.expand_btn.textContent = '▼'
|
||||||
|
this.expand_btn.setAttribute('title', 'Show palette window')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ const { $id } = SvgCanvas
|
|||||||
* register actions for left panel
|
* register actions for left panel
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* @type {module}
|
* @type {module}
|
||||||
*/
|
*/
|
||||||
class BottomPanel {
|
class BottomPanel {
|
||||||
/**
|
/**
|
||||||
* @param {PlainObject} editor svgedit handler
|
* @param {PlainObject} editor svgedit handler
|
||||||
*/
|
*/
|
||||||
constructor (editor) {
|
constructor (editor) {
|
||||||
this.editor = editor
|
this.editor = editor
|
||||||
}
|
}
|
||||||
@@ -26,26 +26,30 @@ class BottomPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {module}
|
* @type {module}
|
||||||
*/
|
*/
|
||||||
get multiselected () {
|
get multiselected () {
|
||||||
return this.editor.multiselected
|
return this.editor.multiselected
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {module}
|
* @type {module}
|
||||||
*/
|
*/
|
||||||
changeStrokeWidth (e) {
|
changeStrokeWidth (e) {
|
||||||
let val = e.target.value
|
let val = e.target.value
|
||||||
if (val === 0 && this.editor.selectedElement && ['line', 'polyline'].includes(this.editor.selectedElement.nodeName)) {
|
if (
|
||||||
|
val === 0 &&
|
||||||
|
this.editor.selectedElement &&
|
||||||
|
['line', 'polyline'].includes(this.editor.selectedElement.nodeName)
|
||||||
|
) {
|
||||||
val = 1
|
val = 1
|
||||||
}
|
}
|
||||||
this.editor.svgCanvas.setStrokeWidth(val)
|
this.editor.svgCanvas.setStrokeWidth(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {module}
|
* @type {module}
|
||||||
*/
|
*/
|
||||||
changeZoom (value) {
|
changeZoom (value) {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case 'canvas':
|
case 'canvas':
|
||||||
@@ -54,34 +58,51 @@ class BottomPanel {
|
|||||||
case 'content':
|
case 'content':
|
||||||
this.editor.zoomChanged(window, value)
|
this.editor.zoomChanged(window, value)
|
||||||
break
|
break
|
||||||
default:
|
default: {
|
||||||
{
|
|
||||||
const zoomlevel = Number(value) > 0.1 ? Number(value) * 0.01 : 0.1
|
const zoomlevel = Number(value) > 0.1 ? Number(value) * 0.01 : 0.1
|
||||||
const zoom = this.editor.svgCanvas.getZoom()
|
const zoom = this.editor.svgCanvas.getZoom()
|
||||||
const { workarea } = this.editor
|
const { workarea } = this.editor
|
||||||
this.editor.zoomChanged(window, {
|
this.editor.zoomChanged(
|
||||||
width: 0,
|
window,
|
||||||
height: 0,
|
{
|
||||||
// center pt of scroll position
|
width: 0,
|
||||||
x: (workarea.scrollLeft + parseFloat(getComputedStyle(workarea, null).width.replace('px', '')) / 2) / zoom,
|
height: 0,
|
||||||
y: (workarea.scrollTop + parseFloat(getComputedStyle(workarea, null).height.replace('px', '')) / 2) / zoom,
|
// center pt of scroll position
|
||||||
zoom: zoomlevel
|
x:
|
||||||
}, true)
|
(workarea.scrollLeft +
|
||||||
|
parseFloat(
|
||||||
|
getComputedStyle(workarea, null).width.replace('px', '')
|
||||||
|
) /
|
||||||
|
2) /
|
||||||
|
zoom,
|
||||||
|
y:
|
||||||
|
(workarea.scrollTop +
|
||||||
|
parseFloat(
|
||||||
|
getComputedStyle(workarea, null).height.replace('px', '')
|
||||||
|
) /
|
||||||
|
2) /
|
||||||
|
zoom,
|
||||||
|
zoom: zoomlevel
|
||||||
|
},
|
||||||
|
true
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @fires module:svgcanvas.SvgCanvas#event:ext_toolButtonStateUpdate
|
* @fires module:svgcanvas.SvgCanvas#event:ext_toolButtonStateUpdate
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
updateToolButtonState () {
|
updateToolButtonState () {
|
||||||
const bNoFill = (this.editor.svgCanvas.getColor('fill') === 'none')
|
const bNoFill = this.editor.svgCanvas.getColor('fill') === 'none'
|
||||||
const bNoStroke = (this.editor.svgCanvas.getColor('stroke') === 'none')
|
const bNoStroke = this.editor.svgCanvas.getColor('stroke') === 'none'
|
||||||
const buttonsNeedingStroke = ['tool_fhpath', 'tool_line']
|
const buttonsNeedingStroke = ['tool_fhpath', 'tool_line']
|
||||||
const buttonsNeedingFillAndStroke = [
|
const buttonsNeedingFillAndStroke = [
|
||||||
'tools_rect', 'tools_ellipse',
|
'tools_rect',
|
||||||
'tool_text', 'tool_path'
|
'tools_ellipse',
|
||||||
|
'tool_text',
|
||||||
|
'tool_path'
|
||||||
]
|
]
|
||||||
|
|
||||||
if (bNoStroke) {
|
if (bNoStroke) {
|
||||||
@@ -120,8 +141,8 @@ class BottomPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {module}
|
* @type {module}
|
||||||
*/
|
*/
|
||||||
handleColorPicker (type, evt) {
|
handleColorPicker (type, evt) {
|
||||||
const { paint } = evt.detail
|
const { paint } = evt.detail
|
||||||
this.editor.svgCanvas.setPaint(type, paint)
|
this.editor.svgCanvas.setPaint(type, paint)
|
||||||
@@ -129,44 +150,50 @@ class BottomPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {module}
|
* @type {module}
|
||||||
*/
|
*/
|
||||||
handleStrokeAttr (type, evt) {
|
handleStrokeAttr (type, evt) {
|
||||||
this.editor.svgCanvas.setStrokeAttr(type, evt.detail.value)
|
this.editor.svgCanvas.setStrokeAttr(type, evt.detail.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {module}
|
* @type {module}
|
||||||
*/
|
*/
|
||||||
handleOpacity (evt) {
|
handleOpacity (evt) {
|
||||||
const val = Number.parseInt(evt.currentTarget.value.split('%')[0])
|
const val = Number.parseInt(evt.currentTarget.value.split('%')[0])
|
||||||
this.editor.svgCanvas.setOpacity(val / 100)
|
this.editor.svgCanvas.setOpacity(val / 100)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {module}
|
* @type {module}
|
||||||
*/
|
*/
|
||||||
handlePalette (e) {
|
handlePalette (e) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
// shift key or right click for stroke
|
// shift key or right click for stroke
|
||||||
const { picker, color } = e.detail
|
const { picker, color } = e.detail
|
||||||
// Webkit-based browsers returned 'initial' here for no stroke
|
// Webkit-based browsers returned 'initial' here for no stroke
|
||||||
const paint = color === 'none' ? new jGraduate.Paint() : new jGraduate.Paint({ alpha: 100, solidColor: color.substr(1) })
|
const paint =
|
||||||
|
color === 'none'
|
||||||
|
? new jGraduate.Paint()
|
||||||
|
: new jGraduate.Paint({ alpha: 100, solidColor: color.substr(1) })
|
||||||
if (picker === 'fill') {
|
if (picker === 'fill') {
|
||||||
$id('fill_color').setPaint(paint)
|
$id('fill_color').setPaint(paint)
|
||||||
} else {
|
} else {
|
||||||
$id('stroke_color').setPaint(paint)
|
$id('stroke_color').setPaint(paint)
|
||||||
}
|
}
|
||||||
this.editor.svgCanvas.setColor(picker, color)
|
this.editor.svgCanvas.setColor(picker, color)
|
||||||
if (color !== 'none' && this.editor.svgCanvas.getPaintOpacity(picker) !== 1) {
|
if (
|
||||||
|
color !== 'none' &&
|
||||||
|
this.editor.svgCanvas.getPaintOpacity(picker) !== 1
|
||||||
|
) {
|
||||||
this.editor.svgCanvas.setPaintOpacity(picker, 1.0)
|
this.editor.svgCanvas.setPaintOpacity(picker, 1.0)
|
||||||
}
|
}
|
||||||
this.updateToolButtonState()
|
this.updateToolButtonState()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {module}
|
* @type {module}
|
||||||
*/
|
*/
|
||||||
init () {
|
init () {
|
||||||
// register actions for Bottom panel
|
// register actions for Bottom panel
|
||||||
const template = document.createElement('template')
|
const template = document.createElement('template')
|
||||||
@@ -177,26 +204,56 @@ class BottomPanel {
|
|||||||
$id('palette').addEventListener('change', this.handlePalette.bind(this))
|
$id('palette').addEventListener('change', this.handlePalette.bind(this))
|
||||||
$id('palette').init(i18next)
|
$id('palette').init(i18next)
|
||||||
const { curConfig } = this.editor.configObj
|
const { curConfig } = this.editor.configObj
|
||||||
$id('fill_color').setPaint(new jGraduate.Paint({ alpha: 100, solidColor: curConfig.initFill.color }))
|
$id('fill_color').setPaint(
|
||||||
$id('stroke_color').setPaint(new jGraduate.Paint({ alpha: 100, solidColor: curConfig.initStroke.color }))
|
new jGraduate.Paint({ alpha: 100, solidColor: curConfig.initFill.color })
|
||||||
$id('zoom').addEventListener('change', (e) => this.changeZoom.bind(this)(e.detail.value))
|
)
|
||||||
$id('stroke_color').addEventListener('change', (evt) => this.handleColorPicker.bind(this)('stroke', evt))
|
$id('stroke_color').setPaint(
|
||||||
$id('fill_color').addEventListener('change', (evt) => this.handleColorPicker.bind(this)('fill', evt))
|
new jGraduate.Paint({
|
||||||
$id('stroke_width').addEventListener('change', this.changeStrokeWidth.bind(this))
|
alpha: 100,
|
||||||
$id('stroke_style').addEventListener('change', (evt) => this.handleStrokeAttr.bind(this)('stroke-dasharray', evt))
|
solidColor: curConfig.initStroke.color
|
||||||
$id('stroke_linejoin').addEventListener('change', (evt) => this.handleStrokeAttr.bind(this)('stroke-linejoin', evt))
|
})
|
||||||
$id('stroke_linecap').addEventListener('change', (evt) => this.handleStrokeAttr.bind(this)('stroke-linecap', evt))
|
)
|
||||||
|
$id('zoom').addEventListener('change', (e) =>
|
||||||
|
this.changeZoom.bind(this)(e.detail.value)
|
||||||
|
)
|
||||||
|
$id('stroke_color').addEventListener('change', (evt) =>
|
||||||
|
this.handleColorPicker.bind(this)('stroke', evt)
|
||||||
|
)
|
||||||
|
$id('fill_color').addEventListener('change', (evt) =>
|
||||||
|
this.handleColorPicker.bind(this)('fill', evt)
|
||||||
|
)
|
||||||
|
$id('stroke_width').addEventListener(
|
||||||
|
'change',
|
||||||
|
this.changeStrokeWidth.bind(this)
|
||||||
|
)
|
||||||
|
$id('stroke_style').addEventListener('change', (evt) =>
|
||||||
|
this.handleStrokeAttr.bind(this)('stroke-dasharray', evt)
|
||||||
|
)
|
||||||
|
$id('stroke_linejoin').addEventListener('change', (evt) =>
|
||||||
|
this.handleStrokeAttr.bind(this)('stroke-linejoin', evt)
|
||||||
|
)
|
||||||
|
$id('stroke_linecap').addEventListener('change', (evt) =>
|
||||||
|
this.handleStrokeAttr.bind(this)('stroke-linecap', evt)
|
||||||
|
)
|
||||||
$id('opacity').addEventListener('change', this.handleOpacity.bind(this))
|
$id('opacity').addEventListener('change', this.handleOpacity.bind(this))
|
||||||
$id('fill_color').init(i18next)
|
$id('fill_color').init(i18next)
|
||||||
$id('stroke_color').init(i18next)
|
$id('stroke_color').init(i18next)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {module}
|
* @type {module}
|
||||||
*/
|
*/
|
||||||
updateColorpickers (apply) {
|
updateColorpickers (apply) {
|
||||||
$id('fill_color').update(this.editor.svgCanvas, this.editor.selectedElement, apply)
|
$id('fill_color').update(
|
||||||
$id('stroke_color').update(this.editor.svgCanvas, this.editor.selectedElement, apply)
|
this.editor.svgCanvas,
|
||||||
|
this.editor.selectedElement,
|
||||||
|
apply
|
||||||
|
)
|
||||||
|
$id('stroke_color').update(
|
||||||
|
this.editor.svgCanvas,
|
||||||
|
this.editor.selectedElement,
|
||||||
|
apply
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -323,14 +323,16 @@ hr {
|
|||||||
|
|
||||||
#tools_bottom {
|
#tools_bottom {
|
||||||
grid-area: bottom;
|
grid-area: bottom;
|
||||||
overflow: auto;
|
overflow-x: auto;
|
||||||
|
overflow-y: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
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;
|
width: 3px;
|
||||||
|
height: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#tools_bottom se-list, #tools_bottom se-select {
|
#tools_bottom se-list, #tools_bottom se-select {
|
||||||
@@ -358,11 +360,11 @@ hr {
|
|||||||
width: 3px;
|
width: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#tools_left::-webkit-scrollbar-track {
|
#tools_left::-webkit-scrollbar-track, #tools_bottom::-webkit-scrollbar-track{
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
#tools_left::-webkit-scrollbar-thumb {
|
#tools_left::-webkit-scrollbar-thumb, #tools_bottom::-webkit-scrollbar-thumb {
|
||||||
background-color:rgb(70, 70, 70);
|
background-color:rgb(70, 70, 70);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -530,6 +532,9 @@ input[type=text] {
|
|||||||
|
|
||||||
#palette {
|
#palette {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
|
margin-right: 16px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#stroke_expand {
|
#stroke_expand {
|
||||||
|
|||||||
Reference in New Issue
Block a user