@node-projects/web-component-designer 0.1.321 → 0.1.323
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/dist/elements/helper/getBoxQuads.js +375 -18
- package/dist/elements/helper/getBoxQuads.js.map +1 -1
- package/dist/elements/services/propertiesService/services/CssCustomPropertiesService.js +17 -5
- package/dist/elements/services/propertiesService/services/CssCustomPropertiesService.js.map +1 -1
- package/dist/elements/widgets/designerView/designerCanvas.js +1 -1
- package/dist/elements/widgets/designerView/designerCanvas.js.map +1 -1
- package/dist/elements/widgets/designerView/extensions/PositionExtension.js +12 -3
- package/dist/elements/widgets/designerView/extensions/PositionExtension.js.map +1 -1
- package/dist/index-min.js +147 -147
- package/package.json +1 -1
|
@@ -364,7 +364,7 @@ export function getResultingTransformationBetweenElementAndAllAncestors(node, an
|
|
|
364
364
|
}
|
|
365
365
|
let lastOffsetParent = null;
|
|
366
366
|
while (actualElement != ancestor && actualElement != null) {
|
|
367
|
-
|
|
367
|
+
let parentElement = getParentElementIncludingSlots(actualElement, iframes);
|
|
368
368
|
if (actualElement.assignedSlot != null) {
|
|
369
369
|
const l = offsetTopLeftPolyfill(actualElement, 'offsetLeft');
|
|
370
370
|
const t = offsetTopLeftPolyfill(actualElement, 'offsetTop');
|
|
@@ -372,7 +372,16 @@ export function getResultingTransformationBetweenElementAndAllAncestors(node, an
|
|
|
372
372
|
originalElementAndAllParentsMultipliedMatrix = mvMat.multiplySelf(originalElementAndAllParentsMultipliedMatrix);
|
|
373
373
|
}
|
|
374
374
|
else {
|
|
375
|
-
if ((actualElement instanceof
|
|
375
|
+
if (!(actualElement instanceof SVGSVGElement) && !(actualElement instanceof (actualElement.ownerDocument.defaultView ?? window).SVGSVGElement) &&
|
|
376
|
+
(actualElement instanceof SVGGraphicsElement || actualElement instanceof (actualElement.ownerDocument.defaultView ?? window).SVGGraphicsElement)) {
|
|
377
|
+
const ctm = actualElement.getCTM();
|
|
378
|
+
const bb = actualElement.getBBox();
|
|
379
|
+
const mvMat = new DOMMatrix().translateSelf(bb.x, bb.y);
|
|
380
|
+
originalElementAndAllParentsMultipliedMatrix = mvMat.multiplySelf(originalElementAndAllParentsMultipliedMatrix);
|
|
381
|
+
originalElementAndAllParentsMultipliedMatrix = new DOMMatrix([ctm.a, ctm.b, ctm.c, ctm.d, ctm.e, ctm.f]).multiplySelf(originalElementAndAllParentsMultipliedMatrix);
|
|
382
|
+
parentElement = actualElement.ownerSVGElement;
|
|
383
|
+
}
|
|
384
|
+
else if ((actualElement instanceof HTMLElement || actualElement instanceof (actualElement.ownerDocument.defaultView ?? window).HTMLElement)) {
|
|
376
385
|
if (lastOffsetParent !== actualElement.offsetParent && !((actualElement instanceof HTMLSlotElement || actualElement instanceof (actualElement.ownerDocument.defaultView ?? window).HTMLSlotElement))) {
|
|
377
386
|
const offsets = getElementOffsetsInContainer(actualElement, actualElement !== node, iframes);
|
|
378
387
|
lastOffsetParent = actualElement.offsetParent;
|
|
@@ -411,6 +420,130 @@ export function getResultingTransformationBetweenElementAndAllAncestors(node, an
|
|
|
411
420
|
}
|
|
412
421
|
return originalElementAndAllParentsMultipliedMatrix;
|
|
413
422
|
}
|
|
423
|
+
/*
|
|
424
|
+
getResultingTransformationBetweenElementAndAllAncestors -> but with extra layout matrix (does not work yet....)
|
|
425
|
+
|
|
426
|
+
export function getResultingTransformationBetweenElementAndAllAncestors(node, ancestor, iframes) {
|
|
427
|
+
let key;
|
|
428
|
+
if (transformCache) {
|
|
429
|
+
let i1 = hash.get(node);
|
|
430
|
+
if (i1 === undefined)
|
|
431
|
+
hash.set(node, i1 = hashId++);
|
|
432
|
+
let i2 = hash.get(ancestor);
|
|
433
|
+
if (i2 === undefined)
|
|
434
|
+
hash.set(ancestor, i2 = hashId++);
|
|
435
|
+
key = i1 + '_' + i2;
|
|
436
|
+
const q = transformCache.get(key);
|
|
437
|
+
if (q)
|
|
438
|
+
return q;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// NEW — two matrices instead of one
|
|
442
|
+
let layoutMatrix = new DOMMatrix();
|
|
443
|
+
|
|
444
|
+
let actualElement = node;
|
|
445
|
+
|
|
446
|
+
let transformMatrix = getElementCombinedTransform(actualElement, iframes); //.multiplySelf(transformMatrix);
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
const perspectiveParent = getParentElementIncludingSlots(actualElement, iframes);
|
|
450
|
+
if (perspectiveParent) {
|
|
451
|
+
const s = getCachedComputedStyle(perspectiveParent);
|
|
452
|
+
if (s.transformStyle !== "preserve-3d")
|
|
453
|
+
projectTo2D(transformMatrix);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
let lastOffsetParent = null;
|
|
458
|
+
|
|
459
|
+
while (actualElement !== ancestor && actualElement != null) {
|
|
460
|
+
|
|
461
|
+
const parentElement = getParentElementIncludingSlots(actualElement, iframes);
|
|
462
|
+
|
|
463
|
+
// ------------------------
|
|
464
|
+
// LAYOUT MATRIX (offsets)
|
|
465
|
+
// ------------------------
|
|
466
|
+
|
|
467
|
+
if (actualElement.assignedSlot != null) {
|
|
468
|
+
|
|
469
|
+
const l = offsetTopLeftPolyfill(actualElement, "offsetLeft");
|
|
470
|
+
const t = offsetTopLeftPolyfill(actualElement, "offsetTop");
|
|
471
|
+
layoutMatrix = new DOMMatrix().translateSelf(l, t).multiplySelf(layoutMatrix);
|
|
472
|
+
|
|
473
|
+
} else {
|
|
474
|
+
|
|
475
|
+
if (actualElement instanceof HTMLElement ||
|
|
476
|
+
actualElement instanceof (actualElement.ownerDocument.defaultView ?? window).HTMLElement) {
|
|
477
|
+
|
|
478
|
+
if (lastOffsetParent !== actualElement.offsetParent &&
|
|
479
|
+
!(actualElement instanceof HTMLSlotElement)) {
|
|
480
|
+
|
|
481
|
+
const offsets = getElementOffsetsInContainer(actualElement, actualElement !== node, iframes);
|
|
482
|
+
lastOffsetParent = actualElement.offsetParent;
|
|
483
|
+
|
|
484
|
+
layoutMatrix = new DOMMatrix().translateSelf(offsets.x, offsets.y).multiplySelf(layoutMatrix);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
} else {
|
|
488
|
+
|
|
489
|
+
const offsets = getElementOffsetsInContainer(actualElement, actualElement !== node, iframes);
|
|
490
|
+
lastOffsetParent = null;
|
|
491
|
+
|
|
492
|
+
layoutMatrix = new DOMMatrix().translateSelf(offsets.x, offsets.y).multiplySelf(layoutMatrix);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// ------------------------
|
|
497
|
+
// TRANSFORM MATRIX (CSS)
|
|
498
|
+
// ------------------------
|
|
499
|
+
|
|
500
|
+
if (parentElement) {
|
|
501
|
+
|
|
502
|
+
// NEW — only affects transform pipeline
|
|
503
|
+
const parentTransform = getElementCombinedTransform(parentElement, iframes);
|
|
504
|
+
transformMatrix = parentTransform.multiply(transformMatrix);
|
|
505
|
+
|
|
506
|
+
// flattening boundary
|
|
507
|
+
const perspectiveParent = getParentElementIncludingSlots(parentElement, iframes);
|
|
508
|
+
if (perspectiveParent) {
|
|
509
|
+
const s = getCachedComputedStyle(perspectiveParent);
|
|
510
|
+
if (s.transformStyle !== "preserve-3d")
|
|
511
|
+
projectTo2D(transformMatrix);
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// ------------------------
|
|
515
|
+
// EXIT CONDITION
|
|
516
|
+
// ------------------------
|
|
517
|
+
|
|
518
|
+
if (parentElement === ancestor) {
|
|
519
|
+
|
|
520
|
+
// NEW — scroll offsets belong to layout
|
|
521
|
+
if (parentElement.scrollTop || parentElement.scrollLeft) {
|
|
522
|
+
layoutMatrix = new DOMMatrix()
|
|
523
|
+
.translate(-parentElement.scrollLeft, -parentElement.scrollTop)
|
|
524
|
+
.multiply(layoutMatrix);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
const result = layoutMatrix.multiply(transformMatrix);
|
|
528
|
+
|
|
529
|
+
if (transformCache)
|
|
530
|
+
transformCache.set(key, result);
|
|
531
|
+
|
|
532
|
+
return result;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
actualElement = parentElement;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
const result = layoutMatrix.multiply(transformMatrix);
|
|
540
|
+
|
|
541
|
+
if (transformCache)
|
|
542
|
+
transformCache.set(key, result);
|
|
543
|
+
|
|
544
|
+
return result;
|
|
545
|
+
}
|
|
546
|
+
*/
|
|
414
547
|
/**
|
|
415
548
|
* @param {Node} node
|
|
416
549
|
* @param {HTMLIFrameElement[]} iframes
|
|
@@ -447,7 +580,7 @@ export function getElementCombinedTransform(element, iframes) {
|
|
|
447
580
|
const originX = parseFloat(origin[0]);
|
|
448
581
|
const originY = parseFloat(origin[1]);
|
|
449
582
|
const originZ = origin[2] ? parseFloat(origin[2]) : 0;
|
|
450
|
-
const mOri = new DOMMatrix().
|
|
583
|
+
const mOri = new DOMMatrix().translateSelf(originX, originY, originZ);
|
|
451
584
|
if (s.translate != 'none' && s.translate) {
|
|
452
585
|
let tr = s.translate;
|
|
453
586
|
if (tr.includes('%')) {
|
|
@@ -467,17 +600,17 @@ export function getElementCombinedTransform(element, iframes) {
|
|
|
467
600
|
if (s.scale != 'none' && s.scale) {
|
|
468
601
|
m.multiplySelf(new DOMMatrix('scale(' + s.scale.replaceAll(' ', ',') + ')'));
|
|
469
602
|
}
|
|
470
|
-
if (s.transform != 'none' && s.transform) {
|
|
471
|
-
m.multiplySelf(new DOMMatrix(s.transform));
|
|
472
|
-
}
|
|
473
|
-
m = mOri.multiply(m.multiply(mOri.inverse()));
|
|
474
603
|
if (s.offsetPath && s.offsetPath !== 'none') {
|
|
475
604
|
m.multiplySelf(computeOffsetTransformMatrix(element));
|
|
476
605
|
}
|
|
606
|
+
if (s.transform != 'none' && s.transform) {
|
|
607
|
+
m.multiplySelf(new DOMMatrix(s.transform));
|
|
608
|
+
}
|
|
609
|
+
m = mOri.multiply(m.multiplySelf(mOri.inverse()));
|
|
477
610
|
//@ts-ignore
|
|
478
611
|
const pt = getElementPerspectiveTransform(element, iframes);
|
|
479
612
|
if (pt != null) {
|
|
480
|
-
m = pt.
|
|
613
|
+
m = pt.multiplySelf(m);
|
|
481
614
|
}
|
|
482
615
|
return m;
|
|
483
616
|
}
|
|
@@ -531,9 +664,9 @@ function getElementPerspectiveTransform(element, iframes) {
|
|
|
531
664
|
const origin = s.perspectiveOrigin.split(' ');
|
|
532
665
|
const originX = parseFloat(origin[0]) - element.offsetLeft;
|
|
533
666
|
const originY = parseFloat(origin[1]) - element.offsetTop;
|
|
534
|
-
const mOri = new DOMMatrix().
|
|
535
|
-
const mOriInv = new DOMMatrix().
|
|
536
|
-
return mOri.
|
|
667
|
+
const mOri = new DOMMatrix().translateSelf(originX, originY);
|
|
668
|
+
const mOriInv = new DOMMatrix().translateSelf(-originX, -originY);
|
|
669
|
+
return mOri.multiplySelf(m.multiplySelf(mOriInv));
|
|
537
670
|
}
|
|
538
671
|
}
|
|
539
672
|
}
|
|
@@ -634,7 +767,7 @@ function computeOffsetPathPoint(elem, offsetPath, distNorm) {
|
|
|
634
767
|
if (value.startsWith("ellipse("))
|
|
635
768
|
return computeEllipse(value, distNorm);
|
|
636
769
|
if (value.startsWith("inset("))
|
|
637
|
-
return computeInset(value, distNorm);
|
|
770
|
+
return computeInset(value, elem, distNorm);
|
|
638
771
|
if (value.startsWith("rect("))
|
|
639
772
|
return computeRect(value, distNorm);
|
|
640
773
|
if (value.startsWith("xywh("))
|
|
@@ -709,12 +842,6 @@ function computeEllipse(str, t) {
|
|
|
709
842
|
let tangentAngleDeg = Math.atan2(dy, dx) * 180 / Math.PI;
|
|
710
843
|
return { x, y, angle: tangentAngleDeg };
|
|
711
844
|
}
|
|
712
|
-
function computeInset(str, t) {
|
|
713
|
-
let m = str.match(/inset\(([^)]+)\)/);
|
|
714
|
-
let nums = m[1].split(/\s+/).map(s => parseFloat(s));
|
|
715
|
-
let top = nums[0], right = nums[1], bottom = nums[2], left = nums[3];
|
|
716
|
-
return rectPath(top, left, right, bottom, t);
|
|
717
|
-
}
|
|
718
845
|
function computeRect(str, t) {
|
|
719
846
|
let m = str.match(/rect\(([^)]+)\)/);
|
|
720
847
|
let nums = m[1].split(/\s+/).map(s => parseFloat(s));
|
|
@@ -790,6 +917,236 @@ function rectPath(top, left, right, bottom, t) {
|
|
|
790
917
|
let y = bottom - dist;
|
|
791
918
|
return { x: left, y, angle: 270 };
|
|
792
919
|
}
|
|
920
|
+
// normalized inset uses calc
|
|
921
|
+
function tokenizeCalc(input) {
|
|
922
|
+
let tokens = [];
|
|
923
|
+
let i = 0;
|
|
924
|
+
while (i < input.length) {
|
|
925
|
+
let ch = input[i];
|
|
926
|
+
if (/\s/.test(ch)) {
|
|
927
|
+
i++;
|
|
928
|
+
continue;
|
|
929
|
+
}
|
|
930
|
+
// operators & parentheses
|
|
931
|
+
if ("+-*/()".includes(ch)) {
|
|
932
|
+
tokens.push({ type: ch, value: ch });
|
|
933
|
+
i++;
|
|
934
|
+
continue;
|
|
935
|
+
}
|
|
936
|
+
// numbers or dimensions or %
|
|
937
|
+
if (/[0-9.]/.test(ch)) {
|
|
938
|
+
let start = i;
|
|
939
|
+
while (/[0-9.]/.test(input[i]))
|
|
940
|
+
i++;
|
|
941
|
+
let num = input.slice(start, i);
|
|
942
|
+
if (input[i] === "%") {
|
|
943
|
+
i++;
|
|
944
|
+
tokens.push({ type: "percentage", value: parseFloat(num) });
|
|
945
|
+
continue;
|
|
946
|
+
}
|
|
947
|
+
// only px supported
|
|
948
|
+
if (input.slice(i, i + 2) === "px") {
|
|
949
|
+
i += 2;
|
|
950
|
+
tokens.push({ type: "dimension", value: parseFloat(num), unit: "px" });
|
|
951
|
+
continue;
|
|
952
|
+
}
|
|
953
|
+
// plain number
|
|
954
|
+
tokens.push({ type: "number", value: parseFloat(num) });
|
|
955
|
+
continue;
|
|
956
|
+
}
|
|
957
|
+
// function name (calc)
|
|
958
|
+
if (/[a-zA-Z]/.test(ch)) {
|
|
959
|
+
let start = i;
|
|
960
|
+
while (/[a-zA-Z]/.test(input[i]))
|
|
961
|
+
i++;
|
|
962
|
+
let name = input.slice(start, i);
|
|
963
|
+
if (name === "calc" && input[i] === "(") {
|
|
964
|
+
tokens.push({ type: "func", value: "calc" });
|
|
965
|
+
continue;
|
|
966
|
+
}
|
|
967
|
+
throw new Error("Unsupported function: " + name);
|
|
968
|
+
}
|
|
969
|
+
throw new Error("Unexpected character in calc(): " + ch);
|
|
970
|
+
}
|
|
971
|
+
return tokens;
|
|
972
|
+
}
|
|
973
|
+
// normalized inset uses calc
|
|
974
|
+
function parseCalc(tokens) {
|
|
975
|
+
let i = 0;
|
|
976
|
+
function peek() { return tokens[i]; }
|
|
977
|
+
function consume() { return tokens[i++]; }
|
|
978
|
+
function parseExpression() {
|
|
979
|
+
let node = parseTerm();
|
|
980
|
+
while (peek() && (peek().type === "+" || peek().type === "-")) {
|
|
981
|
+
let op = consume().type;
|
|
982
|
+
let right = parseTerm();
|
|
983
|
+
node = { type: "binary", op, left: node, right };
|
|
984
|
+
}
|
|
985
|
+
return node;
|
|
986
|
+
}
|
|
987
|
+
function parseTerm() {
|
|
988
|
+
let node = parseFactor();
|
|
989
|
+
while (peek() && (peek().type === "*" || peek().type === "/")) {
|
|
990
|
+
let op = consume().type;
|
|
991
|
+
let right = parseFactor();
|
|
992
|
+
node = { type: "binary", op, left: node, right };
|
|
993
|
+
}
|
|
994
|
+
return node;
|
|
995
|
+
}
|
|
996
|
+
function parseFactor() {
|
|
997
|
+
let t = peek();
|
|
998
|
+
if (!t)
|
|
999
|
+
throw "Unexpected end in calc()";
|
|
1000
|
+
if (t.type === "number") {
|
|
1001
|
+
consume();
|
|
1002
|
+
return { type: "number", value: t.value };
|
|
1003
|
+
}
|
|
1004
|
+
if (t.type === "dimension") {
|
|
1005
|
+
consume();
|
|
1006
|
+
return { type: "dimension", value: t.value, unit: t.unit };
|
|
1007
|
+
}
|
|
1008
|
+
if (t.type === "percentage") {
|
|
1009
|
+
consume();
|
|
1010
|
+
return { type: "percentage", value: t.value };
|
|
1011
|
+
}
|
|
1012
|
+
if (t.type === "func") {
|
|
1013
|
+
consume(); // "calc"
|
|
1014
|
+
if (peek().type !== "(")
|
|
1015
|
+
throw "Expected '(' after calc";
|
|
1016
|
+
consume();
|
|
1017
|
+
let node = parseExpression();
|
|
1018
|
+
if (!peek() || peek().type !== ")")
|
|
1019
|
+
throw "Expected ')'";
|
|
1020
|
+
consume();
|
|
1021
|
+
return node;
|
|
1022
|
+
}
|
|
1023
|
+
if (t.type === "(") {
|
|
1024
|
+
consume();
|
|
1025
|
+
let node = parseExpression();
|
|
1026
|
+
if (!peek() || peek().type !== ")")
|
|
1027
|
+
throw "Expected ')'";
|
|
1028
|
+
consume();
|
|
1029
|
+
return node;
|
|
1030
|
+
}
|
|
1031
|
+
throw new Error("Unexpected calc token " + JSON.stringify(t));
|
|
1032
|
+
}
|
|
1033
|
+
let ast = parseExpression();
|
|
1034
|
+
if (i !== tokens.length)
|
|
1035
|
+
throw "Extra tokens after calc";
|
|
1036
|
+
return ast;
|
|
1037
|
+
}
|
|
1038
|
+
// normalized inset uses calc
|
|
1039
|
+
function evalCalc(ast, env) {
|
|
1040
|
+
switch (ast.type) {
|
|
1041
|
+
case "number":
|
|
1042
|
+
return ast.value;
|
|
1043
|
+
case "dimension":
|
|
1044
|
+
return ast.value; // px only → already a number
|
|
1045
|
+
case "percentage":
|
|
1046
|
+
return env.percentBase * (ast.value / 100);
|
|
1047
|
+
case "binary": {
|
|
1048
|
+
let l = evalCalc(ast.left, env);
|
|
1049
|
+
let r = evalCalc(ast.right, env);
|
|
1050
|
+
switch (ast.op) {
|
|
1051
|
+
case "+": return l + r;
|
|
1052
|
+
case "-": return l - r;
|
|
1053
|
+
case "*": return l * r;
|
|
1054
|
+
case "/": return l / r;
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
throw "Invalid AST node " + ast.type;
|
|
1059
|
+
}
|
|
1060
|
+
function resolveLength(expr, element) {
|
|
1061
|
+
expr = expr.trim();
|
|
1062
|
+
// Fast path: pure px
|
|
1063
|
+
if (/^[0-9.]+px$/.test(expr))
|
|
1064
|
+
return parseFloat(expr);
|
|
1065
|
+
// Pure %
|
|
1066
|
+
if (/^[0-9.]+%$/.test(expr)) {
|
|
1067
|
+
let p = parseFloat(expr);
|
|
1068
|
+
let base = element.offsetWidth; // <- width reference
|
|
1069
|
+
return base * (p / 100);
|
|
1070
|
+
}
|
|
1071
|
+
// calc(...) or mixed values
|
|
1072
|
+
const ast = parseCalc(tokenizeCalc(expr));
|
|
1073
|
+
return evalCalc(ast, {
|
|
1074
|
+
percentBase: element.offsetWidth
|
|
1075
|
+
});
|
|
1076
|
+
}
|
|
1077
|
+
function parseInsetArgs(str) {
|
|
1078
|
+
let inside = str.trim()
|
|
1079
|
+
.replace(/^inset\s*\(/, "")
|
|
1080
|
+
.replace(/\)\s*$/, "");
|
|
1081
|
+
let args = [];
|
|
1082
|
+
let current = "";
|
|
1083
|
+
let depth = 0;
|
|
1084
|
+
for (let i = 0; i < inside.length; i++) {
|
|
1085
|
+
let ch = inside[i];
|
|
1086
|
+
if (ch === "(") {
|
|
1087
|
+
depth++;
|
|
1088
|
+
current += ch;
|
|
1089
|
+
}
|
|
1090
|
+
else if (ch === ")") {
|
|
1091
|
+
depth--;
|
|
1092
|
+
current += ch;
|
|
1093
|
+
}
|
|
1094
|
+
else if (/\s/.test(ch) && depth === 0) {
|
|
1095
|
+
if (current.trim() !== "") {
|
|
1096
|
+
args.push(current.trim());
|
|
1097
|
+
current = "";
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
else {
|
|
1101
|
+
current += ch;
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
if (current.trim() !== "") {
|
|
1105
|
+
args.push(current.trim());
|
|
1106
|
+
}
|
|
1107
|
+
return args;
|
|
1108
|
+
}
|
|
1109
|
+
/**
|
|
1110
|
+
*
|
|
1111
|
+
* @param {string} str
|
|
1112
|
+
* @param {HTMLElement} element
|
|
1113
|
+
* @param {number} progress
|
|
1114
|
+
* @returns
|
|
1115
|
+
*/
|
|
1116
|
+
function computeInset(str, element, progress) {
|
|
1117
|
+
const args = parseInsetArgs(str);
|
|
1118
|
+
if (args.length !== 4)
|
|
1119
|
+
throw new Error("inset() must have 4 arguments");
|
|
1120
|
+
const [topPx, rightPx, bottomPx, leftPx] = args.map(a => resolveLength(a, element));
|
|
1121
|
+
const w = element.offsetWidth;
|
|
1122
|
+
const h = element.offsetHeight;
|
|
1123
|
+
// Actual rectangle coordinates
|
|
1124
|
+
const x1 = leftPx;
|
|
1125
|
+
const y1 = topPx;
|
|
1126
|
+
const x2 = w - rightPx;
|
|
1127
|
+
const y2 = h - bottomPx;
|
|
1128
|
+
// Rectangle perimeter
|
|
1129
|
+
const P = 2 * ((x2 - x1) + (y2 - y1));
|
|
1130
|
+
let d = P * progress;
|
|
1131
|
+
// Walk the rectangle clockwise, return point
|
|
1132
|
+
// Top edge: (x1 → x2, y1)
|
|
1133
|
+
let len = x2 - x1;
|
|
1134
|
+
if (d <= len)
|
|
1135
|
+
return { x: x1 + d, y: y1 };
|
|
1136
|
+
d -= len;
|
|
1137
|
+
// Right edge: (x2, y1 → y2)
|
|
1138
|
+
len = y2 - y1;
|
|
1139
|
+
if (d <= len)
|
|
1140
|
+
return { x: x2, y: y1 + d };
|
|
1141
|
+
d -= len;
|
|
1142
|
+
// Bottom edge: (x2 → x1, y2)
|
|
1143
|
+
len = x2 - x1;
|
|
1144
|
+
if (d <= len)
|
|
1145
|
+
return { x: x2 - d, y: y2 };
|
|
1146
|
+
d -= len;
|
|
1147
|
+
// Left edge: (x1, y2 → y1)
|
|
1148
|
+
return { x: x1, y: y2 - d };
|
|
1149
|
+
}
|
|
793
1150
|
//Code from: https://github.com/floating-ui/floating-ui/blob/master/packages/utils/src/dom.ts
|
|
794
1151
|
const transformProperties = ['transform', 'translate', 'scale', 'rotate', 'perspective'];
|
|
795
1152
|
const willChangeValues = ['transform', 'translate', 'scale', 'rotate', 'perspective', 'filter'];
|