Fix: Zoom selector rewrite (#826)
parent
f9fe802dcd
commit
ad1b9df6a5
|
@ -0,0 +1,217 @@
|
||||||
|
import { visitAndApproveStorage } from '../../support/ui-test-helper.js'
|
||||||
|
|
||||||
|
describe('UI - Zoom tool', function () {
|
||||||
|
beforeEach(() => {
|
||||||
|
visitAndApproveStorage()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should be able to open', function () {
|
||||||
|
cy.get('#zoom')
|
||||||
|
.click()
|
||||||
|
.shadow()
|
||||||
|
.find('#options-container')
|
||||||
|
.should('have.css', 'display', 'flex')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should be able to close', function () {
|
||||||
|
cy.get('#zoom')
|
||||||
|
.click()
|
||||||
|
.shadow()
|
||||||
|
.find('#options-container')
|
||||||
|
.should('have.css', 'display', 'flex')
|
||||||
|
|
||||||
|
cy.get('#tool_select')
|
||||||
|
.click({ force: true })
|
||||||
|
.get('#zoom')
|
||||||
|
.shadow()
|
||||||
|
.find('#options-container')
|
||||||
|
.should('have.css', 'display', 'none')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should be able to input zoom level', function () {
|
||||||
|
cy.get('#canvasBackground')
|
||||||
|
.invoke('attr', 'width')
|
||||||
|
.then(width => {
|
||||||
|
cy.get('#zoom')
|
||||||
|
.shadow()
|
||||||
|
.find('input')
|
||||||
|
.type('200')
|
||||||
|
cy.get('#tool_select')
|
||||||
|
.click({ force: true })
|
||||||
|
cy.get('#canvasBackground')
|
||||||
|
.invoke('attr', 'width')
|
||||||
|
.should('equal', (width * 2).toString())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should be able to increment zoom level', function () {
|
||||||
|
cy.get('#canvasBackground')
|
||||||
|
.invoke('attr', 'width')
|
||||||
|
.then(width => {
|
||||||
|
cy.get('#zoom')
|
||||||
|
.shadow()
|
||||||
|
.find('#arrow-up')
|
||||||
|
.click()
|
||||||
|
cy.get('#canvasBackground')
|
||||||
|
.invoke('attr', 'width')
|
||||||
|
.should('equal', (width * 1.1).toString())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should be able to decrement zoom level', function () {
|
||||||
|
cy.get('#canvasBackground')
|
||||||
|
.invoke('attr', 'width')
|
||||||
|
.then(width => {
|
||||||
|
cy.get('#zoom')
|
||||||
|
.shadow()
|
||||||
|
.find('#arrow-down')
|
||||||
|
.click()
|
||||||
|
cy.get('#canvasBackground')
|
||||||
|
.invoke('attr', 'width')
|
||||||
|
.should('equal', (width * 0.9).toString())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should be able to select from popup', function () {
|
||||||
|
cy.get('#canvasBackground')
|
||||||
|
.invoke('attr', 'width')
|
||||||
|
.then(width => {
|
||||||
|
cy.get('#zoom')
|
||||||
|
.click()
|
||||||
|
.find('se-text')
|
||||||
|
.first()
|
||||||
|
.click({ force: true })
|
||||||
|
.invoke('attr', 'value')
|
||||||
|
.then(value => {
|
||||||
|
cy.get('#canvasBackground')
|
||||||
|
.invoke('attr', 'width')
|
||||||
|
.should('equal', (width * (value / 100)).toString())
|
||||||
|
.toString()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should be able to resize to fit the current selection', function () {
|
||||||
|
cy.get('#tool_path').click({ force: true })
|
||||||
|
cy.get('#svgcontent')
|
||||||
|
.trigger('mousedown', 50, 50, { force: true })
|
||||||
|
.trigger('mouseup', { force: true })
|
||||||
|
.trigger('mousemove', 100, 50, { force: true })
|
||||||
|
.trigger('mousedown', 100, 50, { force: true })
|
||||||
|
.trigger('mouseup', { force: true })
|
||||||
|
.trigger('mousemove', 75, 150, { force: true })
|
||||||
|
.trigger('mousedown', 75, 150, { force: true })
|
||||||
|
.trigger('mouseup', { force: true })
|
||||||
|
.trigger('mousemove', 0, 0, { force: true })
|
||||||
|
.trigger('mousedown', 0, 0, { force: true })
|
||||||
|
.trigger('mouseup', { force: true })
|
||||||
|
|
||||||
|
cy.get('#tool_select')
|
||||||
|
.click({ force: true })
|
||||||
|
.trigger('mousedown', 50, 50, { force: true })
|
||||||
|
.trigger('mousemove', 100, 50, { force: true })
|
||||||
|
.trigger('mouseup', { force: true })
|
||||||
|
|
||||||
|
cy.get('#canvasBackground')
|
||||||
|
.invoke('attr', 'width')
|
||||||
|
.then(width => {
|
||||||
|
cy.get('#zoom')
|
||||||
|
.click()
|
||||||
|
.find("se-text[value='layer']")
|
||||||
|
.click({ force: true })
|
||||||
|
cy.get('#zoom')
|
||||||
|
.invoke('attr', 'value')
|
||||||
|
.then(value => {
|
||||||
|
cy.get('#canvasBackground')
|
||||||
|
.invoke('attr', 'width')
|
||||||
|
.should('not.equal', '100')
|
||||||
|
.toString()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should be able to resize to fit the canvas', function () {
|
||||||
|
cy.get('#canvasBackground')
|
||||||
|
.invoke('attr', 'width')
|
||||||
|
.then(width => {
|
||||||
|
cy.get('#zoom')
|
||||||
|
.click()
|
||||||
|
.find("se-text[value='canvas']")
|
||||||
|
.click({ force: true })
|
||||||
|
cy.get('#zoom')
|
||||||
|
.invoke('attr', 'value')
|
||||||
|
.then(value => {
|
||||||
|
cy.get('#canvasBackground')
|
||||||
|
.invoke('attr', 'width')
|
||||||
|
.should('not.equal', '100')
|
||||||
|
.toString()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should be able to resize to fit the current layer', function () {
|
||||||
|
cy.get('#tool_path').click({ force: true })
|
||||||
|
cy.get('#svgcontent')
|
||||||
|
.trigger('mousedown', 50, 50, { force: true })
|
||||||
|
.trigger('mouseup', { force: true })
|
||||||
|
.trigger('mousemove', 100, 50, { force: true })
|
||||||
|
.trigger('mousedown', 100, 50, { force: true })
|
||||||
|
.trigger('mouseup', { force: true })
|
||||||
|
.trigger('mousemove', 75, 150, { force: true })
|
||||||
|
.trigger('mousedown', 75, 150, { force: true })
|
||||||
|
.trigger('mouseup', { force: true })
|
||||||
|
.trigger('mousemove', 0, 0, { force: true })
|
||||||
|
.trigger('mousedown', 0, 0, { force: true })
|
||||||
|
.trigger('mouseup', { force: true })
|
||||||
|
|
||||||
|
cy.get('#canvasBackground')
|
||||||
|
.invoke('attr', 'width')
|
||||||
|
.then(width => {
|
||||||
|
cy.get('#zoom')
|
||||||
|
.click()
|
||||||
|
.find("se-text[value='layer']")
|
||||||
|
.click({ force: true })
|
||||||
|
cy.get('#zoom')
|
||||||
|
.invoke('attr', 'value')
|
||||||
|
.then(value => {
|
||||||
|
cy.get('#canvasBackground')
|
||||||
|
.invoke('attr', 'width')
|
||||||
|
.should('not.equal', '100')
|
||||||
|
.toString()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should be able to resize to fit the current content', function () {
|
||||||
|
cy.get('#tool_path').click({ force: true })
|
||||||
|
cy.get('#svgcontent')
|
||||||
|
.trigger('mousedown', 50, 50, { force: true })
|
||||||
|
.trigger('mouseup', { force: true })
|
||||||
|
.trigger('mousemove', 100, 50, { force: true })
|
||||||
|
.trigger('mousedown', 100, 50, { force: true })
|
||||||
|
.trigger('mouseup', { force: true })
|
||||||
|
.trigger('mousemove', 75, 150, { force: true })
|
||||||
|
.trigger('mousedown', 75, 150, { force: true })
|
||||||
|
.trigger('mouseup', { force: true })
|
||||||
|
.trigger('mousemove', 0, 0, { force: true })
|
||||||
|
.trigger('mousedown', 0, 0, { force: true })
|
||||||
|
.trigger('mouseup', { force: true })
|
||||||
|
|
||||||
|
cy.get('#canvasBackground')
|
||||||
|
.invoke('attr', 'width')
|
||||||
|
.then(width => {
|
||||||
|
cy.get('#zoom')
|
||||||
|
.click()
|
||||||
|
.find("se-text[value='content']")
|
||||||
|
.click({ force: true })
|
||||||
|
cy.get('#zoom')
|
||||||
|
.invoke('attr', 'value')
|
||||||
|
.then(value => {
|
||||||
|
cy.get('#canvasBackground')
|
||||||
|
.invoke('attr', 'width')
|
||||||
|
.should('not.equal', '100')
|
||||||
|
.toString()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
|
@ -1,73 +1,180 @@
|
||||||
/* globals svgEditor */
|
/* globals svgEditor */
|
||||||
import ListComboBox from 'elix/define/ListComboBox.js'
|
const template = document.createElement('template')
|
||||||
import * as internal from 'elix/src/base/internal.js'
|
template.innerHTML = `
|
||||||
import { templateFrom, fragmentFrom } from 'elix/src/core/htmlLiterals.js'
|
<style>
|
||||||
import NumberSpinBox from '../dialogs/se-elix/define/NumberSpinBox.js'
|
input{
|
||||||
|
border:unset;
|
||||||
/**
|
background-color:var(--input-color);
|
||||||
* @class Dropdown
|
min-width:unset;
|
||||||
*/
|
width:40px;
|
||||||
class Zoom extends ListComboBox {
|
height:23px;
|
||||||
/**
|
padding:1px 2px;
|
||||||
* @function get
|
border:2px;
|
||||||
* @returns {PlainObject}
|
font: inherit;
|
||||||
*/
|
margin: 2px 1px 0px 2px;
|
||||||
get [internal.defaultState] () {
|
box-sizing:border-box;
|
||||||
return Object.assign(super[internal.defaultState], {
|
text-align: center;
|
||||||
inputPartType: NumberSpinBox,
|
border-radius: 3px 0px 0px 3px;
|
||||||
src: 'logo.svg',
|
|
||||||
inputsize: '100%'
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
#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);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div id="tool-wrapper">
|
||||||
|
<img id="icon" alt="icon" width="18" height="18"/>
|
||||||
|
<input/>
|
||||||
|
<div id="spinner">
|
||||||
|
<div id="arrow-up">▲</div>
|
||||||
|
<div id="arrow-down">▼</div>
|
||||||
|
</div>
|
||||||
|
<div id="down">
|
||||||
|
<img width="16" height="8" src="./images/arrow_down.svg"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="options-container" style="display:none">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
|
||||||
/**
|
class SeZoom extends HTMLElement {
|
||||||
* @function get
|
constructor () {
|
||||||
* @returns {PlainObject}
|
super()
|
||||||
*/
|
|
||||||
get [internal.template] () {
|
|
||||||
const result = super[internal.template]
|
|
||||||
const source = result.content.getElementById('source')
|
|
||||||
// add a icon before our dropdown
|
|
||||||
source.prepend(fragmentFrom.html`
|
|
||||||
<img src="zoom" alt="icon" width="18" height="18">
|
|
||||||
</img>
|
|
||||||
`.cloneNode(true))
|
|
||||||
// change the style so it fits in our toolbar
|
|
||||||
result.content.append(
|
|
||||||
templateFrom.html`
|
|
||||||
<style>
|
|
||||||
[part~="source"] {
|
|
||||||
grid-template-columns: 20px 1fr auto;
|
|
||||||
}
|
|
||||||
::slotted(*) {
|
|
||||||
padding: 4px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
[part~="popup"] {
|
|
||||||
width: 150%;
|
|
||||||
}
|
|
||||||
elix-number-spin-box {
|
|
||||||
background-color: var(--input-color);
|
|
||||||
border-radius: 3px;
|
|
||||||
height: 20px !important;
|
|
||||||
margin-top: 1px;
|
|
||||||
}
|
|
||||||
elix-number-spin-box::part(spin-button) {
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
this.handleMouseDown = this.handleMouseDown.bind(this)
|
||||||
`.content
|
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)
|
||||||
)
|
)
|
||||||
return result
|
|
||||||
|
// 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))
|
||||||
|
|
||||||
|
// set src for imageElement
|
||||||
|
this.imageElement = this._shadowRoot.querySelector('img')
|
||||||
|
this.imageElement.setAttribute(
|
||||||
|
'src',
|
||||||
|
(this.imgPath =
|
||||||
|
svgEditor.configObj.curConfig.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 observedAttributes
|
* @function get
|
||||||
* @returns {any} observed
|
* @returns {any}
|
||||||
*/
|
*/
|
||||||
static get observedAttributes () {
|
get value () {
|
||||||
return ['title', 'src', 'inputsize', 'value']
|
return this.getAttribute('value')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function set
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
set value (value) {
|
||||||
|
this.setAttribute('value', value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,116 +185,196 @@ class Zoom extends ListComboBox {
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
attributeChangedCallback (name, oldValue, newValue) {
|
attributeChangedCallback (name, oldValue, newValue) {
|
||||||
if (oldValue === newValue && name !== 'src') return
|
if (oldValue === newValue) {
|
||||||
|
switch (name) {
|
||||||
|
case 'value':
|
||||||
|
if (parseInt(this.inputElement.value) !== newValue) {
|
||||||
|
this.inputElement.value = newValue
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case 'title':
|
case 'value':
|
||||||
// this.$span.setAttribute('title', `${newValue} ${shortcut ? `[${shortcut}]` : ''}`);
|
this.inputElement.value = newValue
|
||||||
break
|
this.dispatchEvent(
|
||||||
case 'src':
|
new CustomEvent('change', { detail: { value: newValue } })
|
||||||
{
|
)
|
||||||
const { imgPath } = svgEditor.configObj.curConfig
|
|
||||||
this.src = imgPath + '/' + newValue
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case 'inputsize':
|
|
||||||
this.inputsize = newValue
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
super.attributeChangedCallback(name, oldValue, newValue)
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function [internal.render]
|
* @function handleOptionsChange
|
||||||
* @param {PlainObject} changed
|
* @returns {void}
|
||||||
* @returns {void}
|
*/
|
||||||
*/
|
handleOptionsChange () {
|
||||||
[internal.render] (changed) {
|
if (this.slotElement.assignedElements().length > 0) {
|
||||||
super[internal.render](changed)
|
this.options = this.slotElement.assignedElements()
|
||||||
if (this[internal.firstRender]) {
|
this.selectedValue = this.options[0].textContent
|
||||||
this.$img = this.shadowRoot.querySelector('img')
|
|
||||||
this.$input = this.shadowRoot.getElementById('input')
|
this.initPopup()
|
||||||
}
|
|
||||||
if (changed.src) {
|
this.options.forEach(option => {
|
||||||
this.$img.setAttribute('src', this[internal.state].src)
|
option.addEventListener('click', e => this.handleSelect(e))
|
||||||
}
|
|
||||||
if (changed.inputsize) {
|
|
||||||
this.$input.shadowRoot.querySelector('[part~="input"]').style.width = this[internal.state].inputsize
|
|
||||||
}
|
|
||||||
if (changed.inputPartType) {
|
|
||||||
const self = this
|
|
||||||
this.$input.setAttribute('step', '10')
|
|
||||||
this.$input.setAttribute('min', '0')
|
|
||||||
// Handle NumberSpinBox input.
|
|
||||||
this.$input.addEventListener('change', function (e) {
|
|
||||||
e.preventDefault()
|
|
||||||
const value = e.detail?.value
|
|
||||||
if (value) {
|
|
||||||
const changeEvent = new CustomEvent('change', { detail: { value } })
|
|
||||||
self.dispatchEvent(changeEvent)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// Wire up handler on new input.
|
|
||||||
this.addEventListener('close', (e) => {
|
|
||||||
e.preventDefault()
|
|
||||||
const value = e.detail?.closeResult?.getAttribute('value')
|
|
||||||
if (value) {
|
|
||||||
const closeEvent = new CustomEvent('change', { detail: { value } })
|
|
||||||
this.dispatchEvent(closeEvent)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function src
|
* @function handleClick
|
||||||
* @returns {string} src
|
|
||||||
*/
|
|
||||||
get src () {
|
|
||||||
return this[internal.state].src
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @function src
|
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
set src (src) {
|
handleClick () {
|
||||||
this[internal.setState]({ src })
|
this.optionsContainer.style.display = 'flex'
|
||||||
|
this.inputElement.select()
|
||||||
|
this.initPopup()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function inputsize
|
* @function handleSelect
|
||||||
* @returns {string} src
|
* @param {Event} e
|
||||||
*/
|
|
||||||
get inputsize () {
|
|
||||||
return this[internal.state].inputsize
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @function src
|
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
set inputsize (inputsize) {
|
handleSelect (e) {
|
||||||
this[internal.setState]({ inputsize })
|
this.value = e.target.getAttribute('value')
|
||||||
|
this.title = e.target.getAttribute('text')
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function value
|
* @function handleShow
|
||||||
* @returns {string} src
|
* @returns {void}
|
||||||
|
* initialises the popup menu position
|
||||||
*/
|
*/
|
||||||
get value () {
|
initPopup () {
|
||||||
return this[internal.state].value
|
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 value
|
* @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}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
set value (value) {
|
handleInput () {
|
||||||
this[internal.setState]({ value })
|
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 <= 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 && this.increment()
|
||||||
|
|
||||||
|
setTimeout(
|
||||||
|
() => {
|
||||||
|
if (this.incrementHold) {
|
||||||
|
this.handleMouseDown(dir, false)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isFirst ? 500 : 50
|
||||||
|
)
|
||||||
|
} else if (dir === 'down') {
|
||||||
|
this.decrementHold = true
|
||||||
|
!isFirst && 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
|
// Register
|
||||||
customElements.define('se-zoom', Zoom)
|
customElements.define('se-zoom', SeZoom)
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
<div id="tools_bottom">
|
<div id="tools_bottom">
|
||||||
<!-- Zoom buttons -->
|
<!-- Zoom buttons -->
|
||||||
<se-zoom id="zoom" src="zoom.svg" title="Change zoom level" inputsize="40px">
|
<se-zoom id="zoom" src="zoom.svg" title="Change zoom level" inputsize="40px">
|
||||||
<se-text value="1000" text="1000"></se-text>
|
<se-text value="1000" text="1000%"></se-text>
|
||||||
<se-text value="400" text="400"></se-text>
|
<se-text value="400" text="400%"></se-text>
|
||||||
<se-text value="200" text="200"></se-text>
|
<se-text value="200" text="200%"></se-text>
|
||||||
<se-text value="100" text="100"></se-text>
|
<se-text value="100" text="100%"></se-text>
|
||||||
<se-text value="50" text="50"></se-text>
|
<se-text value="50" text="50%"></se-text>
|
||||||
<se-text value="25" text="25"></se-text>
|
<se-text value="25" text="25%"></se-text>
|
||||||
<se-text value="canvas" text="tools.fit_to_canvas"></se-text>
|
<se-text value="canvas" text="tools.fit_to_canvas"></se-text>
|
||||||
<se-text value="selection" text="tools.fit_to_sel"></se-text>
|
<se-text value="selection" text="tools.fit_to_sel"></se-text>
|
||||||
<se-text value="layer" text="tools.fit_to_layer_content"></se-text>"
|
<se-text value="layer" text="tools.fit_to_layer_content"></se-text>
|
||||||
<se-text value="content" text="tools.fit_to_all"></se-text>
|
<se-text value="content" text="tools.fit_to_all"></se-text>
|
||||||
</se-zoom>
|
</se-zoom>
|
||||||
<se-colorpicker id="fill_color" src="fill.svg" label="properties.fill_color" type="fill"></se-colorpicker>
|
<se-colorpicker id="fill_color" src="fill.svg" label="properties.fill_color" type="fill"></se-colorpicker>
|
||||||
|
|
Loading…
Reference in New Issue