From e8d430372c7c17e7d88317bcb1137a034c5c82c1 Mon Sep 17 00:00:00 2001 From: Orion Reed Date: Tue, 3 Dec 2024 19:14:38 -0500 Subject: [PATCH] use actual bottom for rotated shapes with rope --- src/folk-event-propagator.ts | 3 ++- src/folk-rope.ts | 42 ++++++++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/folk-event-propagator.ts b/src/folk-event-propagator.ts index 351a174..596b0e7 100644 --- a/src/folk-event-propagator.ts +++ b/src/folk-event-propagator.ts @@ -1,4 +1,5 @@ import { css } from './common/tags.ts'; +import type { RotatedDOMRect } from './common/types'; import { FolkRope } from './folk-rope.ts'; import * as parser from '@babel/parser'; import type { Node } from '@babel/types'; @@ -136,7 +137,7 @@ to.${key} = ${value};`); this.expression = this.#expressionTextarea.value = this.getAttribute('expression') || ''; } - override render(sourceRect: DOMRectReadOnly, targetRect: DOMRectReadOnly) { + override render(sourceRect: RotatedDOMRect | DOMRectReadOnly, targetRect: RotatedDOMRect | DOMRectReadOnly) { super.render(sourceRect, targetRect); } diff --git a/src/folk-rope.ts b/src/folk-rope.ts index 31660cc..ba202e7 100644 --- a/src/folk-rope.ts +++ b/src/folk-rope.ts @@ -1,7 +1,7 @@ // This is a rewrite of https://github.com/guerrillacontra/html5-es6-physics-rope import { Vector } from './common/Vector.ts'; -import type { Point } from './common/types.ts'; +import type { Point, RotatedDOMRect } from './common/types.ts'; import { FolkConnection } from './folk-connection.ts'; const lerp = (first: number, second: number, percentage: number) => first + (second - first) * percentage; @@ -63,10 +63,13 @@ export class FolkRope extends FolkConnection { this.#shadow.appendChild(this.#svg); this.#path.setAttribute('stroke-width', '3'); + this.#path.setAttribute('stroke-linecap', 'round'); + this.#path.setAttribute('fill', 'none'); this.#path.style.pointerEvents = 'auto'; this.#path2.setAttribute('stroke-width', '3'); + this.#path2.setAttribute('stroke-linecap', 'round'); this.#path2.setAttribute('fill', 'none'); this.#path2.style.pointerEvents = 'auto'; @@ -108,12 +111,32 @@ export class FolkRope extends FolkConnection { this.draw(); }; - override render(sourceRect: DOMRectReadOnly, targetRect: DOMRectReadOnly) { + override render(sourceRect: RotatedDOMRect | DOMRectReadOnly, targetRect: RotatedDOMRect | DOMRectReadOnly) { + let source: Point; + let target: Point; + + if ('corners' in sourceRect) { + const [_a, _b, bottomRight, bottomLeft] = sourceRect.corners(); + source = Vector.lerp(bottomRight, bottomLeft, 0.5); + } else { + source = { + x: sourceRect.x + sourceRect.width / 2, + y: sourceRect.y + sourceRect.height, + }; + } + + if ('corners' in targetRect) { + const [_a, _b, bottomRight, bottomLeft] = targetRect.corners(); + target = Vector.lerp(bottomRight, bottomLeft, 0.5); + } else { + target = { + x: targetRect.x + targetRect.width / 2, + y: targetRect.y + targetRect.height, + }; + } + if (this.#points.length === 0) { - this.#points = this.#generatePoints( - { x: sourceRect.x + sourceRect.width / 2, y: sourceRect.bottom }, - { x: targetRect.x + targetRect.width / 2, y: targetRect.bottom } - ); + this.#points = this.#generatePoints(source, target); this.#lastTime = 0; @@ -125,11 +148,8 @@ export class FolkRope extends FolkConnection { if (startingPoint === undefined || endingPoint === undefined) return; - startingPoint.pos.x = sourceRect.x + sourceRect.width / 2; - startingPoint.pos.y = sourceRect.bottom; - - endingPoint.pos.x = targetRect.x + targetRect.width / 2; - endingPoint.pos.y = targetRect.bottom; + startingPoint.pos = source; + endingPoint.pos = target; } draw() {