resize element
This commit is contained in:
parent
8503437d4c
commit
9feca14de0
|
|
@ -20,15 +20,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
spatial-geometry {
|
spatial-geometry {
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
border: 2px solid black;
|
border: 2px solid black;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<spatial-geometry x="100" y="100">Shape with some text</spatial-geometry>
|
<spatial-geometry x="100" y="100" width="50" height="50">Shape with some text</spatial-geometry>
|
||||||
<spatial-geometry x="200" y="200">Shape with some text</spatial-geometry>
|
<spatial-geometry x="200" y="200" width="50" height="50">Shape with some text</spatial-geometry>
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import { SpatialGeometry } from '../src/elements/spatial-geometry.ts';
|
import { SpatialGeometry } from '../src/elements/spatial-geometry.ts';
|
||||||
|
|
@ -45,20 +43,28 @@
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('move', (e) => {
|
function handleCollision(e) {
|
||||||
geometryElements.forEach((el) => {
|
geometryElements.forEach((el) => {
|
||||||
if (
|
if (
|
||||||
el !== e.target &&
|
el !== e.target &&
|
||||||
collisionDetection(
|
collisionDetection(
|
||||||
// TODO: refactor this hack once resizing and the vertices API are figured out
|
// TODO: refactor this hack once resizing and the vertices API are figured out
|
||||||
DOMRectReadOnly.fromRect({ x: el.x, y: el.y, height: 50, width: 50 }),
|
DOMRectReadOnly.fromRect({ x: el.x, y: el.y, height: el.height, width: el.width }),
|
||||||
DOMRectReadOnly.fromRect({ x: e.target.x, y: e.target.y, height: 50, width: 50 })
|
DOMRectReadOnly.fromRect({
|
||||||
|
x: e.target.x,
|
||||||
|
y: e.target.y,
|
||||||
|
height: e.target.height,
|
||||||
|
width: e.target.width,
|
||||||
|
})
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
document.addEventListener('move', handleCollision);
|
||||||
|
document.addEventListener('resize', handleCollision);
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -16,14 +16,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
spatial-geometry {
|
spatial-geometry {
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
background: rgb(187, 178, 178);
|
background: rgb(187, 178, 178);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<spatial-geometry x="100" y="100">Shape with some text</spatial-geometry>
|
<input type="text" value="Hello" />
|
||||||
|
<input type="text" value="World" />
|
||||||
|
<spatial-geometry x="100" y="100" width="50" height="50">Shape with some text</spatial-geometry>
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import { SpatialGeometry } from '../src/elements/spatial-geometry.ts';
|
import { SpatialGeometry } from '../src/elements/spatial-geometry.ts';
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,21 @@ export type Shape = 'rectangle' | 'circle' | 'triangle';
|
||||||
// Can we make adding new shapes extensible via a static property?
|
// Can we make adding new shapes extensible via a static property?
|
||||||
const shapes = new Set(['rectangle', 'circle', 'triangle']);
|
const shapes = new Set(['rectangle', 'circle', 'triangle']);
|
||||||
|
|
||||||
export type MoveEventDetail = { x: number; y: number; movementX: number; movementY: number };
|
export type MoveEventDetail = { movementX: number; movementY: number };
|
||||||
|
|
||||||
// Should the move event bubble?
|
// Should the move event bubble?
|
||||||
export class MoveEvent extends CustomEvent<MoveEventDetail> {
|
export class MoveEvent extends CustomEvent<MoveEventDetail> {
|
||||||
constructor(vector: MoveEventDetail) {
|
constructor(detail: MoveEventDetail) {
|
||||||
super('move', { detail: vector, cancelable: true, bubbles: true });
|
super('move', { detail, cancelable: true, bubbles: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ResizeEventDetail = { movementX: number; movementY: number };
|
||||||
|
|
||||||
|
// Should the move event bubble?
|
||||||
|
export class ResizeEvent extends CustomEvent<MoveEventDetail> {
|
||||||
|
constructor(detail: MoveEventDetail) {
|
||||||
|
super('resize', { detail, cancelable: true, bubbles: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -135,7 +144,7 @@ export class SpatialGeometry extends HTMLElement {
|
||||||
customElements.define(this.tagName, this);
|
customElements.define(this.tagName, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static observedAttributes = ['type', 'x', 'y'];
|
static observedAttributes = ['type', 'x', 'y', 'width', 'height'];
|
||||||
|
|
||||||
#internals: ElementInternals;
|
#internals: ElementInternals;
|
||||||
|
|
||||||
|
|
@ -190,6 +199,26 @@ export class SpatialGeometry extends HTMLElement {
|
||||||
this.setAttribute('y', y.toString());
|
this.setAttribute('y', y.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#previousWidth = 0;
|
||||||
|
#width = 0;
|
||||||
|
get width(): number {
|
||||||
|
return this.#width;
|
||||||
|
}
|
||||||
|
|
||||||
|
set width(width: number) {
|
||||||
|
this.setAttribute('width', width.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
#previousHeight = 0;
|
||||||
|
#height = 0;
|
||||||
|
get height(): number {
|
||||||
|
return this.#height;
|
||||||
|
}
|
||||||
|
|
||||||
|
set height(height: number) {
|
||||||
|
this.setAttribute('height', height.toString());
|
||||||
|
}
|
||||||
|
|
||||||
attributeChangedCallback(name: string, _oldValue: string, newValue: string) {
|
attributeChangedCallback(name: string, _oldValue: string, newValue: string) {
|
||||||
if (name === 'x') {
|
if (name === 'x') {
|
||||||
this.#previousX = this.#x;
|
this.#previousX = this.#x;
|
||||||
|
|
@ -199,6 +228,14 @@ export class SpatialGeometry extends HTMLElement {
|
||||||
this.#previousY = this.#y;
|
this.#previousY = this.#y;
|
||||||
this.#y = Number(newValue);
|
this.#y = Number(newValue);
|
||||||
this.#requestUpdate('y');
|
this.#requestUpdate('y');
|
||||||
|
} else if (name === 'width') {
|
||||||
|
this.#previousWidth = this.#width;
|
||||||
|
this.#width = Number(newValue);
|
||||||
|
this.#requestUpdate('width');
|
||||||
|
} else if (name === 'height') {
|
||||||
|
this.#previousHeight = this.#height;
|
||||||
|
this.#height = Number(newValue);
|
||||||
|
this.#requestUpdate('height');
|
||||||
} else if (name === 'type') {
|
} else if (name === 'type') {
|
||||||
if (shapes.has(newValue)) {
|
if (shapes.has(newValue)) {
|
||||||
this.#type = newValue as Shape;
|
this.#type = newValue as Shape;
|
||||||
|
|
@ -238,8 +275,29 @@ export class SpatialGeometry extends HTMLElement {
|
||||||
if (event.target === this) {
|
if (event.target === this) {
|
||||||
this.x += event.movementX;
|
this.x += event.movementX;
|
||||||
this.y += event.movementY;
|
this.y += event.movementY;
|
||||||
} else if ((event.target as HTMLElement).matches('[resize-handler]')) {
|
return;
|
||||||
console.log('resizing');
|
}
|
||||||
|
|
||||||
|
const direction = (event.target as HTMLElement).getAttribute('resize-handler');
|
||||||
|
|
||||||
|
if (direction === null) return;
|
||||||
|
|
||||||
|
if (direction.includes('top')) {
|
||||||
|
this.y += event.movementY;
|
||||||
|
this.height -= event.movementY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (direction.includes('right')) {
|
||||||
|
this.width += event.movementX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (direction.includes('bottom')) {
|
||||||
|
this.height += event.movementY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (direction.includes('left')) {
|
||||||
|
this.x += event.movementX;
|
||||||
|
this.width -= event.movementX;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -288,8 +346,6 @@ export class SpatialGeometry extends HTMLElement {
|
||||||
// Although the change in movement isn't useful inside this component, the outside world might find it helpful to calculate acceleration and other physics
|
// Although the change in movement isn't useful inside this component, the outside world might find it helpful to calculate acceleration and other physics
|
||||||
const notCancelled = this.dispatchEvent(
|
const notCancelled = this.dispatchEvent(
|
||||||
new MoveEvent({
|
new MoveEvent({
|
||||||
x: this.#x,
|
|
||||||
y: this.#y,
|
|
||||||
movementX: this.#x - this.#previousX,
|
movementX: this.#x - this.#previousX,
|
||||||
movementY: this.#y - this.#previousY,
|
movementY: this.#y - this.#previousY,
|
||||||
})
|
})
|
||||||
|
|
@ -310,5 +366,29 @@ export class SpatialGeometry extends HTMLElement {
|
||||||
this.#y = this.#previousY;
|
this.#y = this.#previousY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (updatedProperties.has('width') || updatedProperties.has('height')) {
|
||||||
|
// Although the change in resize isn't useful inside this component, the outside world might find it helpful to calculate acceleration and other physics
|
||||||
|
const notCancelled = this.dispatchEvent(
|
||||||
|
new ResizeEvent({
|
||||||
|
movementX: this.#width - this.#previousWidth,
|
||||||
|
movementY: this.#height - this.#previousHeight,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
if (notCancelled) {
|
||||||
|
if (updatedProperties.has('width')) {
|
||||||
|
this.style.width = `${this.#width}px`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updatedProperties.has('height')) {
|
||||||
|
this.style.height = `${this.#height}px`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Revert changes to movement
|
||||||
|
this.#height = this.#previousHeight;
|
||||||
|
this.#width = this.#previousWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue