/* Scrub */
const Scrub = {
finiteNumber: function(value, defaultValue) {
return Number.isFinite(value) ? value : defaultValue;
},
units: function(value, defaultValue) {
switch(value) {
case "px":
case "pt":
case "em": return value;
default: return defaultValue;
}
}
};
/* Pairs of Vetted Values */
/* Position */
/** A location expressed in terms of x and y values and units.
* Synonymous with OrderedPairWithUnits or OrderedPairAndUnits.
*/
function Position(x, y, units) {
return OrderedPairWithUnits.call(this, x, y, units);
}
Position.defaultUnits = "px";
/** An object composed of an OrderedPair object and units.
*/
function OrderedPairAndUnits(x, y, units) {
// Private Constant
const thisObject= this;
const orderedPair = new OrderedPair(x, y);
// Public Methods
thisObject.getXAndUnits = function() {
return orderedPair.getX().toString() + units;
}
thisObject.getYAndUnits = function() {
return orderedPair.getY().toString() + units;
};
thisObject.getX = function() {
return orderedPair.getX();
};
thisObject.getY = function() {
return orderedPair.getY();
};
thisObject.setX = function(newX) {
orderedPair.setX(newX);
return thisObject;
};
thisObject.setY = function(newY) {
orderedPair.setY(newY);
return thisObject;
};
thisObject.getUnits = function() {
return units;
};
thisObject.setUnits = function(newUnits) {
units = Scrub.units(newUnits, Position.defaultUnits);
return thisObject;
};
thisObject.toString = function() {
return "(" + thisObject.getXAndUnits() +
"," + thisObject.getYAndUnits() + ")";
};
// Initialization
thisObject.setUnits(units);
return thisObject;
}
/** An object that is an OrderedPair object with units.
*/
function OrderedPairWithUnits(x, y, units) {
// Private Constant
const thisObject = OrderedPair.call(this, x, y);
// Public Methods
thisObject.getXAndUnits = function() {
return thisObject.getX().toString() + units;
}
thisObject.getYAndUnits = function() {
return thisObject.getY().toString() + units;
};
thisObject.getUnits = function() {
return units;
};
thisObject.setUnits = function(newUnits) {
units = Scrub.units(newUnits, Position.defaultUnits);
return thisObject;
};
thisObject.toString = function() {
return "(" + thisObject.getXAndUnits() +
"," + thisObject.getYAndUnits() + ")";
};
// Initialization
thisObject.setUnits(units);
return thisObject;
}
/* Shapes */
/** An object consisting of an HTML element that represents a shape.
*/
function Shape(opts, getElement) {
const thisObject = this;
const element = document.createElement("div");
if (opts === undefined) opts = {};
let units = (opts.units !== undefined) ?
opts.units : Shape.default.units;
let color = (opts.color !== undefined) ?
opts.color : Shape.default.color;
let position = (opts.position !== undefined) ?
opts.position : Shape.default.position;
thisObject.appendElementTo = function(otherElement) {
otherElement.append(element);
};
thisObject.removeElementFrom = function(otherElement) {
otherElement.remove(element);
}
thisObject.getUnits = function() {
return units;
};
thisObject.setUnits = function(newUnits) {
return setUnits(newUnits);
};
thisObject.getPosition = function() {
return position;
};
thisObject.setPosition = function(newPosition) {
return setPosition(newPosition);
};
thisObject.getColor = function() {
return color;
};
thisObject.setColor = function(newColor) {
return setColor(newColor);
}
function setPosition(p) {
element.style.top = p.getYAndUnits();
element.style.left = p.getXAndUnits();
return thisObject;
}
function setColor(c) {
element.style.backgroundColor = color;
return thisObject;
}
function setUnits(u) {
units = u;
return thisObject;
}
element.style.position= "absolute";
setPosition(position);
setColor(color);
setUnits(u);
return getElement === true ? element : thisObject;
}
Shape.default = {
position: new Position(),
units: "px",
color: "black"
}
/** An object derived from Shape that represents a rectangle.
*/
function Rectangle(width, height, opts, getElement) {
const thisObject = this;
const element = Shape.call(thisObject, opts, true);
if (width === undefined) width = Rectangle.default.width;
if (height === undefined) height = Rectangle.default.height;
element.style.width = width.toString() + thisObject.getUnits();
element.style.height = height.toString() + thisObject.getUnits();
return getElement === true ? element : thisObject;
}
Rectangle.default = {
width: 1,
height: 1,
};
/** An object derived from Rectangle that represents a square.
*/
function Square(width, opts, getElement) {
return Rectangle.call(this, width, width, opts, getElement);
}
/** An object derived from Square that represents a circle.
*/
function Circle(width, opts, getElement) {
const thisObject= this;
const element = Square.call(thisObject, width, opts, true);
element.style.borderRadius = "50%";
return getElement === true ? element : thisObject;
}