first pass

This commit is contained in:
JFH
2020-12-20 19:12:43 +01:00
parent 53e7c91731
commit 88690b6a2b
7 changed files with 348 additions and 341 deletions

View File

@@ -0,0 +1,172 @@
/* globals $ */
/**
*
*/
class PaintBox {
/**
* @param {string|Element|external:jQuery} container
* @param {PlainObject} svgcanvas
* @param {"fill"} type
* @param {string} color
* @param {number} opacity
*/
constructor (container, svgcanvas, type, color, opacity) {
// set up gradients to be used for the buttons
const svgdocbox = new DOMParser().parseFromString(
`<svg xmlns="http://www.w3.org/2000/svg" width="16.5" height="16.5">
<rect
fill="#${color}" opacity="${opacity}"/>
<defs><linearGradient id="gradbox_${PaintBox.ctr++}"/></defs>
</svg>`,
'text/xml'
);
let docElem = svgdocbox.documentElement;
docElem = $(container)[0].appendChild(document.importNode(docElem, true));
docElem.setAttribute('width', 16.5);
this.rect = docElem.firstElementChild;
this.defs = docElem.getElementsByTagName('defs')[0];
this.grad = this.defs.firstElementChild;
this.paint = new $.jGraduate.Paint({solidColor: color});
this.type = type;
this.svgcanvas = svgcanvas;
}
/**
* @param {module:jGraduate~Paint} paint
* @param {boolean} apply
* @returns {void}
*/
setPaint (paint, apply) {
this.paint = paint;
const ptype = paint.type;
const opac = paint.alpha / 100;
let fillAttr = 'none';
switch (ptype) {
case 'solidColor':
fillAttr = (paint[ptype] !== 'none') ? '#' + paint[ptype] : paint[ptype];
break;
case 'linearGradient':
case 'radialGradient': {
this.grad.remove();
this.grad = this.defs.appendChild(paint[ptype]);
const id = this.grad.id = 'gradbox_' + this.type;
fillAttr = 'url(#' + id + ')';
break;
}
}
this.rect.setAttribute('fill', fillAttr);
this.rect.setAttribute('opacity', opac);
if (apply) {
this.svgCanvas.setColor(this.type, this._paintColor, true);
this.svgCanvas.setPaintOpacity(this.type, this._paintOpacity, true);
}
}
/**
* @param {string} color
* @param {Float} opac
* @param {string} type
* @returns {module:jGraduate~Paint}
*/
getPaint (color, opac, type) {
// update the editor's fill paint
const opts = {alpha: opac};
if (color.startsWith('url(#')) {
let refElem = this.svgCanvas.getRefElem(color);
refElem = (refElem) ? refElem.cloneNode(true) : $('#' + 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);
}
/**
* @param {PlainObject} selectedElement
* @param {boolean} apply
* @returns {void}
*/
update (selectedElement, apply) {
if (!selectedElement) { return; }
const {type} = this;
switch (selectedElement.tagName) {
case 'use':
case 'image':
case 'foreignObject':
// These elements don't have fill or stroke, so don't change
// the current value
return;
case 'g':
case 'a': {
const childs = selectedElement.getElementsByTagName('*');
let gPaint = null;
for (let i = 0, len = childs.length; i < len; i++) {
const elem = childs[i];
const p = elem.getAttribute(type);
if (i === 0) {
gPaint = p;
} else if (gPaint !== p) {
gPaint = null;
break;
}
}
if (gPaint === null) {
// No common color, don't update anything
this._paintColor = null;
return;
}
this._paintColor = gPaint;
this._paintOpacity = 1;
break;
} default: {
this._paintOpacity = Number.parseFloat(selectedElement.getAttribute(type + '-opacity'));
if (Number.isNaN(this._paintOpacity)) {
this._paintOpacity = 1.0;
}
const defColor = type === 'fill' ? 'black' : 'none';
this._paintColor = selectedElement.getAttribute(type) || defColor;
}
}
if (apply) {
this.svgCanvas.setColor(type, this._paintColor, true);
this.svgCanvas.setPaintOpacity(type, this._paintOpacity, true);
}
this._paintOpacity *= 100;
const paint = this.getPaint(this._paintColor, this._paintOpacity, type);
// update the rect inside #fill_color/#stroke_color
this.setPaint(paint);
}
/**
* @returns {void}
*/
prep () {
const ptype = this.paint.type;
switch (ptype) {
case 'linearGradient':
case 'radialGradient': {
const paint = new $.jGraduate.Paint({copy: this.paint});
this.svgCanvas.setPaint(this.type, paint);
break;
}
}
}
}
PaintBox.ctr = 0;
export default PaintBox;

View File

@@ -7,3 +7,4 @@ import './seSpinInput.js';
import './sePalette.js';
import './seMenu.js';
import './seMenuItem.js';
import './seColorPicker.js';

View File

@@ -0,0 +1,146 @@
/* globals jQuery */
import jQueryPluginJGraduate from '../jgraduate/jQuery.jGraduate.js';
import jQueryPluginJPicker from '../jgraduate/jQuery.jPicker.js';
import PaintBox from './PaintBox.js';
const $ = [
jQueryPluginJGraduate,
jQueryPluginJPicker
].reduce((jq, func) => func(jq), jQuery);
const template = document.createElement('template');
template.innerHTML = `
<style>
</style>
<div id="picker">
<img src="./images/logo.svg" alt="icon">
<label for="color" title="Change xxx color"></label>
<div class="block">
<div id="bg"></div>
<div id="color" class="block"></div>
</div>
</div>
<!-- hidden div -->
<div id="color_picker"></div>
`;
/**
* @class SeMenuItem
*/
export class SeColorPicker extends HTMLElement {
/**
* @function constructor
*/
constructor () {
super();
// create the shadowDom and insert the template
this._shadowRoot = this.attachShadow({mode: 'open'});
this._shadowRoot.appendChild(template.content.cloneNode(true));
this.$img = this._shadowRoot.querySelector('img');
this.$label = this._shadowRoot.querySelector('label');
this.$picker = this._shadowRoot.getElementById('picker');
this.paintBox = null;
}
/**
* @function observedAttributes
* @returns {any} observed
*/
static get observedAttributes () {
return ['label', 'src', 'value', 'picker'];
}
/**
* @function attributeChangedCallback
* @param {string} name
* @param {string} oldValue
* @param {string} newValue
* @returns {void}
*/
attributeChangedCallback (name, oldValue, newValue) {
if (oldValue === newValue) return;
switch (name) {
case 'src':
this.$img.setAttribute('src', newValue);
break;
case 'label':
this.$label.setAttribute('title', newValue);
break;
default:
// eslint-disable-next-line no-console
console.error(`unknown attribute: ${name}`);
break;
}
}
/**
* @function get
* @returns {any}
*/
get label () {
return this.getAttribute('label');
}
/**
* @function set
* @returns {void}
*/
set label (value) {
this.setAttribute('label', value);
}
/**
* @function get
* @returns {any}
*/
get src () {
return this.getAttribute('src');
}
/**
* @function set
* @returns {void}
*/
set src (value) {
this.setAttribute('src', value);
}
/**
* @param {PlainObject} selectedElement
* @param {bool} apply
* @returns {void}
*/
update (selectedElement, apply) {
this.paintBox.update(selectedElement, apply);
}
/**
* @function connectedCallback
* @returns {void}
*/
connectedCallback () {
this.paintBox = new PaintBox(this, this.type);
let {paint} = this.paintBox;
$('#color_picker')
.draggable({
cancel: '.jGraduate_tabs, .jGraduate_colPick, .jGraduate_gradPick, .jPicker',
containment: 'window'
})
.jGraduate(
{
images: {clientPath: './jgraduate/images/'},
paint,
window: {pickerTitle: this.label},
// images: {clientPath: configObj.curConfig.imgPath},
newstop: 'inverse'
},
function (p) {
paint = new $.jGraduate.Paint(p);
this.paintBox.setPaint(paint);
this.svgCanvas.setPaint(this.picker, paint);
$('#color_picker').hide();
},
() => {
$('#color_picker').hide();
}
);
}
}
// Register
customElements.define('se-colorpicker', SeColorPicker);