rope cleanup
This commit is contained in:
parent
ce2b0581ae
commit
1475c41a85
|
|
@ -1,6 +1,5 @@
|
||||||
// This is a rewrite of https://github.com/guerrillacontra/html5-es6-physics-rope
|
// This is a rewrite of https://github.com/guerrillacontra/html5-es6-physics-rope
|
||||||
|
|
||||||
import { ResizeObserverManager } from '../resize-observer.ts';
|
|
||||||
import { Vector, type Vector2 } from '../utils/Vector2.ts';
|
import { Vector, type Vector2 } from '../utils/Vector2.ts';
|
||||||
import { AbstractArrow } from './abstract-arrow.ts';
|
import { AbstractArrow } from './abstract-arrow.ts';
|
||||||
import { Vertex } from './utils.ts';
|
import { Vertex } from './utils.ts';
|
||||||
|
|
@ -20,8 +19,6 @@ interface RopePoint {
|
||||||
next: RopePoint | null;
|
next: RopePoint | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const resizeObserver = new ResizeObserverManager();
|
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
'fc-rope': FolkRope;
|
'fc-rope': FolkRope;
|
||||||
|
|
@ -37,8 +34,6 @@ export class FolkRope extends AbstractArrow {
|
||||||
|
|
||||||
#rAFId = -1;
|
#rAFId = -1;
|
||||||
#lastTime = 0;
|
#lastTime = 0;
|
||||||
#currentTime = 0;
|
|
||||||
#deltaTime = 0;
|
|
||||||
#gravity = { x: 0, y: 3000 };
|
#gravity = { x: 0, y: 3000 };
|
||||||
#points: RopePoint[] = [];
|
#points: RopePoint[] = [];
|
||||||
|
|
||||||
|
|
@ -46,41 +41,32 @@ export class FolkRope extends AbstractArrow {
|
||||||
return this.#points;
|
return this.#points;
|
||||||
}
|
}
|
||||||
|
|
||||||
#stroke = this.getAttribute('stroke') || 'black';
|
#stroke = '';
|
||||||
get stroke() {
|
get stroke() {
|
||||||
return this.#stroke;
|
return this.#stroke;
|
||||||
}
|
}
|
||||||
set stroke(stroke) {
|
set stroke(stroke) {
|
||||||
this.#stroke = stroke;
|
this.#stroke = stroke;
|
||||||
// TODO: redraw rope?
|
this.#path.setAttribute('stroke', this.#stroke);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
this.#svg.style.height = '100%';
|
||||||
|
this.#svg.style.width = '100%';
|
||||||
this.#svg.appendChild(this.#path);
|
this.#svg.appendChild(this.#path);
|
||||||
this.#shadow.appendChild(this.#svg);
|
this.#shadow.appendChild(this.#svg);
|
||||||
}
|
this.#path.setAttribute('stroke-width', '2');
|
||||||
|
this.#path.setAttribute('fill', 'none');
|
||||||
override connectedCallback(): void {
|
this.stroke = this.getAttribute('stroke') || 'black';
|
||||||
super.connectedCallback();
|
|
||||||
|
|
||||||
resizeObserver.observe(this, this.#onResize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override disconnectedCallback(): void {
|
override disconnectedCallback(): void {
|
||||||
super.disconnectedCallback();
|
super.disconnectedCallback();
|
||||||
|
|
||||||
resizeObserver.unobserve(this, this.#onResize);
|
|
||||||
cancelAnimationFrame(this.#rAFId);
|
cancelAnimationFrame(this.#rAFId);
|
||||||
}
|
}
|
||||||
|
|
||||||
#onResize = (entry: ResizeObserverEntry) => {
|
|
||||||
this.#svg.setAttribute('width', entry.contentRect.width.toString());
|
|
||||||
this.#svg.setAttribute('height', entry.contentRect.height.toString());
|
|
||||||
this.draw();
|
|
||||||
};
|
|
||||||
|
|
||||||
#dtAccumulator = 0;
|
#dtAccumulator = 0;
|
||||||
#fixedTimestep = 1 / 60;
|
#fixedTimestep = 1 / 60;
|
||||||
|
|
||||||
|
|
@ -118,8 +104,6 @@ export class FolkRope extends AbstractArrow {
|
||||||
);
|
);
|
||||||
|
|
||||||
this.#lastTime = 0;
|
this.#lastTime = 0;
|
||||||
this.#currentTime = 0;
|
|
||||||
this.#deltaTime = 0;
|
|
||||||
|
|
||||||
this.#tick();
|
this.#tick();
|
||||||
}
|
}
|
||||||
|
|
@ -146,9 +130,6 @@ export class FolkRope extends AbstractArrow {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.#path.setAttribute('d', pathData);
|
this.#path.setAttribute('d', pathData);
|
||||||
this.#path.setAttribute('stroke', this.#stroke);
|
|
||||||
this.#path.setAttribute('stroke-width', '2');
|
|
||||||
this.#path.setAttribute('fill', 'none');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#generatePoints(start: Vertex, end: Vertex) {
|
#generatePoints(start: Vertex, end: Vertex) {
|
||||||
|
|
@ -209,25 +190,6 @@ export class FolkRope extends AbstractArrow {
|
||||||
|
|
||||||
// Apply constraints related to other nodes next to it (keeps each node within distance)
|
// Apply constraints related to other nodes next to it (keeps each node within distance)
|
||||||
#constrainPoint(point: RopePoint) {
|
#constrainPoint(point: RopePoint) {
|
||||||
const applyConstraint = (p1: RopePoint, p2: RopePoint) => {
|
|
||||||
const delta = Vector.sub(p2.pos, p1.pos);
|
|
||||||
const len = Vector.mag(delta);
|
|
||||||
|
|
||||||
// Prevent division by zero
|
|
||||||
if (len < 0.0001) return;
|
|
||||||
|
|
||||||
const diff = len - p1.distanceToNextPoint;
|
|
||||||
const normal = Vector.normalized(delta);
|
|
||||||
const adjustment = Vector.scale(normal, diff * 0.75);
|
|
||||||
|
|
||||||
if (!p1.isFixed) {
|
|
||||||
p1.pos = Vector.add(p1.pos, adjustment);
|
|
||||||
}
|
|
||||||
if (!p2.isFixed) {
|
|
||||||
p2.pos = Vector.sub(p2.pos, adjustment);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (point.next) applyConstraint(point, point.next);
|
if (point.next) applyConstraint(point, point.next);
|
||||||
if (point.prev) applyConstraint(point, point.prev);
|
if (point.prev) applyConstraint(point, point.prev);
|
||||||
}
|
}
|
||||||
|
|
@ -246,3 +208,22 @@ export class FolkRope extends AbstractArrow {
|
||||||
this.#points[index + 1].prev = this.#points[index];
|
this.#points[index + 1].prev = this.#points[index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function applyConstraint(p1: RopePoint, p2: RopePoint) {
|
||||||
|
const delta = Vector.sub(p2.pos, p1.pos);
|
||||||
|
const len = Vector.mag(delta);
|
||||||
|
|
||||||
|
// Prevent division by zero
|
||||||
|
if (len < 0.0001) return;
|
||||||
|
|
||||||
|
const diff = len - p1.distanceToNextPoint;
|
||||||
|
const normal = Vector.normalized(delta);
|
||||||
|
const adjustment = Vector.scale(normal, diff * 0.75);
|
||||||
|
|
||||||
|
if (!p1.isFixed) {
|
||||||
|
p1.pos = Vector.add(p1.pos, adjustment);
|
||||||
|
}
|
||||||
|
if (!p2.isFixed) {
|
||||||
|
p2.pos = Vector.sub(p2.pos, adjustment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue