ooxml-core 0.21.2 → 0.22.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/README.md +3 -4
- package/dist/automation/index.cjs +34 -13
- package/dist/automation/index.mjs +34 -13
- package/dist/chart/index.cjs +242 -0
- package/dist/chart/index.d.ts +5 -0
- package/dist/chart/index.d.ts.map +1 -1
- package/dist/chart/index.mjs +227 -1
- package/dist/chart/pie-best-fit.d.ts +51 -0
- package/dist/chart/pie-best-fit.d.ts.map +1 -0
- package/dist/chart/pie-label-collision.d.ts +48 -0
- package/dist/chart/pie-label-collision.d.ts.map +1 -0
- package/dist/chart/radar-geometry.d.ts +19 -0
- package/dist/chart/radar-geometry.d.ts.map +1 -0
- package/dist/chart/treemap-squarify.d.ts +31 -0
- package/dist/chart/treemap-squarify.d.ts.map +1 -0
- package/dist/chart/trendline-equation.d.ts +39 -0
- package/dist/chart/trendline-equation.d.ts.map +1 -0
- package/dist/collab/index.cjs +6 -1
- package/dist/collab/index.mjs +6 -1
- package/dist/color/contrast.d.ts +18 -0
- package/dist/color/contrast.d.ts.map +1 -0
- package/dist/color/index.cjs +33 -0
- package/dist/color/index.d.ts +2 -0
- package/dist/color/index.d.ts.map +1 -1
- package/dist/color/index.mjs +31 -1
- package/dist/color/unit-rgb.d.ts +21 -0
- package/dist/color/unit-rgb.d.ts.map +1 -0
- package/dist/docx/embedded.cjs +1 -1
- package/dist/docx/embedded.mjs +1 -1
- package/dist/docx/index.cjs +1 -1
- package/dist/docx/index.mjs +1 -1
- package/dist/docx/load/index.cjs +1 -1
- package/dist/docx/load/index.mjs +1 -1
- package/dist/geometry/align-distribute.d.ts +145 -0
- package/dist/geometry/align-distribute.d.ts.map +1 -0
- package/dist/geometry/index.cjs +318 -0
- package/dist/geometry/index.d.ts +2 -0
- package/dist/geometry/index.d.ts.map +1 -1
- package/dist/geometry/index.mjs +307 -1
- package/dist/geometry/snap-guides.d.ts +125 -0
- package/dist/geometry/snap-guides.d.ts.map +1 -0
- package/dist/index.cjs +665 -0
- package/dist/index.mjs +665 -0
- package/dist/pptx/automation/index.cjs +24 -1
- package/dist/pptx/automation/index.d.ts +3 -3
- package/dist/pptx/automation/index.mjs +24 -1
- package/dist/pptx/chunks/{index-JaNVJ6Tf.d.ts → index-D2y7ehZ5.d.ts} +3 -3
- package/dist/pptx/chunks/{index-JaNVJ6Tf.d.ts.map → index-D2y7ehZ5.d.ts.map} +1 -1
- package/dist/pptx/chunks/{index-DHdHU9Qr.d.ts → index-ucqKcqvI.d.ts} +10 -2
- package/dist/pptx/chunks/{index-DHdHU9Qr.d.ts.map → index-ucqKcqvI.d.ts.map} +1 -1
- package/dist/pptx/chunks/{text-operations-DUEhSW5Z.d.ts → text-operations-CR3pUJi-.d.ts} +14 -2
- package/dist/pptx/chunks/text-operations-CR3pUJi-.d.ts.map +1 -0
- package/dist/pptx/cli/index.cjs +23 -0
- package/dist/pptx/cli/index.d.ts +1 -1
- package/dist/pptx/cli/index.mjs +23 -0
- package/dist/pptx/converter/index.d.ts +1 -1
- package/dist/pptx/index.cjs +33 -3
- package/dist/pptx/index.d.ts +3 -3
- package/dist/pptx/index.mjs +33 -3
- package/dist/teams/index.cjs +7 -2
- package/dist/teams/index.mjs +7 -2
- package/dist/text/decimal-tab.d.ts +24 -0
- package/dist/text/decimal-tab.d.ts.map +1 -0
- package/dist/text/index.cjs +72 -0
- package/dist/text/index.d.ts +2 -0
- package/dist/text/index.d.ts.map +1 -1
- package/dist/text/index.mjs +68 -1
- package/dist/text/tab-leader.d.ts +36 -0
- package/dist/text/tab-leader.d.ts.map +1 -0
- package/dist/xlsx/edit/charts.d.ts.map +1 -1
- package/dist/xlsx/edit/clipboard-html-parse.d.ts.map +1 -1
- package/dist/xlsx/index.cjs +33 -12
- package/dist/xlsx/index.mjs +33 -12
- package/dist/xlsx/ui/grid/cell-paint.d.ts.map +1 -1
- package/dist/xlsx/ui/index.cjs +37 -16
- package/dist/xlsx/ui/index.mjs +37 -16
- package/package.json +2 -2
- package/dist/pptx/chunks/text-operations-DUEhSW5Z.d.ts.map +0 -1
package/dist/geometry/index.mjs
CHANGED
|
@@ -15085,4 +15085,310 @@ function flattenSvgPath(d, curveSegments = 16) {
|
|
|
15085
15085
|
return loops;
|
|
15086
15086
|
}
|
|
15087
15087
|
|
|
15088
|
-
|
|
15088
|
+
// geometry/snap-guides.ts
|
|
15089
|
+
var SNAP_THRESHOLD = 6;
|
|
15090
|
+
function computeSnapToShape(dragX, dragY, dragW, dragH, siblings, draggedIds, guides, threshold = SNAP_THRESHOLD) {
|
|
15091
|
+
let bestDx = Infinity;
|
|
15092
|
+
let bestDy = Infinity;
|
|
15093
|
+
let snapX = dragX;
|
|
15094
|
+
let snapY = dragY;
|
|
15095
|
+
const lines = [];
|
|
15096
|
+
const dragCx = dragX + dragW / 2;
|
|
15097
|
+
const dragCy = dragY + dragH / 2;
|
|
15098
|
+
const dragRight = dragX + dragW;
|
|
15099
|
+
const dragBottom = dragY + dragH;
|
|
15100
|
+
const hRefs = [dragX, dragCx, dragRight];
|
|
15101
|
+
const vRefs = [dragY, dragCy, dragBottom];
|
|
15102
|
+
for (const sib of siblings) {
|
|
15103
|
+
if (draggedIds.has(sib.id)) {
|
|
15104
|
+
continue;
|
|
15105
|
+
}
|
|
15106
|
+
const sibCx = sib.x + sib.width / 2;
|
|
15107
|
+
const sibCy = sib.y + sib.height / 2;
|
|
15108
|
+
const sibRight = sib.x + sib.width;
|
|
15109
|
+
const sibBottom = sib.y + sib.height;
|
|
15110
|
+
for (const ref of [sib.x, sibCx, sibRight]) {
|
|
15111
|
+
for (const hr of hRefs) {
|
|
15112
|
+
const dx = Math.abs(ref - hr);
|
|
15113
|
+
if (dx < threshold && dx < bestDx) {
|
|
15114
|
+
bestDx = dx;
|
|
15115
|
+
snapX = dragX + (ref - hr);
|
|
15116
|
+
}
|
|
15117
|
+
}
|
|
15118
|
+
}
|
|
15119
|
+
for (const ref of [sib.y, sibCy, sibBottom]) {
|
|
15120
|
+
for (const vr of vRefs) {
|
|
15121
|
+
const dy = Math.abs(ref - vr);
|
|
15122
|
+
if (dy < threshold && dy < bestDy) {
|
|
15123
|
+
bestDy = dy;
|
|
15124
|
+
snapY = dragY + (ref - vr);
|
|
15125
|
+
}
|
|
15126
|
+
}
|
|
15127
|
+
}
|
|
15128
|
+
}
|
|
15129
|
+
for (const guide of guides) {
|
|
15130
|
+
if (guide.axis === "v") {
|
|
15131
|
+
for (const hr of hRefs) {
|
|
15132
|
+
const dx = Math.abs(guide.position - hr);
|
|
15133
|
+
if (dx < threshold && dx < bestDx) {
|
|
15134
|
+
bestDx = dx;
|
|
15135
|
+
snapX = dragX + (guide.position - hr);
|
|
15136
|
+
}
|
|
15137
|
+
}
|
|
15138
|
+
} else {
|
|
15139
|
+
for (const vr of vRefs) {
|
|
15140
|
+
const dy = Math.abs(guide.position - vr);
|
|
15141
|
+
if (dy < threshold && dy < bestDy) {
|
|
15142
|
+
bestDy = dy;
|
|
15143
|
+
snapY = dragY + (guide.position - vr);
|
|
15144
|
+
}
|
|
15145
|
+
}
|
|
15146
|
+
}
|
|
15147
|
+
}
|
|
15148
|
+
if (bestDx < threshold) {
|
|
15149
|
+
const snappedCx = snapX + dragW / 2;
|
|
15150
|
+
const snappedRight = snapX + dragW;
|
|
15151
|
+
for (const sib of siblings) {
|
|
15152
|
+
if (draggedIds.has(sib.id)) {
|
|
15153
|
+
continue;
|
|
15154
|
+
}
|
|
15155
|
+
for (const ref of [sib.x, sib.x + sib.width / 2, sib.x + sib.width]) {
|
|
15156
|
+
if (Math.abs(ref - snapX) < 1 || Math.abs(ref - snappedCx) < 1 || Math.abs(ref - snappedRight) < 1) {
|
|
15157
|
+
lines.push({ axis: "v", position: ref });
|
|
15158
|
+
}
|
|
15159
|
+
}
|
|
15160
|
+
}
|
|
15161
|
+
for (const g of guides) {
|
|
15162
|
+
if (g.axis === "v" && (Math.abs(g.position - snapX) < 1 || Math.abs(g.position - snappedCx) < 1 || Math.abs(g.position - snappedRight) < 1)) {
|
|
15163
|
+
lines.push({ axis: "v", position: g.position });
|
|
15164
|
+
}
|
|
15165
|
+
}
|
|
15166
|
+
}
|
|
15167
|
+
if (bestDy < threshold) {
|
|
15168
|
+
const snappedCy = snapY + dragH / 2;
|
|
15169
|
+
const snappedBottom = snapY + dragH;
|
|
15170
|
+
for (const sib of siblings) {
|
|
15171
|
+
if (draggedIds.has(sib.id)) {
|
|
15172
|
+
continue;
|
|
15173
|
+
}
|
|
15174
|
+
for (const ref of [sib.y, sib.y + sib.height / 2, sib.y + sib.height]) {
|
|
15175
|
+
if (Math.abs(ref - snapY) < 1 || Math.abs(ref - snappedCy) < 1 || Math.abs(ref - snappedBottom) < 1) {
|
|
15176
|
+
lines.push({ axis: "h", position: ref });
|
|
15177
|
+
}
|
|
15178
|
+
}
|
|
15179
|
+
}
|
|
15180
|
+
for (const g of guides) {
|
|
15181
|
+
if (g.axis === "h" && (Math.abs(g.position - snapY) < 1 || Math.abs(g.position - snappedCy) < 1 || Math.abs(g.position - snappedBottom) < 1)) {
|
|
15182
|
+
lines.push({ axis: "h", position: g.position });
|
|
15183
|
+
}
|
|
15184
|
+
}
|
|
15185
|
+
}
|
|
15186
|
+
return { x: snapX, y: snapY, lines };
|
|
15187
|
+
}
|
|
15188
|
+
function xCandidates(box) {
|
|
15189
|
+
return {
|
|
15190
|
+
leading: box.x,
|
|
15191
|
+
centre: box.x + box.width / 2,
|
|
15192
|
+
trailing: box.x + box.width
|
|
15193
|
+
};
|
|
15194
|
+
}
|
|
15195
|
+
function yCandidates(box) {
|
|
15196
|
+
return {
|
|
15197
|
+
leading: box.y,
|
|
15198
|
+
centre: box.y + box.height / 2,
|
|
15199
|
+
trailing: box.y + box.height
|
|
15200
|
+
};
|
|
15201
|
+
}
|
|
15202
|
+
function findSnapHit(movingValues, others, axisCandidates, threshold) {
|
|
15203
|
+
let best = null;
|
|
15204
|
+
let bestDist = threshold + 1;
|
|
15205
|
+
for (const other of others) {
|
|
15206
|
+
const target = axisCandidates(other);
|
|
15207
|
+
const targetValues = [target.leading, target.centre, target.trailing];
|
|
15208
|
+
for (const mv of movingValues) {
|
|
15209
|
+
for (const tv of targetValues) {
|
|
15210
|
+
const dist = mv > tv ? mv - tv : tv - mv;
|
|
15211
|
+
if (dist <= threshold && dist < bestDist) {
|
|
15212
|
+
bestDist = dist;
|
|
15213
|
+
best = { delta: tv - mv, matchedLine: tv, otherBox: other };
|
|
15214
|
+
}
|
|
15215
|
+
}
|
|
15216
|
+
}
|
|
15217
|
+
}
|
|
15218
|
+
return best;
|
|
15219
|
+
}
|
|
15220
|
+
function unionExtent(aStart, aEnd, bStart, bEnd) {
|
|
15221
|
+
const start = aStart < bStart ? aStart : bStart;
|
|
15222
|
+
const end = aEnd > bEnd ? aEnd : bEnd;
|
|
15223
|
+
return { start, end };
|
|
15224
|
+
}
|
|
15225
|
+
function computeSnap(box, others, threshold) {
|
|
15226
|
+
const guides = [];
|
|
15227
|
+
let snappedX = box.x;
|
|
15228
|
+
let snappedY = box.y;
|
|
15229
|
+
const xMoving = xCandidates(box);
|
|
15230
|
+
const hitX = findSnapHit(
|
|
15231
|
+
[xMoving.leading, xMoving.centre, xMoving.trailing],
|
|
15232
|
+
others,
|
|
15233
|
+
xCandidates,
|
|
15234
|
+
threshold
|
|
15235
|
+
);
|
|
15236
|
+
if (hitX !== null) {
|
|
15237
|
+
snappedX = box.x + hitX.delta;
|
|
15238
|
+
const { start, end } = unionExtent(
|
|
15239
|
+
box.y,
|
|
15240
|
+
box.y + box.height,
|
|
15241
|
+
hitX.otherBox.y,
|
|
15242
|
+
hitX.otherBox.y + hitX.otherBox.height
|
|
15243
|
+
);
|
|
15244
|
+
guides.push({ axis: "x", pos: hitX.matchedLine, start, end });
|
|
15245
|
+
}
|
|
15246
|
+
const yMoving = yCandidates(box);
|
|
15247
|
+
const hitY = findSnapHit(
|
|
15248
|
+
[yMoving.leading, yMoving.centre, yMoving.trailing],
|
|
15249
|
+
others,
|
|
15250
|
+
yCandidates,
|
|
15251
|
+
threshold
|
|
15252
|
+
);
|
|
15253
|
+
if (hitY !== null) {
|
|
15254
|
+
snappedY = box.y + hitY.delta;
|
|
15255
|
+
const { start, end } = unionExtent(
|
|
15256
|
+
snappedX,
|
|
15257
|
+
snappedX + box.width,
|
|
15258
|
+
hitY.otherBox.x,
|
|
15259
|
+
hitY.otherBox.x + hitY.otherBox.width
|
|
15260
|
+
);
|
|
15261
|
+
guides.push({ axis: "y", pos: hitY.matchedLine, start, end });
|
|
15262
|
+
}
|
|
15263
|
+
return { x: snappedX, y: snappedY, guides };
|
|
15264
|
+
}
|
|
15265
|
+
function snapToGridStep(value, step) {
|
|
15266
|
+
if (step <= 0) {
|
|
15267
|
+
return value;
|
|
15268
|
+
}
|
|
15269
|
+
return Math.round(value / step) * step || 0;
|
|
15270
|
+
}
|
|
15271
|
+
function snapValue(value, size) {
|
|
15272
|
+
return Math.round(value / size) * size;
|
|
15273
|
+
}
|
|
15274
|
+
function snapBox(box, size) {
|
|
15275
|
+
return {
|
|
15276
|
+
x: snapValue(box.x, size),
|
|
15277
|
+
y: snapValue(box.y, size),
|
|
15278
|
+
width: Math.max(size, snapValue(box.width, size)),
|
|
15279
|
+
height: Math.max(size, snapValue(box.height, size))
|
|
15280
|
+
};
|
|
15281
|
+
}
|
|
15282
|
+
|
|
15283
|
+
// geometry/align-distribute.ts
|
|
15284
|
+
function usesSlideReference(elementCount, options) {
|
|
15285
|
+
if (!options?.slideSize) {
|
|
15286
|
+
return false;
|
|
15287
|
+
}
|
|
15288
|
+
return options.reference === "slide" || options.reference === void 0 && elementCount === 1;
|
|
15289
|
+
}
|
|
15290
|
+
function resolveAlignReferenceBox(elements, options) {
|
|
15291
|
+
if (elements.length === 0) {
|
|
15292
|
+
return null;
|
|
15293
|
+
}
|
|
15294
|
+
if (usesSlideReference(elements.length, options)) {
|
|
15295
|
+
return { minX: 0, minY: 0, maxX: options.slideSize.width, maxY: options.slideSize.height };
|
|
15296
|
+
}
|
|
15297
|
+
if (elements.length < 2) {
|
|
15298
|
+
return null;
|
|
15299
|
+
}
|
|
15300
|
+
return {
|
|
15301
|
+
minX: Math.min(...elements.map((e) => e.x)),
|
|
15302
|
+
minY: Math.min(...elements.map((e) => e.y)),
|
|
15303
|
+
maxX: Math.max(...elements.map((e) => e.x + e.width)),
|
|
15304
|
+
maxY: Math.max(...elements.map((e) => e.y + e.height))
|
|
15305
|
+
};
|
|
15306
|
+
}
|
|
15307
|
+
function alignElements(elements, edge, options) {
|
|
15308
|
+
const result = /* @__PURE__ */ new Map();
|
|
15309
|
+
const ref = resolveAlignReferenceBox(elements, options);
|
|
15310
|
+
if (!ref) {
|
|
15311
|
+
return result;
|
|
15312
|
+
}
|
|
15313
|
+
const { minX, minY, maxX, maxY } = ref;
|
|
15314
|
+
const centerX = (minX + maxX) / 2;
|
|
15315
|
+
const centerY = (minY + maxY) / 2;
|
|
15316
|
+
for (const el of elements) {
|
|
15317
|
+
switch (edge) {
|
|
15318
|
+
case "left":
|
|
15319
|
+
result.set(el.id, { x: minX });
|
|
15320
|
+
break;
|
|
15321
|
+
case "right":
|
|
15322
|
+
result.set(el.id, { x: maxX - el.width });
|
|
15323
|
+
break;
|
|
15324
|
+
case "centerH":
|
|
15325
|
+
result.set(el.id, { x: centerX - el.width / 2 });
|
|
15326
|
+
break;
|
|
15327
|
+
case "top":
|
|
15328
|
+
result.set(el.id, { y: minY });
|
|
15329
|
+
break;
|
|
15330
|
+
case "bottom":
|
|
15331
|
+
result.set(el.id, { y: maxY - el.height });
|
|
15332
|
+
break;
|
|
15333
|
+
case "middle":
|
|
15334
|
+
result.set(el.id, { y: centerY - el.height / 2 });
|
|
15335
|
+
break;
|
|
15336
|
+
}
|
|
15337
|
+
}
|
|
15338
|
+
return result;
|
|
15339
|
+
}
|
|
15340
|
+
function distributeElements(elements, axis, options) {
|
|
15341
|
+
const result = /* @__PURE__ */ new Map();
|
|
15342
|
+
const horizontal = axis === "horizontal";
|
|
15343
|
+
const start = (e) => horizontal ? e.x : e.y;
|
|
15344
|
+
const size = (e) => horizontal ? e.width : e.height;
|
|
15345
|
+
const sorted = [...elements].sort((a, b) => start(a) - start(b));
|
|
15346
|
+
const totalSize = sorted.reduce((sum, e) => sum + size(e), 0);
|
|
15347
|
+
let cursor;
|
|
15348
|
+
let gap;
|
|
15349
|
+
if (usesSlideReference(elements.length, options)) {
|
|
15350
|
+
if (sorted.length === 0) {
|
|
15351
|
+
return result;
|
|
15352
|
+
}
|
|
15353
|
+
const span = horizontal ? options.slideSize.width : options.slideSize.height;
|
|
15354
|
+
gap = (span - totalSize) / (sorted.length + 1);
|
|
15355
|
+
cursor = gap;
|
|
15356
|
+
} else {
|
|
15357
|
+
if (sorted.length < 3) {
|
|
15358
|
+
return result;
|
|
15359
|
+
}
|
|
15360
|
+
const first = sorted[0];
|
|
15361
|
+
const last = sorted[sorted.length - 1];
|
|
15362
|
+
const span = start(last) + size(last) - start(first);
|
|
15363
|
+
gap = (span - totalSize) / (sorted.length - 1);
|
|
15364
|
+
cursor = start(first);
|
|
15365
|
+
}
|
|
15366
|
+
for (const el of sorted) {
|
|
15367
|
+
result.set(el.id, horizontal ? { x: cursor } : { y: cursor });
|
|
15368
|
+
cursor += size(el) + gap;
|
|
15369
|
+
}
|
|
15370
|
+
return result;
|
|
15371
|
+
}
|
|
15372
|
+
function onlyMoved(boxes, positions) {
|
|
15373
|
+
const byId = new Map(boxes.map((box) => [box.id, box]));
|
|
15374
|
+
const result = /* @__PURE__ */ new Map();
|
|
15375
|
+
for (const [id, pos] of positions) {
|
|
15376
|
+
const box = byId.get(id);
|
|
15377
|
+
if (!box) {
|
|
15378
|
+
continue;
|
|
15379
|
+
}
|
|
15380
|
+
const moved = pos.x !== void 0 && pos.x !== box.x || pos.y !== void 0 && pos.y !== box.y;
|
|
15381
|
+
if (moved) {
|
|
15382
|
+
result.set(id, pos);
|
|
15383
|
+
}
|
|
15384
|
+
}
|
|
15385
|
+
return result;
|
|
15386
|
+
}
|
|
15387
|
+
function computeAlign(boxes, mode, options) {
|
|
15388
|
+
return onlyMoved(boxes, alignElements(boxes, mode, options));
|
|
15389
|
+
}
|
|
15390
|
+
function computeDistribute(boxes, mode, options) {
|
|
15391
|
+
return onlyMoved(boxes, distributeElements(boxes, mode, options));
|
|
15392
|
+
}
|
|
15393
|
+
|
|
15394
|
+
export { ACTION_BUTTON_CONNECTION_SITES, ACTION_BUTTON_PRESET_DEFINITIONS, ACTION_BUTTON_TEXT_RECTS, ANGLE_SCALE, ARROW_CALLOUT_CONNECTION_SITES, ARROW_CALLOUT_PRESET_DEFINITIONS, ARROW_CONNECTION_SITES, ARROW_PRESET_DEFINITIONS, ARROW_TEXT_RECTS, BASIC_SHAPE_CONNECTION_SITES_A, BASIC_SHAPE_CONNECTION_SITES_B, BRACE_CONNECTION_SITES, BRACE_TEXT_RECTS, CALLOUT_CONNECTION_SITES, CALLOUT_TEXT_RECTS, CARDINAL_SITES, CHART_MARK_PRESET_DEFINITIONS, CIRCULAR_ARROW_CONNECTION_SITES, CIRCULAR_ARROW_TEXT_RECTS, CLIP_PATHS_CORE, CLIP_PATHS_EXTENDED, CLOUD_CALLOUT_PRESET_DEFINITIONS, CLOUD_CALLOUT_TAIL_COUNT, CLOUD_LOBE_COUNT, COM_AVLST_GROUND_TRUTH, CONNECTORS_BRACKETS_PRESET_DEFINITIONS, CURVED_ARROWS_CONNECTORS_PRESET_DEFINITIONS, CURVED_ARROW_CONNECTION_SITES, EPSILON, EXACT_CURVED_ARROW_PRESET_DEFINITIONS, EXTENDED_SHAPE_DEFINITIONS, FLOWCHART_CONNECTION_SITES, FLOWCHART_PRESET_DEFINITIONS, FLOWCHART_TEXT_RECTS, GEAR9_CONNECTION_SITES, LEFT_CIRCULAR_ARROW_CONNECTION_SITES, LEFT_RIGHT_CIRCULAR_ARROW_CONNECTION_SITES, MATH_SYMBOL_CONNECTION_SITES, MISC_ARROW_CONNECTION_SITES, MISC_PRESET_DEFINITIONS, MISC_SHAPE_CONNECTION_SITES, MISC_TEXT_RECTS_A, MISC_TEXT_RECTS_B, POLYGON_CONNECTION_SITES, POLYGON_TEXT_RECTS, PRESET_GEOMETRY_ALIASES, PRESET_SHAPE_CATEGORY_LABELS, PRESET_SHAPE_CLIP_PATHS, PRESET_SHAPE_DEFINITIONS, PRESET_SHAPE_GEOMETRY_TABLE, PRIMARY_SHAPE_DEFINITIONS, QUAD_CONNECTION_SITES, QUAD_TEXT_RECTS, RECTS_SNIPS_PRESET_DEFINITIONS, RECT_VARIANT_CONNECTION_SITES, REFINED_ARROW_PRESET_DEFINITIONS, RIBBON_CONNECTION_SITES, RIBBON_TEXT_RECTS, SCROLLS_ACCENT_CALLOUTS_PRESET_DEFINITIONS, SNAP_THRESHOLD, STAR_CONNECTION_SITES, STAR_TEXT_RECTS, ST_SHAPE_TYPE_VALUES, TABS_DECORATIONS_PRESET_DEFINITIONS, TAB_CONNECTION_SITES, TAB_TEXT_RECTS, _internalForTests, alignElements, angleToRadians, at, buildCalloutLeaderLineSvgPath, clipPolygons, combineShapes, computeAlign, computeDistribute, computeSnap, computeSnapToShape, computeUnionWalk, convexHull, createBuiltinVariables, cross2, cxn, dedupPoly, distributeElements, elbowCurveSegments, elbowWaypoints, ensureCCW, ensureCW, evaluateFormula, evaluateGuides, findAllIntersections, flattenSvgPath, fmtNum, fragmentShapes, gd, gear6, gear9, getAdjustmentAwareClipPath, getCalloutLeaderLineGeometry, getCalloutTier, getCalloutViewBoxBounds, getCloudCalloutClipPath, getCloudClipPath, getPresetConnectionSites, getPresetShapeClipPath, getPresetTextRect, insertIntersections, intersectPolygons, intersectShapes, intersectSvgPaths, isCalloutShape, isConvex, isHorizontalPrimaryAxis, isStShapeType, lineIntersection, lookupPresetConnectionSites, lookupPresetTextRectOverride, mergeOverlappingPolygons, mergeShapes, normalizeStShapeType, parseAdjustmentValues, parseFormula, parseGuideDefinitions, pointInPolygon, pointInTriangle, polygonArea, polygonsToSvgPath, resolveAlignReferenceBox, resolveCoordinate, resolveOperand, segmentIntersection, signedArea, snapBox, snapToGridStep, snapValue, subtractPolygons, subtractShapes, subtractSvgPaths, sutherlandHodgman, svgPathToPolygons, triangulate, unionPolygons, unionShapes, unionSvgPaths, usesSlideReference, vec2Eq };
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure snap-and-alignment-guide geometry shared by the React, Vue, and Angular
|
|
3
|
+
* editor bindings. No framework imports, no DOM, no side effects - only data
|
|
4
|
+
* in, data out. All inputs are treated as immutable.
|
|
5
|
+
*
|
|
6
|
+
* Two snap models live here because the bindings grew two distinct flavours;
|
|
7
|
+
* both are exact ports kept feature-for-feature so consumers stay unchanged:
|
|
8
|
+
*
|
|
9
|
+
* 1. `computeSnapToShape` (React / Vue model) - snaps a dragged box to the
|
|
10
|
+
* edges/centres of sibling boxes **and** user-placed guides within
|
|
11
|
+
* {@link SNAP_THRESHOLD}px, returning `{ x, y, lines }` where `lines` are
|
|
12
|
+
* thin axis-positioned guide indicators (no span info).
|
|
13
|
+
*
|
|
14
|
+
* 2. `computeSnap` (Angular model) - snaps a box to a list of other boxes
|
|
15
|
+
* within an explicit `threshold`, returning `{ x, y, guides }` where each
|
|
16
|
+
* guide additionally carries the perpendicular `start`/`end` span covering
|
|
17
|
+
* both boxes. At most one snap per axis (closest wins).
|
|
18
|
+
*
|
|
19
|
+
* `snapToGridStep` rounds a single value to the nearest grid multiple.
|
|
20
|
+
*
|
|
21
|
+
* The pointer/drag driver (event handling, refs, reactive state) stays in each
|
|
22
|
+
* binding; only this geometry is shared.
|
|
23
|
+
*/
|
|
24
|
+
/** Max gap (slide px) at which an edge/centre snaps to a sibling or guide. */
|
|
25
|
+
export declare const SNAP_THRESHOLD = 6;
|
|
26
|
+
/** A sibling element reduced to its bounding box. */
|
|
27
|
+
export interface SnapSibling {
|
|
28
|
+
id: string;
|
|
29
|
+
x: number;
|
|
30
|
+
y: number;
|
|
31
|
+
width: number;
|
|
32
|
+
height: number;
|
|
33
|
+
}
|
|
34
|
+
/** A user-placed alignment guide: `axis: 'v'` is a vertical line at x=`position`. */
|
|
35
|
+
export interface SnapGuideInput {
|
|
36
|
+
axis: 'h' | 'v';
|
|
37
|
+
position: number;
|
|
38
|
+
}
|
|
39
|
+
/** A snap alignment line: `axis: 'v'` is a vertical line at x=`position`. */
|
|
40
|
+
export interface SnapLine {
|
|
41
|
+
axis: 'h' | 'v';
|
|
42
|
+
position: number;
|
|
43
|
+
}
|
|
44
|
+
/** Result of {@link computeSnapToShape}: (optionally snapped) position + lines. */
|
|
45
|
+
export interface SnapToShapeResult {
|
|
46
|
+
x: number;
|
|
47
|
+
y: number;
|
|
48
|
+
lines: SnapLine[];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Compute snap-to-shape alignment lines and optionally snap a dragged element's
|
|
52
|
+
* position to the nearest matching edge/centre of sibling elements and guides.
|
|
53
|
+
*
|
|
54
|
+
* Returns `{ x, y, lines }` where x/y are (optionally snapped) positions and
|
|
55
|
+
* lines is the set of visual guide indicators to render.
|
|
56
|
+
*
|
|
57
|
+
* @param threshold - Snap distance in slide px (defaults to {@link SNAP_THRESHOLD}).
|
|
58
|
+
*/
|
|
59
|
+
export declare function computeSnapToShape(dragX: number, dragY: number, dragW: number, dragH: number, siblings: readonly SnapSibling[], draggedIds: Set<string>, guides: readonly SnapGuideInput[], threshold?: number): SnapToShapeResult;
|
|
60
|
+
/** An axis-aligned bounding box in stage (slide) coordinates. */
|
|
61
|
+
export interface SnapBox {
|
|
62
|
+
x: number;
|
|
63
|
+
y: number;
|
|
64
|
+
width: number;
|
|
65
|
+
height: number;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* A single span guide line to draw.
|
|
69
|
+
*
|
|
70
|
+
* `axis: 'x'` → a vertical line at x = `pos`, spanning y ∈ [start, end].
|
|
71
|
+
* `axis: 'y'` → a horizontal line at y = `pos`, spanning x ∈ [start, end].
|
|
72
|
+
*/
|
|
73
|
+
export interface SnapGuide {
|
|
74
|
+
axis: 'x' | 'y';
|
|
75
|
+
/** The fixed coordinate of the line on its own axis. */
|
|
76
|
+
pos: number;
|
|
77
|
+
/** Start of the line along the perpendicular axis. */
|
|
78
|
+
start: number;
|
|
79
|
+
/** End of the line along the perpendicular axis. */
|
|
80
|
+
end: number;
|
|
81
|
+
}
|
|
82
|
+
/** The result of a {@link computeSnap} computation for one drag frame. */
|
|
83
|
+
export interface SnapResult {
|
|
84
|
+
/** Snapped x origin of the moving box. */
|
|
85
|
+
x: number;
|
|
86
|
+
/** Snapped y origin of the moving box. */
|
|
87
|
+
y: number;
|
|
88
|
+
/** Guide lines to draw; empty when nothing is within threshold. */
|
|
89
|
+
guides: SnapGuide[];
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Compute snap adjustments and span guide lines for a box being dragged.
|
|
93
|
+
*
|
|
94
|
+
* For each axis independently the moving box exposes three candidate positions
|
|
95
|
+
* (leading, centre, trailing) and so does every other box. If any
|
|
96
|
+
* `|candidate − otherPos| ≤ threshold`, the closest pair snaps: the returned
|
|
97
|
+
* x (or y) is adjusted so the candidate aligns exactly with the other
|
|
98
|
+
* position, and a {@link SnapGuide} is emitted spanning both boxes'
|
|
99
|
+
* perpendicular extents. At most one snap per axis (closest wins). When nothing
|
|
100
|
+
* is within threshold, x/y are returned unchanged and guides is empty.
|
|
101
|
+
*/
|
|
102
|
+
export declare function computeSnap(box: SnapBox, others: readonly SnapBox[], threshold: number): SnapResult;
|
|
103
|
+
/**
|
|
104
|
+
* Snap a raw position value to the nearest grid step.
|
|
105
|
+
*
|
|
106
|
+
* @param value - Raw position in stage coordinates.
|
|
107
|
+
* @param step - Grid spacing in px (must be > 0; if ≤ 0 the value is returned
|
|
108
|
+
* unchanged so callers do not need to guard against zero).
|
|
109
|
+
* @returns The nearest multiple of `step`.
|
|
110
|
+
*/
|
|
111
|
+
export declare function snapToGridStep(value: number, step: number): number;
|
|
112
|
+
/**
|
|
113
|
+
* Round a value to the nearest multiple of `size` (the grid spacing).
|
|
114
|
+
*
|
|
115
|
+
* Unlike {@link snapToGridStep} this does not guard against a non-positive
|
|
116
|
+
* step (Vue's "Snap to Grid" caller always passes a positive grid size) and
|
|
117
|
+
* does not normalise −0; it mirrors React's `Math.round(v / gs) * gs`.
|
|
118
|
+
*/
|
|
119
|
+
export declare function snapValue(value: number, size: number): number;
|
|
120
|
+
/**
|
|
121
|
+
* Snap a box's position + size to the grid (View ▸ Snap to Grid). Sizes are
|
|
122
|
+
* clamped to at least one grid cell so an element never collapses to zero.
|
|
123
|
+
*/
|
|
124
|
+
export declare function snapBox(box: SnapBox, size: number): SnapBox;
|
|
125
|
+
//# sourceMappingURL=snap-guides.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snap-guides.d.ts","sourceRoot":"","sources":["../../geometry/snap-guides.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAMH,8EAA8E;AAC9E,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,qDAAqD;AACrD,MAAM,WAAW,WAAW;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf;AAED,qFAAqF;AACrF,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,GAAG,GAAG,GAAG,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,6EAA6E;AAC7E,MAAM,WAAW,QAAQ;IACxB,IAAI,EAAE,GAAG,GAAG,GAAG,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,mFAAmF;AACnF,MAAM,WAAW,iBAAiB;IACjC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,QAAQ,EAAE,CAAC;CAClB;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CACjC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,SAAS,WAAW,EAAE,EAChC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,EACvB,MAAM,EAAE,SAAS,cAAc,EAAE,EACjC,SAAS,GAAE,MAAuB,GAChC,iBAAiB,CA+HnB;AAMD,iEAAiE;AACjE,MAAM,WAAW,OAAO;IACvB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,GAAG,GAAG,GAAG,CAAC;IAChB,wDAAwD;IACxD,GAAG,EAAE,MAAM,CAAC;IACZ,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,GAAG,EAAE,MAAM,CAAC;CACZ;AAED,0EAA0E;AAC1E,MAAM,WAAW,UAAU;IAC1B,0CAA0C;IAC1C,CAAC,EAAE,MAAM,CAAC;IACV,0CAA0C;IAC1C,CAAC,EAAE,MAAM,CAAC;IACV,mEAAmE;IACnE,MAAM,EAAE,SAAS,EAAE,CAAC;CACpB;AAsED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAC1B,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,SAAS,OAAO,EAAE,EAC1B,SAAS,EAAE,MAAM,GACf,UAAU,CA2CZ;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAOlE;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAO3D"}
|