|
|
|
@ -11,7 +11,7 @@ import {
|
|
|
|
|
import {
|
|
|
|
|
add,
|
|
|
|
|
angle,
|
|
|
|
|
between,
|
|
|
|
|
middle,
|
|
|
|
|
distance,
|
|
|
|
|
middlePos,
|
|
|
|
|
minus,
|
|
|
|
@ -20,7 +20,7 @@ import {
|
|
|
|
|
posWithinBase,
|
|
|
|
|
ratioWithinBase,
|
|
|
|
|
relativeTo,
|
|
|
|
|
size,
|
|
|
|
|
norm,
|
|
|
|
|
} from "./Pos"
|
|
|
|
|
|
|
|
|
|
import "../../style/bendable_arrows.css"
|
|
|
|
@ -137,14 +137,14 @@ export default function BendableArrow({
|
|
|
|
|
if (idx == 0) {
|
|
|
|
|
return {
|
|
|
|
|
start: startPos,
|
|
|
|
|
controlPoint: segment.controlPoint,
|
|
|
|
|
controlPoint: segment.controlPoint ?? null,
|
|
|
|
|
end: segment.next,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
const start = segments[idx - 1].next
|
|
|
|
|
return {
|
|
|
|
|
start,
|
|
|
|
|
controlPoint: segment.controlPoint,
|
|
|
|
|
controlPoint: segment.controlPoint ?? null,
|
|
|
|
|
end: segment.next,
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
@ -164,15 +164,15 @@ export default function BendableArrow({
|
|
|
|
|
const cpPos =
|
|
|
|
|
controlPoint ||
|
|
|
|
|
ratioWithinBase(
|
|
|
|
|
add(between(prevRelative, nextRelative), parentBase),
|
|
|
|
|
add(middle(prevRelative, nextRelative), parentBase),
|
|
|
|
|
parentBase,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const setControlPointPos = (newPos: Pos | undefined) => {
|
|
|
|
|
const setControlPointPos = (newPos: Pos | null) => {
|
|
|
|
|
const segment = segments[i]
|
|
|
|
|
const newSegments = segments.toSpliced(i, 1, {
|
|
|
|
|
...segment,
|
|
|
|
|
controlPoint: newPos,
|
|
|
|
|
controlPoint: newPos ?? undefined,
|
|
|
|
|
})
|
|
|
|
|
onSegmentsChanges(newSegments)
|
|
|
|
|
}
|
|
|
|
@ -185,7 +185,7 @@ export default function BendableArrow({
|
|
|
|
|
posRatio={cpPos}
|
|
|
|
|
parentBase={parentBase}
|
|
|
|
|
onPosValidated={setControlPointPos}
|
|
|
|
|
onRemove={() => setControlPointPos(undefined)}
|
|
|
|
|
onRemove={() => setControlPointPos(null)}
|
|
|
|
|
onMoves={(controlPoint) => {
|
|
|
|
|
setInternalSegments((is) => {
|
|
|
|
|
return is.toSpliced(i, 1, {
|
|
|
|
@ -322,7 +322,7 @@ export default function BendableArrow({
|
|
|
|
|
posWithinBase(controlPoint, parentBase),
|
|
|
|
|
svgPosRelativeToBase,
|
|
|
|
|
)
|
|
|
|
|
: between(startRelative, nextRelative)
|
|
|
|
|
: middle(startRelative, nextRelative)
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
start: startRelative,
|
|
|
|
@ -344,7 +344,7 @@ export default function BendableArrow({
|
|
|
|
|
|
|
|
|
|
const previousSegmentCpAndCurrentPosVector = minus(
|
|
|
|
|
start,
|
|
|
|
|
previousSegment?.cp ?? between(start, end),
|
|
|
|
|
previousSegment?.cp ?? middle(start, end),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const smoothCp = previousSegment
|
|
|
|
@ -422,7 +422,7 @@ export default function BendableArrow({
|
|
|
|
|
const nextPos = segment.next
|
|
|
|
|
const segmentCp = segment.controlPoint
|
|
|
|
|
? segment.controlPoint
|
|
|
|
|
: between(currentPos, nextPos)
|
|
|
|
|
: middle(currentPos, nextPos)
|
|
|
|
|
|
|
|
|
|
const smoothCp = beforeSegment
|
|
|
|
|
? add(
|
|
|
|
@ -430,7 +430,7 @@ export default function BendableArrow({
|
|
|
|
|
minus(
|
|
|
|
|
currentPos,
|
|
|
|
|
beforeSegment.controlPoint ??
|
|
|
|
|
between(beforeSegmentPos, currentPos),
|
|
|
|
|
middle(beforeSegmentPos, currentPos),
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
: segmentCp
|
|
|
|
@ -549,7 +549,7 @@ enum PointSegmentSearchResult {
|
|
|
|
|
|
|
|
|
|
interface FullSegment {
|
|
|
|
|
start: Pos
|
|
|
|
|
controlPoint: Pos | undefined
|
|
|
|
|
controlPoint: Pos | null
|
|
|
|
|
end: Pos
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -573,7 +573,7 @@ function wavyBezier(
|
|
|
|
|
): string {
|
|
|
|
|
function getVerticalAmplification(t: number): Pos {
|
|
|
|
|
const velocity = cubicBeziersDerivative(start, cp1, cp2, end, t)
|
|
|
|
|
const velocityLength = size(velocity)
|
|
|
|
|
const velocityLength = norm(velocity)
|
|
|
|
|
//rotate the velocity by 90 deg
|
|
|
|
|
const projection = { x: velocity.y, y: -velocity.x }
|
|
|
|
|
|
|
|
|
|