Skip to content

Commit 4134cb1

Browse files
committed
Support transparent.
1 parent 2c5a2ad commit 4134cb1

File tree

4 files changed

+150
-31
lines changed

4 files changed

+150
-31
lines changed

src/pg/inputPixelEditor/README.md

Lines changed: 102 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,37 +15,117 @@ import { PgInputPixelEditor } from '@pictogrammers/components/pgInputPixelEditor
1515

1616
| Attributes | Tested | Description |
1717
| ----------- | -------- | ----------- |
18-
| name | | Unique name in `pg-form` |
19-
| width | | Pixel width. Default `10` |
20-
| height | | Pixel height. Default `10` |
21-
| size | | Pixel size, minimum value `4`. Default `10` |
22-
| gridSize | | Grid spacing between cells. Default `1` |
18+
| `name` | | Unique name in `pg-form` |
19+
| `width` | | Pixel width. Default `10` |
20+
| `height` | | Pixel height. Default `10` |
21+
| `size` | | Pixel size, minimum value `4`. Default `10` |
22+
| `gridSize` | | Grid spacing between cells. Default `1` |
2323

2424
## Events
2525

2626
| Events | Tested | Description |
2727
| ---------- | -------- | ----------- |
28-
| change | | `{ detail: { value }` |
29-
| input | | `{ detail: { value }` |
28+
| `change` | | `{ detail: { value }` |
29+
| `input` | | `{ detail: { value }` |
3030

3131
## Methods
3232

3333
See usage for each method below.
3434

3535
| Method | Tested | Description |
3636
| ---------- | -------- | ----------- |
37-
| `save(callback, options)` | - | Save file. |
38-
| `open(file, callback)` | - | Open file. |
39-
| undo() | - | Undo. |
40-
| hasUndo() | - | Has undo |
41-
| hasRedo() | - | Has redo |
42-
| redo() | - | Redo. |
43-
| selectLayer() | - | |
44-
| getLayers() | - | Get layer array. |
45-
| addLayer(option) | - | Add layer. |
46-
| removeLayer(index) | - | Remove layer. |
47-
| rotateClockwise() | - | Rotate. |
48-
| rotateCounterclockwise() | - | Rotate. |
49-
| move(x, y[, layer]) | - | Move canvas. |
50-
| flipHorizontal() |
51-
| flipVertical() |
37+
| `save(options)` | - | Save file. |
38+
| `open(json)` | - | Open file. |
39+
| `undo()` | - | Undo. |
40+
| `hasUndo()` | - | Has undo |
41+
| `hasRedo()` | - | Has redo |
42+
| `redo()` | - | Redo. |
43+
| `selectLayer()` | - | Select layer. |
44+
| `getLayers()` | - | Get layer array. |
45+
| `addLayer(option)` | - | Add layer. |
46+
| `removeLayer(index)` | - | Remove layer. |
47+
| `moveLayer(startIndex, endIndex)` | - | Move layer. |
48+
| `getColors()` | - | Get colors. |
49+
| `addColor(r, g, b, a)` | - | Add color. |
50+
| `removeColor(index)` | - | Remove color. |
51+
| `moveColor(startIndex, endIndex)` | - | Move index. |
52+
| `rotateClockwise()` | - | Rotate. |
53+
| `rotateCounterclockwise()` | - | Rotate. |
54+
| `move(x, y[, layer])` | - | Move. |
55+
| `flipHorizontal()` | - | Flip horizontal. |
56+
| `flipVertical()` | - | Flip vertical. |
57+
| `invert()` | - | Invert layer. |
58+
59+
### `save(options)` Method
60+
61+
The save method allows getting the JSON representation of the current editor.
62+
63+
```typescript
64+
@Part() $editor: PgInputPixelEditor;
65+
66+
handleSave() {
67+
const json = await this.$editor.save({
68+
// Include history
69+
history: true,
70+
});
71+
// use json
72+
}
73+
```
74+
75+
### `open(json)` Method
76+
77+
The open method allows loading json for previously created images.
78+
79+
```typescript
80+
@Part() $editor: PgInputPixelEditor;
81+
82+
handleOpen() {
83+
const error = await this.$editor.open(json);
84+
if (error) {
85+
throw new Error(error.message);
86+
}
87+
}
88+
```
89+
90+
## JSON Format
91+
92+
- `width` - Image width.
93+
- `height` - Image width.
94+
- `transparent` - Render transparent background.
95+
96+
A complete JSON storage for a 10x10 image.
97+
98+
```json
99+
{
100+
"width": 10,
101+
"height": 10,
102+
"transparent": true,
103+
"colors": [
104+
[0, 0, 0, 0],
105+
[0, 0, 0, 1]
106+
],
107+
"layers": [
108+
{
109+
"name": "Layer 1",
110+
"export": true,
111+
"locked": false,
112+
"visible": true,
113+
"opacity": 1
114+
}
115+
],
116+
"data": [
117+
[
118+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
119+
[0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
120+
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
121+
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
122+
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
123+
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
124+
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
125+
[0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
126+
[0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
127+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
128+
]
129+
]
130+
}
131+
```

src/pg/inputPixelEditor/__examples__/basic/basic.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export default class XPgInputPixelEditorBasic extends HTMLElement {
1818
@Part() $width: HTMLInputElement;
1919
@Part() $height: HTMLInputElement;
2020
@Part() $size: HTMLInputElement;
21+
@Part() $transparent: HTMLInputElement;
2122

2223
@Part() $reset: HTMLButtonElement;
2324
@Part() $clear: HTMLButtonElement;
@@ -36,6 +37,7 @@ export default class XPgInputPixelEditorBasic extends HTMLElement {
3637
this.$width.addEventListener('input', this.handleWidthChange.bind(this));
3738
this.$height.addEventListener('input', this.handleHeightChange.bind(this));
3839
this.$size.addEventListener('input', this.handleSizeChange.bind(this));
40+
this.$transparent.addEventListener('input', this.handleTransparentChange.bind(this));
3941
this.$input.addEventListener('input', this.handleInput.bind(this));
4042
this.$input.addEventListener('debug', this.handleDebug.bind(this));
4143
this.$modePixel.addEventListener('click', () => {
@@ -99,4 +101,8 @@ export default class XPgInputPixelEditorBasic extends HTMLElement {
99101
this.$input.size = e.target.value;
100102
this.$debug.innerHTML = '';
101103
}
104+
105+
handleTransparentChange(e) {
106+
this.$input.transparent = e.target.checked;
107+
}
102108
}

src/pg/inputPixelEditor/inputPixelEditor.ts

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,25 @@ export default class PgInputPixelEditor extends HTMLElement {
152152
if (changes.width || changes.height || changes.size) {
153153
this.#init();
154154
}
155+
if (changes.transparent) {
156+
const totalSize = this.size + this.gridSize;
157+
const actualWidth = this.width * totalSize - this.gridSize;
158+
const actualHeight = this.height * totalSize - this.gridSize;
159+
if (this.transparent) {
160+
for (let y = 0; y < this.height; y++) {
161+
for (let x = 0; x < this.width; x++) {
162+
this.#baseLayerContext.fillStyle = WHITE;
163+
this.#baseLayerContext.fillRect(x * totalSize, y * totalSize, this.size + 1, this.size + 1);
164+
this.#baseLayerContext.fillStyle = '#DDD';
165+
this.#baseLayerContext.fillRect(x * totalSize + 5, y * totalSize, 5, 5);
166+
this.#baseLayerContext.fillRect(x * totalSize, y * totalSize + 5, 5, 5);
167+
}
168+
}
169+
} else {
170+
this.#baseLayerContext.clearRect(0, 0, actualWidth, actualHeight);
171+
}
172+
this.#updateGrid();
173+
}
155174
}
156175

157176
#reset = true;
@@ -247,14 +266,6 @@ export default class PgInputPixelEditor extends HTMLElement {
247266
// No Edit Layer
248267
this.#noEditLayerContext.fillStyle = this.#colors[color] === 'transparent' ? WHITE : this.#colors[color];
249268
this.#noEditLayerContext.fillRect(x * totalSize, y * totalSize, this.size, this.size);
250-
// Update pixel grid
251-
/*if (!props.disableTransparency && colors[color] === 'transparent') {
252-
pixelContext.fillStyle = '#DDD';
253-
pixelContext.fillRect(x * totalSize + 1, y * totalSize + 1, size, size);
254-
pixelContext.fillStyle = WHITE;
255-
pixelContext.fillRect(x * totalSize + 1, y * totalSize + 1, 5, 5);
256-
pixelContext.fillRect(x * totalSize + 6, y * totalSize + 6, 5, 5);
257-
} else {*/
258269
// base layer to main canvas
259270
this.#context.drawImage(
260271
this.#baseLayer,
@@ -341,7 +352,7 @@ export default class PgInputPixelEditor extends HTMLElement {
341352

342353
handleKeyDown(event: KeyboardEvent) {
343354
console.log(event.shiftKey, event.ctrlKey, event.altKey, event.key);
344-
switch(event.key) {
355+
switch (event.key) {
345356
case ' ':
346357
console.log('space');
347358
break;
@@ -622,6 +633,7 @@ export default class PgInputPixelEditor extends HTMLElement {
622633
});
623634
this.#data[this.#layer] = cloned;
624635
}
636+
625637
invert() {
626638
// Only works with 2 colors
627639
if (this.#colors.length > 2) {
@@ -640,6 +652,7 @@ export default class PgInputPixelEditor extends HTMLElement {
640652
clearGuides() {
641653

642654
}
655+
643656
undo() {
644657
// ToDo: Rewrite to use new history api
645658
const revert = this.#undoHistory.pop();
@@ -655,6 +668,7 @@ export default class PgInputPixelEditor extends HTMLElement {
655668
break;
656669
}
657670
}
671+
658672
redo() {
659673
// ToDo: Rewrite to use new history api
660674
/*const revert = this.#redoHistory.pop();
@@ -694,27 +708,35 @@ export default class PgInputPixelEditor extends HTMLElement {
694708
}
695709
this.#data[this.#layer] = cloned;
696710
}
711+
697712
hasUndo() {
698713
return this.#undoHistory.length !== 0;
699714
}
715+
700716
hasRedo() {
701717
return this.#redoHistory.length !== 0;
702718
}
719+
703720
inputModePixel() {
704721
this.#inputMode = InputMode.Pixel;
705722
}
723+
706724
inputModeLine() {
707725
this.#inputMode = InputMode.Line;
708726
}
727+
709728
inputModeRectangle() {
710729
this.#inputMode = InputMode.Rectangle;
711730
}
731+
712732
inputModeRectangleOutline() {
713733
this.#inputMode = InputMode.RectangleOutline;
714734
}
735+
715736
inputModeEllipse() {
716737
this.#inputMode = InputMode.Ellipse;
717738
}
739+
718740
inputModeEllipseOutline() {
719741
this.#inputMode = InputMode.EllipseOutline;
720742
}

src/pg/markdown/markdown.css

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,17 @@ table code {
221221
transform: translateY(-1px);
222222
}
223223

224+
h1 > code,
225+
h2 > code,
226+
h3 > code,
227+
h4 > code,
228+
h5 > code {
229+
border: 1px solid #DDD;
230+
padding: 0.25rem 0.5rem;
231+
border-radius: 0.5rem;
232+
background: #F1F1F1;
233+
}
234+
224235
p > svg.icon,
225236
blockquote > svg.icon,
226237
p > a.icon > svg.icon,

0 commit comments

Comments
 (0)