1
1
mirror of https://github.com/varkor/quiver.git synced 2024-09-11 05:46:13 +03:00
quiver/ds.js
varkor 7f985358ee Split ui.js up a bit
This could be more fine-grained, but it's a start, and allows me to start sharing data structures for the curved arrow refactor.
2020-02-22 13:16:10 +00:00

110 lines
2.4 KiB
JavaScript

"use strict";
/// An enumeration type.
class Enum {
constructor(name, ...variants) {
for (const variant of variants) {
this[variant] = Symbol(`${name}::${variant}`);
}
}
}
/// A quintessential (x, y) position.
class Position {
constructor(x, y) {
[this.x, this.y] = [x, y];
}
static zero() {
return new Position(0, 0);
}
toString() {
return `${this.x} ${this.y}`;
}
toArray() {
return [this.x, this.y];
}
eq(other) {
return this.x === other.x && this.y === other.y;
}
add(other) {
return new (this.constructor)(this.x + other.x, this.y + other.y);
}
sub(other) {
return new (this.constructor)(this.x - other.x, this.y - other.y);
}
div(divisor) {
return new (this.constructor)(this.x / divisor, this.y / divisor);
}
min(other) {
return new (this.constructor)(Math.min(this.x, other.x), Math.min(this.y, other.y));
}
max(other) {
return new (this.constructor)(Math.max(this.x, other.x), Math.max(this.y, other.y));
}
length() {
return Math.hypot(this.y, this.x);
}
angle() {
return Math.atan2(this.y, this.x);
}
is_zero() {
return this.x === 0 && this.y === 0;
}
}
/// An (width, height) pair. This is functionally equivalent to `Position`, but has different
/// semantic intent.
const Dimensions = class extends Position {
/// Returns a `Dimensions` with `{ width: 0, height: 0}`.
static zero() {
return new Dimensions(0, 0);
}
get width() {
return this.x;
}
get height() {
return this.y;
}
};
/// An HTML position. This is functionally equivalent to `Position`, but has different semantic
/// intent.
class Offset {
constructor(left, top) {
[this.left, this.top] = [left, top];
}
/// Returns an `Offset` with `{ left: 0, top: 0}`.
static zero() {
return new Offset(0, 0);
}
/// Return a [left, top] arrow of CSS length values.
to_CSS() {
return [`${this.left}px`, `${this.top}px`];
}
/// Moves an `element` to the offset.
reposition(element) {
[element.style.left, element.style.top] = this.to_CSS();
}
sub(other) {
return new (this.constructor)(this.left - other.left, this.top - other.top);
}
}