V7 preview (#480)
* #issue-fix The new menu will ask if you want to erase the current content but it will ignore the answer * #issue-fix dialog needs to be closer than the original * #issue-fix main menu alignment changes * #issue_fix double click and opensvg issue fixed * #issue-fix process_cancel change to seConfirm * #issue-fix review how the top toolbar display when many buttons are displayed * #issue-fix unwanted css reoved * #issue-fix BOTTOM TOOLS Make sure all features of the bottom toolbar are working * #issue-fix IMPORT IMAGE menu open issue fixed * #issue-fix alert dialog overwrite style * #issue-fix lint issue fixed * npm update + associated fixes * #36 look of opacity button should like the zoom button (without the dropdown button) * #37 Clicking anywhere on the bottom bar (for example below the opacity button is displaying the “color popup”.) * #38 The opacity button does not update with the current element * #42 When you import an image, it works well but the dialog should disappear automatically * Fixes #53: 4th option for the background display fixed * Fixes #53: 4th option for the background fixed * #49 the x button does not work * Fixes #41: Alignment fixes in bottom bar * fix test scenario * #39 opacity button/stroke size/radius button don’t allow the 0 value * #41 The look and alignment of stroke size and stroke style should be consistent with the rest of the bottom bar. * #44 Text font dropdown is broken * #52 Fix the export * Fixes #44: Text font dropdown fixed * Fixes #44: Text font dropdown fixed * Fixes #44: Text font dropdown fixed * Fixes #44: Text font dropdown fixed * Update index.html * update husky * fixes * moves from index.html to js * fix #66 * fix #48 first set of new icons * Reorganize tools in left panel to be more intuitive * Update button styles to adapt to new icons * Fix #48 new set of icons for alignments * Variabilisation of icon bkgd colors Update of color choice to fit new icons design * Update canvas and rulers colors * Improve layer handle design * Modernize SVG Logo but keeping original spirit * Fix #48 continue improve icons * Continue to reorganise left panel * Update right panel handle for layers * Fix #48 new set of icons for main menu * Improve main menu design * Rework menu organisation * Rework menu organisation * Update input element design * New icons * Improve Zoom Module * Improve Color Picker Module * New icons * New icons * #65 restore the feature of start/end marker lines partially did * #64 The export dialog needs to include the quality options (except for PDF) * #39 opacity button/stroke size/radius button don’t allow the 0 value * #39 eslint changes * #69 menu button style overwrite * #65 restore the feature of start/end marker lines * #43 With a small window, the look of the top toolbar is broken * #43 tool top alignment revert * #46 Move this jQuery component to a web component for graduate and picker components * #46 Move this jQuery component to a web component * remove some non standard lint rules * #46 picker convert as pure javascript changes * #46 jquery plugin convert to pure javascript * #46 jquery plugin change to pure javascript * #46 jquery remove and convert to pure javascript * #46 slider issue fixed * #46 ColorValuePicker and js convertion * #46 globals $ remov from slider class * #46 jquery convert pure javascript changes * #46 jquery to js convertion changes * #46 paintbox and current element color set issue fixed * #46 unwanted files removed * #46 $.extend modify changes * #46 extend modifiey changes * #46 $.extend change to pure javascript * #46 extend and data changes * #46 jquery removed * #45 These buttons don't work and dropdown is broken * #45 These buttons don't work and dropdown is broken * #45 These buttons don't work and dropdown is broken commit reverted * #43 With a small window, the look of the top toolbar is broken * Update jQuery.jPicker.js * #76 draggable modification changes * #76 jquery-ui-1.8.17.custom.min.js removed from editor * #76 jquery ui file removed * npm update * #77 console issue fixed * #77 <SVG> button issue fixed * #77 shortkey issue fixed * #77 jquery hotkeys plugin changes * #77 hotkey plugin related changes * #78 hotkey related code comment. * #78 js-hotkeys/jquery.hotkeys.min.js file removed from svgedit.js * #51 Rewrite the color palette without elix * #81 unwanted files removed * #81 folder name renamed * #81 folder rename changes * #81 jquery-ui folder renamed * #81 jquery modify changes * #81 globals $ removed Co-authored-by: Agriya Dev5 <agriya.dev5@agriya.in> Co-authored-by: mathieucura <mathieu@optimistik.fr>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* globals $ */
|
||||
import {jGraduate} from './jgraduate/jQuery.jGraduate.js';
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -10,16 +10,17 @@ class PaintBox {
|
||||
constructor (container, type) {
|
||||
// set up gradients to be used for the buttons
|
||||
const svgdocbox = new DOMParser().parseFromString(
|
||||
`<svg xmlns="http://www.w3.org/2000/svg">
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14">
|
||||
<rect
|
||||
fill="#000000" opacity="1" width="22" height="22"/>
|
||||
fill="#000000" opacity="1" width="14" height="14"/>
|
||||
<defs><linearGradient id="gradbox_${PaintBox.ctr++}"/></defs>
|
||||
</svg>`,
|
||||
'text/xml'
|
||||
);
|
||||
|
||||
let docElem = svgdocbox.documentElement;
|
||||
docElem = container.appendChild(document.importNode(docElem, true));
|
||||
docElem = document.importNode(docElem, true);
|
||||
container.appendChild(docElem);
|
||||
|
||||
this.rect = docElem.firstElementChild;
|
||||
this.defs = docElem.getElementsByTagName('defs')[0];
|
||||
@@ -46,7 +47,8 @@ class PaintBox {
|
||||
case 'linearGradient':
|
||||
case 'radialGradient': {
|
||||
this.grad.remove();
|
||||
this.grad = this.defs.appendChild(paint[ptype]);
|
||||
this.grad = paint[ptype];
|
||||
this.defs.appendChild(this.grad);
|
||||
const id = this.grad.id = 'gradbox_' + this.type;
|
||||
fillAttr = 'url(#' + id + ')';
|
||||
break;
|
||||
@@ -68,14 +70,14 @@ class PaintBox {
|
||||
const opts = {alpha: opac};
|
||||
if (color.startsWith('url(#')) {
|
||||
let refElem = svgCanvas.getRefElem(color);
|
||||
refElem = (refElem) ? refElem.cloneNode(true) : $('#' + type + '_color defs *')[0];
|
||||
refElem = (refElem) ? refElem.cloneNode(true) : document.querySelectorAll('#' + type + '_color defs *')[0];
|
||||
opts[refElem.tagName] = refElem;
|
||||
} else if (color.startsWith('#')) {
|
||||
opts.solidColor = color.substr(1);
|
||||
} else {
|
||||
opts.solidColor = 'none';
|
||||
}
|
||||
return new $.jGraduate.Paint(opts);
|
||||
return new jGraduate.Paint(opts);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
391
src/editor/components/jgraduate/ColorValuePicker.js
Normal file
391
src/editor/components/jgraduate/ColorValuePicker.js
Normal file
@@ -0,0 +1,391 @@
|
||||
/* eslint-disable max-len */
|
||||
/* eslint-disable no-bitwise */
|
||||
/**
|
||||
* @external Math
|
||||
*/
|
||||
/**
|
||||
* @memberof external:Math
|
||||
* @param {Float} value
|
||||
* @param {Float} precision
|
||||
* @returns {Float}
|
||||
*/
|
||||
function toFixedNumeric (value, precision) {
|
||||
if (precision === undefined) precision = 0;
|
||||
return Math.round(value * (10 ** precision)) / (10 ** precision);
|
||||
}
|
||||
/**
|
||||
* Whether a value is `null` or `undefined`.
|
||||
* @param {any} val
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const isNullish = (val) => {
|
||||
return val === null || val === undefined;
|
||||
};
|
||||
/**
|
||||
* Controls for all the input elements for the typing in color values.
|
||||
*/
|
||||
export default class ColorValuePicker {
|
||||
/**
|
||||
* @param {external:jQuery} picker
|
||||
* @param {external:jQuery.jPicker.Color} color
|
||||
* @param {external:jQuery.fn.$.fn.jPicker} bindedHex
|
||||
* @param {Float} alphaPrecision
|
||||
*/
|
||||
constructor (picker, color, bindedHex, alphaPrecision) {
|
||||
const that = this; // private properties and methods
|
||||
const inputs = picker.querySelectorAll('td.Text input');
|
||||
// input box key down - use arrows to alter color
|
||||
/**
|
||||
*
|
||||
* @param {Event} e
|
||||
* @returns {Event|false|void}
|
||||
*/
|
||||
function keyDown (e) {
|
||||
if (e.target.value === '' && e.target !== hex && ((!isNullish(bindedHex) && e.target !== bindedHex) || isNullish(bindedHex))) return undefined;
|
||||
if (!validateKey(e)) return e;
|
||||
switch (e.target) {
|
||||
case red:
|
||||
switch (e.keyCode) {
|
||||
case 38:
|
||||
red.value = setValueInRange.call(that, (red.value << 0) + 1, 0, 255);
|
||||
color.val('r', red.value, e.target);
|
||||
return false;
|
||||
case 40:
|
||||
red.value = setValueInRange.call(that, (red.value << 0) - 1, 0, 255);
|
||||
color.val('r', red.value, e.target);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case green:
|
||||
switch (e.keyCode) {
|
||||
case 38:
|
||||
green.value = setValueInRange.call(that, (green.value << 0) + 1, 0, 255);
|
||||
color.val('g', green.value, e.target);
|
||||
return false;
|
||||
case 40:
|
||||
green.value = setValueInRange.call(that, (green.value << 0) - 1, 0, 255);
|
||||
color.val('g', green.value, e.target);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case blue:
|
||||
switch (e.keyCode) {
|
||||
case 38:
|
||||
blue.value = setValueInRange.call(that, (blue.value << 0) + 1, 0, 255);
|
||||
color.val('b', blue.value, e.target);
|
||||
return false;
|
||||
case 40:
|
||||
blue.value = setValueInRange.call(that, (blue.value << 0) - 1, 0, 255);
|
||||
color.val('b', blue.value, e.target);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case alpha:
|
||||
switch (e.keyCode) {
|
||||
case 38:
|
||||
alpha.value = setValueInRange.call(that, Number.parseFloat(alpha.value) + 1, 0, 100);
|
||||
color.val('a', toFixedNumeric((alpha.value * 255) / 100, alphaPrecision), e.target);
|
||||
return false;
|
||||
case 40:
|
||||
alpha.value = setValueInRange.call(that, Number.parseFloat(alpha.value) - 1, 0, 100);
|
||||
color.val('a', toFixedNumeric((alpha.value * 255) / 100, alphaPrecision), e.target);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case hue:
|
||||
switch (e.keyCode) {
|
||||
case 38:
|
||||
hue.value = setValueInRange.call(that, (hue.value << 0) + 1, 0, 360);
|
||||
color.val('h', hue.value, e.target);
|
||||
return false;
|
||||
case 40:
|
||||
hue.value =setValueInRange.call(that, (hue.value << 0) - 1, 0, 360);
|
||||
color.val('h', hue.value, e.target);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case saturation:
|
||||
switch (e.keyCode) {
|
||||
case 38:
|
||||
saturation.value = setValueInRange.call(that, (saturation.value << 0) + 1, 0, 100);
|
||||
color.val('s', saturation.value, e.target);
|
||||
return false;
|
||||
case 40:
|
||||
saturation.value = setValueInRange.call(that, (saturation.value << 0) - 1, 0, 100);
|
||||
color.val('s', saturation.value, e.target);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case value:
|
||||
switch (e.keyCode) {
|
||||
case 38:
|
||||
value.value = setValueInRange.call(that, (value.value << 0) + 1, 0, 100);
|
||||
color.val('v', value.value, e.target);
|
||||
return false;
|
||||
case 40:
|
||||
value.value = setValueInRange.call(that, (value.value << 0) - 1, 0, 100);
|
||||
color.val('v', value.value, e.target);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
// input box key up - validate value and set color
|
||||
/**
|
||||
* @param {Event} e
|
||||
* @returns {Event|void}
|
||||
* @todo Why is this returning an event?
|
||||
*/
|
||||
function keyUp (e) {
|
||||
if (e.target.value === '' && e.target !== hex &&
|
||||
((!isNullish(bindedHex) && e.target !== bindedHex) ||
|
||||
isNullish(bindedHex))) return undefined;
|
||||
if (!validateKey(e)) return e;
|
||||
switch (e.target) {
|
||||
case red:
|
||||
red.value = setValueInRange.call(that, red.value, 0, 255);
|
||||
color.val('r', red.value, e.target);
|
||||
break;
|
||||
case green:
|
||||
green.value = setValueInRange.call(that, green.value, 0, 255);
|
||||
color.val('g', green.value, e.target);
|
||||
break;
|
||||
case blue:
|
||||
blue.value = setValueInRange.call(that, blue.value, 0, 255);
|
||||
color.val('b', blue.value, e.target);
|
||||
break;
|
||||
case alpha:
|
||||
alpha.value = setValueInRange.call(that, alpha.value, 0, 100);
|
||||
color.val('a', toFixedNumeric((alpha.value * 255) / 100, alphaPrecision), e.target);
|
||||
break;
|
||||
case hue:
|
||||
hue.value = setValueInRange.call(that, hue.value, 0, 360);
|
||||
color.val('h', hue.value, e.target);
|
||||
break;
|
||||
case saturation:
|
||||
saturation.value = setValueInRange.call(that, saturation.value, 0, 100);
|
||||
color.val('s', saturation.value, e.target);
|
||||
break;
|
||||
case value:
|
||||
value.value = setValueInRange.call(that, value.value, 0, 100);
|
||||
color.val('v', value.value, e.target);
|
||||
break;
|
||||
case hex:
|
||||
hex.value = hex.value.replace(/[^a-fA-F\d]/g, '').toLowerCase().substring(0, 6);
|
||||
bindedHex && bindedHex.val(hex.value);
|
||||
color.val('hex', hex.value !== '' ? hex.value : null, e.target);
|
||||
break;
|
||||
case bindedHex:
|
||||
bindedHex.value = bindedHex.value.replace(/[^a-fA-F\d]/g, '').toLowerCase().substring(0, 6);
|
||||
hex.val(bindedHex.value);
|
||||
color.val('hex', bindedHex.value !== '' ? bindedHex.value : null, e.target);
|
||||
break;
|
||||
case ahex:
|
||||
ahex.value = ahex.value.replace(/[^a-fA-F\d]/g, '').toLowerCase().substring(0, 2);
|
||||
color.val('a', !isNullish(ahex.value) ? Number.parseInt(ahex.value, 16) : null, e.target);
|
||||
break;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
// input box blur - reset to original if value empty
|
||||
/**
|
||||
* @param {Event} e
|
||||
* @returns {void}
|
||||
*/
|
||||
function blur (e) {
|
||||
if (!isNullish(color.value)) {
|
||||
switch (e.target) {
|
||||
case red:
|
||||
color.value = 'r';
|
||||
red.value = color.value;
|
||||
break;
|
||||
case green:
|
||||
color.value = 'g';
|
||||
green.value = color.value;
|
||||
break;
|
||||
case blue:
|
||||
color.value = 'b';
|
||||
blue.value = color.value;
|
||||
break;
|
||||
case alpha:
|
||||
color.value = 'a';
|
||||
alpha.value = toFixedNumeric((color.value * 100) / 255, alphaPrecision);
|
||||
break;
|
||||
case hue:
|
||||
color.value = 'h';
|
||||
hue.value = color.value;
|
||||
break;
|
||||
case saturation:
|
||||
color.value = 's';
|
||||
saturation.value = color.value;
|
||||
break;
|
||||
case value:
|
||||
color.value = 'v';
|
||||
value.value = color.value;
|
||||
break;
|
||||
case hex:
|
||||
case bindedHex:
|
||||
color.value = 'hex';
|
||||
hex.value = color.value;
|
||||
bindedHex.value = color.value;
|
||||
break;
|
||||
case ahex:
|
||||
color.value = 'ahex';
|
||||
ahex.value = color.value.substring(6);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param {Event} e
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function validateKey (e) {
|
||||
switch (e.keyCode) {
|
||||
case 9:
|
||||
case 16:
|
||||
case 29:
|
||||
case 37:
|
||||
case 39:
|
||||
return false;
|
||||
case 'c'.charCodeAt():
|
||||
case 'v'.charCodeAt():
|
||||
if (e.ctrlKey) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constrain value within range.
|
||||
* @param {Float|string} value
|
||||
* @param {Float} min
|
||||
* @param {Float} max
|
||||
* @returns {Float|string} Returns a number or numeric string
|
||||
*/
|
||||
function setValueInRange (value, min, max) {
|
||||
if (value === '' || isNaN(value)) return min;
|
||||
if (value > max) return max;
|
||||
if (value < min) return min;
|
||||
return value;
|
||||
}
|
||||
/**
|
||||
* @param {external:jQuery} ui
|
||||
* @param {Element} context
|
||||
* @returns {void}
|
||||
*/
|
||||
function colorChanged (ui, context) {
|
||||
const all = ui.val('all');
|
||||
if (context !== red) red.value = (!isNullish(all) ? all.r : '');
|
||||
if (context !== green) green.value = (!isNullish(all) ? all.g : '');
|
||||
if (context !== blue) blue.value = (!isNullish(all) ? all.b : '');
|
||||
if (alpha && context !== alpha) alpha.value = (!isNullish(all) ? toFixedNumeric((all.a * 100) / 255, alphaPrecision) : '');
|
||||
if (context !== hue) hue.value = (!isNullish(all) ? all.h : '');
|
||||
if (context !== saturation) saturation.value = (!isNullish(all) ? all.s : '');
|
||||
if (context !== value) value.value = (!isNullish(all) ? all.v : '');
|
||||
if (context !== hex && ((bindedHex && context !== bindedHex) || !bindedHex)) hex.value = (!isNullish(all) ? all.hex : '');
|
||||
if (bindedHex && context !== bindedHex && context !== hex) bindedHex.value = (!isNullish(all) ? all.hex : '');
|
||||
if (ahex && context !== ahex) ahex.value = (!isNullish(all) ? all.ahex.substring(6) : '');
|
||||
}
|
||||
/**
|
||||
* Unbind all events and null objects.
|
||||
* @returns {void}
|
||||
*/
|
||||
function destroy () {
|
||||
red.removeEventListener('keyup', keyUp);
|
||||
green.removeEventListener('keyup', keyUp);
|
||||
blue.removeEventListener('keyup', keyUp);
|
||||
hue.removeEventListener('keyup', keyUp);
|
||||
saturation.removeEventListener('keyup', keyUp);
|
||||
value.removeEventListener('keyup', keyUp);
|
||||
hex.removeEventListener('keyup', keyUp);
|
||||
|
||||
red.removeEventListener('blur', blur);
|
||||
green.removeEventListener('blur', blur);
|
||||
blue.removeEventListener('blur', blur);
|
||||
hue.removeEventListener('blur', blur);
|
||||
saturation.removeEventListener('blur', blur);
|
||||
value.removeEventListener('blur', blur);
|
||||
hex.removeEventListener('blur', blur);
|
||||
|
||||
red.removeEventListener('keydown', keyDown);
|
||||
green.removeEventListener('keydown', keyDown);
|
||||
blue.removeEventListener('keydown', keyDown);
|
||||
hue.removeEventListener('keydown', keyDown);
|
||||
saturation.removeEventListener('keydown', keyDown);
|
||||
value.removeEventListener('keydown', keyDown);
|
||||
|
||||
if (alpha !== null) {
|
||||
alpha.removeEventListener('keyup', keyUp);
|
||||
alpha.removeEventListener('blur', blur);
|
||||
alpha.removeEventListener('keydown', keyDown);
|
||||
}
|
||||
if (ahex !== null) {
|
||||
ahex.removeEventListener('keyup', keyUp);
|
||||
ahex.removeEventListener('blur', blur);
|
||||
}
|
||||
if (bindedHex !== null) {
|
||||
bindedHex.removeEventListener('keyup', keyUp);
|
||||
bindedHex.removeEventListener('blur', blur);
|
||||
}
|
||||
color.unbind(colorChanged);
|
||||
red = null;
|
||||
green = null;
|
||||
blue = null;
|
||||
alpha = null;
|
||||
hue = null;
|
||||
saturation = null;
|
||||
value = null;
|
||||
hex = null;
|
||||
ahex = null;
|
||||
}
|
||||
let
|
||||
red = inputs[3],
|
||||
green = inputs[4],
|
||||
blue = inputs[5],
|
||||
alpha = inputs.length > 7 ? inputs[6] : null,
|
||||
hue = inputs[0],
|
||||
saturation = inputs[1],
|
||||
value = inputs[2],
|
||||
hex = inputs[(inputs.length > 7) ? 7 : 6],
|
||||
ahex = inputs.length > 7 ? inputs[8] : null;
|
||||
Object.assign(that, {destroy});
|
||||
red.addEventListener('keyup', keyUp);
|
||||
green.addEventListener('keyup', keyUp);
|
||||
blue.addEventListener('keyup', keyUp);
|
||||
hue.addEventListener('keyup', keyUp);
|
||||
saturation.addEventListener('keyup', keyUp);
|
||||
value.addEventListener('keyup', keyUp);
|
||||
hex.addEventListener('keyup', keyUp);
|
||||
|
||||
red.addEventListener('blur', blur);
|
||||
green.addEventListener('blur', blur);
|
||||
blue.addEventListener('blur', blur);
|
||||
hue.addEventListener('blur', blur);
|
||||
saturation.addEventListener('blur', blur);
|
||||
value.addEventListener('blur', blur);
|
||||
hex.addEventListener('blur', blur);
|
||||
|
||||
red.addEventListener('keydown', keyDown);
|
||||
green.addEventListener('keydown', keyDown);
|
||||
blue.addEventListener('keydown', keyDown);
|
||||
hue.addEventListener('keydown', keyDown);
|
||||
saturation.addEventListener('keydown', keyDown);
|
||||
value.addEventListener('keydown', keyDown);
|
||||
|
||||
if (alpha !== null) {
|
||||
alpha.addEventListener('keyup', keyUp);
|
||||
alpha.addEventListener('blur', blur);
|
||||
alpha.addEventListener('keydown', keyDown);
|
||||
}
|
||||
if (ahex !== null) {
|
||||
ahex.addEventListener('keyup', keyUp);
|
||||
ahex.addEventListener('blur', blur);
|
||||
}
|
||||
if (bindedHex !== null) {
|
||||
bindedHex.addEventListener('keyup', keyUp);
|
||||
bindedHex.addEventListener('blur', blur);
|
||||
}
|
||||
color.bind(colorChanged);
|
||||
}
|
||||
}
|
||||
338
src/editor/components/jgraduate/Slider.js
Normal file
338
src/editor/components/jgraduate/Slider.js
Normal file
@@ -0,0 +1,338 @@
|
||||
/* eslint-disable no-bitwise */
|
||||
import {findPos} from './Util.js';
|
||||
/**
|
||||
* Whether a value is `null` or `undefined`.
|
||||
* @param {any} val
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const isNullish = (val) => {
|
||||
return val === null || val === undefined;
|
||||
};
|
||||
/**
|
||||
* Encapsulate slider functionality for the ColorMap and ColorBar -
|
||||
* could be useful to use a jQuery UI draggable for this with certain extensions.
|
||||
* @memberof module:jPicker
|
||||
*/
|
||||
export default class Slider {
|
||||
/**
|
||||
* @param {external:jQuery} bar
|
||||
* @param {module:jPicker.SliderOptions} options
|
||||
*/
|
||||
constructor (bar, options) {
|
||||
const that = this;
|
||||
/**
|
||||
* Fire events on the supplied `context`
|
||||
* @param {module:jPicker.JPickerInit} context
|
||||
* @returns {void}
|
||||
*/
|
||||
function fireChangeEvents (context) {
|
||||
changeEvents.forEach((changeEvent) => {
|
||||
changeEvent.call(that, that, context);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind the mousedown to the bar not the arrow for quick snapping to the clicked location.
|
||||
* @param {external:jQuery.Event} e
|
||||
* @returns {void}
|
||||
*/
|
||||
function mouseDown (e) {
|
||||
const off = findPos(bar);
|
||||
offset = {l: off.left | 0, t: off.top | 0};
|
||||
clearTimeout(timeout);
|
||||
// using setTimeout for visual updates - once the style is updated the browser will re-render internally allowing the next Javascript to run
|
||||
timeout = setTimeout(function () {
|
||||
setValuesFromMousePosition.call(that, e);
|
||||
}, 0);
|
||||
// Bind mousemove and mouseup event to the document so it responds when dragged of of the bar - we will unbind these when on mouseup to save processing
|
||||
document.addEventListener('mousemove', mouseMove);
|
||||
document.addEventListener('mouseup', mouseUp);
|
||||
e.preventDefault(); // don't try to select anything or drag the image to the desktop
|
||||
}
|
||||
/**
|
||||
* Set the values as the mouse moves.
|
||||
* @param {external:jQuery.Event} e
|
||||
* @returns {false}
|
||||
*/
|
||||
function mouseMove (e) {
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(function () {
|
||||
setValuesFromMousePosition.call(that, e);
|
||||
}, 0);
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Unbind the document events - they aren't needed when not dragging.
|
||||
* @param {external:jQuery.Event} e
|
||||
* @returns {false}
|
||||
*/
|
||||
function mouseUp (e) {
|
||||
document.removeEventListener('mousemove', mouseMove);
|
||||
document.removeEventListener('mouseup', mouseUp);
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate mouse position and set value within the current range.
|
||||
* @param {Event} e
|
||||
* @returns {void}
|
||||
*/
|
||||
function setValuesFromMousePosition (e) {
|
||||
const barW = bar.w, // local copies for YUI compressor
|
||||
barH = bar.h;
|
||||
let locX = e.pageX - offset.l,
|
||||
locY = e.pageY - offset.t;
|
||||
// keep the arrow within the bounds of the bar
|
||||
if (locX < 0) locX = 0;
|
||||
else if (locX > barW) locX = barW;
|
||||
if (locY < 0) locY = 0;
|
||||
else if (locY > barH) locY = barH;
|
||||
val.call(that, 'xy', {
|
||||
x: ((locX / barW) * rangeX) + minX,
|
||||
y: ((locY / barH) * rangeY) + minY
|
||||
});
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function draw () {
|
||||
const
|
||||
barW = bar.w,
|
||||
barH = bar.h,
|
||||
arrowW = arrow.w,
|
||||
arrowH = arrow.h;
|
||||
let arrowOffsetX = 0,
|
||||
arrowOffsetY = 0;
|
||||
setTimeout(function () {
|
||||
if (rangeX > 0) { // range is greater than zero
|
||||
// constrain to bounds
|
||||
if (x === maxX) arrowOffsetX = barW;
|
||||
else arrowOffsetX = ((x / rangeX) * barW) | 0;
|
||||
}
|
||||
if (rangeY > 0) { // range is greater than zero
|
||||
// constrain to bounds
|
||||
if (y === maxY) arrowOffsetY = barH;
|
||||
else arrowOffsetY = ((y / rangeY) * barH) | 0;
|
||||
}
|
||||
// if arrow width is greater than bar width, center arrow and prevent horizontal dragging
|
||||
if (arrowW >= barW) arrowOffsetX = (barW >> 1) - (arrowW >> 1); // number >> 1 - superfast bitwise divide by two and truncate (move bits over one bit discarding lowest)
|
||||
else arrowOffsetX -= arrowW >> 1;
|
||||
// if arrow height is greater than bar height, center arrow and prevent vertical dragging
|
||||
if (arrowH >= barH) arrowOffsetY = (barH >> 1) - (arrowH >> 1);
|
||||
else arrowOffsetY -= arrowH >> 1;
|
||||
// set the arrow position based on these offsets
|
||||
arrow.style.left = arrowOffsetX + 'px';
|
||||
arrow.style.top = arrowOffsetY + 'px';
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or set a value.
|
||||
* @param {?("xy"|"x"|"y")} name
|
||||
* @param {module:math.XYObject} value
|
||||
* @param {module:jPicker.Slider} context
|
||||
* @returns {module:math.XYObject|Float|void}
|
||||
*/
|
||||
function val (name, value, context) {
|
||||
const set = value !== undefined;
|
||||
if (!set) {
|
||||
if (isNullish(name)) name = 'xy';
|
||||
switch (name.toLowerCase()) {
|
||||
case 'x': return x;
|
||||
case 'y': return y;
|
||||
case 'xy':
|
||||
default: return {x, y};
|
||||
}
|
||||
}
|
||||
if (!isNullish(context) && context === that) return undefined;
|
||||
let changed = false;
|
||||
|
||||
let newX, newY;
|
||||
if (isNullish(name)) name = 'xy';
|
||||
switch (name.toLowerCase()) {
|
||||
case 'x':
|
||||
newX = (value && ((value.x && value.x | 0) || value | 0)) || 0;
|
||||
break;
|
||||
case 'y':
|
||||
newY = (value && ((value.y && value.y | 0) || value | 0)) || 0;
|
||||
break;
|
||||
case 'xy':
|
||||
default:
|
||||
newX = (value && value.x && value.x | 0) || 0;
|
||||
newY = (value && value.y && value.y | 0) || 0;
|
||||
break;
|
||||
}
|
||||
if (!isNullish(newX)) {
|
||||
if (newX < minX) newX = minX;
|
||||
else if (newX > maxX) newX = maxX;
|
||||
if (x !== newX) {
|
||||
x = newX;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (!isNullish(newY)) {
|
||||
if (newY < minY) newY = minY;
|
||||
else if (newY > maxY) newY = maxY;
|
||||
if (y !== newY) {
|
||||
y = newY;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
changed && fireChangeEvents.call(that, context || that);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {PlainObject} module:jPicker.MinMaxRangeX
|
||||
* @property {Float} minX
|
||||
* @property {Float} maxX
|
||||
* @property {Float} rangeX
|
||||
*/
|
||||
/**
|
||||
* @typedef {PlainObject} module:jPicker.MinMaxRangeY
|
||||
* @property {Float} minY
|
||||
* @property {Float} maxY
|
||||
* @property {Float} rangeY
|
||||
*/
|
||||
/**
|
||||
* @typedef {module:jPicker.MinMaxRangeY|module:jPicker.MinMaxRangeX} module:jPicker.MinMaxRangeXY
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {"minx"|"maxx"|"rangex"|"miny"|"maxy"|"rangey"|"all"} name
|
||||
* @param {module:jPicker.MinMaxRangeXY} value
|
||||
* @returns {module:jPicker.MinMaxRangeXY|module:jPicker.MinMaxRangeX|module:jPicker.MinMaxRangeY|void}
|
||||
*/
|
||||
function range (name, value) {
|
||||
const set = value !== undefined;
|
||||
if (!set) {
|
||||
if (isNullish(name)) name = 'all';
|
||||
switch (name.toLowerCase()) {
|
||||
case 'minx': return minX;
|
||||
case 'maxx': return maxX;
|
||||
case 'rangex': return {minX, maxX, rangeX};
|
||||
case 'miny': return minY;
|
||||
case 'maxy': return maxY;
|
||||
case 'rangey': return {minY, maxY, rangeY};
|
||||
case 'all':
|
||||
default: return {minX, maxX, rangeX, minY, maxY, rangeY};
|
||||
}
|
||||
}
|
||||
let // changed = false,
|
||||
newMinX,
|
||||
newMaxX,
|
||||
newMinY,
|
||||
newMaxY;
|
||||
if (isNullish(name)) name = 'all';
|
||||
switch (name.toLowerCase()) {
|
||||
case 'minx':
|
||||
newMinX = (value && ((value.minX && value.minX | 0) || value | 0)) || 0;
|
||||
break;
|
||||
case 'maxx':
|
||||
newMaxX = (value && ((value.maxX && value.maxX | 0) || value | 0)) || 0;
|
||||
break;
|
||||
case 'rangex':
|
||||
newMinX = (value && value.minX && value.minX | 0) || 0;
|
||||
newMaxX = (value && value.maxX && value.maxX | 0) || 0;
|
||||
break;
|
||||
case 'miny':
|
||||
newMinY = (value && ((value.minY && value.minY | 0) || value | 0)) || 0;
|
||||
break;
|
||||
case 'maxy':
|
||||
newMaxY = (value && ((value.maxY && value.maxY | 0) || value | 0)) || 0;
|
||||
break;
|
||||
case 'rangey':
|
||||
newMinY = (value && value.minY && value.minY | 0) || 0;
|
||||
newMaxY = (value && value.maxY && value.maxY | 0) || 0;
|
||||
break;
|
||||
case 'all':
|
||||
default:
|
||||
newMinX = (value && value.minX && value.minX | 0) || 0;
|
||||
newMaxX = (value && value.maxX && value.maxX | 0) || 0;
|
||||
newMinY = (value && value.minY && value.minY | 0) || 0;
|
||||
newMaxY = (value && value.maxY && value.maxY | 0) || 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isNullish(newMinX) && minX !== newMinX) {
|
||||
minX = newMinX;
|
||||
rangeX = maxX - minX;
|
||||
}
|
||||
if (!isNullish(newMaxX) && maxX !== newMaxX) {
|
||||
maxX = newMaxX;
|
||||
rangeX = maxX - minX;
|
||||
}
|
||||
if (!isNullish(newMinY) && minY !== newMinY) {
|
||||
minY = newMinY;
|
||||
rangeY = maxY - minY;
|
||||
}
|
||||
if (!isNullish(newMaxY) && maxY !== newMaxY) {
|
||||
maxY = newMaxY;
|
||||
rangeY = maxY - minY;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
/**
|
||||
* @param {GenericCallback} callback
|
||||
* @returns {void}
|
||||
*/
|
||||
function bind (callback) { // eslint-disable-line promise/prefer-await-to-callbacks
|
||||
if (typeof callback === 'function') changeEvents.push(callback);
|
||||
}
|
||||
/**
|
||||
* @param {GenericCallback} callback
|
||||
* @returns {void}
|
||||
*/
|
||||
function unbind (callback) { // eslint-disable-line promise/prefer-await-to-callbacks
|
||||
if (typeof callback !== 'function') return;
|
||||
let i;
|
||||
while ((i = changeEvents.includes(callback))) changeEvents.splice(i, 1);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function destroy () {
|
||||
// unbind all possible events and null objects
|
||||
document.removeEventListener('mousemove', mouseMove);
|
||||
document.removeEventListener('mouseup', mouseUp);
|
||||
bar.removeEventListener('mousedown', mouseDown);
|
||||
bar = null;
|
||||
arrow = null;
|
||||
changeEvents = null;
|
||||
}
|
||||
let offset,
|
||||
timeout,
|
||||
x = 0,
|
||||
y = 0,
|
||||
minX = 0,
|
||||
maxX = 100,
|
||||
rangeX = 100,
|
||||
minY = 0,
|
||||
maxY = 100,
|
||||
rangeY = 100,
|
||||
arrow = bar.querySelector('img'), // the arrow image to drag
|
||||
changeEvents = [];
|
||||
Object.assign(that, {
|
||||
val,
|
||||
range,
|
||||
bind,
|
||||
unbind,
|
||||
destroy
|
||||
});
|
||||
// initialize this control
|
||||
arrow.src = options.arrow && options.arrow.image;
|
||||
arrow.w = (options.arrow && options.arrow.width) || arrow.width();
|
||||
arrow.h = (options.arrow && options.arrow.height) || arrow.height();
|
||||
bar.w = (options.map && options.map.width) || bar.width();
|
||||
bar.h = (options.map && options.map.height) || bar.height();
|
||||
bar.addEventListener('mousedown', mouseDown);
|
||||
bind.call(that, draw);
|
||||
}
|
||||
}
|
||||
37
src/editor/components/jgraduate/Util.js
Normal file
37
src/editor/components/jgraduate/Util.js
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* @param {any} obj
|
||||
* @returns {any}
|
||||
*/
|
||||
export function findPos (obj) {
|
||||
let curleft = 0;
|
||||
let curtop = 0;
|
||||
if (obj.offsetParent) {
|
||||
do {
|
||||
curleft += obj.offsetLeft;
|
||||
curtop += obj.offsetTop;
|
||||
} while (obj = obj.offsetParent);
|
||||
return {left: curleft, top: curtop};
|
||||
}
|
||||
return {left: curleft, top: curtop};
|
||||
}
|
||||
|
||||
export function isObject(item) {
|
||||
return (item && typeof item === 'object' && !Array.isArray(item));
|
||||
}
|
||||
|
||||
export function mergeDeep(target, source) {
|
||||
let output = Object.assign({}, target);
|
||||
if (isObject(target) && isObject(source)) {
|
||||
Object.keys(source).forEach(key => {
|
||||
if (isObject(source[key])) {
|
||||
if (!(key in target))
|
||||
Object.assign(output, { [key]: source[key] });
|
||||
else
|
||||
output[key] = mergeDeep(target[key], source[key]);
|
||||
} else {
|
||||
Object.assign(output, { [key]: source[key] });
|
||||
}
|
||||
});
|
||||
}
|
||||
return output;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
78
src/editor/components/jgraduate/paint.js
Normal file
78
src/editor/components/jgraduate/paint.js
Normal file
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export default class Paint {
|
||||
/**
|
||||
* @param {module:jGraduate.jGraduatePaintOptions} [opt]
|
||||
*/
|
||||
constructor (opt) {
|
||||
const options = opt || {};
|
||||
this.alpha = isNaN(options.alpha) ? 100 : options.alpha;
|
||||
// copy paint object
|
||||
if (options.copy) {
|
||||
/**
|
||||
* @name module:jGraduate~Paint#type
|
||||
* @type {"none"|"solidColor"|"linearGradient"|"radialGradient"}
|
||||
*/
|
||||
this.type = options.copy.type;
|
||||
/**
|
||||
* Represents opacity (0-100).
|
||||
* @name module:jGraduate~Paint#alpha
|
||||
* @type {Float}
|
||||
*/
|
||||
this.alpha = options.copy.alpha;
|
||||
/**
|
||||
* Represents #RRGGBB hex of color.
|
||||
* @name module:jGraduate~Paint#solidColor
|
||||
* @type {string}
|
||||
*/
|
||||
this.solidColor = null;
|
||||
/**
|
||||
* @name module:jGraduate~Paint#linearGradient
|
||||
* @type {SVGLinearGradientElement}
|
||||
*/
|
||||
this.linearGradient = null;
|
||||
/**
|
||||
* @name module:jGraduate~Paint#radialGradient
|
||||
* @type {SVGRadialGradientElement}
|
||||
*/
|
||||
this.radialGradient = null;
|
||||
|
||||
switch (this.type) {
|
||||
case 'none':
|
||||
break;
|
||||
case 'solidColor':
|
||||
this.solidColor = options.copy.solidColor;
|
||||
break;
|
||||
case 'linearGradient':
|
||||
this.linearGradient = options.copy.linearGradient.cloneNode(true);
|
||||
break;
|
||||
case 'radialGradient':
|
||||
this.radialGradient = options.copy.radialGradient.cloneNode(true);
|
||||
break;
|
||||
}
|
||||
// create linear gradient paint
|
||||
} else if (options.linearGradient) {
|
||||
this.type = 'linearGradient';
|
||||
this.solidColor = null;
|
||||
this.radialGradient = null;
|
||||
this.linearGradient = options.linearGradient.cloneNode(true);
|
||||
// create linear gradient paint
|
||||
} else if (options.radialGradient) {
|
||||
this.type = 'radialGradient';
|
||||
this.solidColor = null;
|
||||
this.linearGradient = null;
|
||||
this.radialGradient = options.radialGradient.cloneNode(true);
|
||||
// create solid color paint
|
||||
} else if (options.solidColor) {
|
||||
this.type = 'solidColor';
|
||||
this.solidColor = options.solidColor;
|
||||
// create empty paint
|
||||
} else {
|
||||
this.type = 'none';
|
||||
this.solidColor = null;
|
||||
this.linearGradient = null;
|
||||
this.radialGradient = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,16 +6,15 @@ template.innerHTML = `
|
||||
<style>
|
||||
:host(:hover) :not(.disabled)
|
||||
{
|
||||
background-color: #ffc;
|
||||
background-color: var(--icon-bg-color-hover);
|
||||
}
|
||||
div
|
||||
{
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
margin: 2px 2px 4px;
|
||||
margin: 2px 1px 4px;
|
||||
padding: 3px;
|
||||
box-shadow: inset 1px 1px 2px white, 1px 1px 1px rgba(0,0,0,0.3);
|
||||
background-color: #E8E8E8;
|
||||
background-color: var(--icon-bg-color);
|
||||
cursor: pointer;
|
||||
border-radius: 3px;
|
||||
}
|
||||
@@ -31,8 +30,7 @@ template.innerHTML = `
|
||||
height: 100%;
|
||||
}
|
||||
.pressed {
|
||||
background-color: #F4E284;
|
||||
box-shadow: inset 1px 1px 2px rgba(0,0,0,0.4), 1px 1px 0 white !important;
|
||||
background-color: var(--icon-bg-color-hover);
|
||||
}
|
||||
.disabled {
|
||||
opacity: 0.3;
|
||||
@@ -54,7 +52,7 @@ export class ToolButton extends HTMLElement {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot.appendChild(template.content.cloneNode(true));
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
// locate the component
|
||||
this.$div = this._shadowRoot.querySelector('div');
|
||||
this.$img = this._shadowRoot.querySelector('img');
|
||||
|
||||
@@ -1,42 +1,36 @@
|
||||
/* globals jQuery */
|
||||
import jQueryPluginJGraduate from './jgraduate/jQuery.jGraduate.js';
|
||||
import jQueryPluginJPicker from './jgraduate/jQuery.jPicker.js';
|
||||
import {jGraduate, jGraduateMethod} from './jgraduate/jQuery.jGraduate.js';
|
||||
import PaintBox from './PaintBox.js';
|
||||
|
||||
const $ = [
|
||||
jQueryPluginJGraduate,
|
||||
jQueryPluginJPicker
|
||||
].reduce((jq, func) => func(jq), jQuery);
|
||||
|
||||
const template = document.createElement('template');
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
@import "./components/jgraduate/css/jGraduate.css";
|
||||
@import "./components/jgraduate/css/jPicker.css";
|
||||
#logo {
|
||||
height: 22px;
|
||||
width: 22px;
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
}
|
||||
#block {
|
||||
height: 22px;
|
||||
width: 22px;
|
||||
height: 13px;
|
||||
width: 14px;
|
||||
float: right;
|
||||
background-color: darkgrey;
|
||||
}
|
||||
#picker {
|
||||
background: #f0f0f0;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
background: var(--input-color);
|
||||
height: 19px;
|
||||
line-height: 19px;
|
||||
border-radius: 3px;
|
||||
width: 52px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 4px;
|
||||
margin-top: 1px;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
#color_picker {
|
||||
position: absolute;
|
||||
bottom: 40px;
|
||||
z-index: 1000;
|
||||
top: -350px;
|
||||
}
|
||||
</style>
|
||||
<div id="picker">
|
||||
@@ -59,7 +53,7 @@ export class SeColorPicker extends HTMLElement {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot.appendChild(template.content.cloneNode(true));
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$logo = this._shadowRoot.getElementById('logo');
|
||||
this.$label = this._shadowRoot.getElementById('label');
|
||||
this.$block = this._shadowRoot.getElementById('block');
|
||||
@@ -174,33 +168,29 @@ export class SeColorPicker extends HTMLElement {
|
||||
*/
|
||||
connectedCallback () {
|
||||
this.paintBox = new PaintBox(this.$block, this.type);
|
||||
let {paint} = this.paintBox;
|
||||
$(this.$picker).click(() => {
|
||||
$(this.$color_picker)
|
||||
.draggable({
|
||||
cancel: '.jGraduate_tabs, .jGraduate_colPick, .jGraduate_gradPick, .jPicker',
|
||||
containment: 'window'
|
||||
})
|
||||
.jGraduate(
|
||||
{
|
||||
images: {clientPath: './components/jgraduate/images/'},
|
||||
paint,
|
||||
window: {pickerTitle: this.label},
|
||||
newstop: 'inverse'
|
||||
},
|
||||
(p) => {
|
||||
paint = new $.jGraduate.Paint(p);
|
||||
this.setPaint(paint);
|
||||
const changeEvent = new CustomEvent('change', {detail: {
|
||||
paint
|
||||
}});
|
||||
this.dispatchEvent(changeEvent);
|
||||
$('#color_picker').hide();
|
||||
},
|
||||
() => {
|
||||
$('#color_picker').hide();
|
||||
}
|
||||
);
|
||||
this.$picker.addEventListener('click', () => {
|
||||
let {paint} = this.paintBox;
|
||||
jGraduateMethod(
|
||||
this.$color_picker,
|
||||
{
|
||||
images: {clientPath: './components/jgraduate/images/'},
|
||||
paint,
|
||||
window: {pickerTitle: this.label},
|
||||
newstop: 'inverse'
|
||||
},
|
||||
(p) => {
|
||||
paint = new jGraduate.Paint(p);
|
||||
this.setPaint(paint);
|
||||
const changeEvent = new CustomEvent('change', {detail: {
|
||||
paint
|
||||
}});
|
||||
this.dispatchEvent(changeEvent);
|
||||
this.$color_picker.style.display = 'none';
|
||||
},
|
||||
() => {
|
||||
this.$color_picker.style.display = 'none';
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
/* eslint-disable node/no-unpublished-import */
|
||||
import ListComboBox from 'elix/define/ListComboBox.js';
|
||||
import NumberSpinBox from 'elix/define/NumberSpinBox.js';
|
||||
// import Input from 'elix/src/base/Input.js';
|
||||
import {defaultState} from 'elix/src/base/internal.js';
|
||||
import {templateFrom, fragmentFrom} from 'elix/src/core/htmlLiterals.js';
|
||||
import {internal} from 'elix';
|
||||
import NumberSpinBox from '../dialogs/se-elix/define/NumberSpinBox.js';
|
||||
|
||||
/**
|
||||
* @class Dropdown
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
/* eslint-disable no-unsanitized/property */
|
||||
const template = document.createElement('template');
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
:host {
|
||||
position:relative;
|
||||
}
|
||||
.menu-button:hover, se-button:hover, .menu-item:hover
|
||||
.menu-button:hover, se-button:hover, .menu-item:hover
|
||||
{
|
||||
background-color: #ffc;
|
||||
background-color: var(--icon-bg-color-hover);
|
||||
}
|
||||
img {
|
||||
border: none;
|
||||
@@ -14,13 +15,12 @@ template.innerHTML = `
|
||||
height: 24px;
|
||||
}
|
||||
.overall.pressed .button-icon,
|
||||
.overall.pressed .handle,
|
||||
.overall.pressed,
|
||||
.menu-item.pressed {
|
||||
background-color: #F4E284 !important;
|
||||
background-color: var(--icon-bg-color-hover) !important;
|
||||
}
|
||||
.overall.pressed .menu-button {
|
||||
box-shadow: inset 1px 1px 2px rgba(0,0,0,0.4), 1px 1px 0 white !important;
|
||||
background-color: #F4E284 !important;
|
||||
background-color: var(--icon-bg-color-hover) !important;
|
||||
}
|
||||
.disabled {
|
||||
opacity: 0.3;
|
||||
@@ -29,10 +29,9 @@ template.innerHTML = `
|
||||
.menu-button {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
margin: 2px 2px 4px;
|
||||
margin: 2px 1px 4px;
|
||||
padding: 3px;
|
||||
box-shadow: inset 1px 1px 2px white, 1px 1px 1px rgba(0,0,0,0.3);
|
||||
background-color: #E8E8E8;
|
||||
background-color: var(--icon-bg-color);
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
border-radius: 3px;
|
||||
@@ -83,7 +82,7 @@ template.innerHTML = `
|
||||
background: none !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<div class="overall">
|
||||
<div class="menu-button">
|
||||
<img class="button-icon" src="./images/logo.svg" alt="icon">
|
||||
@@ -96,7 +95,7 @@ template.innerHTML = `
|
||||
<div class="menu-item">menu</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
`;
|
||||
/**
|
||||
* @class ExplorerButton
|
||||
@@ -109,7 +108,7 @@ export class ExplorerButton extends HTMLElement {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot.appendChild(template.content.cloneNode(true));
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
// locate the component
|
||||
this.$button = this._shadowRoot.querySelector('.menu-button');
|
||||
this.$overall = this._shadowRoot.querySelector('.overall');
|
||||
@@ -162,7 +161,6 @@ export class ExplorerButton extends HTMLElement {
|
||||
const response = await fetch(`${newValue}index.json`);
|
||||
const json = await response.json();
|
||||
const {lib} = json;
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
this.$menu.innerHTML = lib.map((menu, i) => (
|
||||
`<div data-menu="${menu}" class="menu-item ${(i === 0) ? 'pressed' : ''} ">${menu}</div>`
|
||||
)).join('');
|
||||
@@ -299,7 +297,6 @@ export class ExplorerButton extends HTMLElement {
|
||||
const off = size * 0.05;
|
||||
const vb = [-off, -off, size + off * 2, size + off * 2].join(' ');
|
||||
const stroke = json.fill ? 0 : (size / 30);
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
this.$lib.innerHTML = Object.entries(this.data).map(([key, path]) => {
|
||||
const encoded = btoa(`
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24">
|
||||
|
||||
@@ -6,7 +6,7 @@ template.innerHTML = `
|
||||
}
|
||||
.overall:hover *
|
||||
{
|
||||
background-color: #ffc;
|
||||
background-color: var(--icon-bg-color-hover);
|
||||
}
|
||||
img {
|
||||
border: none;
|
||||
@@ -15,11 +15,10 @@ template.innerHTML = `
|
||||
}
|
||||
.overall.pressed .button-icon,
|
||||
.overall.pressed .handle {
|
||||
background-color: #F4E284 !important;
|
||||
background-color: var(--icon-bg-color-hover) !important;
|
||||
}
|
||||
.overall.pressed .menu-button {
|
||||
box-shadow: inset 1px 1px 2px rgba(0,0,0,0.4), 1px 1px 0 white !important;
|
||||
background-color: #F4E284 !important;
|
||||
background-color: var(--icon-bg-color-hover) !important;
|
||||
}
|
||||
.disabled {
|
||||
opacity: 0.3;
|
||||
@@ -28,10 +27,9 @@ template.innerHTML = `
|
||||
.menu-button {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
margin: 2px 2px 4px;
|
||||
margin: 2px 1px 4px;
|
||||
padding: 3px;
|
||||
box-shadow: inset 1px 1px 2px white, 1px 1px 1px rgba(0,0,0,0.3);
|
||||
background-color: #E8E8E8;
|
||||
background-color: var(--icon-bg-color);
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
border-radius: 3px;
|
||||
@@ -68,7 +66,7 @@ template.innerHTML = `
|
||||
background: none !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<div class="overall">
|
||||
<div class="menu-button">
|
||||
<img class="button-icon" src="./images/logo.svg" alt="icon">
|
||||
@@ -78,7 +76,7 @@ template.innerHTML = `
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
`;
|
||||
/**
|
||||
* @class FlyingButton
|
||||
@@ -91,7 +89,7 @@ export class FlyingButton extends HTMLElement {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot.appendChild(template.content.cloneNode(true));
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
// locate the component
|
||||
this.$button = this._shadowRoot.querySelector('.menu-button');
|
||||
this.$handle = this._shadowRoot.querySelector('.handle');
|
||||
@@ -107,7 +105,7 @@ export class FlyingButton extends HTMLElement {
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['title', 'pressed', 'disabled'];
|
||||
return ['title', 'pressed', 'disabled', 'opened'];
|
||||
}
|
||||
/**
|
||||
* @function attributeChangedCallback
|
||||
@@ -132,6 +130,13 @@ export class FlyingButton extends HTMLElement {
|
||||
this.$overall.classList.remove('pressed');
|
||||
}
|
||||
break;
|
||||
case 'opened':
|
||||
if (newValue) {
|
||||
this.$menu.classList.add('open');
|
||||
} else {
|
||||
this.$menu.classList.remove('open');
|
||||
}
|
||||
break;
|
||||
case 'disabled':
|
||||
if (newValue) {
|
||||
this.$div.classList.add('disabled');
|
||||
@@ -178,6 +183,28 @@ export class FlyingButton extends HTMLElement {
|
||||
this.setAttribute('pressed', 'true');
|
||||
} else {
|
||||
this.removeAttribute('pressed', '');
|
||||
// close also the menu if open
|
||||
this.removeAttribute('opened');
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get opened () {
|
||||
return this.hasAttribute('opened');
|
||||
}
|
||||
|
||||
/**
|
||||
* @function set
|
||||
* @returns {void}
|
||||
*/
|
||||
set opened (value) {
|
||||
// boolean value => existence = true
|
||||
if (value) {
|
||||
this.setAttribute('opened', 'opened');
|
||||
} else {
|
||||
this.removeAttribute('opened');
|
||||
}
|
||||
}
|
||||
/**
|
||||
@@ -214,7 +241,7 @@ export class FlyingButton extends HTMLElement {
|
||||
switch (ev.target.nodeName) {
|
||||
case 'SE-FLYINGBUTTON':
|
||||
if (this.pressed) {
|
||||
this.$menu.classList.toggle('open');
|
||||
this.setAttribute('opened', 'opened');
|
||||
} else {
|
||||
// launch current action
|
||||
this.activeSlot.click();
|
||||
@@ -231,7 +258,11 @@ export class FlyingButton extends HTMLElement {
|
||||
break;
|
||||
case 'DIV':
|
||||
// this is a click on the handle so let's open/close the menu.
|
||||
this.$menu.classList.toggle('open');
|
||||
if (this.opened) {
|
||||
this.removeAttribute('opened');
|
||||
} else {
|
||||
this.setAttribute('opened', 'opened');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// eslint-disable-next-line no-console
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable node/no-unpublished-import */
|
||||
import 'elix/define/Input.js';
|
||||
|
||||
const template = document.createElement('template');
|
||||
@@ -13,6 +12,12 @@ template.innerHTML = `
|
||||
bottom: 1px;
|
||||
right: -4px;
|
||||
position: relative;
|
||||
margin-right: 4px;
|
||||
color: #fff;
|
||||
}
|
||||
elix-input {
|
||||
background-color: var(--input-color);
|
||||
border-radius: 3px;
|
||||
}
|
||||
</style>
|
||||
<img src="./images/logo.svg" alt="icon" width="12" height="12" />
|
||||
@@ -31,7 +36,7 @@ export class SEInput extends HTMLElement {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot.appendChild(template.content.cloneNode(true));
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
// locate the component
|
||||
this.$img = this._shadowRoot.querySelector('img');
|
||||
this.$label = this.shadowRoot.getElementById('label');
|
||||
|
||||
@@ -1,25 +1,29 @@
|
||||
/* eslint-disable node/no-unpublished-import */
|
||||
import 'elix/define/DropdownList.js';
|
||||
|
||||
const template = document.createElement('template');
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
[part~="source"] {
|
||||
grid-template-columns: 20px 1fr auto;
|
||||
elix-dropdown-list {
|
||||
margin: 1px;
|
||||
}
|
||||
::slotted(*) {
|
||||
background: #E8E8E8;
|
||||
border: 1px solid #B0B0B0;
|
||||
|
||||
elix-dropdown-list:hover {
|
||||
background-color: var(--icon-bg-color-hover);
|
||||
}
|
||||
|
||||
::part(popup-toggle) {
|
||||
display: none;
|
||||
}
|
||||
::slotted(*) {
|
||||
padding:0;
|
||||
width:100%;
|
||||
}
|
||||
</style>
|
||||
<label>Label</label>
|
||||
<elix-dropdown-list>
|
||||
<slot></slot>
|
||||
</elix-dropdown-list>
|
||||
|
||||
|
||||
`;
|
||||
/**
|
||||
* @class SeList
|
||||
@@ -32,7 +36,7 @@ export class SeList extends HTMLElement {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot.appendChild(template.content.cloneNode(true));
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$dropdown = this._shadowRoot.querySelector('elix-dropdown-list');
|
||||
this.$label = this._shadowRoot.querySelector('label');
|
||||
}
|
||||
@@ -41,7 +45,7 @@ export class SeList extends HTMLElement {
|
||||
* @returns {any} observed
|
||||
*/
|
||||
static get observedAttributes () {
|
||||
return ['label'];
|
||||
return ['label', 'width', 'height'];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,6 +61,12 @@ export class SeList extends HTMLElement {
|
||||
case 'label':
|
||||
this.$label.textContent = newValue;
|
||||
break;
|
||||
case 'height':
|
||||
this.$dropdown.style.height = newValue;
|
||||
break;
|
||||
case 'width':
|
||||
this.$dropdown.style.width = newValue;
|
||||
break;
|
||||
default:
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`unknown attribute: ${name}`);
|
||||
@@ -78,16 +88,49 @@ export class SeList extends HTMLElement {
|
||||
set label (value) {
|
||||
this.setAttribute('label', value);
|
||||
}
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get width () {
|
||||
return this.getAttribute('width');
|
||||
}
|
||||
|
||||
/**
|
||||
* @function set
|
||||
* @returns {void}
|
||||
*/
|
||||
set width (value) {
|
||||
this.setAttribute('width', value);
|
||||
}
|
||||
/**
|
||||
* @function get
|
||||
* @returns {any}
|
||||
*/
|
||||
get height () {
|
||||
return this.getAttribute('height');
|
||||
}
|
||||
|
||||
/**
|
||||
* @function set
|
||||
* @returns {void}
|
||||
*/
|
||||
set height (value) {
|
||||
this.setAttribute('height', value);
|
||||
}
|
||||
/**
|
||||
* @function connectedCallback
|
||||
* @returns {void}
|
||||
*/
|
||||
connectedCallback () {
|
||||
this.$dropdown.addEventListener('change', (e) => {
|
||||
const currentObj = this;
|
||||
this.$dropdown.addEventListener('selectedindexchange', (e) => {
|
||||
e.preventDefault();
|
||||
const selectedItem = e?.detail?.closeResult;
|
||||
if (selectedItem !== undefined && selectedItem?.id !== undefined) {
|
||||
document.getElementById(selectedItem.id).click();
|
||||
if (e?.detail?.selectedIndex !== undefined) {
|
||||
const value = this.$dropdown.selectedItem.getAttribute('value');
|
||||
const closeEvent = new CustomEvent('change', {detail: {value}});
|
||||
currentObj.dispatchEvent(closeEvent);
|
||||
currentObj.value = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
/* eslint-disable node/no-unpublished-import */
|
||||
import 'elix/define/Option.js';
|
||||
|
||||
const template = document.createElement('template');
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
</style>
|
||||
elix-option{
|
||||
padding:0.25rem 0.125rem !important;
|
||||
background-color: var(--icon-bg-color);
|
||||
}
|
||||
elix-option:hover{
|
||||
background-color: var(--icon-bg-color-hover);
|
||||
}
|
||||
</style>
|
||||
<elix-option aria-label="option">
|
||||
<slot></slot>
|
||||
</elix-option>
|
||||
</elix-option>
|
||||
`;
|
||||
/**
|
||||
* @class SeMenu
|
||||
@@ -20,8 +26,10 @@ export class SeListItem extends HTMLElement {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot.appendChild(template.content.cloneNode(true));
|
||||
this.$menuitem = this._shadowRoot.querySelector('elix-menu-item');
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$menuitem = this._shadowRoot.querySelector('elix-option');
|
||||
this.$svg = this.$menuitem.shadowRoot.querySelector('#checkmark');
|
||||
this.$svg.setAttribute('style', 'display: none;');
|
||||
}
|
||||
/**
|
||||
* @function observedAttributes
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/* eslint-disable node/no-unpublished-import */
|
||||
import 'elix/define/MenuButton.js';
|
||||
import 'elix/define/MenuItem.js';
|
||||
import './sePlainMenuButton.js';
|
||||
|
||||
const template = document.createElement('template');
|
||||
template.innerHTML = `
|
||||
@@ -9,20 +8,26 @@ template.innerHTML = `
|
||||
padding: 0px;
|
||||
}
|
||||
elix-menu-button::part(menu) {
|
||||
background-color: #eee !important;
|
||||
background-color: var(--icon-bg-color) !important;
|
||||
color: #fff;
|
||||
}
|
||||
elix-menu-button::part(popup-toggle) {
|
||||
padding: 0.25em 0.60em !important
|
||||
padding: 0.25em 0.30em !important
|
||||
}
|
||||
:host ::slotted([current]){
|
||||
background-color: #F4E284 !important;
|
||||
background-color: var(--icon-bg-color-hover) !important;
|
||||
color: #fff;
|
||||
}
|
||||
:host ::slotted(*){
|
||||
padding: 0.25em 1.25em 0.25em 0.25em !important;
|
||||
margin: 2px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<elix-menu-button id="MenuButton" aria-label="Main Menu">
|
||||
<slot></slot>
|
||||
</elix-menu-button>
|
||||
|
||||
|
||||
`;
|
||||
/**
|
||||
* @class SeMenu
|
||||
@@ -35,7 +40,7 @@ export class SeMenu extends HTMLElement {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot.appendChild(template.content.cloneNode(true));
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$menu = this._shadowRoot.querySelector('elix-menu-button');
|
||||
this.$label = this.$menu.shadowRoot.querySelector('#popupToggle').shadowRoot;
|
||||
}
|
||||
@@ -60,8 +65,8 @@ export class SeMenu extends HTMLElement {
|
||||
switch (name) {
|
||||
case 'src':
|
||||
image.src = newValue;
|
||||
image.width = 18;
|
||||
image.height = 18;
|
||||
image.width = 24;
|
||||
image.height = 24;
|
||||
this.$label.prepend(image);
|
||||
break;
|
||||
case 'label':
|
||||
@@ -107,7 +112,7 @@ export class SeMenu extends HTMLElement {
|
||||
* @function connectedCallback
|
||||
* @returns {void}
|
||||
*/
|
||||
connectedCallback () {
|
||||
/* connectedCallback () {
|
||||
this.$menu.addEventListener('openedchange', (e) => {
|
||||
e.preventDefault();
|
||||
const selectedItem = e?.detail?.closeResult;
|
||||
@@ -115,7 +120,7 @@ export class SeMenu extends HTMLElement {
|
||||
document.getElementById(selectedItem.id).click();
|
||||
}
|
||||
});
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
||||
// Register
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
/* eslint-disable node/no-unpublished-import */
|
||||
import 'elix/define/Menu.js';
|
||||
import 'elix/define/MenuItem.js';
|
||||
|
||||
const template = document.createElement('template');
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
</style>
|
||||
</style>
|
||||
<elix-menu-item>
|
||||
<div style="display:inline-block;">
|
||||
<img src="./images/logo.svg" alt="icon" style="display:none;" />
|
||||
<span></span>
|
||||
<div style="display:flex; align-items: center;">
|
||||
<img src="./images/logo.svg" alt="icon" style="display:none;" width="24"/>
|
||||
<span style="margin-left: 7px;"></span>
|
||||
</div>
|
||||
</elix-menu-item>
|
||||
</elix-menu-item>
|
||||
`;
|
||||
/**
|
||||
* @class SeMenuItem
|
||||
@@ -24,12 +23,12 @@ export class SeMenuItem extends HTMLElement {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot.appendChild(template.content.cloneNode(true));
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$img = this._shadowRoot.querySelector('img');
|
||||
this.$label = this._shadowRoot.querySelector('span');
|
||||
this.$menuitem = this._shadowRoot.querySelector('elix-menu-item');
|
||||
this.$svg = this.$menuitem.shadowRoot.querySelector('#checkmark');
|
||||
this.$svg.setAttribute('style', 'width:1px;height:1px;');
|
||||
this.$svg.setAttribute('style', 'display: none;');
|
||||
}
|
||||
/**
|
||||
* @function observedAttributes
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
/* eslint-disable node/no-unpublished-import */
|
||||
import 'elix/define/CenteredStrip.js';
|
||||
|
||||
/* eslint-disable max-len */
|
||||
const palette = [
|
||||
// Todo: Make into configuration item?
|
||||
'#000000', '#3f3f3f', '#7f7f7f', '#bfbfbf', '#ffffff',
|
||||
'none', '#000000', '#3f3f3f', '#7f7f7f', '#bfbfbf', '#ffffff',
|
||||
'#ff0000', '#ff7f00', '#ffff00', '#7fff00',
|
||||
'#00ff00', '#00ff7f', '#00ffff', '#007fff',
|
||||
'#0000ff', '#7f00ff', '#ff00ff', '#ff007f',
|
||||
@@ -21,11 +19,66 @@ template.innerHTML = `
|
||||
.square {
|
||||
height: 15px;
|
||||
width: 15px;
|
||||
float: left;
|
||||
}
|
||||
#palette_holder {
|
||||
overflow: hidden;
|
||||
margin-top: 5px;
|
||||
padding: 5px;
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
height: 16px;
|
||||
background: #f0f0f0;
|
||||
border-radius: 3px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#js-se-palette {
|
||||
float: left;
|
||||
width: 632px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
div.palette_item {
|
||||
height: 15px;
|
||||
width: 15px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
div.palette_item:first-child {
|
||||
background: white;
|
||||
}
|
||||
@media screen and (max-width:1100px) {
|
||||
#palette_holder {
|
||||
left: 410px;
|
||||
overflow-x: scroll;
|
||||
padding: 0 5px;
|
||||
margin-top: 2px;
|
||||
height: 30px;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width:1250px) {
|
||||
#palette_holder {
|
||||
left: 560px;
|
||||
overflow-x: scroll;
|
||||
padding: 0 5px;
|
||||
margin-top: 2px;
|
||||
height: 30px;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width:540px) {
|
||||
#palette_holder {
|
||||
left: 0px;
|
||||
overflow-x: scroll;
|
||||
padding: 0 5px;
|
||||
margin-top: 32px;
|
||||
height: 30px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<div title="Click to change fill color, shift-click to change stroke color">
|
||||
<elix-centered-strip style="width:300px">
|
||||
</elix-centered-strip>
|
||||
<div id="palette_holder" title="Click to change fill color, shift-click to change stroke color">
|
||||
<div id="js-se-palette">
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -40,14 +93,34 @@ export class SEPalette extends HTMLElement {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot.appendChild(template.content.cloneNode(true));
|
||||
this.$strip = this._shadowRoot.querySelector('elix-centered-strip');
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
this.$strip = this._shadowRoot.querySelector('#js-se-palette');
|
||||
palette.forEach((rgb) => {
|
||||
const newDiv = document.createElement('div');
|
||||
newDiv.classList.add('square');
|
||||
newDiv.style.backgroundColor = rgb;
|
||||
if(rgb === 'none') {
|
||||
var img = document.createElement('img');
|
||||
img.src = `data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgY2xhc3M9InN2Z19pY29uIj48c3ZnIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+CiAgICA8bGluZSBmaWxsPSJub25lIiBzdHJva2U9IiNkNDAwMDAiIGlkPSJzdmdfOTAiIHkyPSIyNCIgeDI9IjI0IiB5MT0iMCIgeDE9IjAiLz4KICAgIDxsaW5lIGlkPSJzdmdfOTIiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2Q0MDAwMCIgeTI9IjI0IiB4Mj0iMCIgeTE9IjAiIHgxPSIyNCIvPgogIDwvc3ZnPjwvc3ZnPg==`;
|
||||
img.style.width = "15px";
|
||||
img.style.height = "15px";
|
||||
newDiv.append(img);
|
||||
} else {
|
||||
newDiv.style.backgroundColor = rgb;
|
||||
}
|
||||
newDiv.dataset.rgb = rgb;
|
||||
this.$strip.appendChild(newDiv);
|
||||
newDiv.addEventListener('click', (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') {
|
||||
color = 'none';
|
||||
}
|
||||
const paletteEvent = new CustomEvent('change', {detail: {picker, color}, bubbles: false});
|
||||
this.dispatchEvent(paletteEvent);
|
||||
});
|
||||
this.$strip.append(newDiv);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -56,18 +129,6 @@ export class SEPalette extends HTMLElement {
|
||||
* @returns {void}
|
||||
*/
|
||||
connectedCallback () {
|
||||
this.$strip.addEventListener('click', (evt) => {
|
||||
evt.preventDefault();
|
||||
// shift key or right click for stroke
|
||||
const picker = evt.shiftKey || evt.button === 2 ? 'stroke' : 'fill';
|
||||
let color = this.$strip.currentItem.dataset.rgb;
|
||||
// Webkit-based browsers returned 'initial' here for no stroke
|
||||
if (color === 'none' || color === 'transparent' || color === 'initial') {
|
||||
color = 'none';
|
||||
}
|
||||
const paletteEvent = new CustomEvent('change', {detail: {picker, color}, bubbles: false});
|
||||
this.dispatchEvent(paletteEvent);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
32
src/editor/components/sePlainBorderButton.js
Normal file
32
src/editor/components/sePlainBorderButton.js
Normal file
@@ -0,0 +1,32 @@
|
||||
import {template} from 'elix/src/base/internal.js';
|
||||
import {fragmentFrom} from 'elix/src/core/htmlLiterals.js';
|
||||
import PlainButton from 'elix/src/plain/PlainButton.js';
|
||||
|
||||
/**
|
||||
* @class SePlainBorderButton
|
||||
* Button with a border in the Plain reference design system
|
||||
*
|
||||
* @inherits PlainButton
|
||||
*/
|
||||
class SePlainBorderButton extends PlainButton {
|
||||
/**
|
||||
* @function get
|
||||
* @returns {PlainObject}
|
||||
*/
|
||||
get [template] () {
|
||||
const result = super[template];
|
||||
result.content.append(
|
||||
fragmentFrom.html`
|
||||
<style>
|
||||
[part~="button"] {
|
||||
background: #72797A;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
</style>
|
||||
`
|
||||
);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
export default SePlainBorderButton;
|
||||
20
src/editor/components/sePlainMenuButton.js
Normal file
20
src/editor/components/sePlainMenuButton.js
Normal file
@@ -0,0 +1,20 @@
|
||||
import PlainMenuButton from 'elix/src/plain/PlainMenuButton.js';
|
||||
import {defaultState} from 'elix/src/base/internal.js';
|
||||
import sePlainBorderButton from './sePlainBorderButton.js';
|
||||
|
||||
/**
|
||||
* @class ElixMenuButton
|
||||
*/
|
||||
export default class ElixMenuButton extends PlainMenuButton {
|
||||
/**
|
||||
* @function get
|
||||
* @returns {PlainObject}
|
||||
*/
|
||||
get [defaultState] () {
|
||||
return Object.assign(super[defaultState], {
|
||||
sourcePartType: sePlainBorderButton
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('elix-menu-button', ElixMenuButton);
|
||||
@@ -1,24 +1,40 @@
|
||||
/* eslint-disable node/no-unpublished-import */
|
||||
import 'elix/define/NumberSpinBox.js';
|
||||
import '../dialogs/se-elix/define/NumberSpinBox.js';
|
||||
|
||||
const template = document.createElement('template');
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
img {
|
||||
top: 2px;
|
||||
left: 4px;
|
||||
position: relative;
|
||||
right: -4px;
|
||||
}
|
||||
span {
|
||||
bottom: 1px;
|
||||
bottom: -3px;
|
||||
right: -4px;
|
||||
position: relative;
|
||||
margin-left: 4px;
|
||||
margin-right: 4px;
|
||||
color: #fff;
|
||||
vertical-align: ;
|
||||
}
|
||||
elix-number-spin-box {
|
||||
background-color: var(--input-color);
|
||||
border-radius: 3px;
|
||||
height: 20px !important;
|
||||
margin-top: 1px;
|
||||
vertical-align: top;
|
||||
}
|
||||
elix-number-spin-box::part(spin-button) {
|
||||
padding: 0px;
|
||||
}
|
||||
elix-number-spin-box::part(input) {
|
||||
width: 3em;
|
||||
}
|
||||
elix-number-spin-box{
|
||||
width: 54px;
|
||||
height: 24px;
|
||||
}
|
||||
</style>
|
||||
<img src="./images/logo.svg" alt="icon" width="12" height="12" aria-labelledby="label" />
|
||||
<img src="./images/logo.svg" alt="icon" width="24" height="24" aria-labelledby="label" />
|
||||
<span id="label">label</span>
|
||||
<elix-number-spin-box min="1" step="1"></elix-number-spin-box>
|
||||
`;
|
||||
@@ -34,7 +50,7 @@ export class SESpinInput extends HTMLElement {
|
||||
super();
|
||||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({mode: 'open'});
|
||||
this._shadowRoot.appendChild(template.content.cloneNode(true));
|
||||
this._shadowRoot.append(template.content.cloneNode(true));
|
||||
// locate the component
|
||||
this.$img = this._shadowRoot.querySelector('img');
|
||||
this.$label = this.shadowRoot.getElementById('label');
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
/* eslint-disable node/no-unpublished-import */
|
||||
import ListComboBox from 'elix/define/ListComboBox.js';
|
||||
import NumberSpinBox from 'elix/define/NumberSpinBox.js';
|
||||
// import Input from 'elix/src/base/Input.js';
|
||||
import * as internal from 'elix/src/base/internal.js';
|
||||
import {templateFrom, fragmentFrom} from 'elix/src/core/htmlLiterals.js';
|
||||
import NumberSpinBox from '../dialogs/se-elix/define/NumberSpinBox.js';
|
||||
|
||||
/**
|
||||
* @class Dropdown
|
||||
@@ -40,13 +38,24 @@ class Zoom extends ListComboBox {
|
||||
}
|
||||
::slotted(*) {
|
||||
padding: 4px;
|
||||
background: #E8E8E8;
|
||||
border: 1px solid #B0B0B0;
|
||||
width: 100%;
|
||||
background-color: var(--icon-bg-color);
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
[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>
|
||||
`.content
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user