Tap to pause animation. Release to unpause and get a screenshot save option.
A fork of Geometric Beings by FAL
xxxxxxxxxx
// Title: Geometric Beings
// Author: FAL
// Date: 13. Dec. 2017
// Made with p5.js v0.5.16
// Compiled by TypeScript v2.6.2 (target: ES2015), browserify v14.5.0, tsify v3.0.3
/* Log:
13. Dec. 2017 First version.
15. Dec. 2017 Performance tuning.
*/
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//
// ------------ Geometric Being -----------------------------
//
const p5Instance_1 = require("./common/p5Instance");
const settings_1 = require("./common/settings");
const Drawer_1 = require("./common/Drawer");
const ShadowedDrawer_1 = require("./common/ShadowedDrawer");
const Sprite_1 = require("./common/Sprite");
const ShapeColor_1 = require("./common/ShapeColor");
const Edge_1 = require("./common/Edge");
const TimedFrameCounter_1 = require("./common/TimedFrameCounter");
const ScalableShape_1 = require("./common/ScalableShape");
const ShapeType_1 = require("./common/ShapeType");
const NumberWrapper_1 = require("./common/NumberWrapper");
const Grid_1 = require("./common/Grid");
const popRandom_1 = require("./common/functions/popRandom");
const RandomShapeColor_1 = require("./common/RandomShapeColor");
let randomShapeColor;
let edgeColor;
let shadowColor;
let shadowOffsetPosition;
let backgroundColor;
function initialize(bgColor) {
randomShapeColor = new RandomShapeColor_1.default(() => { return new ShapeColor_1.default(p5Instance_1.p.color(p5Instance_1.p.random(0, 96)), null, true, 128); }, 32);
edgeColor = new ShapeColor_1.default(p5Instance_1.p.color(64), undefined, true, 128);
shadowColor = new ShapeColor_1.default(p5Instance_1.p.color(0, 48), null, true, 128);
shadowOffsetPosition = p5Instance_1.p.createVector(4, 4);
backgroundColor = new ShapeColor_1.default(null, bgColor);
}
exports.initialize = initialize;
class GeometricNode {
constructor(x, y, beginAppearAction, appearanceDelayFrameCount) {
this.position = p5Instance_1.p.createVector();
this.position.set(x, y);
this.appearanceFrameCounter = new TimedFrameCounter_1.default(false, 0.5 * settings_1.idealFrameRate);
this.appearanceDelayFrameCounter = new TimedFrameCounter_1.default(true, appearanceDelayFrameCount, () => {
beginAppearAction();
this.appearanceFrameCounter.on();
});
this.moveFrameCounter = new TimedFrameCounter_1.default(false, 1 * settings_1.idealFrameRate);
this.previousPosition = p5Instance_1.p.createVector();
this.targetPosition = p5Instance_1.p.createVector();
}
step() {
this.appearanceDelayFrameCounter.step();
this.appearanceFrameCounter.step();
this.moveFrameCounter.step();
if (this.moveFrameCounter.isOn) {
const ratio = pow(this.moveFrameCounter.getProgressRatio() - 1, 5) + 1;
this.position.set(this.previousPosition.x + ratio * (this.targetPosition.x - this.previousPosition.x), this.previousPosition.y + ratio * (this.targetPosition.y - this.previousPosition.y));
}
}
draw() {
if (this.appearanceDelayFrameCounter.isCompleted) {
this.drawer.draw();
}
}
beginMove(targetX, targetY) {
this.previousPosition.set(this.position);
this.targetPosition.set(targetX, targetY);
this.moveFrameCounter.on();
}
}
class ScalableGeometricNode extends GeometricNode {
constructor(x, y, beginAppearAction, appearanceDelayFrameCount, alphaRef) {
super(x, y, beginAppearAction, appearanceDelayFrameCount);
this.sizeFactor = new NumberWrapper_1.default(0);
this.baseStrokeWeightValue = p5Instance_1.p.sq(p5Instance_1.p.random(1, 1.8));
this.shapeStrokeWeight = new NumberWrapper_1.default(this.baseStrokeWeightValue);
let shapeType;
let shapeSize;
let rotationAngle;
if (Math.random() < 0.5) {
shapeType = ShapeType_1.circle;
shapeSize = 12 + p5Instance_1.p.sq(Math.random() * 4);
rotationAngle = undefined;
}
else {
shapeType = ShapeType_1.rectangle;
shapeSize = 8 + p5Instance_1.p.sq(Math.random() * 4);
rotationAngle = (Math.random() < 0.5) ? new NumberWrapper_1.default(0.25 * Math.PI) : undefined;
}
this.drawer = new ShadowedDrawer_1.ShadowedDrawer(new ScalableShape_1.default(shapeType, shapeSize, this.sizeFactor), {
positionRef: this.position,
shapeColorRef: randomShapeColor.get(),
strokeWeightRef: this.shapeStrokeWeight,
rotationAngleRef: rotationAngle,
alphaChannelRef: alphaRef,
}, shadowOffsetPosition, shadowColor);
}
step() {
super.step();
if (this.appearanceDelayFrameCounter.isCompleted) {
const ratio = this.appearanceFrameCounter.getProgressRatio();
this.sizeFactor.value = -pow((ratio - 1), 4) + 1;
this.shapeStrokeWeight.value = ratio * this.baseStrokeWeightValue;
}
}
}
class TrimmableGeometricNode extends GeometricNode {
constructor(x, y, beginAppearAction, appearanceDelayFrameCount, alphaRef) {
super(x, y, beginAppearAction, appearanceDelayFrameCount);
this.renderProgressFactor = new NumberWrapper_1.default(0);
const shapeSize = 12 + p5Instance_1.p.sq(Math.random() * 4);
this.drawer = new ShadowedDrawer_1.ShadowedDrawer({
factor: this.renderProgressFactor,
draw() {
if (this.factor.value === 1) {
settings_1.currentRenderer.ellipse(0, 0, shapeSize, shapeSize);
}
else {
settings_1.currentRenderer.arc(0, 0, shapeSize, shapeSize, 0, this.factor.value * p5Instance_1.p.TWO_PI);
}
},
}, {
positionRef: this.position,
shapeColorRef: randomShapeColor.get(),
strokeWeightRef: new NumberWrapper_1.default(p5Instance_1.p.sq(p5Instance_1.p.random(1, 1.8))),
rotationAngleRef: new NumberWrapper_1.default(Math.random() * p5Instance_1.p.TWO_PI),
alphaChannelRef: alphaRef,
}, shadowOffsetPosition, shadowColor);
}
step() {
super.step();
if (this.appearanceDelayFrameCounter.isCompleted) {
const ratio = this.appearanceFrameCounter.getProgressRatio();
this.renderProgressFactor.value = -pow((ratio - 1), 2) + 1;
}
}
}
class GeometricEdge extends Edge_1.NaiveEdge {
constructor(nodeA, nodeB, alphaChannelRef) {
super(nodeA, nodeB);
this.appearanceFrameCounter = new TimedFrameCounter_1.default(true, settings_1.idealFrameRate);
this.alphaChannelRef = alphaChannelRef;
}
step() {
this.appearanceFrameCounter.step();
}
draw() {
const positionA = this.nodeA.position;
const positionB = this.nodeB.position;
const ratio = -pow((this.appearanceFrameCounter.getProgressRatio() - 1), 4) + 1;
shadowColor.applyColor(this.alphaChannelRef.value);
settings_1.currentRenderer.translate(shadowOffsetPosition.x, shadowOffsetPosition.y);
this.drawLine(positionA, positionB, ratio);
settings_1.currentRenderer.translate(-shadowOffsetPosition.x, -shadowOffsetPosition.y);
edgeColor.applyColor(this.alphaChannelRef.value);
this.drawLine(positionA, positionB, ratio);
}
drawLine(positionA, positionB, ratio) {
settings_1.currentRenderer.line(positionA.x, positionA.y, positionA.x + ratio * (positionB.x - positionA.x), positionA.y + ratio * (positionB.y - positionA.y));
}
}
class GeometricGraph {
constructor() {
this.nodeArray = new Sprite_1.SpriteArray();
this.edgeArray = new Sprite_1.SpriteArray();
}
step() {
this.nodeArray.step();
this.edgeArray.step();
}
draw() {
settings_1.currentRenderer.strokeWeight(1.5);
this.edgeArray.draw();
this.nodeArray.draw();
}
clear() {
this.nodeArray.clear();
this.edgeArray.clear();
}
}
class GeometricBeing {
constructor(positionX, positionY, gridSize = 4, areaSize = 0.33 * 640) {
this.position = createVector(positionX, positionY);
this.neighborRange = 2;
this.grid = new Grid_1.Grid(gridSize, gridSize, this.neighborRange, false);
this.cellIntervalLength = areaSize / (gridSize + 1);
this.emptyCellArray = [];
this.cellIsEmpty = (cell) => { return this.emptyCellArray.indexOf(cell) >= 0; };
this.moveDelayFrameCounter = new TimedFrameCounter_1.default(true, 0, () => {
this.emptyCellArray.length = 0;
p5Instance_1.p.arrayCopy(this.grid.cell2DArray.array, this.emptyCellArray);
this.graph.nodeArray.loop((node) => {
const targetCell = popRandom_1.default(this.emptyCellArray);
const targetCellIndex = this.grid.getCellIndex(targetCell);
node.beginMove(this.cellIntervalLength * (targetCellIndex.x + 1), this.cellIntervalLength * (targetCellIndex.y + 1));
});
});
this.dyingDelayFrameCounter = new TimedFrameCounter_1.default(true, 0, () => {
this.dyingFrameCounter.on();
this.alphaChannel.value = 128;
});
this.dyingFrameCounter = new TimedFrameCounter_1.default(false, 1 * settings_1.idealFrameRate, () => { this.reset(); });
this.alphaChannel = new NumberWrapper_1.default(255);
this.graph = new GeometricGraph();
this.drawer = new Drawer_1.Drawer(this.graph, { positionRef: this.position });
this.areaSize = areaSize;
this.reset();
}
reset() {
this.graph.clear();
this.emptyCellArray.length = 0;
p5Instance_1.p.arrayCopy(this.grid.cell2DArray.array, this.emptyCellArray);
this.lastNode = undefined;
this.lastNodeCell = undefined;
const appearanceDelayFrameCount = Math.floor(Math.random() * 5 * settings_1.idealFrameRate);
this.createNode(appearanceDelayFrameCount);
this.moveDelayFrameCounter.resetCount();
this.moveDelayFrameCounter.on(appearanceDelayFrameCount + 4 * settings_1.idealFrameRate);
this.dyingDelayFrameCounter.resetCount();
this.dyingDelayFrameCounter.on(appearanceDelayFrameCount + 6 * settings_1.idealFrameRate);
this.dyingFrameCounter.resetCount();
this.dyingFrameCounter.off();
this.alphaChannel.value = 255;
}
step() {
this.graph.step();
this.moveDelayFrameCounter.step();
this.dyingDelayFrameCounter.step();
this.dyingFrameCounter.step();
if (this.dyingFrameCounter.isOn)
this.alphaChannel.value *= 0.95;
}
draw() {
const lastNode = this.lastNode;
if (!lastNode)
return;
if (!lastNode.appearanceFrameCounter.isCompleted || lastNode.moveFrameCounter.isOn) {
this.drawGraph();
return;
}
if (this.dyingFrameCounter.isOn) {
switch (this.dyingFrameCounter.mod(4)) {
case 0:
this.drawBackground();
return;
case 2:
this.drawGraph();
return;
default:
return;
}
}
}
drawBackground() {
backgroundColor.applyColor();
const halfAreaSize = 0.5 * this.areaSize;
settings_1.currentRenderer.rect(this.position.x + halfAreaSize, this.position.y + halfAreaSize, this.areaSize, this.areaSize);
}
drawGraph() {
this.drawBackground();
this.drawer.draw();
}
createNode(appearanceDelayFrameCount = 0.5 * settings_1.idealFrameRate) {
if (this.emptyCellArray.length === 0)
return;
let nextCell;
if (this.lastNodeCell) {
nextCell = p5Instance_1.p.random(this.lastNodeCell.neighborCells.array.filter(this.cellIsEmpty));
this.emptyCellArray.splice(this.emptyCellArray.indexOf(nextCell), 1);
}
else {
nextCell = popRandom_1.default(this.emptyCellArray);
}
this.lastNodeCell = nextCell;
const cellIndex = this.grid.getCellIndex(nextCell);
const nodeClass = (Math.random() < 0.85) ? ScalableGeometricNode : TrimmableGeometricNode;
const newNode = new nodeClass(this.cellIntervalLength * (cellIndex.x + 1), this.cellIntervalLength * (cellIndex.y + 1), () => {
if (this.graph.nodeArray.length > 4)
return;
this.createNode();
}, appearanceDelayFrameCount, this.alphaChannel);
this.graph.nodeArray.push(newNode);
if (this.lastNode) {
this.graph.edgeArray.push(new GeometricEdge(this.lastNode, newNode, this.alphaChannel));
}
this.lastNode = newNode;
}
}
exports.default = GeometricBeing;
},{"./common/Drawer":4,"./common/Edge":5,"./common/Grid":7,"./common/NumberWrapper":8,"./common/RandomShapeColor":9,"./common/ScalableShape":10,"./common/ShadowedDrawer":12,"./common/ShapeColor":13,"./common/ShapeType":14,"./common/Sprite":15,"./common/TimedFrameCounter":17,"./common/functions/popRandom":22,"./common/p5Instance":25,"./common/settings":26}],2:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//
// ------------ Array wrapper -----------------------------
//
const loopArray_1 = require("./functions/loopArray");
const roundRobin_1 = require("./functions/roundRobin");
const nestedLoopJoin_1 = require("./functions/nestedLoopJoin");
class ArrayWrapper {
constructor(initialCapacity = 256) {
// tslint:disable-next-line:prefer-array-literal
this.array = new Array(initialCapacity);
this.currentLength = 0;
}
get length() {
return this.currentLength;
}
get(index) {
return this.array[index];
}
getLast() {
return this.array[this.currentLength - 1];
}
push(element) {
this.array[this.currentLength] = element;
this.currentLength += 1;
}
pushAll(elementArray) {
const elementArrayLength = elementArray.length;
for (let i = 0; i < elementArrayLength; i += 1) {
this.array[this.currentLength + i] = elementArray[i];
}
this.currentLength += elementArrayLength;
}
pop() {
this.currentLength -= 1;
return this.array[this.currentLength];
}
clear() {
this.currentLength = 0;
}
loop(callback) {
loopArray_1.loopArray(this.array, callback, this.currentLength);
}
loopBackward(callback) {
loopArray_1.loopArrayBackward(this.array, callback, this.currentLength);
}
roundRobin(callback) {
roundRobin_1.default(this.array, callback, this.currentLength);
}
nestedLoopJoin(otherArray, callback) {
nestedLoopJoin_1.default(this.array, otherArray.array, callback, this.currentLength, otherArray.currentLength);
}
}
exports.default = ArrayWrapper;
},{"./functions/loopArray":20,"./functions/nestedLoopJoin":21,"./functions/roundRobin":24}],3:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//
// ------------ Drawable -----------------------------
//
const ArrayWrapper_1 = require("./ArrayWrapper");
class DrawableArray extends ArrayWrapper_1.default {
constructor(initialCapacity) {
super(initialCapacity);
}
static drawFunction(value) {
value.draw();
}
draw() {
this.loop(DrawableArray.drawFunction);
}
}
exports.DrawableArray = DrawableArray;
},{"./ArrayWrapper":2}],4:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//
// ------------ Drawer -----------------------------
//
/// <reference path="../../../my_types/p5/p5.d.ts" />
const settings_1 = require("./settings");
const NumberWrapper_1 = require("./NumberWrapper");
const ScaleFactor_1 = require("./ScaleFactor");
const ShapeColor_1 = require("./ShapeColor");
class DrawParameterImplementation {
constructor() {
this.initialize();
}
initialize() {
this.positionRef = undefined;
this.rotationAngleRef = undefined;
this.scaleFactorRef = undefined;
this.shapeColorRef = undefined;
this.alphaChannelRef = undefined;
this.strokeWeightRef = undefined;
}
}
exports.DrawParameterImplementation = DrawParameterImplementation;
class Drawer {
constructor(element, drawParam) {
this.set(element, drawParam);
}
set(element, drawParam) {
this.element = element;
this.position = drawParam.positionRef || createVector();
this.rotation = drawParam.rotationAngleRef || NumberWrapper_1.NULL_NUMBER;
this.scaleFactor = drawParam.scaleFactorRef || new ScaleFactor_1.default();
this.shapeColor = drawParam.shapeColorRef || ShapeColor_1.NULL_SHAPE_COLOR;
this.alphaChannel = drawParam.alphaChannelRef || NumberWrapper_1.NULL_NUMBER;
this.strokeWeight = drawParam.strokeWeightRef || NumberWrapper_1.NULL_NUMBER;
this.procedureList = this.createProcedureList(drawParam);
this.procedureListLength = this.procedureList.length;
}
draw() {
for (let i = 0, len = this.procedureListLength; i < len; i += 1) {
this.procedureList[i](this);
}
}
drawElement(drawer) {
drawer.element.draw();
}
createProcedureList(drawParam) {
const procedureList = [];
if (drawParam.shapeColorRef) {
if (drawParam.alphaChannelRef)
procedureList.push(this.alphaColor);
else
procedureList.push(this.color);
}
if (drawParam.strokeWeightRef)
procedureList.push(this.applyStrokeWeight);
if (drawParam.positionRef)
procedureList.push(this.translate);
if (drawParam.scaleFactorRef)
procedureList.push(this.scale);
if (drawParam.rotationAngleRef)
procedureList.push(this.rotate);
procedureList.push(this.drawElement);
if (drawParam.rotationAngleRef)
procedureList.push(this.cancelRotate);
if (drawParam.scaleFactorRef)
procedureList.push(this.cancelScale);
if (drawParam.positionRef)
procedureList.push(this.cancelTranslate);
return procedureList;
}
translate(drawer) {
settings_1.currentRenderer.translate(drawer.position.x, drawer.position.y);
}
cancelTranslate(drawer) {
settings_1.currentRenderer.translate(-drawer.position.x, -drawer.position.y);
}
rotate(drawer) {
settings_1.currentRenderer.rotate(drawer.rotation.value);
}
cancelRotate(drawer) {
settings_1.currentRenderer.rotate(-drawer.rotation.value);
}
scale(drawer) {
if (drawer.scaleFactor.value === 1)
return;
drawer.scaleFactor.applyScale();
}
cancelScale(drawer) {
if (drawer.scaleFactor.value === 1)
return;
drawer.scaleFactor.cancel();
}
color(drawer) {
drawer.shapeColor.applyColor();
}
alphaColor(drawer) {
drawer.shapeColor.applyColor(drawer.alphaChannel.value);
}
applyStrokeWeight(drawer) {
settings_1.currentRenderer.strokeWeight(drawer.strokeWeight.value);
}
}
exports.Drawer = Drawer;
},{"./NumberWrapper":8,"./ScaleFactor":11,"./ShapeColor":13,"./settings":26}],5:[function(require,module,exports){
"use strict";
//
// ------------ Edge -----------------------------
//
Object.defineProperty(exports, "__esModule", { value: true });
class NaiveEdge {
constructor(nodeA, nodeB) {
this.nodeA = nodeA;
this.nodeB = nodeB;
}
isIncidentTo(node) {
return node === this.nodeA || node === this.nodeB;
}
/**
* Returns the adjacent node of the given node via this edge.
* If this edge is not incident to the given node, returns alwayes the end point node.
* @param {T} node - any node which is incident to this edge
*/
getAdjacentNode(node) {
if (node === this.nodeB)
return this.nodeA;
return this.nodeB;
}
}
exports.NaiveEdge = NaiveEdge;
},{}],6:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//
// ------------ Frame counter -----------------------------
//
const settings_1 = require("./settings");
class FrameCounter {
constructor() {
this.count = 0;
}
resetCount(count = 0) {
this.count = count;
}
step() {
this.count += 1;
}
mod(divisor) {
return this.count % divisor;
}
/**
* Returns ratio from 0 to 1 according to current frame count and given frequency per second.
* @param frequency {number} - frequency per second
*/
getCycleProgressRatio(frequency) {
return ((frequency * this.count) % settings_1.idealFrameRate) / settings_1.idealFrameRate;
}
/**
* Returns sine value (from 0 to 1)according to
* current frame count and given frequency per second.
* @param frequency {number} - frequency per second
*/
sin(frequency) {
return Math.sin(this.getCycleProgressRatio(frequency) * 2 * Math.PI);
}
}
exports.default = FrameCounter;
},{"./settings":26}],7:[function(require,module,exports){
"use strict";
//
// ------------ Grid -------------------------------------------------
//
Object.defineProperty(exports, "__esModule", { value: true });
const TwoDimensionalArray_1 = require("./TwoDimensionalArray");
class Cell {
constructor(neighborRange = 1) {
this.neighborCells = new TwoDimensionalArray_1.default(2 * neighborRange + 1, 2 * neighborRange + 1, exports.NULL_CELL);
}
getNeighborCell(relativeX, relativeY) {
const neighborRange = Math.floor(this.neighborCells.xCount / 2);
if (relativeX < -neighborRange || relativeX > neighborRange ||
relativeY < -neighborRange || relativeY > neighborRange)
return exports.NULL_CELL;
return this.neighborCells.get2D(relativeX + neighborRange, relativeY + neighborRange);
}
setNeighborCell(relativeX, relativeY, cell) {
const neighborRange = Math.floor(this.neighborCells.xCount / 2);
this.neighborCells.set2D(relativeX + neighborRange, relativeY + neighborRange, cell);
}
}
exports.Cell = Cell;
class NullCell extends Cell {
constructor() {
super(0);
}
getNeighborCell(relativeX, relativeY) {
return this;
}
setNeighborCell(relativeX, relativeY, cell) { }
}
exports.NULL_CELL = new NullCell();
class Grid {
constructor(xCount, yCount, neighborRange, loopAtEndOfScreen) {
this.cell2DArray = new TwoDimensionalArray_1.default(xCount, yCount, exports.NULL_CELL);
this.cellIndexMap = new Map();
for (let yIndex = 0; yIndex < yCount; yIndex += 1) {
for (let xIndex = 0; xIndex < xCount; xIndex += 1) {
const cell = new Cell(neighborRange);
this.cell2DArray.set2D(xIndex, yIndex, cell);
this.cellIndexMap.set(cell, { x: xIndex, y: yIndex });
}
}
this.cell2DArray.loop((cell) => {
this.setNeighborCells(cell, neighborRange, loopAtEndOfScreen);
});
}
getCell(x, y) {
return this.cell2DArray.get2D(x, y);
}
getCellIndex(cell) {
return this.cellIndexMap.get(cell) || { x: -1, y: -1 };
}
getRelativePositionCell(referenceCell, relX, relY, loopAtEndOfScreen) {
if (referenceCell === exports.NULL_CELL)
return referenceCell;
if (relX === 0 && relY === 0)
return referenceCell;
const referenceIndex = this.getCellIndex(referenceCell);
const targetIndex = {
x: referenceIndex.x + relX,
y: referenceIndex.y + relY,
};
if (loopAtEndOfScreen) {
if (targetIndex.x < 0)
targetIndex.x += this.cell2DArray.xCount;
else if (targetIndex.x >= this.cell2DArray.xCount)
targetIndex.x -= this.cell2DArray.xCount;
if (targetIndex.y < 0)
targetIndex.y += this.cell2DArray.yCount;
else if (targetIndex.y >= this.cell2DArray.yCount)
targetIndex.y -= this.cell2DArray.yCount;
}
else {
if (targetIndex.x < 0 || targetIndex.x >= this.cell2DArray.xCount ||
targetIndex.y < 0 || targetIndex.y >= this.cell2DArray.yCount)
return exports.NULL_CELL;
}
return this.cell2DArray.get2D(targetIndex.x, targetIndex.y);
}
setNeighborCells(referenceCell, neighborRange, loopAtEndOfScreen) {
for (let relativeX = -neighborRange; relativeX <= neighborRange; relativeX += 1) {
for (let relativeY = -neighborRange; relativeY <= neighborRange; relativeY += 1) {
referenceCell.setNeighborCell(relativeX + neighborRange, relativeY + neighborRange, this.getRelativePositionCell(referenceCell, relativeX, relativeY, loopAtEndOfScreen));
}
}
}
}
exports.Grid = Grid;
},{"./TwoDimensionalArray":18}],8:[function(require,module,exports){
"use strict";
//
// ------------ Number wrapper -----------------------------
//
Object.defineProperty(exports, "__esModule", { value: true });
class NumberWrapper {
constructor(value = 0) {
this.value = value;
}
}
exports.default = NumberWrapper;
class NullNumberWrapper extends NumberWrapper {
get value() { return 0; }
set value(v) { }
}
exports.NULL_NUMBER = new NullNumberWrapper();
},{}],9:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//
// ------------ Random shape color -----------------------------
//
const getRandom_1 = require("./functions/getRandom");
class RandomShapeColor {
constructor(createShapeColor, candidateCount) {
this.candidateArray = [];
for (let i = 0; i < candidateCount; i += 1) {
this.candidateArray.push(createShapeColor());
}
}
get() {
return getRandom_1.getRandom(this.candidateArray);
}
}
exports.default = RandomShapeColor;
},{"./functions/getRandom":19}],10:[function(require,module,exports){
"use strict";
//
// ------------ Scalable shape -----------------------------
//
Object.defineProperty(exports, "__esModule", { value: true });
const NumberWrapper_1 = require("./NumberWrapper");
class ScalableShape {
constructor(shapeType, baseShapeSize, scaleFactorRef = new NumberWrapper_1.default(1)) {
this.shapeType = shapeType;
this.baseShapeSize = baseShapeSize;
this.scaleFactorRef = scaleFactorRef;
}
draw() {
this.shapeType.drawShape(this.scaleFactorRef.value * this.baseShapeSize);
}
}
exports.default = ScalableShape;
},{"./NumberWrapper":8}],11:[function(require,module,exports){
"use strict";
//
// ------------ Scale factor -----------------------------
//
/// <reference path="../../../my_types/p5/p5.global-mode.d.ts" />
Object.defineProperty(exports, "__esModule", { value: true });
class ScaleFactor {
constructor(value = 1) {
this.internalValue = value;
this.internalReciprocalValue = 1 / value;
}
get value() {
return this.internalValue;
}
set value(v) {
if (v === 0) {
this.internalValue = 0.0001;
this.internalReciprocalValue = 10000;
return;
}
this.internalValue = v;
this.internalReciprocalValue = 1 / v;
}
get reciprocalValue() {
return this.internalValue;
}
applyScale() {
scale(this.internalValue);
}
cancel() {
scale(this.internalReciprocalValue);
}
}
exports.default = ScaleFactor;
},{}],12:[function(require,module,exports){
"use strict";
//
// ------------ Shadowed drawer -----------------------------
//
/// <reference path="../../../my_types/p5/p5.d.ts" />
Object.defineProperty(exports, "__esModule", { value: true });
const Drawer_1 = require("./Drawer");
const ShapeColor_1 = require("./ShapeColor");
const settings_1 = require("./settings");
const NumberWrapper_1 = require("./NumberWrapper");
// Refactoring needed.
class ShadowedDrawer extends Drawer_1.Drawer {
constructor(element, drawParam, offsetPosition, shadowColor) {
super(element, drawParam);
this.offsetPosition = offsetPosition;
this.shadowColor = shadowColor;
}
drawElement(drawer) {
const alphaValue = (drawer.alphaChannel !== NumberWrapper_1.NULL_NUMBER) ? drawer.alphaChannel.value : 255;
drawer.shadowColor.applyColor(alphaValue);
if (drawer.rotation)
settings_1.currentRenderer.rotate(-drawer.rotation.value);
settings_1.currentRenderer.translate(drawer.offsetPosition.x, drawer.offsetPosition.y);
if (drawer.rotation)
settings_1.currentRenderer.rotate(drawer.rotation.value);
super.drawElement(drawer);
if (drawer.rotation)
settings_1.currentRenderer.rotate(-drawer.rotation.value);
settings_1.currentRenderer.translate(-drawer.offsetPosition.x, -drawer.offsetPosition.y);
if (drawer.rotation)
settings_1.currentRenderer.rotate(drawer.rotation.value);
if (drawer.shapeColor !== ShapeColor_1.NULL_SHAPE_COLOR)
drawer.shapeColor.applyColor(alphaValue);
super.drawElement(drawer);
}
}
exports.ShadowedDrawer = ShadowedDrawer;
},{"./Drawer":4,"./NumberWrapper":8,"./ShapeColor":13,"./settings":26}],13:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//
// --------- ShapeColor (Composite of fill & stroke) -------------
//
/// <reference path="../../../my_types/p5/p5.d.ts" />
const common = require("./settings");
const p5Instance_1 = require("./p5Instance");
class NormalColorUnit {
constructor(p5Color) {
this.p5Color = p5Color;
}
stroke() {
common.currentRenderer.stroke(this.p5Color);
}
fill() {
common.currentRenderer.fill(this.p5Color);
}
}
class NoColorUnit {
stroke() {
common.currentRenderer.noStroke();
}
fill() {
common.currentRenderer.noFill();
}
}
class UndefinedColorUnit {
stroke() {
}
fill() {
}
}
class AlphaColorUnit {
constructor(c, alphaResolution = 256) {
const array = [];
for (let alphaFactor = 0; alphaFactor < alphaResolution; alphaFactor += 1) {
array.push(p5Instance_1.p.color(p5Instance_1.p.red(c), p5Instance_1.p.green(c), p5Instance_1.p.blue(c), p5Instance_1.p.alpha(c) * alphaFactor / (alphaResolution - 1)));
}
this.colorArray = array;
this.maxIndex = alphaResolution - 1;
}
stroke(alphaValue) {
common.currentRenderer.stroke(this.getColor(alphaValue));
}
fill(alphaValue) {
common.currentRenderer.stroke(this.getColor(alphaValue));
}
getColor(alphaValue) {
return this.colorArray[alphaValue ? Math.floor(p5Instance_1.p.map(alphaValue, 0, 255, 0, this.maxIndex)) : this.maxIndex];
}
}
function colorUnit(p5Color, alphaEnabled, alphaResolution) {
if (p5Color === undefined)
return new UndefinedColorUnit();
if (p5Color === null)
return new NoColorUnit();
if (alphaEnabled)
return new AlphaColorUnit(p5Color, alphaResolution);
return new NormalColorUnit(p5Color);
}
class ShapeColor {
constructor(strokeColor, fillColor, alphaEnabled, alphaResolution) {
this.strokeColor = colorUnit(strokeColor, alphaEnabled, alphaResolution);
this.fillColor = colorUnit(fillColor, alphaEnabled, alphaResolution);
}
applyColor(alphaValue) {
this.strokeColor.stroke(alphaValue);
this.fillColor.fill(alphaValue);
}
}
exports.default = ShapeColor;
exports.NULL_SHAPE_COLOR = new ShapeColor(undefined, undefined);
},{"./p5Instance":25,"./settings":26}],14:[function(require,module,exports){
"use strict";
//
// --------- Shape type -----------------------------------------
//
/// <reference path="../../../my_types/p5/p5.d.ts" />
Object.defineProperty(exports, "__esModule", { value: true });
const settings_1 = require("./settings");
exports.circle = {
drawShape: (size) => {
settings_1.currentRenderer.ellipse(0, 0, size, size);
},
};
exports.rectangle = {
drawShape: (size) => {
settings_1.currentRenderer.rect(0, 0, size, size);
},
};
},{"./settings":26}],15:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//
// ------------ Sprite -------------------------------------
//
const ArrayWrapper_1 = require("./ArrayWrapper");
const Steppable_1 = require("./Steppable");
const Drawable_1 = require("./Drawable");
class SpriteArray extends ArrayWrapper_1.default {
constructor(initialCapacity) {
super(initialCapacity);
this.step = Steppable_1.SteppableArray.prototype.step;
this.draw = Drawable_1.DrawableArray.prototype.draw;
}
}
exports.SpriteArray = SpriteArray;
},{"./ArrayWrapper":2,"./Drawable":3,"./Steppable":16}],16:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//
// ------------ Steppable -----------------------------
//
const ArrayWrapper_1 = require("./ArrayWrapper");
class SteppableArray extends ArrayWrapper_1.default {
constructor(initialCapacity) {
super(initialCapacity);
}
static stepFunction(value) {
value.step();
}
step() {
this.loop(SteppableArray.stepFunction);
}
}
exports.SteppableArray = SteppableArray;
},{"./ArrayWrapper":2}],17:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//
// ------------ Timed frame counter -----------------------------
//
const FrameCounter_1 = require("./FrameCounter");
class TimedFrameCounter extends FrameCounter_1.default {
constructor(on, duration, completeBehavior = () => { }) {
super();
this.isOn = on;
this.isCompleted = false;
this.completeBehavior = completeBehavior;
this.durationFrameCount = duration;
}
on(duration) {
this.isOn = true;
if (duration)
this.durationFrameCount = duration;
}
off() {
this.isOn = false;
}
resetCount() {
super.resetCount();
this.isCompleted = false;
}
step() {
if (!this.isOn)
return;
this.count += 1;
if (this.count > this.durationFrameCount) {
this.isCompleted = true;
this.isOn = false;
this.completeBehavior();
}
}
getProgressRatio() {
return this.isCompleted ? 1 : Math.min(Math.max(this.count / this.durationFrameCount, 0), 1);
}
}
exports.default = TimedFrameCounter;
},{"./FrameCounter":6}],18:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//
// ------------ Two dimensional array -----------------------------
//
const ArrayWrapper_1 = require("./ArrayWrapper");
class TwoDimensionalArray extends ArrayWrapper_1.default {
constructor(xCount, yCount, fillObject) {
super(xCount * yCount);
this.xCount = xCount;
this.yCount = yCount;
if (fillObject) {
for (let i = 0, len = xCount * yCount; i < len; i += 1) {
this.push(fillObject);
}
}
}
get2D(x, y) {
return this.array[x + this.xCount * y];
}
set2D(x, y, object) {
this.array[x + this.xCount * y] = object;
}
}
exports.default = TwoDimensionalArray;
},{"./ArrayWrapper":2}],19:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//
// ------------ getRandom() -------------------------------------
//
const randomInt_1 = require("./randomInt");
function getRandom(array) {
return array[randomInt_1.randomInt(array.length)];
}
exports.getRandom = getRandom;
},{"./randomInt":23}],20:[function(require,module,exports){
"use strict";
//
// ------------ loopArray() -------------------------------------
//
Object.defineProperty(exports, "__esModule", { value: true });
function loopArray(array, callback, length) {
for (let i = 0; i < length; i += 1) {
callback(array[i], i, array);
}
}
exports.loopArray = loopArray;
function loopArrayBackward(array, callback, length) {
for (let i = length - 1; i >= 0; i -= 1) {
callback(array[i], i, array);
}
}
exports.loopArrayBackward = loopArrayBackward;
},{}],21:[function(require,module,exports){
"use strict";
//
// ------------ nestedLoopJoin() -------------------------------------
//
Object.defineProperty(exports, "__esModule", { value: true });
function nestedLoopJoin(array, otherArray, callback, length, otherLength) {
for (let i = 0; i < length; i += 1) {
for (let k = 0; k < otherLength; k += 1) {
callback(array[i], otherArray[k]);
}
}
}
exports.default = nestedLoopJoin;
},{}],22:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//
// ------------ popRandom() -------------------------------------
//
const randomInt_1 = require("./randomInt");
function popRandom(array) {
return array.splice(randomInt_1.randomInt(array.length), 1)[0]; // bug fixed 2017-11-22
}
exports.default = popRandom;
},{"./randomInt":23}],23:[function(require,module,exports){
"use strict";
//
// ------------ randomInt() -----------------------------
//
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Returns random integer from 0 up to (but not including) the max number.
*/
function randomInt(maxInt) {
return Math.floor(Math.random() * maxInt);
}
exports.randomInt = randomInt;
/**
* Returns random integer from the min number up to (but not including) the max number.
*/
function randomIntBetween(minInt, maxInt) {
return minInt + randomInt(maxInt - minInt);
}
exports.randomIntBetween = randomIntBetween;
},{}],24:[function(require,module,exports){
"use strict";
//
// ------------ roundRobin() -------------------------------------
//
Object.defineProperty(exports, "__esModule", { value: true });
function roundRobin(array, callback, length) {
for (let i = 0, len = length - 1; i < len; i += 1) {
for (let k = i + 1; k < length; k += 1) {
callback(array[i], array[k]);
}
}
}
exports.default = roundRobin;
},{}],25:[function(require,module,exports){
"use strict";
//
// ------------ P5 instance ---------------------------------
//
/// <reference path="../../../my_types/p5/p5.d.ts" />
Object.defineProperty(exports, "__esModule", { value: true });
function setP5Instance(pInst) {
exports.p = pInst;
}
exports.setP5Instance = setP5Instance;
},{}],26:[function(require,module,exports){
"use strict";
//
// ------------ Common settings ------------------------------
//
/// <reference path="../../../my_types/p5/p5.d.ts" />
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Calls p5.frameRate() and updates common variables related to the frame rate.
* @param {p5} pInst - p5 instance
* @param {number} frameRate - the ideal frame rate (default: 60)
*/
function setFrameRate(pInst, frameRate = 60) {
pInst.frameRate(frameRate);
exports.idealFrameRate = 60;
exports.unitAngleSpeed = 2 * Math.PI / exports.idealFrameRate;
exports.unitSpeed = 1 / exports.idealFrameRate;
exports.unitAccelerationMagnitude = exports.unitSpeed / exports.idealFrameRate;
}
exports.setFrameRate = setFrameRate;
exports.CANVAS_SHORT_SIDE_LENGTH = 640; // non-scaled size
/**
* Updates common variables related to the canvas size.
* @param {p5} pInst - p5 instance
*/
function updateCanvasScale(pInst) {
exports.canvasScaleFactor = Math.min(pInst.width, pInst.height) / exports.CANVAS_SHORT_SIDE_LENGTH;
exports.nonScaledWidth = pInst.width / exports.canvasScaleFactor;
exports.nonScaledHeight = pInst.height / exports.canvasScaleFactor;
exports.aspectRatio = pInst.width / pInst.height;
}
exports.updateCanvasScale = updateCanvasScale;
function getNonScaledValueOf(n) {
return n / exports.canvasScaleFactor;
}
exports.getNonScaledValueOf = getNonScaledValueOf;
function mouseIsOnCanvas() {
if (exports.currentRenderer.mouseX < 0)
return false;
if (exports.currentRenderer.mouseX > exports.currentRenderer.width)
return false;
if (exports.currentRenderer.mouseY < 0)
return false;
if (exports.currentRenderer.mouseY > exports.currentRenderer.height)
return false;
return true;
}
exports.mouseIsOnCanvas = mouseIsOnCanvas;
function setRenderer(renderer) {
exports.currentRenderer = renderer;
}
exports.setRenderer = setRenderer;
function getMaxRegionSize(pInst, sketchContainerId) {
const region = {
width: pInst.windowWidth,
height: pInst.windowHeight,
};
if (document) {
const sketchContainer = document.getElementById(sketchContainerId);
if (sketchContainer) {
region.width = sketchContainer.getBoundingClientRect().width;
region.height = sketchContainer.getBoundingClientRect().height;
}
}
return region;
}
exports.getMaxRegionSize = getMaxRegionSize;
function initialize(pInst, frameRate = 60) {
window.noCanvas();
updateCanvasScale(pInst);
setFrameRate(pInst, frameRate);
setRenderer(pInst);
}
exports.initialize = initialize;
},{}],27:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//
// ------------ Main -------------------------------------------------------------------------
//
const common = require("./common/settings");
const p5Instance_1 = require("./common/p5Instance");
const GeometricBeing_1 = require("./GeometricBeing");
const Sprite_1 = require("./common/Sprite");
p5.disableFriendlyErrors = true;
const SKETCH_NAME = 'GeometricBeings20171213';
// At first create a dummy p5 instance as a workaround for error in
// https://www.openprocessing.org/assets/js/sketch/p5js_OPextension.js
new p5();
const sketch = (p) => {
// ---- variables
let geometricBeingArray;
let backgroundColor;
// ---- Setup & Draw etc.
p.setup = () => {
const maxRegion = common.getMaxRegionSize(p, SKETCH_NAME);
const canvasSize = Math.min(maxRegion.width, maxRegion.height);
//p.createCanvas(canvasSize, canvasSize);
p.createCanvas(960, 720);
p.colorMode(HSB, 255);
p5Instance_1.setP5Instance(p);
common.initialize(p);
common.currentRenderer.rectMode(p.CENTER);
common.currentRenderer.noFill();
backgroundColor = p.color(random(255),60,255);
GeometricBeing_1.initialize(backgroundColor);
geometricBeingArray = new Sprite_1.SpriteArray();
const interval = 0.33 * common.CANVAS_SHORT_SIDE_LENGTH;
for (let y = 0; y < common.nonScaledWidth - interval; y += interval) {
for (let x = 0; x < common.nonScaledWidth - interval; x += interval) {
geometricBeingArray.push(new GeometricBeing_1.default(x, y, 4, interval));
}
}
common.currentRenderer.background(backgroundColor);
};
p.draw = () => {
common.currentRenderer.scale(common.canvasScaleFactor);
geometricBeingArray.step();
geometricBeingArray.draw();
};
p.mousePressed = () => {
p.noLoop();
};
p.mouseReleased = () => {
p.loop();
p.save("img_" + month() + '-' + day() + '_' + hour() + '-' + minute() + '-' + second() + ".jpg");
};
};
new p5(sketch, SKETCH_NAME);
},{"./GeometricBeing":1,"./common/Sprite":15,"./common/p5Instance":25,"./common/settings":26}]},{},[27]);