Bottom panel styling, more adaptive palette, shortcuts (#937)

This commit is contained in:
olekhshch
2023-12-24 01:48:27 +01:00
committed by GitHub
parent 2f9f6e2f71
commit d502525cc0
6 changed files with 494 additions and 134 deletions

View File

@@ -1,6 +1,9 @@
name: Node CI
on: [pull_request]
# To be able to write in the PR, we need write permission.
permissions:
pull-requests: write
jobs:
build:

View File

@@ -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', fn: () => { this.svgCanvas.selectAllInCurrentLayer() } },
{ key: modKey + 'x', fn: () => { this.cutSelected() } },
{ key: modKey + 'c', fn: () => { this.copySelected() } },
{ key: modKey + 'v', fn: () => { this.pasteInCenter() } }
{
key: 'a',
fn: () => {
this.svgCanvas.selectAllInCurrentLayer()
}
},
{
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.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()
})
})

View File

@@ -634,7 +634,7 @@ div.jGraduate_Slider img {
}
#color_picker {
z-index: 1000;
top: 60%;
bottom: 0;
}
</style>
<div id="picker">
@@ -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

View File

@@ -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;
}
</style>
<div id="palette_holder" title="">
<div id="js-se-palette">
</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 {
/**
* @function constructor
*/
* @function constructor
*/
constructor () {
super()
// create the shadowDom and insert the template
this._shadowRoot = this.attachShadow({ mode: 'open' })
this._shadowRoot.append(template.content.cloneNode(true))
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) => {
const newDiv = document.createElement('div')
newDiv.classList.add('square')
if (rgb === 'none') {
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.height = '15px'
newDiv.append(img)
@@ -79,19 +158,31 @@ export class SEPalette extends HTMLElement {
newDiv.style.backgroundColor = rgb
}
newDiv.dataset.rgb = rgb
svgEditor.$click(newDiv, (evt) => {
const clickCb = (evt) => {
evt.preventDefault()
// shift key or right click for stroke
const picker = evt.shiftKey || evt.button === 2 ? 'stroke' : 'fill'
let color = newDiv.dataset.rgb
// 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'
}
const paletteEvent = new CustomEvent('change', { detail: { picker, color }, bubbles: false })
const paletteEvent = new CustomEvent('change', {
detail: { picker, color },
bubbles: false
})
this.dispatchEvent(paletteEvent)
})
}
svgEditor.$click(newDiv, clickCb)
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
* @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')
}
}

View File

@@ -8,12 +8,12 @@ const { $id } = SvgCanvas
* register actions for left panel
*/
/**
* @type {module}
*/
* @type {module}
*/
class BottomPanel {
/**
* @param {PlainObject} editor svgedit handler
*/
*/
constructor (editor) {
this.editor = editor
}
@@ -26,26 +26,30 @@ class BottomPanel {
}
/**
* @type {module}
*/
* @type {module}
*/
get multiselected () {
return this.editor.multiselected
}
/**
* @type {module}
*/
* @type {module}
*/
changeStrokeWidth (e) {
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
}
this.editor.svgCanvas.setStrokeWidth(val)
}
/**
* @type {module}
*/
* @type {module}
*/
changeZoom (value) {
switch (value) {
case 'canvas':
@@ -54,34 +58,51 @@ class BottomPanel {
case 'content':
this.editor.zoomChanged(window, value)
break
default:
{
default: {
const zoomlevel = Number(value) > 0.1 ? Number(value) * 0.01 : 0.1
const zoom = this.editor.svgCanvas.getZoom()
const { workarea } = this.editor
this.editor.zoomChanged(window, {
width: 0,
height: 0,
// center pt of scroll position
x: (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)
this.editor.zoomChanged(
window,
{
width: 0,
height: 0,
// center pt of scroll position
x:
(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
* @returns {void}
*/
* @fires module:svgcanvas.SvgCanvas#event:ext_toolButtonStateUpdate
* @returns {void}
*/
updateToolButtonState () {
const bNoFill = (this.editor.svgCanvas.getColor('fill') === 'none')
const bNoStroke = (this.editor.svgCanvas.getColor('stroke') === 'none')
const bNoFill = this.editor.svgCanvas.getColor('fill') === 'none'
const bNoStroke = this.editor.svgCanvas.getColor('stroke') === 'none'
const buttonsNeedingStroke = ['tool_fhpath', 'tool_line']
const buttonsNeedingFillAndStroke = [
'tools_rect', 'tools_ellipse',
'tool_text', 'tool_path'
'tools_rect',
'tools_ellipse',
'tool_text',
'tool_path'
]
if (bNoStroke) {
@@ -120,8 +141,8 @@ class BottomPanel {
}
/**
* @type {module}
*/
* @type {module}
*/
handleColorPicker (type, evt) {
const { paint } = evt.detail
this.editor.svgCanvas.setPaint(type, paint)
@@ -129,44 +150,50 @@ class BottomPanel {
}
/**
* @type {module}
*/
* @type {module}
*/
handleStrokeAttr (type, evt) {
this.editor.svgCanvas.setStrokeAttr(type, evt.detail.value)
}
/**
* @type {module}
*/
* @type {module}
*/
handleOpacity (evt) {
const val = Number.parseInt(evt.currentTarget.value.split('%')[0])
this.editor.svgCanvas.setOpacity(val / 100)
}
/**
* @type {module}
*/
* @type {module}
*/
handlePalette (e) {
e.preventDefault()
// shift key or right click for stroke
const { picker, color } = e.detail
// 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') {
$id('fill_color').setPaint(paint)
} else {
$id('stroke_color').setPaint(paint)
}
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.updateToolButtonState()
}
/**
* @type {module}
*/
* @type {module}
*/
init () {
// register actions for Bottom panel
const template = document.createElement('template')
@@ -177,26 +204,56 @@ class BottomPanel {
$id('palette').addEventListener('change', this.handlePalette.bind(this))
$id('palette').init(i18next)
const { curConfig } = this.editor.configObj
$id('fill_color').setPaint(new jGraduate.Paint({ alpha: 100, solidColor: curConfig.initFill.color }))
$id('stroke_color').setPaint(new jGraduate.Paint({ alpha: 100, solidColor: curConfig.initStroke.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('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('fill_color').setPaint(
new jGraduate.Paint({ alpha: 100, solidColor: curConfig.initFill.color })
)
$id('stroke_color').setPaint(
new jGraduate.Paint({
alpha: 100,
solidColor: curConfig.initStroke.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('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('fill_color').init(i18next)
$id('stroke_color').init(i18next)
}
/**
* @type {module}
*/
* @type {module}
*/
updateColorpickers (apply) {
$id('fill_color').update(this.editor.svgCanvas, this.editor.selectedElement, apply)
$id('stroke_color').update(this.editor.svgCanvas, this.editor.selectedElement, apply)
$id('fill_color').update(
this.editor.svgCanvas,
this.editor.selectedElement,
apply
)
$id('stroke_color').update(
this.editor.svgCanvas,
this.editor.selectedElement,
apply
)
}
}

View File

@@ -323,14 +323,16 @@ hr {
#tools_bottom {
grid-area: bottom;
overflow: auto;
overflow-x: auto;
overflow-y: hidden;
display: flex;
align-items: center;
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 {
@@ -358,11 +360,11 @@ hr {
width: 3px;
}
#tools_left::-webkit-scrollbar-track {
#tools_left::-webkit-scrollbar-track, #tools_bottom::-webkit-scrollbar-track{
background: transparent;
}
#tools_left::-webkit-scrollbar-thumb {
#tools_left::-webkit-scrollbar-thumb, #tools_bottom::-webkit-scrollbar-thumb {
background-color:rgb(70, 70, 70);
}
@@ -530,6 +532,9 @@ input[type=text] {
#palette {
margin-left: auto;
margin-right: 16px;
display: flex;
align-items: center;
}
#stroke_expand {