/* 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; }