@pixerate/editor 0.218.0 → 0.218.1
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.
|
@@ -1039,6 +1039,44 @@ function selectionOutline(mask, threshold = 128) {
|
|
|
1039
1039
|
}
|
|
1040
1040
|
return Float32Array.from(segs);
|
|
1041
1041
|
}
|
|
1042
|
+
function selectionOutlinePaths(mask, threshold = 128) {
|
|
1043
|
+
const segs = selectionOutline(mask, threshold);
|
|
1044
|
+
const n = segs.length / 4;
|
|
1045
|
+
if (!n) return [];
|
|
1046
|
+
const stride = mask.width + 1;
|
|
1047
|
+
const key2 = (x, y) => y * stride + x;
|
|
1048
|
+
const at = /* @__PURE__ */ new Map();
|
|
1049
|
+
for (let s = 0; s < n; s++) {
|
|
1050
|
+
for (const k of [key2(segs[s * 4], segs[s * 4 + 1]), key2(segs[s * 4 + 2], segs[s * 4 + 3])]) {
|
|
1051
|
+
const list = at.get(k);
|
|
1052
|
+
if (list) list.push(s);
|
|
1053
|
+
else at.set(k, [s]);
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
const used = new Uint8Array(n);
|
|
1057
|
+
const paths = [];
|
|
1058
|
+
for (let s0 = 0; s0 < n; s0++) {
|
|
1059
|
+
if (used[s0]) continue;
|
|
1060
|
+
used[s0] = 1;
|
|
1061
|
+
const pts = [segs[s0 * 4], segs[s0 * 4 + 1], segs[s0 * 4 + 2], segs[s0 * 4 + 3]];
|
|
1062
|
+
for (const forward of [true, false]) {
|
|
1063
|
+
for (; ; ) {
|
|
1064
|
+
const x = forward ? pts[pts.length - 2] : pts[0];
|
|
1065
|
+
const y = forward ? pts[pts.length - 1] : pts[1];
|
|
1066
|
+
const next = at.get(key2(x, y))?.find((t) => !used[t]);
|
|
1067
|
+
if (next === void 0) break;
|
|
1068
|
+
used[next] = 1;
|
|
1069
|
+
const a = [segs[next * 4], segs[next * 4 + 1]];
|
|
1070
|
+
const b = [segs[next * 4 + 2], segs[next * 4 + 3]];
|
|
1071
|
+
const far = a[0] === x && a[1] === y ? b : a;
|
|
1072
|
+
if (forward) pts.push(far[0], far[1]);
|
|
1073
|
+
else pts.unshift(far[0], far[1]);
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
paths.push(Float32Array.from(pts));
|
|
1077
|
+
}
|
|
1078
|
+
return paths;
|
|
1079
|
+
}
|
|
1042
1080
|
function quickMaskPixels(mask, style = {}) {
|
|
1043
1081
|
const [r, g, b] = style.color ?? [255, 0, 0];
|
|
1044
1082
|
const k = Math.min(1, Math.max(0, style.opacity ?? 0.5));
|
|
@@ -2168,17 +2206,17 @@ var ImageEditorRenderer = class {
|
|
|
2168
2206
|
* screen pixels per natural pixel (the projection scale times the host's CSS scale).
|
|
2169
2207
|
*/
|
|
2170
2208
|
drawAnts(ctx, selection, scale, offset) {
|
|
2171
|
-
let
|
|
2172
|
-
if (!
|
|
2173
|
-
|
|
2174
|
-
this.outlineCache.set(selection,
|
|
2209
|
+
let paths = this.outlineCache.get(selection);
|
|
2210
|
+
if (!paths) {
|
|
2211
|
+
paths = selectionOutlinePaths(selection);
|
|
2212
|
+
this.outlineCache.set(selection, paths);
|
|
2175
2213
|
}
|
|
2176
|
-
if (!
|
|
2214
|
+
if (!paths.length) return;
|
|
2177
2215
|
const px2 = 1 / (scale || 1);
|
|
2178
2216
|
ctx.beginPath();
|
|
2179
|
-
for (
|
|
2180
|
-
ctx.moveTo(
|
|
2181
|
-
ctx.lineTo(
|
|
2217
|
+
for (const p of paths) {
|
|
2218
|
+
ctx.moveTo(p[0], p[1]);
|
|
2219
|
+
for (let i = 2; i < p.length; i += 2) ctx.lineTo(p[i], p[i + 1]);
|
|
2182
2220
|
}
|
|
2183
2221
|
ctx.lineWidth = px2;
|
|
2184
2222
|
ctx.strokeStyle = "#ffffff";
|
|
@@ -6003,6 +6041,10 @@ var ImageEditorController = class {
|
|
|
6003
6041
|
this.state.imageDimensions = source.dimensions;
|
|
6004
6042
|
if (!this.samplePixelsOverride) this.samplePixels = null;
|
|
6005
6043
|
if (prev.width !== source.dimensions.width || prev.height !== source.dimensions.height) {
|
|
6044
|
+
const c = this.state.crop;
|
|
6045
|
+
if (c && c.x === 0 && c.y === 0 && c.width === prev.width && c.height === prev.height) {
|
|
6046
|
+
this.state.crop = { x: 0, y: 0, width: source.dimensions.width, height: source.dimensions.height };
|
|
6047
|
+
}
|
|
6006
6048
|
this.state.layers = resizeLegacyMasks(this.state.layers, prev, source.dimensions);
|
|
6007
6049
|
}
|
|
6008
6050
|
this.dropMismatchedSelection();
|
|
@@ -23027,6 +23069,7 @@ export {
|
|
|
23027
23069
|
selectionFromTiles,
|
|
23028
23070
|
selectionModeFromModifiers,
|
|
23029
23071
|
selectionOutline,
|
|
23072
|
+
selectionOutlinePaths,
|
|
23030
23073
|
selectionRing,
|
|
23031
23074
|
selectionToCoverage,
|
|
23032
23075
|
selectionToPixels,
|
|
@@ -5,6 +5,13 @@ import type { SelectionMask } from './mask.cjs';
|
|
|
5
5
|
* This is what marching ants are drawn from. Linear in the pixel count.
|
|
6
6
|
*/
|
|
7
7
|
export declare function selectionOutline(mask: SelectionMask, threshold?: number): Float32Array;
|
|
8
|
+
/**
|
|
9
|
+
* The selection's outline (`selectionOutline`) joined into polylines, `[x0, y0, x1, y1, …]` each,
|
|
10
|
+
* closed loops ending where they start. Marching ants are stroked from these, so the dash runs on
|
|
11
|
+
* along a staircase edge instead of restarting at every one-pixel step (which made diagonal edges
|
|
12
|
+
* flash rather than march). A loop may break where two pixels touch only at a corner.
|
|
13
|
+
*/
|
|
14
|
+
export declare function selectionOutlinePaths(mask: SelectionMask, threshold?: number): Float32Array[];
|
|
8
15
|
export interface QuickMaskStyle {
|
|
9
16
|
/** Overlay colour, `[r, g, b]` 0..255 (default Photoshop's rubylith red). */
|
|
10
17
|
color?: readonly [number, number, number];
|
|
@@ -5,6 +5,13 @@ import type { SelectionMask } from './mask.js';
|
|
|
5
5
|
* This is what marching ants are drawn from. Linear in the pixel count.
|
|
6
6
|
*/
|
|
7
7
|
export declare function selectionOutline(mask: SelectionMask, threshold?: number): Float32Array;
|
|
8
|
+
/**
|
|
9
|
+
* The selection's outline (`selectionOutline`) joined into polylines, `[x0, y0, x1, y1, …]` each,
|
|
10
|
+
* closed loops ending where they start. Marching ants are stroked from these, so the dash runs on
|
|
11
|
+
* along a staircase edge instead of restarting at every one-pixel step (which made diagonal edges
|
|
12
|
+
* flash rather than march). A loop may break where two pixels touch only at a corner.
|
|
13
|
+
*/
|
|
14
|
+
export declare function selectionOutlinePaths(mask: SelectionMask, threshold?: number): Float32Array[];
|
|
8
15
|
export interface QuickMaskStyle {
|
|
9
16
|
/** Overlay colour, `[r, g, b]` 0..255 (default Photoshop's rubylith red). */
|
|
10
17
|
color?: readonly [number, number, number];
|