update rope
This commit is contained in:
parent
dec2ab8c4d
commit
8099d4f307
|
|
@ -54,10 +54,7 @@ class App {
|
||||||
this._currentTime = 0;
|
this._currentTime = 0;
|
||||||
this._deltaTime = 0;
|
this._deltaTime = 0;
|
||||||
this._interval = 0;
|
this._interval = 0;
|
||||||
this.onMouseMoveHandler = (x, y) => {};
|
|
||||||
this.onMouseDownHandler = (x, y) => {};
|
|
||||||
this.start = this.start.bind(this);
|
this.start = this.start.bind(this);
|
||||||
this._onMouseEventHandlerWrapper = this._onMouseEventHandlerWrapper.bind(this);
|
|
||||||
this._onRequestAnimationFrame = this._onRequestAnimationFrame.bind(this);
|
this._onRequestAnimationFrame = this._onRequestAnimationFrame.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -67,43 +64,9 @@ class App {
|
||||||
this._deltaTime = 0;
|
this._deltaTime = 0;
|
||||||
this._interval = 1000 / this._frameRate;
|
this._interval = 1000 / this._frameRate;
|
||||||
|
|
||||||
document.addEventListener(
|
|
||||||
'mousemove',
|
|
||||||
(e) => {
|
|
||||||
this._onMouseEventHandlerWrapper(e, this.onMouseMoveHandler);
|
|
||||||
},
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
document.addEventListener(
|
|
||||||
'mousedown',
|
|
||||||
(e) => {
|
|
||||||
this._onMouseEventHandlerWrapper(e, this.onMouseDownHandler);
|
|
||||||
},
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
this._onRequestAnimationFrame();
|
this._onRequestAnimationFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
_onMouseEventHandlerWrapper(e, callback) {
|
|
||||||
let element = this._canvas;
|
|
||||||
let offsetX = 0;
|
|
||||||
let offsetY = 0;
|
|
||||||
|
|
||||||
if (element.offsetParent) {
|
|
||||||
do {
|
|
||||||
offsetX += element.offsetLeft;
|
|
||||||
offsetY += element.offsetTop;
|
|
||||||
} while ((element = element.offsetParent));
|
|
||||||
}
|
|
||||||
|
|
||||||
const x = e.pageX - offsetX;
|
|
||||||
const y = e.pageY - offsetY;
|
|
||||||
|
|
||||||
callback(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
_onRequestAnimationFrame() {
|
_onRequestAnimationFrame() {
|
||||||
this._window.requestAnimationFrame(this._onRequestAnimationFrame);
|
this._window.requestAnimationFrame(this._onRequestAnimationFrame);
|
||||||
|
|
||||||
|
|
@ -248,7 +211,7 @@ class Rope {
|
||||||
}
|
}
|
||||||
|
|
||||||
getPoint(index) {
|
getPoint(index) {
|
||||||
return this._points[index];
|
return this._points.at(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
update(gravity, dt) {
|
update(gravity, dt) {
|
||||||
|
|
@ -282,76 +245,72 @@ export class FolkRope extends AbstractArrow {
|
||||||
#canvas = document.createElement('canvas');
|
#canvas = document.createElement('canvas');
|
||||||
#context = this.#canvas.getContext('2d')!;
|
#context = this.#canvas.getContext('2d')!;
|
||||||
#shadow = this.attachShadow({ mode: 'open' });
|
#shadow = this.attachShadow({ mode: 'open' });
|
||||||
#args;
|
#points: RopePoint[] = [];
|
||||||
|
#rope: Rope | null = null;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
const context = this.#context;
|
|
||||||
this.#canvas.width = this.clientWidth;
|
this.#canvas.width = this.clientWidth;
|
||||||
this.#canvas.height = this.clientHeight;
|
this.#canvas.height = this.clientHeight;
|
||||||
|
|
||||||
const gradient = this.#context.createLinearGradient(0, 0, 500, 0);
|
|
||||||
gradient.addColorStop(0, 'white');
|
|
||||||
gradient.addColorStop(0.25, 'yellow');
|
|
||||||
gradient.addColorStop(0.5, 'blue');
|
|
||||||
gradient.addColorStop(0.75, 'red');
|
|
||||||
gradient.addColorStop(1.0, 'white');
|
|
||||||
|
|
||||||
const args = (this.#args = {
|
|
||||||
start: { x: 100, y: this.#canvas.height / 2 },
|
|
||||||
end: { x: this.#canvas.width - 100, y: this.#canvas.height / 2 },
|
|
||||||
resolution: 10,
|
|
||||||
mass: 1,
|
|
||||||
damping: 0.99,
|
|
||||||
gravity: { x: 0, y: 3000 },
|
|
||||||
solverIterations: 600,
|
|
||||||
ropeColour: gradient,
|
|
||||||
ropeSize: 2,
|
|
||||||
});
|
|
||||||
|
|
||||||
const points = Rope.generate(args.start, args.end, args.resolution, args.mass, args.damping);
|
|
||||||
|
|
||||||
let rope = new Rope(points, args.solverIterations);
|
|
||||||
|
|
||||||
const tick = (dt) => {
|
|
||||||
rope.update(args.gravity, dt);
|
|
||||||
};
|
|
||||||
|
|
||||||
const drawRopePoints = (points, colour, width) => {
|
|
||||||
for (let i = 0; i < points.length; i++) {
|
|
||||||
let p = points[i];
|
|
||||||
|
|
||||||
const prev = i > 0 ? points[i - 1] : null;
|
|
||||||
|
|
||||||
if (prev) {
|
|
||||||
context.beginPath();
|
|
||||||
context.moveTo(prev.pos.x, prev.pos.y);
|
|
||||||
context.lineTo(p.pos.x, p.pos.y);
|
|
||||||
context.lineWidth = width;
|
|
||||||
context.strokeStyle = colour;
|
|
||||||
context.stroke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//render a rope using the verlet points
|
|
||||||
const draw = (dt) => {
|
|
||||||
drawRopePoints(points, args.ropeColour, args.ropeSize);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onMouseMove = (x, y) => {
|
|
||||||
let point = rope.getPoint(0);
|
|
||||||
point.pos.x = x;
|
|
||||||
point.pos.y = y;
|
|
||||||
};
|
|
||||||
|
|
||||||
const app = new App(window, this.#canvas, context, tick, draw);
|
|
||||||
|
|
||||||
app.onMouseMoveHandler = onMouseMove;
|
|
||||||
app.start();
|
|
||||||
|
|
||||||
this.#shadow.appendChild(this.#canvas);
|
this.#shadow.appendChild(this.#canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {}
|
render(sourceRect: DOMRectReadOnly, targetRect: DOMRectReadOnly) {
|
||||||
|
if (this.#rope === null) {
|
||||||
|
const args = {
|
||||||
|
start: { x: 100, y: this.#canvas.height / 2 },
|
||||||
|
end: { x: this.#canvas.width - 100, y: this.#canvas.height / 2 },
|
||||||
|
resolution: 10,
|
||||||
|
mass: 1,
|
||||||
|
damping: 0.99,
|
||||||
|
gravity: { x: 0, y: 3000 },
|
||||||
|
solverIterations: 600,
|
||||||
|
ropeSize: 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.#points = Rope.generate(args.start, args.end, args.resolution, args.mass, args.damping);
|
||||||
|
|
||||||
|
this.#rope = new Rope(this.#points, args.solverIterations);
|
||||||
|
|
||||||
|
const tick = (dt) => {
|
||||||
|
this.#rope?.update(args.gravity, dt);
|
||||||
|
};
|
||||||
|
|
||||||
|
const drawRopePoints = (points, width) => {
|
||||||
|
for (let i = 0; i < points.length; i++) {
|
||||||
|
let p = points[i];
|
||||||
|
|
||||||
|
const prev = i > 0 ? points[i - 1] : null;
|
||||||
|
|
||||||
|
if (prev) {
|
||||||
|
this.#context.beginPath();
|
||||||
|
this.#context.moveTo(prev.pos.x, prev.pos.y);
|
||||||
|
this.#context.lineTo(p.pos.x, p.pos.y);
|
||||||
|
this.#context.lineWidth = width;
|
||||||
|
this.#context.strokeStyle = 'black';
|
||||||
|
this.#context.stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//render a rope using the verlet points
|
||||||
|
const draw = (dt) => {
|
||||||
|
drawRopePoints(this.#points, args.ropeSize);
|
||||||
|
};
|
||||||
|
|
||||||
|
const app = new App(window, this.#canvas, this.#context, tick, draw);
|
||||||
|
|
||||||
|
app.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
const startingPoint = this.#rope.getPoint(0);
|
||||||
|
startingPoint.pos.x = sourceRect.right;
|
||||||
|
startingPoint.pos.y = sourceRect.bottom;
|
||||||
|
|
||||||
|
const endingPoint = this.#rope.getPoint(-1);
|
||||||
|
endingPoint.pos.x = targetRect.x;
|
||||||
|
endingPoint.pos.y = targetRect.bottom;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue