Working in the colission code, moved the fly-in handlers to the board.

This commit is contained in:
Elf M. Sternberg 2024-11-19 14:33:58 -08:00
parent 5efe79173c
commit ee1b763a7a
2 changed files with 178 additions and 18 deletions

View File

@ -2,21 +2,10 @@ import { LitElement, html, css } from "lit";
import { customElement } from "lit/decorators/custom-element.js"; import { customElement } from "lit/decorators/custom-element.js";
import { property } from "lit/decorators/property.js"; import { property } from "lit/decorators/property.js";
import { styleMap } from "lit/directives/style-map.js"; import { styleMap } from "lit/directives/style-map.js";
import { LitDragEvent, LitDraggable } from "./lit-draggable.js"; import { ref, createRef, Ref } from "lit/directives/ref.js";
import { LitDraggable } from "./lit-draggable.js";
export function bound(_target: unknown, key: string, descriptor: PropertyDescriptor): PropertyDescriptor { import { LitDragEvent } from "./types.js";
if (typeof descriptor?.value !== "function") { import { LitDragStart, LitDragEnd } from "./lit-events.js";
throw new Error("Only methods can be @bound.");
}
return {
configurable: true,
get() {
const method = descriptor.value.bind(this);
Object.defineProperty(this, key, { value: method, configurable: true, writable: true });
return method;
},
};
}
@customElement("fridge-tile") @customElement("fridge-tile")
export class FridgeTile extends LitElement { export class FridgeTile extends LitElement {
@ -25,6 +14,13 @@ export class FridgeTile extends LitElement {
dragHandle: LitDraggable; dragHandle: LitDraggable;
transform = {
rotate: Math.random() * 30 - 15,
scale: 1.0,
};
handle: Ref<HTMLDivElement> = createRef();
static get styles() { static get styles() {
return css` return css`
:host { :host {
@ -52,6 +48,9 @@ export class FridgeTile extends LitElement {
position: relative; position: relative;
background: white; background: white;
z-index: 100; z-index: 100;
transition-property: transform;
transition-duration: 200ms;
transition-timing-function: ease-in-out; //other options are ease
} }
.word.dragging { .word.dragging {
@ -64,17 +63,35 @@ export class FridgeTile extends LitElement {
super(); super();
this.dragHandle = new LitDraggable(this); this.dragHandle = new LitDraggable(this);
this.onDragEnd = this.onDragEnd.bind(this); this.onDragEnd = this.onDragEnd.bind(this);
this.addEventListener("lit-drag-end", this.onDragEnd); this.onDragStart = this.onDragStart.bind(this);
this.addEventListener(LitDragEnd.eventName, this.onDragEnd);
this.addEventListener(LitDragStart.eventName, this.onDragStart);
} }
onDragEnd(ev: LitDragEvent) { onDragEnd(ev: LitDragEvent) {
this.transform = { scale: 1.0, rotate: Math.random() * 30 - 15 };
this.handle.value!.style.setProperty(
"transform",
`scale(${+this.transform.scale}) rotate(${+this.transform.rotate}deg)`
);
this.style.setProperty("top", `${+ev.offsetY}px`); this.style.setProperty("top", `${+ev.offsetY}px`);
this.style.setProperty("left", `${+ev.offsetX}px`); this.style.setProperty("left", `${+ev.offsetX}px`);
} }
onDragStart(_ev: LitDragEvent) {
this.transform = { scale: 1.3, rotate: Math.random() * 30 - 15 };
this.handle.value!.style.setProperty(
"transform",
`scale(${+this.transform.scale}) rotate(${+this.transform.rotate}deg)`
);
}
render() { render() {
const styles = styleMap({ width: `${this.word.length}ch` }); const styles = {
return html`<div part="word" style="${styles}" class="word">${this.word}</div>`; width: `${this.word.length}ch`,
transform: `rotate(${this.transform.rotate}deg)`,
};
return html`<div part="word ${ref(this.handle)} " style="${styleMap(styles)}" class="word">${this.word}</div>`;
} }
} }

143
src/sat.ts Normal file
View File

@ -0,0 +1,143 @@
// Copyright (c) 2012 Elf M. Sternberg
//
// Much of the code here I would never have understood if it hadn't
// been for the patient work of Caleb Helbling
// (http://www.propulsionjs.com/), as well as the Wikipedia pages for
// the Separating Axis Theorem. It took me a week to wrap my head
// around these ideas.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
class Vector {
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
add: (v2: Vector) {
return new Vector(this.x + v2.x, this.y + v2.y);
}
add: function (v1, v2) {
return {
x: v1.x + v2.x,
y: v1.y + v2.y,
};
},
scalar: function (v, s) {
return {
x: v.x * s,
y: v.y * s,
};
},
dot: function (v1, v2) {
return v1.x * v2.x + v1.y * v2.y;
},
magnitude2: function (v) {
var x, y;
x = v.x;
y = v.y;
return x * x + y * y;
},
magnitude: function (v) {
return Math.sqrt(Math.vector.magnitude2(v));
},
normalize: function (v) {
var mag;
mag = Math.vector.magnitude(v);
return {
x: v.x / mag,
y: v.y / mag,
};
},
leftNormal: function (v) {
return {
x: -v.y,
y: v.x,
};
},
};
this.colliding = function (shape1, shape2) {
var axes, axes1, axes2, axis, genAxes, genProjection, j, len, proj1, proj2;
genAxes = function (shape) {
var axis, i, j, ref, results;
if (shape.length < 3) {
throw "Cannot handle non-polygons";
}
axis = function (shape, pi) {
var edge, p1, p2;
p1 = shape[pi];
p2 = shape[pi === shape.length - 1 ? 0 : pi + 1];
edge = {
x: p1.x - p2.x,
y: p1.y - p2.y,
};
return Math.vector.normalize(Math.vector.leftNormal(edge));
};
results = [];
for (i = j = 0, ref = shape.length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
results.push(axis(shape, i));
}
return results;
};
genProjection = function (shape, axis) {
var i, j, max, min, p, ref;
min = Math.vector.dot(axis, shape[0]);
max = min;
for (i = j = 1, ref = shape.length; 1 <= ref ? j < ref : j > ref; i = 1 <= ref ? ++j : --j) {
p = Math.vector.dot(axis, shape[i]);
if (p < min) {
min = p;
}
if (p > max) {
max = p;
}
}
return {
min: min,
max: max,
};
};
axes1 = genAxes(shape1);
axes2 = genAxes(shape2);
axes = axes1.concat(axes2);
for (j = 0, len = axes.length; j < len; j++) {
axis = axes[j];
proj1 = genProjection(shape1, axis);
proj2 = genProjection(shape2, axis);
if (
!(
(proj1.min >= proj2.min && proj1.min <= proj2.max) ||
(proj1.max >= proj2.min && proj1.max <= proj2.max) ||
(proj2.min >= proj1.min && proj2.min <= proj1.max) ||
(proj2.max >= proj1.min && proj2.max <= proj1.max)
)
) {
return false;
}
}
return true;
};
}).call(this);