Skip to content

Commit f25c34a

Browse files
committed
Preview pen.
1 parent f9b8820 commit f25c34a

File tree

2 files changed

+135
-0
lines changed

2 files changed

+135
-0
lines changed

src/pg/inputPixelEditor/inputPixelEditor.ts

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import bitmaskToPath from './utils/bitmapToMask';
1616
import createLayer from './utils/createLayer';
1717
import diffGrid from './utils/diffGrid';
1818
import { getGuides } from './utils/getGuides';
19+
import { pixelSizes } from './utils/pixelSizes';
1920

2021
type Pixel = { x: number, y: number };
2122

@@ -380,6 +381,64 @@ export default class PgInputPixelEditor extends HTMLElement {
380381
}));
381382
}
382383

384+
#setPenPreview(pixels: Pixel[], previousX: number, previousY: number) {
385+
const totalSize = this.size + this.gridSize;
386+
const actualWidth = this.width * totalSize - this.gridSize;
387+
const actualHeight = this.height * totalSize - this.gridSize;
388+
const { minX, maxX, minY, maxY } = pixels.reduce((previous, current) => {
389+
return {
390+
minX: Math.min(previous.minX, current.x, previousX),
391+
maxX: Math.max(previous.maxX, current.x, previousX),
392+
minY: Math.min(previous.minY, current.y, previousY),
393+
maxY: Math.max(previous.maxY, current.y, previousY)
394+
};
395+
}, { minX: this.width, maxX: 0, minY: this.height, maxY: 0 });
396+
const x = minX * totalSize;
397+
const y = minY * totalSize;
398+
const width = (maxX - minX + 1) * totalSize;
399+
const height = (maxY - minY + 1) * totalSize;
400+
this.#context.clearRect(x, y, width, height);
401+
// base layer to main canvas
402+
this.#context.drawImage(
403+
this.#baseLayer,
404+
x, y, width, height,
405+
x, y, width, height
406+
);
407+
// edit to main canvas
408+
this.#context.drawImage(
409+
this.#editLayer,
410+
x, y, width, height,
411+
x, y, width, height
412+
);
413+
// preview layer
414+
this.#previewLayerContext.clearRect(0, 0, actualWidth, actualHeight);
415+
pixels.forEach(({ x, y }) => {
416+
this.#previewLayerContext.fillStyle = '#1B79C8';
417+
this.#previewLayerContext.fillRect(x * totalSize + 2, y * totalSize + 2, this.size - 4, this.size - 4);
418+
});
419+
// preview layer to main canvas
420+
this.#context.drawImage(
421+
this.#previewLayer,
422+
x, y, width, height,
423+
x, y, width, height
424+
);
425+
// Debug
426+
this.dispatchEvent(new CustomEvent('debug', {
427+
detail: {
428+
x,
429+
y,
430+
width,
431+
height,
432+
canvas: this.$canvas,
433+
context: this.#context,
434+
editLayer: this.#editLayer,
435+
noEditLayer: this.#noEditLayer,
436+
baseLayer: this.#baseLayer,
437+
previewLayer: this.#previewLayer
438+
}
439+
}));
440+
}
441+
383442
handleKeyDown(event: KeyboardEvent) {
384443
console.log(event.shiftKey, event.ctrlKey, event.altKey, event.key);
385444
switch (event.key) {
@@ -588,17 +647,41 @@ export default class PgInputPixelEditor extends HTMLElement {
588647
this.#context.drawImage(this.#baseLayer, 0, 0);
589648
// editing layer to main canvas
590649
this.#context.drawImage(this.#isEditing ? this.#editLayer : this.#noEditLayer, 0, 0);
650+
// track pointer movement
651+
this.#handlePointerMovePreviewCache = this.handlePointerMovePreview.bind(this);
652+
this.$canvas.addEventListener('pointermove', this.#handlePointerMovePreviewCache);
591653
}
592654
this.#pointerOutside = false;
593655
}
594656

657+
#moveX = 0;
658+
#moveY = 0;
659+
#handlePointerMovePreviewCache;
660+
handlePointerMovePreview(event: MouseEvent) {
661+
const rect = this.$canvas.getBoundingClientRect();
662+
const totalSize = this.size + this.gridSize;
663+
let newX = Math.floor((event.clientX - rect.left) / totalSize);
664+
let newY = Math.floor((event.clientY - rect.top) / totalSize);
665+
if (newX === this.#moveX && newY === this.#moveY) { return; }
666+
if (newX < 0 || newY < 0) { return; }
667+
this.#setPenPreview(
668+
pixelSizes[1].map(arr => ({ x: arr[0] + newX, y: arr[1] + newY })),
669+
this.#moveX,
670+
this.#moveY
671+
);
672+
this.#moveX = newX;
673+
this.#moveY = newY;
674+
}
675+
595676
handlePointerLeave(event: MouseEvent) {
596677
if (!this.#isPressed) {
597678
this.#isEditing = false;
598679
// base layer to main canvas
599680
this.#context.drawImage(this.#baseLayer, 0, 0);
600681
// editing layer to main canvas
601682
this.#context.drawImage(this.#isEditing ? this.#editLayer : this.#noEditLayer, 0, 0);
683+
// remove preview tracking
684+
this.$canvas.removeEventListener('pointermove', this.#handlePointerMovePreviewCache);
602685
} else if (this.#isEditing) {
603686
this.#pointerOutside = true;
604687
}
@@ -769,6 +852,11 @@ export default class PgInputPixelEditor extends HTMLElement {
769852
return this.#redoHistory.length !== 0;
770853
}
771854

855+
#inputModePixelSize = 1;
856+
inputModePixelSize(size = 1) {
857+
this.#inputModePixelSize = size;
858+
}
859+
772860
inputModePixel() {
773861
this.#inputMode = InputMode.Pixel;
774862
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
type Pixel = { x: number, y: number };
2+
3+
export const pixelSizes: { [key: number]: number[][] } = {
4+
1: [
5+
[0, 0]
6+
],
7+
3: [
8+
[0, -1],
9+
[-1, 0],
10+
[0, 0],
11+
[1, 0],
12+
[0, 1],
13+
],
14+
5: [
15+
[0, -2],
16+
[-1, -1],
17+
[0, -1],
18+
[1, -1],
19+
[-2, 0],
20+
[-1, 0],
21+
[0, 0],
22+
[1, 0],
23+
[2, 0],
24+
[-1, 1],
25+
[0, 1],
26+
[1, 1],
27+
[0, 2],
28+
],
29+
7: [
30+
[-1, -3],
31+
[0, -3],
32+
[1, -3],
33+
[-2, -2],
34+
[-1, -1],
35+
[0, -1],
36+
[1, -1],
37+
[-2, 0],
38+
[-1, 0],
39+
[0, 0],
40+
[1, 0],
41+
[2, 0],
42+
[-1, 1],
43+
[0, 1],
44+
[1, 1],
45+
[0, 2],
46+
]
47+
}

0 commit comments

Comments
 (0)