add trigger textarea
This commit is contained in:
parent
328442627f
commit
e61ec657d7
|
|
@ -5,7 +5,7 @@ styles.replaceSync(`
|
||||||
textarea {
|
textarea {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: auto;
|
width: auto;
|
||||||
min-width: 60px;
|
min-width: 3ch;
|
||||||
height: auto;
|
height: auto;
|
||||||
resize: none;
|
resize: none;
|
||||||
background: rgba(256, 256, 256, 0.8);
|
background: rgba(256, 256, 256, 0.8);
|
||||||
|
|
@ -15,18 +15,26 @@ textarea {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
field-sizing: content;
|
field-sizing: content;
|
||||||
translate: -50% -50%;
|
translate: -50% -50%;
|
||||||
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
|
|
||||||
export class EventPropagator extends FolkRope {
|
export class EventPropagator extends FolkRope {
|
||||||
static override tagName = 'event-propagator';
|
static override tagName = 'event-propagator';
|
||||||
|
|
||||||
#triggers = (this.getAttribute('triggers') || '').split(',');
|
#triggers: string[] = [];
|
||||||
get triggers() {
|
get triggers() {
|
||||||
return this.#triggers;
|
return this.#triggers;
|
||||||
}
|
}
|
||||||
set triggers(triggers) {
|
set triggers(triggers: string | string[]) {
|
||||||
|
if (typeof triggers === 'string') {
|
||||||
|
triggers = triggers.split(',');
|
||||||
|
}
|
||||||
|
this.#removeEventListenersToSource();
|
||||||
|
|
||||||
this.#triggers = triggers;
|
this.#triggers = triggers;
|
||||||
|
|
||||||
|
this.#addEventListenersToSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
#expression = '';
|
#expression = '';
|
||||||
|
|
@ -47,62 +55,78 @@ export class EventPropagator extends FolkRope {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#textarea = document.createElement('textarea');
|
#triggerTextarea = document.createElement('textarea');
|
||||||
|
#expressionTextarea = document.createElement('textarea');
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.shadowRoot?.adoptedStyleSheets.push(styles);
|
this.shadowRoot?.adoptedStyleSheets.push(styles);
|
||||||
|
|
||||||
this.#textarea.addEventListener('input', () => {
|
this.#triggerTextarea.addEventListener('change', () => {
|
||||||
this.expression = this.#textarea.value;
|
this.triggers = this.#triggerTextarea.value;
|
||||||
|
});
|
||||||
|
this.triggers = this.#triggerTextarea.value = this.getAttribute('triggers') || '';
|
||||||
|
|
||||||
|
this.shadowRoot?.appendChild(this.#triggerTextarea);
|
||||||
|
|
||||||
|
this.#expressionTextarea.addEventListener('input', () => {
|
||||||
|
this.expression = this.#expressionTextarea.value;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.shadowRoot?.appendChild(this.#textarea);
|
this.shadowRoot?.appendChild(this.#expressionTextarea);
|
||||||
|
|
||||||
this.expression = this.#textarea.value = this.getAttribute('expression') || '';
|
this.expression = this.#expressionTextarea.value = this.getAttribute('expression') || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
override render(sourceRect: DOMRectReadOnly, targetRect: DOMRectReadOnly) {
|
override render(sourceRect: DOMRectReadOnly, targetRect: DOMRectReadOnly) {
|
||||||
super.render(sourceRect, targetRect);
|
super.render(sourceRect, targetRect);
|
||||||
|
|
||||||
// Position textarea between source and target
|
|
||||||
const midX = (sourceRect.x + targetRect.x) / 2;
|
|
||||||
const midY = (sourceRect.y + targetRect.y) / 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override draw() {
|
override draw() {
|
||||||
super.draw();
|
super.draw();
|
||||||
|
|
||||||
const point = this.points[Math.floor(this.points.length / 2)];
|
const triggerPoint = this.points[Math.floor(this.points.length / 5)];
|
||||||
// Center the textarea by subtracting half its width and height
|
|
||||||
this.#textarea.style.left = `${point.pos.x}px`;
|
if (triggerPoint) {
|
||||||
this.#textarea.style.top = `${point.pos.y}px`;
|
this.#triggerTextarea.style.left = `${triggerPoint.pos.x}px`;
|
||||||
|
this.#triggerTextarea.style.top = `${triggerPoint.pos.y}px`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const expressionPoint = this.points[Math.floor((this.points.length * 3) / 5)];
|
||||||
|
|
||||||
|
if (expressionPoint) {
|
||||||
|
this.#expressionTextarea.style.left = `${expressionPoint.pos.x}px`;
|
||||||
|
this.#expressionTextarea.style.top = `${expressionPoint.pos.y}px`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override observeSource() {
|
override observeSource() {
|
||||||
super.observeSource();
|
super.observeSource();
|
||||||
|
|
||||||
|
this.#addEventListenersToSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
#addEventListenersToSource() {
|
||||||
for (const trigger of this.#triggers) {
|
for (const trigger of this.#triggers) {
|
||||||
// TODO: add special triggers for intersection, rAF, etc.
|
// TODO: add special triggers for intersection, rAF, etc.
|
||||||
this.sourceElement?.addEventListener(trigger, this.evaluateExpression);
|
this.sourceElement?.addEventListener(trigger, this.evaluateExpression);
|
||||||
}
|
}
|
||||||
//should we evaluate them immediately?
|
|
||||||
// this.evaluateExpression();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override unobserveSource() {
|
override unobserveSource() {
|
||||||
super.unobserveSource();
|
super.unobserveSource();
|
||||||
|
this.#removeEventListenersToSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
#removeEventListenersToSource() {
|
||||||
for (const trigger of this.#triggers) {
|
for (const trigger of this.#triggers) {
|
||||||
// TODO: add special triggers for intersection, rAF, etc.
|
|
||||||
this.sourceElement?.removeEventListener(trigger, this.evaluateExpression);
|
this.sourceElement?.removeEventListener(trigger, this.evaluateExpression);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override observeTarget() {
|
override observeTarget() {
|
||||||
super.observeTarget();
|
super.observeTarget();
|
||||||
// this.evaluateExpression();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override unobserveTarget() {
|
override unobserveTarget() {
|
||||||
|
|
|
||||||
|
|
@ -100,10 +100,10 @@ export class FolkRope extends AbstractArrow {
|
||||||
};
|
};
|
||||||
|
|
||||||
#tick = (timestamp: number = performance.now()) => {
|
#tick = (timestamp: number = performance.now()) => {
|
||||||
this.#rAFId = requestAnimationFrame(this.#tick);
|
|
||||||
|
|
||||||
this.#currentTime = timestamp;
|
this.#currentTime = timestamp;
|
||||||
|
|
||||||
|
this.#rAFId = requestAnimationFrame(this.#tick);
|
||||||
|
|
||||||
this.#deltaTime = this.#currentTime - this.#lastTime;
|
this.#deltaTime = this.#currentTime - this.#lastTime;
|
||||||
|
|
||||||
if (this.#deltaTime > this.#interval) {
|
if (this.#deltaTime > this.#interval) {
|
||||||
|
|
@ -130,8 +130,8 @@ export class FolkRope extends AbstractArrow {
|
||||||
override render(sourceRect: DOMRectReadOnly, targetRect: DOMRectReadOnly) {
|
override render(sourceRect: DOMRectReadOnly, targetRect: DOMRectReadOnly) {
|
||||||
if (this.#points.length === 0) {
|
if (this.#points.length === 0) {
|
||||||
this.#points = this.#generatePoints(
|
this.#points = this.#generatePoints(
|
||||||
{ x: sourceRect.x, y: sourceRect.y },
|
{ x: sourceRect.x + sourceRect.width / 2, y: sourceRect.bottom },
|
||||||
{ x: targetRect.right, y: targetRect.bottom }
|
{ x: targetRect.x + targetRect.width / 2, y: targetRect.bottom }
|
||||||
);
|
);
|
||||||
|
|
||||||
this.#lastTime = 0;
|
this.#lastTime = 0;
|
||||||
|
|
@ -183,7 +183,7 @@ export class FolkRope extends AbstractArrow {
|
||||||
x: lerp(start.x, end.x, percentage),
|
x: lerp(start.x, end.x, percentage),
|
||||||
y: lerp(start.y, end.y, percentage),
|
y: lerp(start.y, end.y, percentage),
|
||||||
};
|
};
|
||||||
// new RopePoint({ x: lerpX, y: lerpY }, resolution, mass, damping, isFixed)
|
|
||||||
points.push({
|
points.push({
|
||||||
pos,
|
pos,
|
||||||
oldPos: { ...pos },
|
oldPos: { ...pos },
|
||||||
|
|
@ -217,7 +217,7 @@ export class FolkRope extends AbstractArrow {
|
||||||
point.oldPos = { ...point.pos };
|
point.oldPos = { ...point.pos };
|
||||||
|
|
||||||
// Drastically improves stability
|
// Drastically improves stability
|
||||||
const timeCorrection = previousFrameDt != 0.0 ? dt / previousFrameDt : 0.0;
|
const timeCorrection = previousFrameDt !== 0.0 ? dt / previousFrameDt : 0.0;
|
||||||
|
|
||||||
const accel = Vector.add(gravity, { x: 0, y: point.mass });
|
const accel = Vector.add(gravity, { x: 0, y: point.mass });
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue