@plait/common 0.51.1 → 0.51.3
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/esm2022/generators/generator.mjs +3 -3
- package/esm2022/utils/default-orthogonal-routing.mjs +87 -0
- package/esm2022/utils/direction.mjs +15 -3
- package/esm2022/utils/index.mjs +3 -1
- package/esm2022/utils/line-path.mjs +2 -97
- package/esm2022/utils/math.mjs +4 -4
- package/esm2022/utils/rotate.mjs +7 -0
- package/esm2022/utils/vector.mjs +4 -4
- package/fesm2022/plait-common.mjs +169 -160
- package/fesm2022/plait-common.mjs.map +1 -1
- package/package.json +1 -1
- package/utils/default-orthogonal-routing.d.ts +2 -0
- package/utils/direction.d.ts +2 -1
- package/utils/index.d.ts +2 -0
- package/utils/line-path.d.ts +1 -13
- package/utils/rotate.d.ts +2 -0
- package/utils/vector.d.ts +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { setAngleForG, RectangleClient, drawCircle, PlaitBoard, createG, drawRectangle, createForeignObject, updateForeignObject, ResizeCursorClass, setDragging, distanceBetweenPointAndPoint, Point, Direction, hotkeys, PlaitElement, PlaitContextService, rotate, getSelectedElements, Transforms, getRectangleByElements, MERGING, PlaitPointerType, isMainPointer, toViewBoxPoint, toHostPoint, preventTouchMove, PRESS_AND_MOVE_BUFFER, isDragging, throttleRAF, handleTouchTarget, PlaitPluginElementComponent, isSelectionMoving, ACTIVE_STROKE_WIDTH } from '@plait/core';
|
|
2
2
|
import { isKeyHotkey } from 'is-hotkey';
|
|
3
3
|
import { PlaitMarkEditor, MarkTypes, AlignEditor } from '@plait/text';
|
|
4
4
|
import { Node, Transforms as Transforms$1, Editor } from 'slate';
|
|
@@ -55,7 +55,7 @@ class Generator {
|
|
|
55
55
|
this.g = g;
|
|
56
56
|
const rect = this.board.getRectangle(element);
|
|
57
57
|
if (rect && element.angle) {
|
|
58
|
-
|
|
58
|
+
setAngleForG(g, RectangleClient.getCenterPoint(rect), element.angle);
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
else {
|
|
@@ -303,12 +303,157 @@ const isCornerHandle = (board, handle) => {
|
|
|
303
303
|
return !isEdgeHandle(board, handle);
|
|
304
304
|
};
|
|
305
305
|
|
|
306
|
+
function getUnitVectorByPointAndPoint(point1, point2) {
|
|
307
|
+
const deltaX = point2[0] - point1[0];
|
|
308
|
+
const deltaY = point2[1] - point1[1];
|
|
309
|
+
const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
310
|
+
// Avoid division by zero if the points are the same
|
|
311
|
+
if (distance === 0) {
|
|
312
|
+
throw new Error('Points must not be the same for a unit vector calculation.');
|
|
313
|
+
}
|
|
314
|
+
// Calculate the unit vector components
|
|
315
|
+
const unitX = deltaX / distance;
|
|
316
|
+
const unitY = deltaY / distance;
|
|
317
|
+
return [unitX, unitY];
|
|
318
|
+
}
|
|
319
|
+
function getPointByVector(point, vector, component) {
|
|
320
|
+
const distance = Math.hypot(vector[0], vector[1]);
|
|
321
|
+
return [point[0] + (vector[0] / distance) * component, point[1] + (vector[1] / distance) * component];
|
|
322
|
+
}
|
|
323
|
+
function getPointByUnitVectorAndDirectionComponent(point, unitVector, directionComponent, isHorizontal) {
|
|
324
|
+
if (isHorizontal) {
|
|
325
|
+
return [point[0] + directionComponent, point[1] + (directionComponent / unitVector[0]) * unitVector[1]];
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
return [point[0] + (directionComponent / unitVector[1]) * unitVector[0], point[1] + directionComponent];
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
function rotateVectorAnti90(vector) {
|
|
332
|
+
const x = vector[0];
|
|
333
|
+
const y = vector[1];
|
|
334
|
+
const rotatedX = y;
|
|
335
|
+
const rotatedY = -x;
|
|
336
|
+
return [rotatedX, rotatedY];
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
function isPointOnSegment(point, startPoint, endPoint) {
|
|
340
|
+
const distanceToStart = distanceBetweenPointAndPoint(point[0], point[1], startPoint[0], startPoint[1]);
|
|
341
|
+
const distanceToEnd = distanceBetweenPointAndPoint(point[0], point[1], endPoint[0], endPoint[1]);
|
|
342
|
+
const segmentLength = distanceBetweenPointAndPoint(startPoint[0], startPoint[1], endPoint[0], endPoint[1]);
|
|
343
|
+
return Math.abs(distanceToStart + distanceToEnd - segmentLength) < 0.1;
|
|
344
|
+
}
|
|
345
|
+
const getCrossingPointsBetweenPointAndSegment = (point, startPoint, endPoint) => {
|
|
346
|
+
const result = [];
|
|
347
|
+
const xRange = [Math.min(startPoint[0], endPoint[0]), Math.max(startPoint[0], endPoint[0])];
|
|
348
|
+
const yRange = [Math.min(startPoint[1], endPoint[1]), Math.max(startPoint[1], endPoint[1])];
|
|
349
|
+
const unitVector = getUnitVectorByPointAndPoint(startPoint, endPoint);
|
|
350
|
+
if (point[0] >= xRange[0] && point[0] <= xRange[1]) {
|
|
351
|
+
const crossingPoint = getPointByUnitVectorAndDirectionComponent(startPoint, unitVector, point[0] - startPoint[0], true);
|
|
352
|
+
result.push(crossingPoint);
|
|
353
|
+
}
|
|
354
|
+
else if (point[1] >= yRange[0] && point[1] <= yRange[1]) {
|
|
355
|
+
const crossingPoint = getPointByUnitVectorAndDirectionComponent(startPoint, unitVector, point[1] - startPoint[1], false);
|
|
356
|
+
result.push(crossingPoint);
|
|
357
|
+
}
|
|
358
|
+
return result;
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
function getPointOnPolyline(points, ratio) {
|
|
362
|
+
const totalLength = calculatePolylineLength(points);
|
|
363
|
+
const targetDistance = totalLength * ratio;
|
|
364
|
+
let accumulatedDistance = 0;
|
|
365
|
+
for (let i = 0; i < points.length - 1; i++) {
|
|
366
|
+
const [x1, y1] = points[i];
|
|
367
|
+
const [x2, y2] = points[i + 1];
|
|
368
|
+
const segmentLength = distanceBetweenPointAndPoint(x1, y1, x2, y2);
|
|
369
|
+
if (accumulatedDistance + segmentLength >= targetDistance) {
|
|
370
|
+
const remainingDistance = targetDistance - accumulatedDistance;
|
|
371
|
+
const ratioInSegment = remainingDistance / segmentLength;
|
|
372
|
+
const targetX = x1 + (x2 - x1) * ratioInSegment;
|
|
373
|
+
const targetY = y1 + (y2 - y1) * ratioInSegment;
|
|
374
|
+
return [targetX, targetY];
|
|
375
|
+
}
|
|
376
|
+
accumulatedDistance += segmentLength;
|
|
377
|
+
}
|
|
378
|
+
return points[points.length - 1];
|
|
379
|
+
}
|
|
380
|
+
function calculatePolylineLength(points) {
|
|
381
|
+
let length = 0;
|
|
382
|
+
for (let i = 0; i < points.length - 1; i++) {
|
|
383
|
+
const [x1, y1] = points[i];
|
|
384
|
+
const [x2, y2] = points[i + 1];
|
|
385
|
+
length += distanceBetweenPointAndPoint(x1, y1, x2, y2);
|
|
386
|
+
}
|
|
387
|
+
return length;
|
|
388
|
+
}
|
|
389
|
+
function getRatioByPoint(points, point) {
|
|
390
|
+
const totalLength = calculatePolylineLength(points);
|
|
391
|
+
let distance = 0;
|
|
392
|
+
for (let i = 0; i < points.length - 1; i++) {
|
|
393
|
+
const isOverlap = isPointOnSegment(point, points[i], points[i + 1]);
|
|
394
|
+
if (isOverlap) {
|
|
395
|
+
distance += distanceBetweenPointAndPoint(point[0], point[1], points[i][0], points[i][1]);
|
|
396
|
+
return distance / totalLength;
|
|
397
|
+
}
|
|
398
|
+
else {
|
|
399
|
+
distance += distanceBetweenPointAndPoint(points[i][0], points[i][1], points[i + 1][0], points[i + 1][1]);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
throw new Error('Cannot get ratio by point');
|
|
403
|
+
}
|
|
404
|
+
const removeDuplicatePoints = (points) => {
|
|
405
|
+
const newArray = [];
|
|
406
|
+
points.forEach(point => {
|
|
407
|
+
const index = newArray.findIndex(otherPoint => {
|
|
408
|
+
return Point.isEquals(point, otherPoint);
|
|
409
|
+
});
|
|
410
|
+
if (index === -1)
|
|
411
|
+
newArray.push(point);
|
|
412
|
+
});
|
|
413
|
+
return newArray;
|
|
414
|
+
};
|
|
415
|
+
function simplifyOrthogonalPoints(points) {
|
|
416
|
+
if (points.length <= 2)
|
|
417
|
+
return points;
|
|
418
|
+
let simplifiedPoints = [points[0]];
|
|
419
|
+
for (let i = 1; i < points.length - 1; i++) {
|
|
420
|
+
const previous = points[i - 1];
|
|
421
|
+
const current = points[i];
|
|
422
|
+
const next = points[i + 1];
|
|
423
|
+
const isTurn = !(Point.isOverHorizontal([previous, current, next]) || Point.isOverVertical([previous, current, next]));
|
|
424
|
+
if (isTurn) {
|
|
425
|
+
simplifiedPoints.push(current);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
simplifiedPoints.push(points[points.length - 1]);
|
|
429
|
+
return simplifiedPoints;
|
|
430
|
+
}
|
|
431
|
+
const getExtendPoint = (source, target, extendDistance) => {
|
|
432
|
+
const distance = distanceBetweenPointAndPoint(...source, ...target);
|
|
433
|
+
const isEqual = Point.isEquals(source, target);
|
|
434
|
+
const sin = isEqual ? 1 : (target[1] - source[1]) / distance;
|
|
435
|
+
const cos = isEqual ? 1 : (target[0] - source[0]) / distance;
|
|
436
|
+
return [source[0] + extendDistance * cos, source[1] + extendDistance * sin];
|
|
437
|
+
};
|
|
438
|
+
|
|
306
439
|
const handleDirectionFactors = {
|
|
307
440
|
[Direction.left]: { x: -1, y: 0 },
|
|
308
441
|
[Direction.right]: { x: 1, y: 0 },
|
|
309
442
|
[Direction.top]: { x: 0, y: -1 },
|
|
310
443
|
[Direction.bottom]: { x: 0, y: 1 }
|
|
311
444
|
};
|
|
445
|
+
function getOppositeDirection(direction) {
|
|
446
|
+
switch (direction) {
|
|
447
|
+
case Direction.left:
|
|
448
|
+
return Direction.right;
|
|
449
|
+
case Direction.right:
|
|
450
|
+
return Direction.left;
|
|
451
|
+
case Direction.top:
|
|
452
|
+
return Direction.bottom;
|
|
453
|
+
case Direction.bottom:
|
|
454
|
+
return Direction.top;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
312
457
|
function getDirectionByPointOfRectangle(point) {
|
|
313
458
|
if (point[0] === 0) {
|
|
314
459
|
return Direction.left;
|
|
@@ -378,83 +523,18 @@ function getDirectionBetweenPointAndPoint(source, target) {
|
|
|
378
523
|
function getDirectionFactor(direction) {
|
|
379
524
|
return handleDirectionFactors[direction];
|
|
380
525
|
}
|
|
381
|
-
function
|
|
382
|
-
const directionFactor =
|
|
526
|
+
function getDirectionFactorByDirectionComponent(directionComponent) {
|
|
527
|
+
const directionFactor = directionComponent === 0 ? directionComponent : directionComponent / Math.abs(directionComponent);
|
|
383
528
|
return directionFactor;
|
|
384
529
|
}
|
|
385
530
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
const deltaY = point2[1] - point1[1];
|
|
389
|
-
const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
390
|
-
// Avoid division by zero if the points are the same
|
|
391
|
-
if (distance === 0) {
|
|
392
|
-
throw new Error('Points must not be the same for a unit vector calculation.');
|
|
393
|
-
}
|
|
394
|
-
// Calculate the unit vector components
|
|
395
|
-
const unitX = deltaX / distance;
|
|
396
|
-
const unitY = deltaY / distance;
|
|
397
|
-
return [unitX, unitY];
|
|
398
|
-
}
|
|
399
|
-
function getPointByVector(point, vector, component) {
|
|
400
|
-
const distance = Math.hypot(vector[0], vector[1]);
|
|
401
|
-
return [point[0] + (vector[0] / distance) * component, point[1] + (vector[1] / distance) * component];
|
|
402
|
-
}
|
|
403
|
-
function getPointByUnitVectorAndVectorComponent(point, unitVector, vectorComponent, isHorizontal) {
|
|
404
|
-
if (isHorizontal) {
|
|
405
|
-
return [point[0] + vectorComponent, point[1] + (vectorComponent / unitVector[0]) * unitVector[1]];
|
|
406
|
-
}
|
|
407
|
-
else {
|
|
408
|
-
return [point[0] + (vectorComponent / unitVector[1]) * unitVector[0], point[1] + vectorComponent];
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
function rotateVectorAnti90(vector) {
|
|
412
|
-
const x = vector[0];
|
|
413
|
-
const y = vector[1];
|
|
414
|
-
const rotatedX = y;
|
|
415
|
-
const rotatedY = -x;
|
|
416
|
-
return [rotatedX, rotatedY];
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
function isPointOnSegment(point, startPoint, endPoint) {
|
|
420
|
-
const distanceToStart = distanceBetweenPointAndPoint(point[0], point[1], startPoint[0], startPoint[1]);
|
|
421
|
-
const distanceToEnd = distanceBetweenPointAndPoint(point[0], point[1], endPoint[0], endPoint[1]);
|
|
422
|
-
const segmentLength = distanceBetweenPointAndPoint(startPoint[0], startPoint[1], endPoint[0], endPoint[1]);
|
|
423
|
-
return Math.abs(distanceToStart + distanceToEnd - segmentLength) < 0.1;
|
|
424
|
-
}
|
|
425
|
-
const getCrossingPointsBetweenPointAndSegment = (point, startPoint, endPoint) => {
|
|
426
|
-
const result = [];
|
|
427
|
-
const xRange = [Math.min(startPoint[0], endPoint[0]), Math.max(startPoint[0], endPoint[0])];
|
|
428
|
-
const yRange = [Math.min(startPoint[1], endPoint[1]), Math.max(startPoint[1], endPoint[1])];
|
|
429
|
-
const unitVector = getUnitVectorByPointAndPoint(startPoint, endPoint);
|
|
430
|
-
if (point[0] >= xRange[0] && point[0] <= xRange[1]) {
|
|
431
|
-
const crossingPoint = getPointByUnitVectorAndVectorComponent(startPoint, unitVector, point[0] - startPoint[0], true);
|
|
432
|
-
result.push(crossingPoint);
|
|
433
|
-
}
|
|
434
|
-
else if (point[1] >= yRange[0] && point[1] <= yRange[1]) {
|
|
435
|
-
const crossingPoint = getPointByUnitVectorAndVectorComponent(startPoint, unitVector, point[1] - startPoint[1], false);
|
|
436
|
-
result.push(crossingPoint);
|
|
437
|
-
}
|
|
438
|
-
return result;
|
|
439
|
-
};
|
|
440
|
-
|
|
441
|
-
function getOppositeDirection(direction) {
|
|
442
|
-
switch (direction) {
|
|
443
|
-
case Direction.left:
|
|
444
|
-
return Direction.right;
|
|
445
|
-
case Direction.right:
|
|
446
|
-
return Direction.left;
|
|
447
|
-
case Direction.top:
|
|
448
|
-
return Direction.bottom;
|
|
449
|
-
case Direction.bottom:
|
|
450
|
-
return Direction.top;
|
|
451
|
-
}
|
|
452
|
-
}
|
|
531
|
+
// Credits to xyflow
|
|
532
|
+
// https://github.com/xyflow/xyflow/blob/main/packages/system/src/utils/edges/smoothstep-edge.ts
|
|
453
533
|
const getPoints = (source, sourcePosition, target, targetPosition, offset) => {
|
|
454
|
-
const
|
|
455
|
-
const
|
|
456
|
-
const sourceGapped = [source[0] +
|
|
457
|
-
const targetGapped = [target[0] +
|
|
534
|
+
const sourceDirectionFactors = getDirectionFactor(sourcePosition);
|
|
535
|
+
const targetDFs = getDirectionFactor(targetPosition);
|
|
536
|
+
const sourceGapped = [source[0] + sourceDirectionFactors.x * offset, source[1] + sourceDirectionFactors.y * offset];
|
|
537
|
+
const targetGapped = [target[0] + targetDFs.x * offset, target[1] + targetDFs.y * offset];
|
|
458
538
|
const dir = getDirection(sourceGapped, sourcePosition, targetGapped);
|
|
459
539
|
const dirAccessor = dir.x !== 0 ? 'x' : 'y';
|
|
460
540
|
const currDir = dir[dirAccessor];
|
|
@@ -467,7 +547,7 @@ const getPoints = (source, sourcePosition, target, targetPosition, offset) => {
|
|
|
467
547
|
targetY: target[1]
|
|
468
548
|
});
|
|
469
549
|
// opposite handle positions, default case
|
|
470
|
-
if (
|
|
550
|
+
if (sourceDirectionFactors[dirAccessor] * targetDFs[dirAccessor] === -1) {
|
|
471
551
|
centerX = defaultCenterX;
|
|
472
552
|
centerY = defaultCenterY;
|
|
473
553
|
// --->
|
|
@@ -484,7 +564,7 @@ const getPoints = (source, sourcePosition, target, targetPosition, offset) => {
|
|
|
484
564
|
[sourceGapped[0], centerY],
|
|
485
565
|
[targetGapped[0], centerY]
|
|
486
566
|
];
|
|
487
|
-
if (
|
|
567
|
+
if (sourceDirectionFactors[dirAccessor] === currDir) {
|
|
488
568
|
points = dirAccessor === 'x' ? verticalSplit : horizontalSplit;
|
|
489
569
|
}
|
|
490
570
|
else {
|
|
@@ -497,21 +577,21 @@ const getPoints = (source, sourcePosition, target, targetPosition, offset) => {
|
|
|
497
577
|
const targetSource = [[targetGapped[0], sourceGapped[1]]];
|
|
498
578
|
// this handles edges with same handle positions
|
|
499
579
|
if (dirAccessor === 'x') {
|
|
500
|
-
points =
|
|
580
|
+
points = sourceDirectionFactors.x === currDir ? targetSource : sourceTarget;
|
|
501
581
|
}
|
|
502
582
|
else {
|
|
503
|
-
points =
|
|
583
|
+
points = sourceDirectionFactors.y === currDir ? sourceTarget : targetSource;
|
|
504
584
|
}
|
|
505
585
|
// these are conditions for handling mixed handle positions like right -> bottom for example
|
|
506
586
|
let flipSourceTarget;
|
|
507
587
|
if (sourcePosition !== targetPosition) {
|
|
508
588
|
const dirAccessorOpposite = dirAccessor === 'x' ? 1 : 0;
|
|
509
|
-
const isSameDir =
|
|
589
|
+
const isSameDir = sourceDirectionFactors[dirAccessor] === targetDFs[dirAccessor === 'x' ? 'y' : 'x'];
|
|
510
590
|
const sourceGtTarget = sourceGapped[dirAccessorOpposite] > targetGapped[dirAccessorOpposite];
|
|
511
591
|
const sourceLtTarget = sourceGapped[dirAccessorOpposite] < targetGapped[dirAccessorOpposite];
|
|
512
592
|
flipSourceTarget =
|
|
513
|
-
(
|
|
514
|
-
(
|
|
593
|
+
(sourceDirectionFactors[dirAccessor] === 1 && ((!isSameDir && sourceGtTarget) || (isSameDir && sourceLtTarget))) ||
|
|
594
|
+
(sourceDirectionFactors[dirAccessor] !== 1 && ((!isSameDir && sourceLtTarget) || (isSameDir && sourceGtTarget)));
|
|
515
595
|
if (flipSourceTarget) {
|
|
516
596
|
points = dirAccessor === 'x' ? sourceTarget : targetSource;
|
|
517
597
|
}
|
|
@@ -532,83 +612,6 @@ function getEdgeCenter({ sourceX, sourceY, targetX, targetY }) {
|
|
|
532
612
|
const centerY = targetY < sourceY ? targetY + yOffset : targetY - yOffset;
|
|
533
613
|
return [centerX, centerY, xOffset, yOffset];
|
|
534
614
|
}
|
|
535
|
-
function getPointOnPolyline(points, ratio) {
|
|
536
|
-
const totalLength = calculatePolylineLength(points);
|
|
537
|
-
const targetDistance = totalLength * ratio;
|
|
538
|
-
let accumulatedDistance = 0;
|
|
539
|
-
for (let i = 0; i < points.length - 1; i++) {
|
|
540
|
-
const [x1, y1] = points[i];
|
|
541
|
-
const [x2, y2] = points[i + 1];
|
|
542
|
-
const segmentLength = distanceBetweenPointAndPoint(x1, y1, x2, y2);
|
|
543
|
-
if (accumulatedDistance + segmentLength >= targetDistance) {
|
|
544
|
-
const remainingDistance = targetDistance - accumulatedDistance;
|
|
545
|
-
const ratioInSegment = remainingDistance / segmentLength;
|
|
546
|
-
const targetX = x1 + (x2 - x1) * ratioInSegment;
|
|
547
|
-
const targetY = y1 + (y2 - y1) * ratioInSegment;
|
|
548
|
-
return [targetX, targetY];
|
|
549
|
-
}
|
|
550
|
-
accumulatedDistance += segmentLength;
|
|
551
|
-
}
|
|
552
|
-
return points[points.length - 1];
|
|
553
|
-
}
|
|
554
|
-
function calculatePolylineLength(points) {
|
|
555
|
-
let length = 0;
|
|
556
|
-
for (let i = 0; i < points.length - 1; i++) {
|
|
557
|
-
const [x1, y1] = points[i];
|
|
558
|
-
const [x2, y2] = points[i + 1];
|
|
559
|
-
length += distanceBetweenPointAndPoint(x1, y1, x2, y2);
|
|
560
|
-
}
|
|
561
|
-
return length;
|
|
562
|
-
}
|
|
563
|
-
function getRatioByPoint(points, point) {
|
|
564
|
-
const totalLength = calculatePolylineLength(points);
|
|
565
|
-
let distance = 0;
|
|
566
|
-
for (let i = 0; i < points.length - 1; i++) {
|
|
567
|
-
const isOverlap = isPointOnSegment(point, points[i], points[i + 1]);
|
|
568
|
-
if (isOverlap) {
|
|
569
|
-
distance += distanceBetweenPointAndPoint(point[0], point[1], points[i][0], points[i][1]);
|
|
570
|
-
return distance / totalLength;
|
|
571
|
-
}
|
|
572
|
-
else {
|
|
573
|
-
distance += distanceBetweenPointAndPoint(points[i][0], points[i][1], points[i + 1][0], points[i + 1][1]);
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
throw new Error('Cannot get ratio by point');
|
|
577
|
-
}
|
|
578
|
-
const removeDuplicatePoints = (points) => {
|
|
579
|
-
const newArray = [];
|
|
580
|
-
points.forEach(point => {
|
|
581
|
-
const index = newArray.findIndex(otherPoint => {
|
|
582
|
-
return Point.isEquals(point, otherPoint);
|
|
583
|
-
});
|
|
584
|
-
if (index === -1)
|
|
585
|
-
newArray.push(point);
|
|
586
|
-
});
|
|
587
|
-
return newArray;
|
|
588
|
-
};
|
|
589
|
-
function simplifyOrthogonalPoints(points) {
|
|
590
|
-
if (points.length <= 2)
|
|
591
|
-
return points;
|
|
592
|
-
let simplifiedPoints = [points[0]];
|
|
593
|
-
for (let i = 1; i < points.length - 1; i++) {
|
|
594
|
-
const previous = points[i - 1];
|
|
595
|
-
const current = points[i];
|
|
596
|
-
const next = points[i + 1];
|
|
597
|
-
const isTurn = !(Point.isOverHorizontal([previous, current, next]) || Point.isOverVertical([previous, current, next]));
|
|
598
|
-
if (isTurn) {
|
|
599
|
-
simplifiedPoints.push(current);
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
simplifiedPoints.push(points[points.length - 1]);
|
|
603
|
-
return simplifiedPoints;
|
|
604
|
-
}
|
|
605
|
-
const getExtendPoint = (source, target, extendDistance) => {
|
|
606
|
-
const distance = distanceBetweenPointAndPoint(...source, ...target);
|
|
607
|
-
const isEqual = Point.isEquals(source, target);
|
|
608
|
-
const sin = isEqual ? 1 : (target[1] - source[1]) / distance;
|
|
609
|
-
const cos = isEqual ? 1 : (target[0] - source[0]) / distance;
|
|
610
|
-
return [source[0] + extendDistance * cos, source[1] + extendDistance * sin];
|
|
611
|
-
};
|
|
612
615
|
|
|
613
616
|
function isVirtualKey(e) {
|
|
614
617
|
const isMod = e.ctrlKey || e.metaKey;
|
|
@@ -1133,6 +1136,12 @@ const getMemorizedLatest = (memorizedKey) => {
|
|
|
1133
1136
|
return map.get(memorizedKey);
|
|
1134
1137
|
};
|
|
1135
1138
|
|
|
1139
|
+
const rotatePoints = (points, centerPoint, angle) => {
|
|
1140
|
+
return points.map(point => {
|
|
1141
|
+
return rotate(point[0], point[1], centerPoint[0], centerPoint[1], angle);
|
|
1142
|
+
});
|
|
1143
|
+
};
|
|
1144
|
+
|
|
1136
1145
|
const setProperty = (board, properties, options) => {
|
|
1137
1146
|
const selectedElements = getSelectedElements(board);
|
|
1138
1147
|
selectedElements.forEach(element => {
|
|
@@ -1580,5 +1589,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.8", ngImpor
|
|
|
1580
1589
|
* Generated bundle index. Do not edit.
|
|
1581
1590
|
*/
|
|
1582
1591
|
|
|
1583
|
-
export { AStar, ActiveGenerator, AlignTransform, BASE, BoardCreationMode, CommonPluginElement, DEFAULT_ROUTE_MARGIN, Generator, IS_RESIZING, ImageBaseComponent, ImageGenerator, MediaKeys, PICTURE_ACCEPTED_UPLOAD_SIZE, PRIMARY_COLOR, PointGraph, PointNode, PriorityQueue, PropertyTransforms, RESIZE_HANDLE_DIAMETER, ResizeHandle, TRANSPARENT, TextTransforms, WithCommonPluginKey, WithTextPluginKey, acceptImageTypes, addElementOfFocusedImage, addResizing, alignBottom, alignHorizontalCenter, alignLeft, alignRight, alignTop, alignVerticalCenter, buildImage, calculatePolylineLength, createGraph, distributeHorizontal, distributeVertical, drawFillPrimaryHandle, drawHandle, drawPrimaryHandle, generateElbowLineRoute, getCreationMode, getCrossingPointsBetweenPointAndSegment,
|
|
1592
|
+
export { AStar, ActiveGenerator, AlignTransform, BASE, BoardCreationMode, CommonPluginElement, DEFAULT_ROUTE_MARGIN, Generator, IS_RESIZING, ImageBaseComponent, ImageGenerator, MediaKeys, PICTURE_ACCEPTED_UPLOAD_SIZE, PRIMARY_COLOR, PointGraph, PointNode, PriorityQueue, PropertyTransforms, RESIZE_HANDLE_DIAMETER, ResizeHandle, TRANSPARENT, TextTransforms, WithCommonPluginKey, WithTextPluginKey, acceptImageTypes, addElementOfFocusedImage, addResizing, alignBottom, alignHorizontalCenter, alignLeft, alignRight, alignTop, alignVerticalCenter, buildImage, calculatePolylineLength, createGraph, distributeHorizontal, distributeVertical, drawFillPrimaryHandle, drawHandle, drawPrimaryHandle, generateElbowLineRoute, getCreationMode, getCrossingPointsBetweenPointAndSegment, getDirectionBetweenPointAndPoint, getDirectionByPointOfRectangle, getDirectionByVector, getDirectionFactor, getDirectionFactorByDirectionComponent, getElementOfFocusedImage, getElementsText, getExtendPoint, getFirstTextEditor, getFirstTextManage, getGraphPoints, getIndexByResizeHandle, getMemorizedLatest, getNextPoint, getOppositeDirection, getPointByUnitVectorAndDirectionComponent, getPointByVector, getPointOnPolyline, getPoints, getRatioByPoint, getRectangleResizeHandleRefs, getResizeHandleByIndex, getResizeHandlePointByIndex, getSourceAndTargetOuterRectangle, getSymmetricHandleIndex, getTextEditors, getTextManages, getTextMarksByElement, getUnitVectorByPointAndPoint, hasAfterDraw, isCornerHandle, isDelete, isDndMode, isDrawingMode, isEdgeHandle, isEnterHotkey, isExpandHotkey, isPointOnSegment, isResizing, isResizingByCondition, isSourceAndTargetIntersect, isSpaceHotkey, isTabHotkey, isVirtualKey, memorizeLatest, normalizeShapePoints, reduceRouteMargin, removeDuplicatePoints, removeElementOfFocusedImage, removeResizing, rotatePoints, rotateVectorAnti90, routeAdjust, selectImage, setCreationMode, setProperty, simplifyOrthogonalPoints, withResize };
|
|
1584
1593
|
//# sourceMappingURL=plait-common.mjs.map
|