@pictogrammers/components 0.4.8 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/pg/annoy/annoy.css +1 -1
- package/pg/button/button.css +5 -4
- package/pg/buttonLink/buttonLink.css +1 -1
- package/pg/buttonMenu/__examples__/basic/basic.ts +2 -2
- package/pg/buttonMenu/buttonMenu.ts +4 -1
- package/pg/cardUser/cardUser.css +1 -1
- package/pg/database/__examples__/basic/basic.ts +0 -1
- package/pg/grid/__examples__/basic/basic.ts +1 -4
- package/pg/grid/grid.css +1 -1
- package/pg/header/header.css +1 -1
- package/pg/icon/__examples__/basic/basic.ts +1 -1
- package/pg/inputCheck/__examples__/basic/basic.ts +1 -1
- package/pg/inputCheck/inputCheck.css +5 -0
- package/pg/inputCheck/inputCheck.ts +4 -0
- package/pg/inputCheckList/__examples__/basic/basic.ts +1 -1
- package/pg/inputFileLocal/inputFileLocal.css +1 -1
- package/pg/inputNumber/README.md +27 -0
- package/pg/inputNumber/__examples__/basic/basic.html +9 -0
- package/pg/inputNumber/__examples__/basic/basic.ts +30 -0
- package/pg/inputNumber/inputNumber.css +34 -0
- package/pg/inputNumber/inputNumber.html +1 -0
- package/pg/inputNumber/inputNumber.spec.ts +59 -0
- package/pg/inputNumber/inputNumber.ts +63 -0
- package/pg/inputPixelEditor/README.md +211 -29
- package/pg/inputPixelEditor/__examples__/basic/basic.css +8 -0
- package/pg/inputPixelEditor/__examples__/basic/basic.html +29 -7
- package/pg/inputPixelEditor/__examples__/basic/basic.ts +274 -13
- package/pg/inputPixelEditor/__examples__/basic/constants.ts +62 -0
- package/pg/inputPixelEditor/inputPixelEditor.css +37 -2
- package/pg/inputPixelEditor/inputPixelEditor.html +22 -0
- package/pg/inputPixelEditor/inputPixelEditor.ts +822 -82
- package/pg/inputPixelEditor/utils/bitmapToMask.ts +22 -8
- package/pg/inputPixelEditor/utils/blobToImage.ts +11 -0
- package/pg/inputPixelEditor/utils/canvasToPngBuffer.ts +12 -0
- package/pg/inputPixelEditor/utils/constants.ts +55 -1
- package/pg/inputPixelEditor/utils/crc32.ts +116 -0
- package/pg/inputPixelEditor/utils/diffMap.ts +32 -0
- package/pg/inputPixelEditor/utils/generateGradient.ts +112 -0
- package/pg/inputPixelEditor/utils/getEllipsePixels.ts +131 -19
- package/pg/inputPixelEditor/utils/getFloodFill.ts +83 -0
- package/pg/inputPixelEditor/utils/getGridColorIndexes.ts +13 -0
- package/pg/inputPixelEditor/utils/getOutline.ts +92 -0
- package/pg/inputPixelEditor/utils/inputMode.ts +7 -1
- package/pg/inputPixelEditor/utils/pixelSizes.ts +47 -0
- package/pg/inputPixelEditor/utils/pngMetadata.ts +487 -0
- package/pg/inputSelect/inputSelect.css +4 -4
- package/pg/inputText/inputText.css +14 -7
- package/pg/inputText/inputText.ts +5 -1
- package/pg/json/README.md +59 -0
- package/pg/json/__examples__/basic/basic.html +4 -0
- package/pg/json/__examples__/basic/basic.ts +31 -0
- package/pg/json/json.css +9 -0
- package/pg/json/json.html +1 -0
- package/pg/json/json.ts +124 -0
- package/pg/jsonArray/README.md +3 -0
- package/pg/jsonArray/jsonArray.css +15 -0
- package/pg/jsonArray/jsonArray.html +7 -0
- package/pg/jsonArray/jsonArray.ts +55 -0
- package/pg/jsonBoolean/README.md +3 -0
- package/pg/jsonBoolean/jsonBoolean.css +27 -0
- package/pg/jsonBoolean/jsonBoolean.html +5 -0
- package/pg/jsonBoolean/jsonBoolean.ts +69 -0
- package/pg/jsonNumber/README.md +3 -0
- package/pg/jsonNumber/jsonNumber.css +21 -0
- package/pg/jsonNumber/jsonNumber.html +5 -0
- package/pg/jsonNumber/jsonNumber.ts +42 -0
- package/pg/jsonObject/README.md +3 -0
- package/pg/jsonObject/jsonObject.css +11 -0
- package/pg/jsonObject/jsonObject.html +5 -0
- package/pg/jsonObject/jsonObject.ts +55 -0
- package/pg/jsonString/README.md +3 -0
- package/pg/jsonString/jsonString.css +21 -0
- package/pg/jsonString/jsonString.html +5 -0
- package/pg/jsonString/jsonString.ts +42 -0
- package/pg/menu/menu.ts +6 -5
- package/pg/menuItem/README.md +13 -2
- package/pg/menuItem/menuItem.css +17 -22
- package/pg/menuItem/menuItem.ts +8 -3
- package/pg/menuItemIcon/__examples__/basic/basic.html +1 -1
- package/pg/menuItemIcon/__examples__/basic/basic.ts +7 -0
- package/pg/menuItemIcon/menuItemIcon.css +18 -15
- package/pg/menuItemIcon/menuItemIcon.ts +8 -4
- package/pg/modal/README.md +29 -0
- package/pg/modal/__examples__/basic/basic.html +4 -0
- package/pg/modal/__examples__/basic/basic.ts +42 -0
- package/pg/modal/index.ts +3 -0
- package/pg/modal/modal.css +40 -0
- package/pg/modal/modal.html +9 -0
- package/pg/modal/modal.ts +14 -0
- package/pg/modification/__examples__/basic/basic.ts +1 -1
- package/pg/overlayMenu/overlayMenu.ts +6 -2
- package/pg/overlaySelectMenu/overlaySelectMenu.ts +6 -0
- package/pg/overlaySubMenu/overlaySubMenu.ts +6 -2
- package/pg/scroll/__examples__/basic/basic.ts +1 -1
- package/pg/search/search.css +1 -1
- package/pg/table/README.md +108 -0
- package/pg/table/__examples__/basic/basic.css +0 -0
- package/pg/table/__examples__/basic/basic.html +10 -0
- package/pg/table/__examples__/basic/basic.ts +111 -0
- package/pg/table/table.css +20 -0
- package/pg/table/table.html +6 -0
- package/pg/table/table.ts +86 -0
- package/pg/tableCellButtonIcon/README.md +3 -0
- package/pg/tableCellButtonIcon/tableCellButtonIcon.css +16 -0
- package/pg/tableCellButtonIcon/tableCellButtonIcon.html +5 -0
- package/pg/tableCellButtonIcon/tableCellButtonIcon.ts +34 -0
- package/pg/tableCellCheck/README.md +3 -0
- package/pg/tableCellCheck/tableCellCheck.css +15 -0
- package/pg/tableCellCheck/tableCellCheck.html +3 -0
- package/pg/tableCellCheck/tableCellCheck.ts +43 -0
- package/pg/tableCellNumber/README.md +3 -0
- package/pg/tableCellNumber/tableCellNumber.css +11 -0
- package/pg/tableCellNumber/tableCellNumber.html +3 -0
- package/pg/tableCellNumber/tableCellNumber.ts +40 -0
- package/pg/tableCellText/README.md +3 -0
- package/pg/tableCellText/tableCellText.css +11 -0
- package/pg/tableCellText/tableCellText.html +3 -0
- package/pg/tableCellText/tableCellText.ts +62 -0
- package/pg/tableColumn/README.md +3 -0
- package/pg/tableColumn/tableColumn.css +12 -0
- package/pg/tableColumn/tableColumn.html +1 -0
- package/pg/tableColumn/tableColumn.ts +29 -0
- package/pg/tableRow/README.md +3 -0
- package/pg/tableRow/tableRow.css +11 -0
- package/pg/tableRow/tableRow.html +1 -0
- package/pg/tableRow/tableRow.ts +77 -0
- package/pg/tabs/tabs.css +1 -1
- package/pg/tree/README.md +10 -4
- package/pg/tree/__examples__/basic/basic.html +1 -0
- package/pg/tree/__examples__/basic/basic.ts +6 -1
- package/pg/tree/tree.css +1 -0
- package/pg/treeItem/treeItem.css +3 -3
- package/favicon.svg +0 -20
- package/index.html +0 -321
- package/main.js +0 -2
- package/main.js.LICENSE.txt +0 -10
- package/pgAnnoy.js +0 -1
- package/pgApp.js +0 -1
- package/pgAvatar.js +0 -1
- package/pgButton.js +0 -1
- package/pgButtonGroup.js +0 -1
- package/pgButtonLink.js +0 -1
- package/pgButtonMenu.js +0 -1
- package/pgButtonToggle.js +0 -1
- package/pgCard.js +0 -1
- package/pgCardUser.js +0 -1
- package/pgColor.js +0 -1
- package/pgDatabase.js +0 -1
- package/pgDropdown.js +0 -1
- package/pgGrid.js +0 -1
- package/pgHeader.js +0 -1
- package/pgIcon.js +0 -1
- package/pgInputCheck.js +0 -1
- package/pgInputCheckList.js +0 -1
- package/pgInputFileLocal.js +0 -1
- package/pgInputHexRgb.js +0 -1
- package/pgInputPixelEditor.js +0 -1
- package/pgInputRange.js +0 -1
- package/pgInputSelect.js +0 -1
- package/pgInputText.js +0 -1
- package/pgInputTextIcon.js +0 -1
- package/pgInputUserSelect.js +0 -1
- package/pgListTag.js +0 -1
- package/pgMarkdown.js +0 -2
- package/pgMarkdown.js.LICENSE.txt +0 -10
- package/pgMenu.js +0 -1
- package/pgMenuDivider.js +0 -1
- package/pgMenuIcon.js +0 -1
- package/pgMenuItem.js +0 -1
- package/pgMenuItemIcon.js +0 -1
- package/pgModalAlert.js +0 -1
- package/pgModification.js +0 -1
- package/pgNav.js +0 -1
- package/pgOverlay.js +0 -1
- package/pgOverlayContextMenu.js +0 -1
- package/pgOverlayMenu.js +0 -1
- package/pgOverlaySelectMenu.js +0 -1
- package/pgOverlaySubMenu.js +0 -1
- package/pgPicker.js +0 -1
- package/pgPreview.js +0 -1
- package/pgScroll.js +0 -1
- package/pgSearch.js +0 -1
- package/pgTab.js +0 -1
- package/pgTabs.js +0 -1
- package/pgToast.js +0 -1
- package/pgToasts.js +0 -1
- package/pgTooltip.js +0 -1
- package/pgTree.js +0 -1
- package/pgTreeButtonIcon.js +0 -1
- package/pgTreeItem.js +0 -1
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { Component, Part } from '@pictogrammers/element';
|
|
2
2
|
import PgInputPixelEditor from '../../inputPixelEditor';
|
|
3
|
+
import PgTable, { createTableItem } from '../../../table/table';
|
|
4
|
+
import PgTableCellButtonIcon from '../../../tableCellButtonIcon/tableCellButtonIcon';
|
|
3
5
|
import { maskToBitmap } from '../../utils/maskToBitmap';
|
|
6
|
+
import { fileOk, patterns } from './constants';
|
|
4
7
|
|
|
5
8
|
import template from './basic.html';
|
|
6
9
|
import style from './basic.css';
|
|
7
10
|
|
|
11
|
+
const IconPicker = 'M19.35,11.72L17.22,13.85L15.81,12.43L8.1,20.14L3.5,22L2,20.5L3.86,15.9L11.57,8.19L10.15,6.78L12.28,4.65L19.35,11.72M16.76,3C17.93,1.83 19.83,1.83 21,3C22.17,4.17 22.17,6.07 21,7.24L19.08,9.16L14.84,4.92L16.76,3M5.56,17.03L4.5,19.5L6.97,18.44L14.4,11L13,9.6L5.56,17.03Z';
|
|
12
|
+
const IconTrash = 'M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z';
|
|
13
|
+
const IconLayerEdit = 'M4.63 10.27L3 9L12 2L19.94 8.17L12.5 15.61L12 16L4.63 10.27M10 18.94V18.11L10.59 17.53L10.63 17.5L4.62 12.81L3 14.07L10 19.5V18.94M21.7 12.58L20.42 11.3C20.21 11.09 19.86 11.09 19.65 11.3L18.65 12.3L20.7 14.35L21.7 13.35C21.91 13.14 21.91 12.79 21.7 12.58M12 21H14.06L20.11 14.93L18.06 12.88L12 18.94V21Z';
|
|
14
|
+
|
|
8
15
|
@Component({
|
|
9
16
|
selector: 'x-pg-input-pixel-editor-basic',
|
|
10
17
|
style,
|
|
@@ -24,13 +31,26 @@ export default class XPgInputPixelEditorBasic extends HTMLElement {
|
|
|
24
31
|
@Part() $reset: HTMLButtonElement;
|
|
25
32
|
@Part() $clear: HTMLButtonElement;
|
|
26
33
|
@Part() $invert: HTMLButtonElement;
|
|
34
|
+
@Part() $outline: HTMLButtonElement;
|
|
35
|
+
@Part() $glow: HTMLButtonElement;
|
|
36
|
+
@Part() $modeStamp1: HTMLButtonElement;
|
|
37
|
+
@Part() $modeStamp2: HTMLButtonElement;
|
|
38
|
+
@Part() $modeStamp3: HTMLButtonElement;
|
|
39
|
+
@Part() $modeStamp4: HTMLButtonElement;
|
|
27
40
|
@Part() $modePixel: HTMLButtonElement;
|
|
28
41
|
@Part() $modeLine: HTMLButtonElement;
|
|
29
42
|
@Part() $modeRectangle: HTMLButtonElement;
|
|
30
43
|
@Part() $modeRectangleOutline: HTMLButtonElement;
|
|
31
44
|
@Part() $modeEllipse: HTMLButtonElement;
|
|
32
45
|
@Part() $modeEllipseOutline: HTMLButtonElement;
|
|
46
|
+
@Part() $cursor: HTMLButtonElement;
|
|
47
|
+
@Part() $selectRectangle: HTMLButtonElement;
|
|
48
|
+
@Part() $selectEllipse: HTMLButtonElement;
|
|
49
|
+
@Part() $selectLasso: HTMLButtonElement;
|
|
50
|
+
@Part() $selectMagic: HTMLButtonElement;
|
|
33
51
|
|
|
52
|
+
@Part() $undo: HTMLButtonElement;
|
|
53
|
+
@Part() $redo: HTMLButtonElement;
|
|
34
54
|
@Part() $save: HTMLButtonElement;
|
|
35
55
|
@Part() $open: HTMLButtonElement;
|
|
36
56
|
@Part() $output: HTMLPreElement;
|
|
@@ -38,9 +58,12 @@ export default class XPgInputPixelEditorBasic extends HTMLElement {
|
|
|
38
58
|
@Part() $saveSvg: HTMLInputElement;
|
|
39
59
|
@Part() $savePng: HTMLInputElement;
|
|
40
60
|
|
|
41
|
-
|
|
42
|
-
@Part() $
|
|
43
|
-
@Part() $
|
|
61
|
+
@Part() $addLayer: HTMLButtonElement;
|
|
62
|
+
@Part() $addLayerReference: HTMLButtonElement;
|
|
63
|
+
@Part() $addColor: HTMLButtonElement;
|
|
64
|
+
|
|
65
|
+
@Part() $colors: PgTable;
|
|
66
|
+
@Part() $layers: PgTable;
|
|
44
67
|
|
|
45
68
|
connectedCallback() {
|
|
46
69
|
this.$width.value = '10';
|
|
@@ -53,6 +76,19 @@ export default class XPgInputPixelEditorBasic extends HTMLElement {
|
|
|
53
76
|
this.$transparent.addEventListener('input', this.handleTransparentChange.bind(this));
|
|
54
77
|
this.$input.addEventListener('input', this.handleInput.bind(this));
|
|
55
78
|
this.$input.addEventListener('debug', this.handleDebug.bind(this));
|
|
79
|
+
this.$input.addEventListener('selectlayer', this.handleSelectLayer.bind(this));
|
|
80
|
+
this.$input.addEventListener('reference', this.handleReference.bind(this));
|
|
81
|
+
[
|
|
82
|
+
this.$modeStamp1,
|
|
83
|
+
this.$modeStamp2,
|
|
84
|
+
this.$modeStamp3,
|
|
85
|
+
this.$modeStamp4,
|
|
86
|
+
].forEach(($modeStamp) => {
|
|
87
|
+
$modeStamp.addEventListener('click', (e: any) => {
|
|
88
|
+
const stamp = e.target.dataset.stamp;
|
|
89
|
+
this.$input.inputModeStamp(patterns[stamp]);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
56
92
|
this.$modePixel.addEventListener('click', () => {
|
|
57
93
|
this.$input.inputModePixel();
|
|
58
94
|
});
|
|
@@ -71,6 +107,21 @@ export default class XPgInputPixelEditorBasic extends HTMLElement {
|
|
|
71
107
|
this.$modeEllipseOutline.addEventListener('click', () => {
|
|
72
108
|
this.$input.inputModeEllipseOutline();
|
|
73
109
|
});
|
|
110
|
+
this.$cursor.addEventListener('click', () => {
|
|
111
|
+
this.$input.inputModeCursor();
|
|
112
|
+
})
|
|
113
|
+
this.$selectRectangle.addEventListener('click', () => {
|
|
114
|
+
this.$input.inputModeSelectRectangle();
|
|
115
|
+
});
|
|
116
|
+
this.$selectEllipse.addEventListener('click', () => {
|
|
117
|
+
this.$input.inputModeSelectEllipse();
|
|
118
|
+
});
|
|
119
|
+
this.$selectLasso.addEventListener('click', () => {
|
|
120
|
+
this.$input.inputModeSelectLasso();
|
|
121
|
+
});
|
|
122
|
+
this.$selectMagic.addEventListener('click', () => {
|
|
123
|
+
this.$input.inputModeSelectMagicWand();
|
|
124
|
+
});
|
|
74
125
|
this.$reset.addEventListener('click', () => {
|
|
75
126
|
this.$input.reset();
|
|
76
127
|
});
|
|
@@ -80,13 +131,19 @@ export default class XPgInputPixelEditorBasic extends HTMLElement {
|
|
|
80
131
|
this.$invert.addEventListener('click', () => {
|
|
81
132
|
this.$input.invert();
|
|
82
133
|
});
|
|
134
|
+
this.$outline.addEventListener('click', () => {
|
|
135
|
+
this.$input.outline();
|
|
136
|
+
});
|
|
137
|
+
this.$glow.addEventListener('click', () => {
|
|
138
|
+
this.$input.glow();
|
|
139
|
+
});
|
|
83
140
|
this.$save.addEventListener('click', async () => {
|
|
84
|
-
const json = await this.$input.
|
|
141
|
+
const json = await this.$input.getJson();
|
|
85
142
|
this.$output.textContent = JSON.stringify(json, null, 4);
|
|
86
143
|
});
|
|
87
144
|
this.$open.addEventListener('click', () => {
|
|
88
145
|
const json = JSON.parse(this.$output.textContent || '');
|
|
89
|
-
this.$input.
|
|
146
|
+
this.$input.setJson(json as any);
|
|
90
147
|
});
|
|
91
148
|
this.$file.addEventListener('change', this.handleFile.bind(this));
|
|
92
149
|
this.$saveSvg.addEventListener('click', async () => {
|
|
@@ -96,7 +153,7 @@ export default class XPgInputPixelEditorBasic extends HTMLElement {
|
|
|
96
153
|
suggestedName: 'Canvas',
|
|
97
154
|
types: [{
|
|
98
155
|
description: 'SVG Document',
|
|
99
|
-
accept: {'image/svg+xml': ['.svg']},
|
|
156
|
+
accept: { 'image/svg+xml': ['.svg'] },
|
|
100
157
|
}],
|
|
101
158
|
});
|
|
102
159
|
const writable = await handle.createWritable();
|
|
@@ -114,18 +171,197 @@ export default class XPgInputPixelEditorBasic extends HTMLElement {
|
|
|
114
171
|
const handle = await window.showSaveFilePicker({
|
|
115
172
|
suggestedName: 'CanvasName',
|
|
116
173
|
types: [{
|
|
117
|
-
description: '
|
|
118
|
-
accept: {'image/
|
|
174
|
+
description: 'PNG Image',
|
|
175
|
+
accept: { 'image/png': ['.png'] },
|
|
119
176
|
}],
|
|
120
177
|
});
|
|
121
178
|
const writable = await handle.createWritable();
|
|
122
|
-
await
|
|
123
|
-
await writable.write
|
|
179
|
+
const image = await this.$input.getExportPng();
|
|
180
|
+
await writable.write(image);
|
|
124
181
|
await writable.close();
|
|
125
182
|
} catch (e: any) {
|
|
126
183
|
// no save
|
|
127
184
|
}
|
|
128
185
|
});
|
|
186
|
+
// Layers
|
|
187
|
+
this.$layers.columns = [{
|
|
188
|
+
label: 'Name',
|
|
189
|
+
key: 'name',
|
|
190
|
+
}, {
|
|
191
|
+
label: 'Type',
|
|
192
|
+
key: 'type',
|
|
193
|
+
}, {
|
|
194
|
+
label: 'Selected',
|
|
195
|
+
key: 'selected',
|
|
196
|
+
hideLabel: true,
|
|
197
|
+
}, {
|
|
198
|
+
label: 'Select',
|
|
199
|
+
key: 'select',
|
|
200
|
+
hideLabel: true,
|
|
201
|
+
}];
|
|
202
|
+
this.$layers.data = [
|
|
203
|
+
createTableItem({
|
|
204
|
+
name: 'Layer 1',
|
|
205
|
+
type: 'pixel',
|
|
206
|
+
selected: true,
|
|
207
|
+
select: {
|
|
208
|
+
type: PgTableCellButtonIcon,
|
|
209
|
+
icon: IconLayerEdit,
|
|
210
|
+
value: this.$layers.data.length,
|
|
211
|
+
}
|
|
212
|
+
})
|
|
213
|
+
];
|
|
214
|
+
this.$layers.addEventListener('action', (e: any) => {
|
|
215
|
+
const { getColumn, getRows, key, index } = e.detail;
|
|
216
|
+
switch (key) {
|
|
217
|
+
case 'select':
|
|
218
|
+
const selectedLayers: number[] = [];
|
|
219
|
+
getRows().forEach(({ getColumn, index: index2 }) => {
|
|
220
|
+
if (getColumn('selected').value) {
|
|
221
|
+
selectedLayers.push(index2);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
if (
|
|
225
|
+
selectedLayers.length === 1
|
|
226
|
+
&& selectedLayers[0] === index
|
|
227
|
+
) {
|
|
228
|
+
// ignore
|
|
229
|
+
} else {
|
|
230
|
+
const currentValue = getColumn('selected').value;
|
|
231
|
+
getColumn('selected').value = !currentValue;
|
|
232
|
+
if (currentValue) {
|
|
233
|
+
selectedLayers.splice(selectedLayers.findIndex(x => x === index), 1);
|
|
234
|
+
} else {
|
|
235
|
+
selectedLayers.push(index);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
console.log('selected', selectedLayers);
|
|
239
|
+
this.$input.selectLayers(selectedLayers);
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
this.$addLayer.addEventListener('click', () => {
|
|
244
|
+
this.$layers.data.push(
|
|
245
|
+
createTableItem({
|
|
246
|
+
name: 'Layer 2',
|
|
247
|
+
type: 'pixel',
|
|
248
|
+
selected: false,
|
|
249
|
+
select: {
|
|
250
|
+
type: PgTableCellButtonIcon,
|
|
251
|
+
icon: IconLayerEdit,
|
|
252
|
+
value: 1,
|
|
253
|
+
}
|
|
254
|
+
})
|
|
255
|
+
);
|
|
256
|
+
this.$input.addLayer();
|
|
257
|
+
});
|
|
258
|
+
this.$addLayerReference.addEventListener('click', () => {
|
|
259
|
+
this.$layers.data.push(
|
|
260
|
+
createTableItem({
|
|
261
|
+
name: 'Layer 2',
|
|
262
|
+
type: 'reference',
|
|
263
|
+
selected: false,
|
|
264
|
+
select: {
|
|
265
|
+
type: PgTableCellButtonIcon,
|
|
266
|
+
icon: IconLayerEdit,
|
|
267
|
+
value: 1,
|
|
268
|
+
}
|
|
269
|
+
})
|
|
270
|
+
);
|
|
271
|
+
this.$input.addLayer();
|
|
272
|
+
});
|
|
273
|
+
// Colors
|
|
274
|
+
this.$colors.columns = [{
|
|
275
|
+
label: 'Red',
|
|
276
|
+
key: 'r',
|
|
277
|
+
editable: true,
|
|
278
|
+
}, {
|
|
279
|
+
label: 'Green',
|
|
280
|
+
key: 'g',
|
|
281
|
+
editable: true,
|
|
282
|
+
}, {
|
|
283
|
+
label: 'Blue',
|
|
284
|
+
key: 'b',
|
|
285
|
+
editable: true,
|
|
286
|
+
}, {
|
|
287
|
+
label: 'Alpha',
|
|
288
|
+
key: 'a',
|
|
289
|
+
editable: true,
|
|
290
|
+
}, {
|
|
291
|
+
label: 'Selected',
|
|
292
|
+
key: 'selected',
|
|
293
|
+
hideLabel: true,
|
|
294
|
+
}, {
|
|
295
|
+
label: 'Select',
|
|
296
|
+
key: 'select',
|
|
297
|
+
hideLabel: true,
|
|
298
|
+
}, {
|
|
299
|
+
label: 'Delete',
|
|
300
|
+
key: 'delete',
|
|
301
|
+
hideLabel: true,
|
|
302
|
+
}];
|
|
303
|
+
this.$colors.data.push(...this.$input.getColors().map(([r, g, b, a], i) => {
|
|
304
|
+
return createTableItem({
|
|
305
|
+
r,
|
|
306
|
+
g,
|
|
307
|
+
b,
|
|
308
|
+
a,
|
|
309
|
+
selected: i === 1,
|
|
310
|
+
select: {
|
|
311
|
+
type: PgTableCellButtonIcon,
|
|
312
|
+
icon: IconPicker,
|
|
313
|
+
value: i,
|
|
314
|
+
},
|
|
315
|
+
delete: {
|
|
316
|
+
type: PgTableCellButtonIcon,
|
|
317
|
+
icon: IconTrash,
|
|
318
|
+
value: i,
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
}));
|
|
322
|
+
this.$colors.addEventListener('action', (e: any) => {
|
|
323
|
+
const { getColumn, getRows, key, value, index } = e.detail;
|
|
324
|
+
const [r, g, b, a] = this.$input.getColor(index);
|
|
325
|
+
switch (key) {
|
|
326
|
+
case 'select':
|
|
327
|
+
getRows().forEach(({ getColumn }) => {
|
|
328
|
+
getColumn('selected').value = false;
|
|
329
|
+
});
|
|
330
|
+
getColumn('selected').value = true;
|
|
331
|
+
this.$input.selectColor(getColumn('select').value);
|
|
332
|
+
break;
|
|
333
|
+
case 'r':
|
|
334
|
+
this.$input.setColor(index, value, g, b, a);
|
|
335
|
+
break;
|
|
336
|
+
case 'g':
|
|
337
|
+
this.$input.setColor(index, r, value, b, a);
|
|
338
|
+
break;
|
|
339
|
+
case 'b':
|
|
340
|
+
this.$input.setColor(index, r, g, value, a);
|
|
341
|
+
break;
|
|
342
|
+
case 'a':
|
|
343
|
+
this.$input.setColor(index, r, g, b, value);
|
|
344
|
+
break;
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
this.$addColor.addEventListener('click', () => {
|
|
348
|
+
this.$colors.data.push(createTableItem({
|
|
349
|
+
r: 5,
|
|
350
|
+
g: 5,
|
|
351
|
+
b: 5,
|
|
352
|
+
a: 1,
|
|
353
|
+
selected: false,
|
|
354
|
+
select: {
|
|
355
|
+
type: PgTableCellButtonIcon,
|
|
356
|
+
icon: IconPicker,
|
|
357
|
+
value: this.$colors.data.length,
|
|
358
|
+
},
|
|
359
|
+
delete: {
|
|
360
|
+
type: PgTableCellButtonIcon,
|
|
361
|
+
icon: IconTrash
|
|
362
|
+
}
|
|
363
|
+
}));
|
|
364
|
+
});
|
|
129
365
|
}
|
|
130
366
|
|
|
131
367
|
handleFile(e) {
|
|
@@ -133,7 +369,7 @@ export default class XPgInputPixelEditorBasic extends HTMLElement {
|
|
|
133
369
|
if (files.length !== 1) {
|
|
134
370
|
throw new Error('select only 1 file');
|
|
135
371
|
}
|
|
136
|
-
switch(files[0].type) {
|
|
372
|
+
switch (files[0].type) {
|
|
137
373
|
case 'image/svg+xml':
|
|
138
374
|
// Read the file
|
|
139
375
|
const reader = new FileReader();
|
|
@@ -159,8 +395,9 @@ export default class XPgInputPixelEditorBasic extends HTMLElement {
|
|
|
159
395
|
}
|
|
160
396
|
|
|
161
397
|
handleChange(e: CustomEvent) {
|
|
162
|
-
|
|
163
|
-
|
|
398
|
+
this.$value1.textContent = this.$input.getLayerPaths().map((layer) => {
|
|
399
|
+
return layer.map(x => x.join('=')).join(';');
|
|
400
|
+
}).join('\n');
|
|
164
401
|
}
|
|
165
402
|
|
|
166
403
|
handleInput(e: CustomEvent) {
|
|
@@ -179,6 +416,30 @@ export default class XPgInputPixelEditorBasic extends HTMLElement {
|
|
|
179
416
|
//context.strokeRect(x, y, width, height);
|
|
180
417
|
}
|
|
181
418
|
|
|
419
|
+
handleSelectLayer(e: CustomEvent) {
|
|
420
|
+
const { color, index } = e.detail;
|
|
421
|
+
if (index !== null) {
|
|
422
|
+
// Update Table
|
|
423
|
+
this.$layers.data.forEach((layer) => {
|
|
424
|
+
layer.items.find(column => column.key === 'selected').value = false;
|
|
425
|
+
});
|
|
426
|
+
this.$layers.data[index].items.find(column => column.key === 'selected').value = true;
|
|
427
|
+
// Update input
|
|
428
|
+
this.$input.selectLayers([index]);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
handleReference(e: any) {
|
|
433
|
+
const { id, callback } = e.detail;
|
|
434
|
+
// Test Data
|
|
435
|
+
const mock = new Map();
|
|
436
|
+
mock.set('9ee82807-ffa9-411c-abaf-7b8d46d74af4', fileOk);
|
|
437
|
+
if (mock.has(id)) {
|
|
438
|
+
callback(mock.get(id));
|
|
439
|
+
}
|
|
440
|
+
console.error('Unable to load', id);
|
|
441
|
+
}
|
|
442
|
+
|
|
182
443
|
handleWidthChange(e) {
|
|
183
444
|
this.$input.width = e.target.value;
|
|
184
445
|
this.$debug.innerHTML = '';
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export const patterns = {
|
|
2
|
+
'1': [
|
|
3
|
+
[0, 0]
|
|
4
|
+
],
|
|
5
|
+
'3-circle': [
|
|
6
|
+
[0, -1],
|
|
7
|
+
[-1, 0],
|
|
8
|
+
[0, 0],
|
|
9
|
+
[1, 0],
|
|
10
|
+
[0, 1]
|
|
11
|
+
],
|
|
12
|
+
'3-square': [
|
|
13
|
+
[-1, -1],
|
|
14
|
+
[0, -1],
|
|
15
|
+
[1, -1],
|
|
16
|
+
[-1, 0],
|
|
17
|
+
[0, 0],
|
|
18
|
+
[1, 0],
|
|
19
|
+
[-1, 1],
|
|
20
|
+
[0, 1],
|
|
21
|
+
[1, 1],
|
|
22
|
+
],
|
|
23
|
+
'heart': [
|
|
24
|
+
[-1, -1],
|
|
25
|
+
[1, -1],
|
|
26
|
+
[-2, 0],
|
|
27
|
+
[-1, 0],
|
|
28
|
+
[0, 0],
|
|
29
|
+
[1, 0],
|
|
30
|
+
[2, 0],
|
|
31
|
+
[-1, 1],
|
|
32
|
+
[0, 1],
|
|
33
|
+
[1, 1],
|
|
34
|
+
[0, 2],
|
|
35
|
+
]
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const fileOk = {
|
|
39
|
+
"id": "9ee82807-ffa9-411c-abaf-7b8d46d74af4",
|
|
40
|
+
"width": 9,
|
|
41
|
+
"height": 6,
|
|
42
|
+
"transparent": null,
|
|
43
|
+
"colors": [
|
|
44
|
+
[0, 0, 0, 0],
|
|
45
|
+
[0, 0, 0, 1]
|
|
46
|
+
],
|
|
47
|
+
"layers": [
|
|
48
|
+
{
|
|
49
|
+
"name": "Ok",
|
|
50
|
+
"exclude": false,
|
|
51
|
+
"locked": false,
|
|
52
|
+
"hidden": false,
|
|
53
|
+
"type": "pixel",
|
|
54
|
+
"opacity": 1
|
|
55
|
+
}
|
|
56
|
+
],
|
|
57
|
+
"data": [
|
|
58
|
+
[
|
|
59
|
+
[1, "M2,4H3V2H2ZM3,5H2V4H1V2H2V1H3V2H4V4H3ZM8,5H7V4H6V5H5V1H6V3H7V2H8V3H7V4H8Z"]
|
|
60
|
+
]
|
|
61
|
+
]
|
|
62
|
+
};
|
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
}
|
|
4
4
|
|
|
5
5
|
[part="wrapper"] {
|
|
6
|
-
display:
|
|
6
|
+
display: grid;
|
|
7
|
+
grid-template-columns: auto;
|
|
8
|
+
grid-template-rows: auto;
|
|
7
9
|
position: relative;
|
|
8
10
|
outline: 0;
|
|
9
11
|
}
|
|
10
12
|
|
|
11
|
-
[part="wrapper"]:focus-visible::before {
|
|
13
|
+
[part="wrapper"]:not(.ignore):focus-visible::before {
|
|
12
14
|
pointer-events: none;
|
|
13
15
|
content: '';
|
|
14
16
|
position: absolute;
|
|
@@ -21,7 +23,40 @@
|
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
canvas {
|
|
26
|
+
grid-column: 1;
|
|
27
|
+
grid-row: 1;
|
|
24
28
|
touch-action: none;
|
|
25
29
|
user-select: none;
|
|
26
30
|
outline: 0;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
svg {
|
|
34
|
+
pointer-events: none;
|
|
35
|
+
grid-column: 1;
|
|
36
|
+
grid-row: 1;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
path {
|
|
40
|
+
fill: none;
|
|
41
|
+
stroke: #000;
|
|
42
|
+
stroke-width: 1px;
|
|
43
|
+
vector-effect: non-scaling-stroke;
|
|
44
|
+
stroke-dasharray: 5px;
|
|
45
|
+
animation: stroke 0.4s linear infinite;
|
|
46
|
+
shape-rendering: geometricPrecision;
|
|
47
|
+
stroke-dashoffset: 10px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
path.preview {
|
|
51
|
+
stroke: rgb(0 96 255);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
path.hide {
|
|
55
|
+
display: none;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@keyframes stroke {
|
|
59
|
+
to {
|
|
60
|
+
stroke-dashoffset: 0;
|
|
61
|
+
}
|
|
27
62
|
}
|
|
@@ -1,3 +1,25 @@
|
|
|
1
1
|
<div part="wrapper" tabindex="0">
|
|
2
2
|
<canvas part="canvas" draggable="false"></canvas>
|
|
3
|
+
<svg part="selection" viewBox="0 0 10 10">
|
|
4
|
+
<defs>
|
|
5
|
+
<filter id="whiteOutline" x="-50%" y="-50%" width="200%" height="200%">
|
|
6
|
+
<!-- Thicken the source graphic (the original stroke path) -->
|
|
7
|
+
<feMorphology in="SourceGraphic" operator="dilate" radius="1" result="dilated" />
|
|
8
|
+
|
|
9
|
+
<!-- Flood the dilated shape with white color -->
|
|
10
|
+
<feFlood flood-color="white" result="flood" />
|
|
11
|
+
|
|
12
|
+
<!-- Composite the white color with the dilated shape to create the white outline shape -->
|
|
13
|
+
<feComposite in="flood" in2="dilated" operator="in" result="whiteOutlineShape" />
|
|
14
|
+
|
|
15
|
+
<!-- Merge the white outline shape with the original source graphic -->
|
|
16
|
+
<feMerge>
|
|
17
|
+
<feMergeNode in="whiteOutlineShape" />
|
|
18
|
+
<feMergeNode in="SourceGraphic" />
|
|
19
|
+
</feMerge>
|
|
20
|
+
</filter>
|
|
21
|
+
</defs>
|
|
22
|
+
<path part="selectionPath" class="hide" d="M9,7H1V1H9Z" filter="url(#whiteOutline)" />
|
|
23
|
+
<path part="selectionPathPreview" class="hide preview" d="M9,7H1V1H9Z" filter="url(#whiteOutline)" />
|
|
24
|
+
</svg>
|
|
3
25
|
</div>
|