Skip to content

Instantly share code, notes, and snippets.

@domenic
Last active August 29, 2015 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save domenic/60871738e49a2b8c7a01 to your computer and use it in GitHub Desktop.
Save domenic/60871738e49a2b8c7a01 to your computer and use it in GitHub Desktop.
Another take on geometry

DOMRectReadOnly

[Constructor(DOMQuadInit quad)]
[Constructor(unrestricted optional double x = 0, unrestricted optional double y = 0,
             unrestricted optional double width = 0, unrestricted optional double height = 0)]
interface DOMRectReadOnly {
  readonly attribute unrestricted double x;
  readonly attribute unrestricted double y;
  readonly attribute unrestricted double width;
  readonly attribute unrestricted double height;
  readonly attribute unrestricted double right;
  readonly attribute unrestricted double bottom;
  readonly attribute unrestricted double left;
}

DOMRectReadOnly instances have six internal slots: [[type]], [[quad]], [[x]], [[y]], [[width]], and [[height]].

The new DOMRectReadOnly(quad) constructor must:

  1. Set the [[type]] internal slot of this to "quadbounds".
  2. Set the [[quad]] internal slot of this to quad.

The new DOMRectReadOnly(x, y, width, height) constructor must:

  1. Set the [[type]] internal slot of this to "rect".
  2. Set the [[x]] internal slot of this to x.
  3. Set the [[y]] internal slot of this to y.
  4. Set the [[width]] internal slot of this to width.
  5. Set the [[height]] internal slot of this to height.

In the following algorithms, let t be the value of the [[type]] internal slot of this, and q be the value of the [[quad]] internal slot of this. Then:

The x getter must:

  1. If t is "quadbounds", return the minimum of q.p1.x, q.p2.x, q.p3.x, and q.p4.x.
  2. If t is "rect", return the value of the [[x]] internal slot.

The y getter must:

  1. If t is "quad", return the minimum of q.p1.y, q.p2.y, q.p3.y, and q.p4.y.
  2. If t is "rect", return the value of the [[y]] internal slot.

The width getter must:

  1. If t is "quadbounds", return (the maximum of q.p1.x, q.p2.x, q.p3.x, and q.p4.x) minus this.x.
  2. If t is "rect", return the value of the [[width]] internal slot.

The height getter must:

  1. If t is "quadbounds", return (the maximum of q.p1.y, q.p2.y, q.p3.y, and q.p4.y) minus this.y.
  2. If t is "rect", return the value of the [[height]] internal slot.

The top getter must return min(this.y, this.y + this.height).

The right getter must return max(this.x, this.x + this.width).

The bottom getter must return max(this.y, this.y + this.height).

The left getter must return min(this.x, this.x + this.width).

DOMRect

[Constructor(unrestricted optional double x = 0, unrestricted optional double y = 0,
             unrestricted optional double width = 0, unrestricted optional double height = 0)]
interface DOMRect : DOMRectReadOnly {
    attribute unrestricted double x;
    attribute unrestricted double y;
    attribute unrestricted double width;
    attribute unrestricted double height;
};

NOTE: DOMRectReadOnly instances have the same internal slots as DOMRectReadOnly instances; they are instantiated by inheriting the @@create behavior via class-side inheritnace.

The DOMRect(x, y, width, height) constructor must call super(x, y, width, height).

The x, y, width, and height accessors must reflect the [[x]], [[y]], [[width]], and [[height]] internal slots, respectively.

var min = Math.min;
var max = Math.max;
var internalSlots = new WeakMap();
class DOMRectReadOnly {
constructor(x = 0, y = 0, width = 0, height = 0) {
if (typeof x === "object" && x !== null) {
internalSlots.set(this, { type: "quadbounds", quad: x });
} else {
x = +x;
y = +y;
width = +width;
height = +height;
internalSlots.set(this, { type: "rect", x, y, width, height });
}
}
get x() {
if (internalSlots.get(this).type === "quadbounds") {
var q = internalSlots.get(this).quad;
return min(q.p1.x, q.p2.x, q.p3.x, q.p4.x);
}
return internalSlots.get(this).x;
}
get y() {
if (internalSlots.get(this).type === "quadbounds") {
var q = internalSlots.get(this).quad;
return min(q.p1.y, q.p2.y, q.p3.y, q.p4.y);
}
return internalSlots.get(this).y;
}
get width() {
if (internalSlots.get(this).type === "quadbounds") {
var q = internalSlots.get(this).quad;
return max(q.p1.x, q.p2.x, q.p3.x, q.p4.x) - this.x;
}
return internalSlots.get(this).width;
}
get height() {
if (internalSlots.get(this).type === "quadbounds") {
var q = internalSlots.get(this).quad;
return max(q.p1.y, q.p2.y, q.p3.y, q.p4.y) - this.y;
}
return internalSlots.get(this).height;
}
get top() {
return min(this.y, this.y + this.height);
}
get right() {
return max(this.x, this.x + this.width);
}
get bottom() {
return max(this.y, this.y + this.height);
}
get left() {
return min(this.x, this.x + this.width);
}
}
class DOMRect {
constructor(x = 0, y = 0, width = 0, height = 0) {
x = +x;
y = +y;
width = +width;
height = +height;
super(x, y, width, height);
}
get x() {
return internalSlots.get(this).x;
}
set x(value) {
internalSlots.get(this).x = +value;
}
get y() {
return internalSlots.get(this).y;
}
set y(value) {
internalSlots.get(this).y = +value;
}
get width() {
return internalSlots.get(this).width;
}
set width(value) {
internalSlots.get(this).width = +value;
}
get height() {
return internalSlots.get(this).height;
}
set height(value) {
internalSlots.get(this).height = +value;
}
}
@rwaldron
Copy link

rwaldron commented Jul 9, 2014

Should class DOMRect be class DOMRect extends DOMRectReadOnly?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment