diff --git a/.vs/AAWeb/v15/.suo b/.vs/AAWeb/v15/.suo
index 633fd274b..c983a5706 100644
Binary files a/.vs/AAWeb/v15/.suo and b/.vs/AAWeb/v15/.suo differ
diff --git a/Canvas.js b/Canvas.js
index a5625b2f8..50b50300c 100644
--- a/Canvas.js
+++ b/Canvas.js
@@ -45,7 +45,7 @@ function newCanvas() {
/* Mouse event related variables. */
let containerDragStarted = false;
- let ballDragStarted = false;
+ let floatingObjectDragStarted = false;
let floatingObjectBeingDragged;
let containerBeingDragged;
let viewPortBeingDragged = false;
@@ -114,7 +114,7 @@ function newCanvas() {
/* Here we add all the functions that will be called during the animation cycle. */
animation.addCallBackFunction("Chart Space", thisObject.chartSpace.draw, onFunctionAdded);
- animation.addCallBackFunction("Floating Space", thisObject.floatingSpace.physicsLoop, onFunctionAdded);
+ animation.addCallBackFunction("Floating Space", thisObject.floatingSpace.floatingLayer.physicsLoop, onFunctionAdded);
animation.addCallBackFunction("Panels Space", thisObject.panelsSpace.draw, onFunctionAdded);
animation.addCallBackFunction("Splash Screen", splashScreen.draw, onFunctionAdded);
animation.addCallBackFunction("ViewPort Animate", viewPort.animate, onFunctionAdded);
@@ -239,12 +239,12 @@ function newCanvas() {
return;
}
- /* We check first if the mouse is over a ball/ */
+ /* We check first if the mouse is over a floatingObject/ */
- floatingObjectBeingDragged = thisObject.floatingSpace.isInside(event.pageX, event.pageY);
+ floatingObjectBeingDragged = thisObject.floatingSpace.floatingLayer.isInside(event.pageX, event.pageY);
if (floatingObjectBeingDragged >= 0) {
- ballDragStarted = true;
+ floatingObjectDragStarted = true;
return;
}
@@ -283,11 +283,11 @@ function newCanvas() {
return;
}
- /* We check first if the mouse is over a ball/ */
+ /* We check first if the mouse is over a floatingObject/ */
- let ballBeingClicked = thisObject.floatingSpace.isInside(event.pageX, event.pageY);
+ let floatingObjectBeingClicked = thisObject.floatingSpace.floatingLayer.isInside(event.pageX, event.pageY);
- if (ballBeingClicked >= 0) {
+ if (floatingObjectBeingClicked >= 0) {
/* Right now we do nothing with this. */
return;
@@ -309,7 +309,7 @@ function newCanvas() {
if (INFO_LOG === true) { logger.write("[INFO] onMouseUp -> Entering function."); }
- if (containerDragStarted || viewPortBeingDragged || ballDragStarted) {
+ if (containerDragStarted || viewPortBeingDragged || floatingObjectDragStarted) {
thisObject.eventHandler.raiseEvent("Drag Finished", undefined);
@@ -318,7 +318,7 @@ function newCanvas() {
/* Turn off all the possible things that can be dragged. */
containerDragStarted = false;
- ballDragStarted = false;
+ floatingObjectDragStarted = false;
viewPortBeingDragged = false;
containerBeingDragged = undefined;
@@ -334,16 +334,16 @@ function newCanvas() {
viewPort.mousePosition.x = event.pageX;
viewPort.mousePosition.y = event.pageY;
- if (containerDragStarted === true || ballDragStarted === true || viewPortBeingDragged === true) {
+ if (containerDragStarted === true || floatingObjectDragStarted === true || viewPortBeingDragged === true) {
- if (ballDragStarted === true) {
+ if (floatingObjectDragStarted === true) {
- if (thisObject.floatingSpace.isInsideFloatingObject(floatingObjectBeingDragged, event.pageX, event.pageY) === false) {
+ if (thisObject.floatingSpace.floatingLayer.isInsideFloatingObject(floatingObjectBeingDragged, event.pageX, event.pageY) === false) {
- /* This means that the user stop moving the mouse and the ball ball out of the pointer.
+ /* This means that the user stop moving the mouse and the floatingObject floatingObject out of the pointer.
In this case we cancell the drag operation . */
- ballDragStarted = false;
+ floatingObjectDragStarted = false;
browserCanvas.style.cursor = "auto";
return;
}
@@ -374,24 +374,24 @@ function newCanvas() {
if (INFO_LOG === true) { logger.write("[INFO] checkDrag -> Entering function."); }
- if (containerDragStarted === true || ballDragStarted === true || viewPortBeingDragged === true) {
+ if (containerDragStarted === true || floatingObjectDragStarted === true || viewPortBeingDragged === true) {
browserCanvas.style.cursor = "grabbing";
thisObject.eventHandler.raiseEvent("Dragging", undefined);
- let targetFloatingObject = thisObject.floatingSpace.isInside(event.pageX, event.pageY);
+ let targetFloatingObject = thisObject.floatingSpace.floatingLayer.isInside(event.pageX, event.pageY);
- if (ballDragStarted) {
+ if (floatingObjectDragStarted) {
- let ball = thisObject.floatingSpace.floatingObjects[floatingObjectBeingDragged];
+ let floatingObject = thisObject.floatingSpace.floatingLayer.floatingObjects[floatingObjectBeingDragged];
- ball.currentPosition.x = dragVector.upX;
- ball.currentPosition.y = dragVector.upY;
+ floatingObject.currentPosition.x = dragVector.upX;
+ floatingObject.currentPosition.y = dragVector.upY;
- /* Now we estimate if the drag was towards the Target Point of the ball or not. */
+ /* Now we estimate if the drag was towards the Target Point of the floatingObject or not. */
- let distDown = distance(dragVector.downX, dragVector.downY, ball.targetPosition.x, ball.targetPosition.y);
- let distUp = distance(dragVector.upX, dragVector.upY, ball.targetPosition.x, ball.targetPosition.y);
+ let distDown = distance(dragVector.downX, dragVector.downY, floatingObject.targetPosition.x, floatingObject.targetPosition.y);
+ let distUp = distance(dragVector.upX, dragVector.upY, floatingObject.targetPosition.x, floatingObject.targetPosition.y);
let mZoomValue;
@@ -402,7 +402,7 @@ function newCanvas() {
mZoomValue = -1;
}
- //ball.container.zoom.mZoom(mZoomValue); // Zoom is applied to ball mass of all balls in the same container.
+ //floatingObject.container.zoom.mZoom(mZoomValue); // Zoom is applied to floatingObject mass of all floatingObjects in the same container.
}
if (containerDragStarted || viewPortBeingDragged) {
diff --git a/FloatingSpace/BubbleSets.js b/FloatingSpace/BubbleSets.js
new file mode 100644
index 000000000..a43fcb350
--- /dev/null
+++ b/FloatingSpace/BubbleSets.js
@@ -0,0 +1,66 @@
+
+function newBubbleSets() {
+
+ const MODULE_NAME = "Bubble Sets";
+ const INFO_LOG = false;
+ const ERROR_LOG = true;
+ const logger = newDebugLog();
+ logger.fileName = MODULE_NAME;
+
+ let thisObject = {
+ createBubbleSet: createBubbleSet,
+ destroyBubbleSet: destroyBubbleSet,
+ initialize: initialize
+ };
+
+ let bubbleSets = [];
+
+ let floatingLayer;
+
+ return thisObject;
+
+ function initialize(pFloatingLayer, callBackFunction) {
+
+ try {
+
+ if (INFO_LOG === true) { logger.write("[INFO] initialize -> Entering function."); }
+
+ floatingLayer = pFloatingLayer;
+
+ callBackFunction(GLOBAL.CUSTOM_OK_RESPONSE);
+
+ } catch (err) {
+
+ if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> err = " + err); }
+ callBackFunction(GLOBAL.CUSTOM_FAIL_RESPONSE);
+ }
+ }
+
+ function createBubbleSet(pPlotterBubbles) {
+
+ let bubbleSet = {
+ floatingBubbles: [],
+ plotterBubbles: pPlotterBubbles,
+ handle: Math.floor((Math.random() * 10000000) + 1)
+ };
+
+ bubbleSets.push(bubbleSet);
+
+ return bubbleSet.handle;
+ }
+
+ function destroyBubbleSet(pHandle) {
+
+ for (let i = 0; i < bubbleSets.length; i++) {
+
+ let bubbleSet = bubbleSets[i];
+
+ if (bubbleSet.handle === pHandle) {
+ bubbleSets.splice(i, 1); // Delete item from array.
+ return;
+ }
+ }
+ }
+}
+
+
diff --git a/FloatingSpace/FloatingLayer.js b/FloatingSpace/FloatingLayer.js
new file mode 100644
index 000000000..cbe088afa
--- /dev/null
+++ b/FloatingSpace/FloatingLayer.js
@@ -0,0 +1,422 @@
+
+function newFloatingLayer() {
+
+ let thisObject = {
+ floatingObjects: undefined, // This is the array of floatingObjects being displayed
+ addFloatingObject: addFloatingObject,
+ removeFloatingObject: removeFloatingObject,
+ physicsLoop: physicsLoop,
+ isInside: isInside,
+ isInsideFloatingObject: isInsideFloatingObject,
+ initialize: initialize
+ };
+
+ innactiveFloatingObjects = [];
+
+ return thisObject;
+
+ function initialize(callBackFunction) {
+
+ thisObject.floatingObjects = []; // We initialize this in order to start the calculations in a clean way.
+
+ callBackFunction();
+ }
+
+ function addFloatingObject(pFloatingObject) {
+
+ innactiveFloatingObjects.push(pFloatingObject);
+
+ pFloatingObject.handle = Math.floor((Math.random() * 10000000) + 1);
+
+ }
+
+ function removeFloatingObject(pFloatingObjectHandle) {
+
+ for (let i = 0; i < innactiveFloatingObjects.length; i++) {
+
+ let floatingObject = innactiveFloatingObjects[i];
+
+ if (floatingObject.handle === pFloatingObjectHandle) {
+ innactiveFloatingObjects.splice(i, 1); // Delete item from array.
+ return;
+ }
+ }
+
+ for (let i = 0; i < thisObject.floatingObjects.length; i++) {
+
+ let floatingObject = thisObject.floatingObjects[i];
+
+ if (floatingObject.handle === pFloatingObjectHandle) {
+ thisObject.floatingObjects.splice(i, 1); // Delete item from array.
+ return;
+ }
+ }
+ }
+
+ /******************************************/
+ /* */
+ /* Physics Engine Follows */
+ /* */
+ /******************************************/
+
+ function physicsLoop() {
+
+ /* This function makes all the calculations to apply phisycs on all floatingObjects in this space. */
+
+ for (let i = 0; i < thisObject.floatingObjects.length; i++) {
+
+ let floatingObject = thisObject.floatingObjects[i];
+
+ /* Change position based on speed */
+
+ floatingObject.currentPosition.x = floatingObject.currentPosition.x + floatingObject.currentSpeed.x;
+ floatingObject.currentPosition.y = floatingObject.currentPosition.y + floatingObject.currentSpeed.y;
+
+ /* Apply some friction to desacelerate */
+
+ floatingObject.currentSpeed.x = floatingObject.currentSpeed.x * floatingObject.friction; // Desaceleration factor.
+ floatingObject.currentSpeed.y = floatingObject.currentSpeed.y * floatingObject.friction; // Desaceleration factor.
+
+ // Gives a minimun speed towards their taget.
+
+ if (floatingObject.currentPosition.x < floatingObject.input.position.x) {
+ floatingObject.currentSpeed.x = floatingObject.currentSpeed.x + .005;
+ } else {
+ floatingObject.currentSpeed.x = floatingObject.currentSpeed.x - .005;
+ }
+
+ if (floatingObject.currentPosition.y < floatingObject.input.position.y) {
+ floatingObject.currentSpeed.y = floatingObject.currentSpeed.y + .005;
+ } else {
+ floatingObject.currentSpeed.y = floatingObject.currentSpeed.y - .005;
+ }
+
+ // Lets put a maximun speed also.
+
+ const MAX_SPEED = 50;
+
+ if (floatingObject.currentSpeed.x > MAX_SPEED) {
+ floatingObject.currentSpeed.x = MAX_SPEED;
+ }
+
+ if (floatingObject.currentSpeed.y > MAX_SPEED) {
+ floatingObject.currentSpeed.y = MAX_SPEED;
+ }
+
+ if (floatingObject.currentSpeed.x < -MAX_SPEED) {
+ floatingObject.currentSpeed.x = -MAX_SPEED;
+ }
+
+ if (floatingObject.currentSpeed.y < -MAX_SPEED) {
+ floatingObject.currentSpeed.y = -MAX_SPEED;
+ }
+
+ // The radius also have a target.
+
+ if (floatingObject.currentRadius < floatingObject.targetRadius) {
+ floatingObject.currentRadius = floatingObject.currentRadius + .5;
+ } else {
+ floatingObject.currentRadius = floatingObject.currentRadius - .5;
+ }
+
+ // The imageSize also have a target.
+
+ if (floatingObject.currentImageSize < floatingObject.targetImageSize) {
+ floatingObject.currentImageSize = floatingObject.currentImageSize + 1;
+ } else {
+ floatingObject.currentImageSize = floatingObject.currentImageSize - 1;
+ }
+
+ /* Collision Control */
+
+ for (let k = i + 1; k < thisObject.floatingObjects.length; k++) {
+
+ if (colliding(thisObject.floatingObjects[i], thisObject.floatingObjects[k])) {
+
+ resolveCollision(thisObject.floatingObjects[k], thisObject.floatingObjects[i]);
+
+ }
+ }
+
+ /* Calculate repulsion force produced by all other floatingObjects */
+
+ repulsionForce(i);
+
+ gravityForce(floatingObject);
+
+ }
+
+ /* We draw all the thisObject.floatingObjects. */
+
+ for (let i = 0; i < thisObject.floatingObjects.length; i++) {
+ let floatingObject = thisObject.floatingObjects[i];
+ floatingObject.drawBackground();
+ }
+
+ for (let i = 0; i < thisObject.floatingObjects.length; i++) {
+ let floatingObject = thisObject.floatingObjects[thisObject.floatingObjects.length - i - 1];
+ floatingObject.drawForeground();
+ }
+
+ /* Finally we check if any of the created FloatingObjects where enabled to run under the Physics Engine. */
+
+ for (let i = 0; i < innactiveFloatingObjects.length; i++) {
+
+ let floatingObject = innactiveFloatingObjects[i];
+
+ if (floatingObject.input.visible === true) {
+
+ /* The first time that the floatingObject becomes visible, we need to do this. */
+
+ floatingObject.radomizeCurrentPosition(floatingObject.input.position);
+ floatingObject.radomizeCurrentSpeed();
+
+ thisObject.floatingObjects.push(floatingObject);
+ innactiveFloatingObjects.splice(i, 1); // Delete item from array.
+ return; // Only one at the time.
+
+ }
+ }
+ }
+
+ function gravityForce(floatingObject) {
+
+ /* We simulate a kind of gravity towards the target point of each floatingObject. This force will make the floatingObject to keep pushing to reach that point. */
+
+ const coulomb = .00001;
+ const minForce = 0.01;
+
+ var d = Math.sqrt(Math.pow(floatingObject.input.position.x - floatingObject.currentPosition.x, 2) + Math.pow(floatingObject.input.position.y - floatingObject.currentPosition.y, 2)); // ... we calculate the distance ...
+
+ var force = coulomb * d * d / floatingObject.currentMass; // In this case the mass of the floatingObject affects the gravity force that it receives, that gives priority to target position to bigger floatingObjects.
+
+ if (force < minForce) { // We need this attraction force to overcome the friction we imposed to the system.
+ force = minForce;
+ }
+
+ var pos1 = {
+ x: floatingObject.currentPosition.x,
+ y: floatingObject.currentPosition.y
+ };
+
+ var pos2 = {
+ x: floatingObject.input.position.x,
+ y: floatingObject.input.position.y
+ };
+
+ var posDiff = { // Next we need the vector resulting from the 2 positions.
+ x: pos2.x - pos1.x,
+ y: pos2.y - pos1.y
+ };
+
+ var unitVector = { // To find the unit vector, we divide each component by the magnitude of the vector.
+ x: posDiff.x / d,
+ y: posDiff.y / d
+ };
+
+ var forceVector = {
+ x: unitVector.x * force,
+ y: unitVector.y * force
+ };
+
+ /* We add the force vector to the speed vector */
+
+ floatingObject.currentSpeed.x = floatingObject.currentSpeed.x + forceVector.x;
+ floatingObject.currentSpeed.y = floatingObject.currentSpeed.y + forceVector.y;
+
+ }
+
+ function repulsionForce(currentFloatingObject) {
+
+ /* We generate a repulsion force between floatingObjects, that prevents them to be collisioning so often. */
+
+ const coulomb = 2;
+
+ var floatingObject1 = thisObject.floatingObjects[currentFloatingObject];
+
+ for (var i = 0; i < thisObject.floatingObjects.length; i++) { // The force to be applied is considering all other floatingObjects...
+
+ if (i !== currentFloatingObject) { // ... except for the current one.
+
+ var floatingObject2 = thisObject.floatingObjects[i]; // So, for each floatingObject...
+
+ var d = Math.sqrt(Math.pow(floatingObject2.currentPosition.x - floatingObject1.currentPosition.x, 2) + Math.pow(floatingObject2.currentPosition.y - floatingObject1.currentPosition.y, 2)); // ... we calculate the distance ...
+
+ var force = coulomb * floatingObject2.currentMass / (d * d); // ... and with it the repulsion force.
+
+ /* We need to put a hard limit to this force, in order to to eject very little floatingObjects to the infinite and beyond. */
+
+ if (force > 1) {
+ force = 1;
+ }
+
+ var pos1 = {
+ x: floatingObject1.currentPosition.x,
+ y: floatingObject1.currentPosition.y
+ };
+
+ var pos2 = {
+ x: floatingObject2.currentPosition.x,
+ y: floatingObject2.currentPosition.y
+ };
+
+ var posDiff = { // Next we need the vector resulting from the 2 positions.
+ x: pos2.x - pos1.x,
+ y: pos2.y - pos1.y
+ };
+
+ var unitVector = { // To find the unit vector, we divide each component by the magnitude of the vector.
+ x: posDiff.x / d,
+ y: posDiff.y / d
+ };
+
+ var forceVector = {
+ x: unitVector.x * force,
+ y: unitVector.y * force
+ };
+
+ /* We substract the force vector to the speed vector of the current floatingObject */
+
+ floatingObject1.currentSpeed.x = floatingObject1.currentSpeed.x - forceVector.x;
+ floatingObject1.currentSpeed.y = floatingObject1.currentSpeed.y - forceVector.y;
+
+ }
+
+ }
+
+ }
+
+ function colliding(floatingObject1, floatingObject2) {
+ /* This function detects weather 2 floatingObjects collide with each other. */
+
+ var r1 = floatingObject1.currentRadius;
+ var r2 = floatingObject2.currentRadius;
+
+ var distance = Math.sqrt(Math.pow(floatingObject2.currentPosition.x - floatingObject1.currentPosition.x, 2) + Math.pow(floatingObject2.currentPosition.y - floatingObject1.currentPosition.y, 2));
+
+ if (distance > (r1 + r2)) {
+ // No solutions, the circles are too far apart.
+ return false;
+ }
+ else if (distance <= r1 + r2) {
+ // One circle contains the other.
+ return true;
+ }
+ else if ((distance === 0) && (r1 === r2)) {
+ // the circles coincide.
+ return true;
+ }
+ else return true;
+ }
+
+ function isInside(x, y) {
+
+ /* This function detects weather the point x,y is inside any of the floatingObjects. */
+
+ for (var i = 0; i < thisObject.floatingObjects.length; i++) {
+ var floatingObject = thisObject.floatingObjects[i];
+ var distance = Math.sqrt(Math.pow(floatingObject.currentPosition.x - x, 2) + Math.pow(floatingObject.currentPosition.y - y, 2));
+
+ if (distance < floatingObject.currentRadius) {
+ return i;
+ }
+ }
+ return -1;
+
+ }
+
+ function isInsideFloatingObject(floatingObjectIndex, x, y) {
+
+ /* This function detects weather the point x,y is inside one particular floatingObjects. */
+
+
+ var floatingObject = thisObject.floatingObjects[floatingObjectIndex];
+ var distance = Math.sqrt(Math.pow(floatingObject.currentPosition.x - x, 2) + Math.pow(floatingObject.currentPosition.y - y, 2));
+
+ if (distance < floatingObject.currentRadius) {
+ return true;
+ }
+
+ return false;
+
+ }
+
+ function distance(x1, y1, x2, y2) {
+ return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
+ }
+
+ function resolveCollision(floatingObject1, floatingObject2) {
+
+ /* This function changes speed and position of floatingObjects that are in collision */
+
+ var collisionision_angle = Math.atan2((floatingObject2.currentPosition.y - floatingObject1.currentPosition.y), (floatingObject2.currentPosition.x - floatingObject1.currentPosition.x));
+
+ var speed1 = Math.sqrt(floatingObject1.currentSpeed.x * floatingObject1.currentSpeed.x + floatingObject1.currentSpeed.y * floatingObject1.currentSpeed.y); // Magnitude of Speed Vector for floatingObject 1
+ var speed2 = Math.sqrt(floatingObject2.currentSpeed.x * floatingObject2.currentSpeed.x + floatingObject2.currentSpeed.y * floatingObject2.currentSpeed.y); // Magnitude of Speed Vector for floatingObject 2
+
+ var direction_1 = Math.atan2(floatingObject1.currentSpeed.y, floatingObject1.currentSpeed.x);
+ var direction_2 = Math.atan2(floatingObject2.currentSpeed.y, floatingObject2.currentSpeed.x);
+
+ var new_xspeed_1 = speed1 * Math.cos(direction_1 - collisionision_angle);
+ var new_yspeed_1 = speed1 * Math.sin(direction_1 - collisionision_angle);
+ var new_xspeed_2 = speed2 * Math.cos(direction_2 - collisionision_angle);
+ var new_yspeed_2 = speed2 * Math.sin(direction_2 - collisionision_angle);
+
+ var final_xspeed_1 = ((floatingObject1.currentMass - floatingObject2.currentMass) * new_xspeed_1 + (floatingObject2.currentMass + floatingObject2.currentMass) * new_xspeed_2) / (floatingObject1.currentMass + floatingObject2.currentMass);
+ var final_xspeed_2 = ((floatingObject1.currentMass + floatingObject1.currentMass) * new_xspeed_1 + (floatingObject2.currentMass - floatingObject1.currentMass) * new_xspeed_2) / (floatingObject1.currentMass + floatingObject2.currentMass);
+ var final_yspeed_1 = new_yspeed_1;
+ var final_yspeed_2 = new_yspeed_2;
+
+ var cosAngle = Math.cos(collisionision_angle);
+ var sinAngle = Math.sin(collisionision_angle);
+
+ floatingObject1.currentSpeed.x = cosAngle * final_xspeed_1 - sinAngle * final_yspeed_1;
+ floatingObject1.currentSpeed.y = sinAngle * final_xspeed_1 + cosAngle * final_yspeed_1;
+
+ floatingObject2.currentSpeed.x = cosAngle * final_xspeed_2 - sinAngle * final_yspeed_2;
+ floatingObject2.currentSpeed.y = sinAngle * final_xspeed_2 + cosAngle * final_yspeed_2;
+
+ var pos1 = {
+ x: floatingObject1.currentPosition.x,
+ y: floatingObject1.currentPosition.y
+ };
+
+ var pos2 = {
+ x: floatingObject2.currentPosition.x,
+ y: floatingObject2.currentPosition.y
+ };
+
+ // get the mtd
+ var posDiff = {
+ x: pos1.x - pos2.x,
+ y: pos1.y - pos2.y
+ };
+
+ var d = Math.sqrt(Math.pow(floatingObject2.currentPosition.x - floatingObject1.currentPosition.x, 2) + Math.pow(floatingObject2.currentPosition.y - floatingObject1.currentPosition.y, 2));
+
+ // minimum translation distance to push floatingObjects apart after intersecting
+ var scalar = (((floatingObject1.currentRadius + floatingObject2.currentRadius) - d) / d);
+
+ var minTD = {
+ x: posDiff.x * scalar,
+ y: posDiff.y * scalar
+ };
+
+ // resolve intersection --
+ // computing inverse mass quantities
+ var im1 = 1 / floatingObject1.currentMass;
+ var im2 = 1 / floatingObject2.currentMass;
+
+ // push-pull them apart based off their mass
+
+ pos1.x = pos1.x + minTD.x * (im1 / (im1 + im2));
+ pos1.y = pos1.y + minTD.y * (im1 / (im1 + im2));
+ pos2.x = pos2.x - minTD.x * (im2 / (im1 + im2));
+ pos2.y = pos2.y - minTD.y * (im2 / (im1 + im2));
+
+ floatingObject1.currentPosition = pos1;
+ floatingObject2.currentPosition = pos2;
+ }
+}
+
+
diff --git a/FloatingObject.js b/FloatingSpace/FloatingObject.js
similarity index 50%
rename from FloatingObject.js
rename to FloatingSpace/FloatingObject.js
index c276acee8..433375ed7 100644
--- a/FloatingObject.js
+++ b/FloatingSpace/FloatingObject.js
@@ -31,8 +31,8 @@ function newFloatingObject() {
radomizeCurrentPosition: radomizeCurrentPosition,
radomizeCurrentSpeed: radomizeCurrentSpeed,
- drawBackground: drawBackgrond, // Function to draw the floating object elements on the canvas layer.
- drawForeground: drawForeground, // Function to draw the floating object elements on the floating objects layer.
+ drawBackground: drawBackground,
+ drawForeground: drawForeground,
updateMass: updateMass, // Function to update the mass when the zoom level changed.
updateRadius: updateRadius, // Function to update the radius when the zoom level changed.
@@ -40,11 +40,55 @@ function newFloatingObject() {
linkedObject: undefined, // This is a reference to the object that this floating object is representing.
linkedObjectType: "", // Since there might be floating objects for different types of objects, here we store the type of object we are linking to.
- container: undefined // This is a pointer to the object where the floating object belongs to.
+ container: undefined, // This is a pointer to the object where the floating object belongs to.
+ initialize: initialize
+
};
+ let underlayingObject;
+
return thisObject;
+ function initialize(pType, callBackFunction) {
+
+ switch (pType) {
+
+ case "Profile Ball": {
+
+ underlayingObject = newProfileBall();
+ underlayingObject.initialize(onInitialized);
+
+ function onInitialized(err) {
+
+
+ }
+
+ break;
+ }
+ case "Bubble": {
+
+ break;
+ }
+ default: {
+
+ break;
+ }
+ }
+
+ callBackFunction();
+ }
+
+ function drawBackground() {
+
+ underlayingObject.drawBackground(thisObject);
+
+ }
+
+ function drawForeground() {
+
+ underlayingObject.drawForeground(thisObject);
+
+ }
function initializeMass(suggestedValue) {
@@ -131,135 +175,6 @@ function newFloatingObject() {
//thisObject.targetRadius = thisObject.rawRadius + thisObject.rawRadius * thisObject.container.zoom.incrementR * thisObject.container.zoom.levelR;
}
-
- function drawBackgrond() {
-
- if (thisObject.currentRadius > 1) {
-
- /* Target Line */
-
- browserCanvasContext.beginPath();
- browserCanvasContext.moveTo(thisObject.currentPosition.x, thisObject.currentPosition.y);
- browserCanvasContext.lineTo(thisObject.input.position.x, thisObject.input.position.y);
- browserCanvasContext.strokeStyle = 'rgba(204, 204, 204, 0.5)';
- browserCanvasContext.setLineDash([4, 2]);
- browserCanvasContext.lineWidth = 1;
- browserCanvasContext.stroke();
- browserCanvasContext.setLineDash([0, 0]);
-
- }
-
- if (thisObject.currentRadius > 0.5) {
-
- /* Target Spot */
-
- var radius = 1;
-
- browserCanvasContext.beginPath();
- browserCanvasContext.arc(thisObject.input.position.x, thisObject.input.position.y, radius, 0, Math.PI * 2, true);
- browserCanvasContext.closePath();
- browserCanvasContext.fillStyle = 'rgba(30, 30, 30, 1)';
- browserCanvasContext.fill();
-
- }
- }
-
- function drawForeground() {
-
- if (thisObject.currentRadius > 5) {
-
- /* Contourn */
-
- browserCanvasContext.beginPath();
- browserCanvasContext.arc(thisObject.currentPosition.x, thisObject.currentPosition.y, thisObject.currentRadius, 0, Math.PI * 2, true);
- browserCanvasContext.closePath();
- browserCanvasContext.strokeStyle = 'rgba(30, 30, 30, 0.75)';
- browserCanvasContext.lineWidth = 1;
- browserCanvasContext.stroke();
-
- }
-
- if (thisObject.currentRadius > 0.5) {
-
- /* Main FloatingObject */
-
- var alphaA;
-
- if (thisObject.currentRadius < 3) {
- alphaA = 1;
- } else {
- alphaA = 0.75;
- }
-
- alphaA = 0.75;
-
- browserCanvasContext.beginPath();
- browserCanvasContext.arc(thisObject.currentPosition.x, thisObject.currentPosition.y, thisObject.currentRadius, 0, Math.PI * 2, true);
- browserCanvasContext.closePath();
-
- browserCanvasContext.fillStyle = thisObject.fillStyle;
-
- browserCanvasContext.fill();
-
- }
-
- /* Image */
-
- if (thisObject.input.imageId !== undefined) {
-
- let image = document.getElementById(thisObject.input.imageId);
-
- if (image !== null) {
-
- browserCanvasContext.drawImage(image, thisObject.currentPosition.x - thisObject.currentImageSize / 2, thisObject.currentPosition.y - thisObject.currentImageSize / 2, thisObject.currentImageSize, thisObject.currentImageSize);
-
- }
- }
-
- /* Label Text */
-
- if (thisObject.currentRadius > 6) {
-
- browserCanvasContext.strokeStyle = thisObject.labelStrokeStyle;
-
- let labelPoint;
- let fontSize = 10;
-
- browserCanvasContext.font = fontSize + 'px Courier New';
-
- let label;
-
- label = thisObject.input.upLabel;
-
- if (label !== undefined) {
-
- labelPoint = {
- x: thisObject.currentPosition.x - label.length / 2 * fontSize * 0.60,
- y: thisObject.currentPosition.y - thisObject.currentImageSize / 2 - fontSize * 0.60 - 5
- };
-
- browserCanvasContext.font = fontSize + 'px Courier New';
- browserCanvasContext.fillStyle = thisObject.labelStrokeStyle;
- browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y);
-
- }
-
- label = thisObject.input.downLabel;
-
- if (label !== undefined) {
-
- labelPoint = {
- x: thisObject.currentPosition.x - label.length / 2 * fontSize * 0.60,
- y: thisObject.currentPosition.y + thisObject.currentImageSize / 2 + fontSize * 0.60 + 10
- };
-
- browserCanvasContext.font = fontSize + 'px Courier New';
- browserCanvasContext.fillStyle = thisObject.labelStrokeStyle;
- browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y);
-
- }
- }
- }
}
diff --git a/FloatingSpace/ProfileBall.js b/FloatingSpace/ProfileBall.js
new file mode 100644
index 000000000..dbfa706b5
--- /dev/null
+++ b/FloatingSpace/ProfileBall.js
@@ -0,0 +1,151 @@
+
+function newProfileBall() {
+
+ var thisObject = {
+
+ drawBackground: drawBackground,
+ drawForeground: drawForeground,
+ initialize: initialize
+
+ };
+
+ return thisObject;
+
+ function initialize(callBackFunction) {
+
+ callBackFunction();
+
+ }
+
+ function drawBackground(pFloatingObject) {
+
+ if (pFloatingObject.currentRadius > 1) {
+
+ /* Target Line */
+
+ browserCanvasContext.beginPath();
+ browserCanvasContext.moveTo(pFloatingObject.currentPosition.x, pFloatingObject.currentPosition.y);
+ browserCanvasContext.lineTo(pFloatingObject.input.position.x, pFloatingObject.input.position.y);
+ browserCanvasContext.strokeStyle = 'rgba(204, 204, 204, 0.5)';
+ browserCanvasContext.setLineDash([4, 2]);
+ browserCanvasContext.lineWidth = 1;
+ browserCanvasContext.stroke();
+ browserCanvasContext.setLineDash([0, 0]);
+
+ }
+
+ if (pFloatingObject.currentRadius > 0.5) {
+
+ /* Target Spot */
+
+ var radius = 1;
+
+ browserCanvasContext.beginPath();
+ browserCanvasContext.arc(pFloatingObject.input.position.x, pFloatingObject.input.position.y, radius, 0, Math.PI * 2, true);
+ browserCanvasContext.closePath();
+ browserCanvasContext.fillStyle = 'rgba(30, 30, 30, 1)';
+ browserCanvasContext.fill();
+
+ }
+ }
+
+ function drawForeground(pFloatingObject) {
+
+ if (pFloatingObject.currentRadius > 5) {
+
+ /* Contourn */
+
+ browserCanvasContext.beginPath();
+ browserCanvasContext.arc(pFloatingObject.currentPosition.x, pFloatingObject.currentPosition.y, pFloatingObject.currentRadius, 0, Math.PI * 2, true);
+ browserCanvasContext.closePath();
+ browserCanvasContext.strokeStyle = 'rgba(30, 30, 30, 0.75)';
+ browserCanvasContext.lineWidth = 1;
+ browserCanvasContext.stroke();
+
+ }
+
+ if (pFloatingObject.currentRadius > 0.5) {
+
+ /* Main FloatingObject */
+
+ var alphaA;
+
+ if (pFloatingObject.currentRadius < 3) {
+ alphaA = 1;
+ } else {
+ alphaA = 0.75;
+ }
+
+ alphaA = 0.75;
+
+ browserCanvasContext.beginPath();
+ browserCanvasContext.arc(pFloatingObject.currentPosition.x, pFloatingObject.currentPosition.y, pFloatingObject.currentRadius, 0, Math.PI * 2, true);
+ browserCanvasContext.closePath();
+
+ browserCanvasContext.fillStyle = pFloatingObject.fillStyle;
+
+ browserCanvasContext.fill();
+
+ }
+
+ /* Image */
+
+ if (pFloatingObject.input.imageId !== undefined) {
+
+ let image = document.getElementById(pFloatingObject.input.imageId);
+
+ if (image !== null) {
+
+ browserCanvasContext.drawImage(image, pFloatingObject.currentPosition.x - pFloatingObject.currentImageSize / 2, pFloatingObject.currentPosition.y - pFloatingObject.currentImageSize / 2, pFloatingObject.currentImageSize, pFloatingObject.currentImageSize);
+
+ }
+ }
+
+ /* Label Text */
+
+ if (pFloatingObject.currentRadius > 6) {
+
+ browserCanvasContext.strokeStyle = pFloatingObject.labelStrokeStyle;
+
+ let labelPoint;
+ let fontSize = 10;
+
+ browserCanvasContext.font = fontSize + 'px Courier New';
+
+ let label;
+
+ label = pFloatingObject.input.upLabel;
+
+ if (label !== undefined) {
+
+ labelPoint = {
+ x: pFloatingObject.currentPosition.x - label.length / 2 * fontSize * 0.60,
+ y: pFloatingObject.currentPosition.y - pFloatingObject.currentImageSize / 2 - fontSize * 0.60 - 5
+ };
+
+ browserCanvasContext.font = fontSize + 'px Courier New';
+ browserCanvasContext.fillStyle = pFloatingObject.labelStrokeStyle;
+ browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y);
+
+ }
+
+ label = pFloatingObject.input.downLabel;
+
+ if (label !== undefined) {
+
+ labelPoint = {
+ x: pFloatingObject.currentPosition.x - label.length / 2 * fontSize * 0.60,
+ y: pFloatingObject.currentPosition.y + pFloatingObject.currentImageSize / 2 + fontSize * 0.60 + 10
+ };
+
+ browserCanvasContext.font = fontSize + 'px Courier New';
+ browserCanvasContext.fillStyle = pFloatingObject.labelStrokeStyle;
+ browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y);
+
+ }
+ }
+ }
+}
+
+
+
diff --git a/FloatingSpace/ProfileBalls.js b/FloatingSpace/ProfileBalls.js
new file mode 100644
index 000000000..205a535fc
--- /dev/null
+++ b/FloatingSpace/ProfileBalls.js
@@ -0,0 +1,78 @@
+
+function newProfileBalls() {
+
+ const MODULE_NAME = "Profile Balls";
+ const INFO_LOG = false;
+ const ERROR_LOG = true;
+ const logger = newDebugLog();
+ logger.fileName = MODULE_NAME;
+
+ /*
+
+ This object deals with Profile Balls, a type of Floating Object that shows profile info in a floating ball.
+
+ */
+
+ let thisObject = {
+
+ createNewProfileBall: createNewProfileBall,
+ destroyProfileBall: destroyProfileBall,
+ initialize: initialize
+
+ }
+
+ let floatingLayer;
+
+ return thisObject;
+
+ function initialize(pFloatingLayer, callBackFunction) {
+
+ try {
+
+ if (INFO_LOG === true) { logger.write("[INFO] initialize -> Entering function."); }
+
+ floatingLayer = pFloatingLayer;
+
+ callBackFunction(GLOBAL.CUSTOM_OK_RESPONSE);
+
+ } catch (err) {
+
+ if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> err = " + err); }
+ callBackFunction(GLOBAL.CUSTOM_FAIL_RESPONSE);
+ }
+ }
+
+ function createNewProfileBall(pInput, pContainer, callBackFunction) {
+
+ let floatingObject = newFloatingObject();
+ floatingObject.initialize("Profile Ball", onInitialized);
+
+ function onInitialized(err) {
+
+ floatingObject.input = pInput;
+
+ floatingObject.container = pContainer;
+
+ floatingObject.friction = .995;
+
+ floatingObject.initializeMass(100);
+ floatingObject.initializeRadius(30);
+ floatingObject.initializeImageSize(50);
+
+ floatingObject.fillStyle = 'rgba(255, 255, 255, 0.5)';
+ floatingObject.labelStrokeStyle = 'rgba(60, 60, 60, 0.50)';
+
+ floatingLayer.addFloatingObject(floatingObject);
+
+ callBackFunction(GLOBAL.CUSTOM_OK_RESPONSE, floatingObject.handle);
+
+ }
+ }
+
+ function destroyProfileBall(pFloatingObjectHandle) {
+
+ floatingLayer.removeFloatingObject(pFloatingObjectHandle);
+
+ }
+}
+
diff --git a/Project.njsproj b/Project.njsproj
index 311261be0..b3022b5c5 100644
--- a/Project.njsproj
+++ b/Project.njsproj
@@ -32,19 +32,31 @@
-
+
+ Code
+
+
Code
Code
+
+ Code
+
Code
Code
+
+ Code
+
+
+ Code
+
Code
@@ -112,6 +124,7 @@
+
diff --git a/Spaces/FloatingSpace.js b/Spaces/FloatingSpace.js
index bcb82a779..cba37e7c2 100644
--- a/Spaces/FloatingSpace.js
+++ b/Spaces/FloatingSpace.js
@@ -1,473 +1,43 @@
-/*
-The Floating Space is the place where floating elements like floatingObjects, live and are rendered.
-This space has its own physics which helps with the animation of these objects and also preventing them to overlap.
-*/
-
+
function newFloatingSpace() {
+ /*
+ The Floating Space is the place where floating elements like floatingObjects, live and are rendered.
+ This space has its own physics which helps with the animation of these objects and also preventing them to overlap.
+ */
+
let thisObject = {
- floatingObjects: undefined, // This is the array of floatingObjects being displayed
- createNewFloatingObject: createNewFloatingObject,
- destroyFloatingObject: destroyFloatingObject,
- createBubbleSet: createBubbleSet,
- destroyBubbleSet: destroyBubbleSet,
- physicsLoop: physicsLoop,
- isInside: isInside,
- isInsideFloatingObject: isInsideFloatingObject,
+ floatingLayer: undefined, // This is the array of floatingObjects being displayed
+ profileBalls: undefined,
+ bubbleSets: undefined,
initialize: initialize
};
- let createdFloatingObjects = [];
- let bubbleSets = [];
-
return thisObject;
- function initialize() {
+ function initialize(callBackFunction) {
- thisObject.floatingObjects = []; // We initialize this in order to start the calculations in a clean way.
-
- }
+ thisObject.floatingLayer = newFloatingLayer();
+ thisObject.floatingLayer.initialize(onFloatingLayerInitialized);
+
+ function onFloatingLayerInitialized(err) {
+
+ thisObject.profileBalls = newProfileBalls();
+ thisObject.profileBalls.initialize(thisObject.floatingLayer, onProfileBallsInitialized);
+
+ function onProfileBallsInitialized(err) {
+
+ thisObject.bubbleSets = newBubbleSets();
+ thisObject.bubbleSets.initialize(thisObject.floatingLayer, onBubbleSetsInitialized);
+
+ function onBubbleSetsInitialized(err) {
- function createNewFloatingObject(pInput, pContainer) {
- /* This function is used to create new floatingObjects */
-
- var floatingObject = newFloatingObject();
-
- floatingObject.input = pInput;
-
- floatingObject.container = pContainer;
-
- floatingObject.friction = .995;
-
- floatingObject.initializeMass(150);
- floatingObject.initializeRadius(30);
- floatingObject.initializeImageSize(50);
-
- floatingObject.fillStyle = 'rgba(255, 255, 255, 0.5)';
- floatingObject.labelStrokeStyle = 'rgba(60, 60, 60, 0.50)';
-
- createdFloatingObjects.push(floatingObject);
-
- floatingObject.handle = Math.floor((Math.random() * 10000000) + 1);
-
- return floatingObject.handle;
- }
-
- function destroyFloatingObject(pFloatingObjectHandle) {
-
- for (let i = 0; i < createdFloatingObjects.length; i++) {
-
- let floatingObject = createdFloatingObjects[i];
-
- if (floatingObject.handle === pFloatingObjectHandle) {
- createdFloatingObjects.splice(i, 1); // Delete item from array.
- return;
- }
- }
-
- for (let i = 0; i < thisObject.floatingObjects.length; i++) {
-
- let floatingObject = thisObject.floatingObjects[i];
-
- if (floatingObject.handle === pFloatingObjectHandle) {
- thisObject.floatingObjects.splice(i, 1); // Delete item from array.
- return;
- }
- }
- }
-
-
- function createBubbleSet(pPlotterBubbles) {
-
- let bubbleSet = {
- floatingBubbles: [],
- plotterBubbles: pPlotterBubbles,
- handle: Math.floor((Math.random() * 10000000) + 1)
- };
-
- bubbleSets.push(bubbleSet);
-
- return bubbleSet.handle;
- }
-
- function destroyBubbleSet(pHandle) {
-
- for (let i = 0; i < bubbleSets.length; i++) {
-
- let bubbleSet = bubbleSets[i];
-
- if (bubbleSet.handle === pHandle) {
- bubbleSets.splice(i, 1); // Delete item from array.
- return;
- }
- }
- }
-
- /******************************************/
- /* */
- /* Physics Engine Follows */
- /* */
- /******************************************/
-
- function physicsLoop() {
-
- /* This function makes all the calculations to apply phisycs on all floatingObjects in this space. */
-
- for (let i = 0; i < thisObject.floatingObjects.length; i++) {
-
- let floatingObject = thisObject.floatingObjects[i];
-
- /* Change position based on speed */
-
- floatingObject.currentPosition.x = floatingObject.currentPosition.x + floatingObject.currentSpeed.x;
- floatingObject.currentPosition.y = floatingObject.currentPosition.y + floatingObject.currentSpeed.y;
-
- /* Apply some friction to desacelerate */
-
- floatingObject.currentSpeed.x = floatingObject.currentSpeed.x * floatingObject.friction; // Desaceleration factor.
- floatingObject.currentSpeed.y = floatingObject.currentSpeed.y * floatingObject.friction; // Desaceleration factor.
-
- // Gives a minimun speed towards their taget.
-
- if (floatingObject.currentPosition.x < floatingObject.input.position.x) {
- floatingObject.currentSpeed.x = floatingObject.currentSpeed.x + .005;
- } else {
- floatingObject.currentSpeed.x = floatingObject.currentSpeed.x - .005;
- }
-
- if (floatingObject.currentPosition.y < floatingObject.input.position.y) {
- floatingObject.currentSpeed.y = floatingObject.currentSpeed.y + .005;
- } else {
- floatingObject.currentSpeed.y = floatingObject.currentSpeed.y - .005;
- }
-
- // Lets put a maximun speed also.
-
- const MAX_SPEED = 50;
-
- if (floatingObject.currentSpeed.x > MAX_SPEED) {
- floatingObject.currentSpeed.x = MAX_SPEED;
- }
-
- if (floatingObject.currentSpeed.y > MAX_SPEED) {
- floatingObject.currentSpeed.y = MAX_SPEED;
- }
-
- if (floatingObject.currentSpeed.x < -MAX_SPEED) {
- floatingObject.currentSpeed.x = -MAX_SPEED;
- }
-
- if (floatingObject.currentSpeed.y < -MAX_SPEED) {
- floatingObject.currentSpeed.y = -MAX_SPEED;
- }
-
- // The radius also have a target.
-
- if (floatingObject.currentRadius < floatingObject.targetRadius) {
- floatingObject.currentRadius = floatingObject.currentRadius + .5;
- } else {
- floatingObject.currentRadius = floatingObject.currentRadius - .5;
- }
-
- // The imageSize also have a target.
-
- if (floatingObject.currentImageSize < floatingObject.targetImageSize) {
- floatingObject.currentImageSize = floatingObject.currentImageSize + 1;
- } else {
- floatingObject.currentImageSize = floatingObject.currentImageSize - 1;
- }
-
- /* Collision Control */
-
- for (let k = i + 1; k < thisObject.floatingObjects.length; k++) {
-
- if (colliding(thisObject.floatingObjects[i], thisObject.floatingObjects[k])) {
-
- resolveCollision(thisObject.floatingObjects[k], thisObject.floatingObjects[i]);
}
}
-
- /* Calculate repulsion force produced by all other floatingObjects */
-
- repulsionForce(i);
-
- gravityForce(floatingObject);
-
}
-
- /* We draw all the thisObject.floatingObjects. */
-
- for (let i = 0; i < thisObject.floatingObjects.length; i++) {
- let floatingObject = thisObject.floatingObjects[i];
- floatingObject.drawBackground();
- }
-
- for (let i = 0; i < thisObject.floatingObjects.length; i++) {
- let floatingObject = thisObject.floatingObjects[thisObject.floatingObjects.length - i - 1];
- floatingObject.drawForeground();
- }
-
- /* Finally we check if any of the created FloatingObjects where enabled to run under the Physics Engine. */
-
- for (let i = 0; i < createdFloatingObjects.length; i++) {
-
- let floatingObject = createdFloatingObjects[i];
-
- if (floatingObject.input.visible === true) {
-
- /* The first time that the floatingObject becomes visible, we need to do this. */
-
- floatingObject.radomizeCurrentPosition(floatingObject.input.position);
- floatingObject.radomizeCurrentSpeed();
-
- thisObject.floatingObjects.push(floatingObject);
- createdFloatingObjects.splice(i, 1); // Delete item from array.
- return; // Only one at the time.
-
- }
- }
- }
-
- function gravityForce(floatingObject) {
-
- /* We simulate a kind of gravity towards the target point of each floatingObject. This force will make the floatingObject to keep pushing to reach that point. */
-
- const coulomb = .00001;
- const minForce = 0.01;
-
- var d = Math.sqrt(Math.pow(floatingObject.input.position.x - floatingObject.currentPosition.x, 2) + Math.pow(floatingObject.input.position.y - floatingObject.currentPosition.y, 2)); // ... we calculate the distance ...
-
- var force = coulomb * d * d / floatingObject.currentMass; // In this case the mass of the floatingObject affects the gravity force that it receives, that gives priority to target position to bigger floatingObjects.
-
- if (force < minForce) { // We need this attraction force to overcome the friction we imposed to the system.
- force = minForce;
- }
-
- var pos1 = {
- x: floatingObject.currentPosition.x,
- y: floatingObject.currentPosition.y
- };
-
- var pos2 = {
- x: floatingObject.input.position.x,
- y: floatingObject.input.position.y
- };
-
- var posDiff = { // Next we need the vector resulting from the 2 positions.
- x: pos2.x - pos1.x,
- y: pos2.y - pos1.y
- };
-
- var unitVector = { // To find the unit vector, we divide each component by the magnitude of the vector.
- x: posDiff.x / d,
- y: posDiff.y / d
- };
-
- var forceVector = {
- x: unitVector.x * force,
- y: unitVector.y * force
- };
-
- /* We add the force vector to the speed vector */
-
- floatingObject.currentSpeed.x = floatingObject.currentSpeed.x + forceVector.x;
- floatingObject.currentSpeed.y = floatingObject.currentSpeed.y + forceVector.y;
-
- }
-
- function repulsionForce(currentFloatingObject) {
-
- /* We generate a repulsion force between floatingObjects, that prevents them to be collisioning so often. */
-
- const coulomb = 2;
-
- var floatingObject1 = thisObject.floatingObjects[currentFloatingObject];
-
- for (var i = 0; i < thisObject.floatingObjects.length; i++) { // The force to be applied is considering all other floatingObjects...
-
- if (i !== currentFloatingObject) { // ... except for the current one.
-
- var floatingObject2 = thisObject.floatingObjects[i]; // So, for each floatingObject...
-
- var d = Math.sqrt(Math.pow(floatingObject2.currentPosition.x - floatingObject1.currentPosition.x, 2) + Math.pow(floatingObject2.currentPosition.y - floatingObject1.currentPosition.y, 2)); // ... we calculate the distance ...
-
- var force = coulomb * floatingObject2.currentMass / (d * d); // ... and with it the repulsion force.
-
- /* We need to put a hard limit to this force, in order to to eject very little floatingObjects to the infinite and beyond. */
-
- if (force > 1) {
- force = 1;
- }
-
- var pos1 = {
- x: floatingObject1.currentPosition.x,
- y: floatingObject1.currentPosition.y
- };
-
- var pos2 = {
- x: floatingObject2.currentPosition.x,
- y: floatingObject2.currentPosition.y
- };
-
- var posDiff = { // Next we need the vector resulting from the 2 positions.
- x: pos2.x - pos1.x,
- y: pos2.y - pos1.y
- };
-
- var unitVector = { // To find the unit vector, we divide each component by the magnitude of the vector.
- x: posDiff.x / d,
- y: posDiff.y / d
- };
-
- var forceVector = {
- x: unitVector.x * force,
- y: unitVector.y * force
- };
-
- /* We substract the force vector to the speed vector of the current floatingObject */
-
- floatingObject1.currentSpeed.x = floatingObject1.currentSpeed.x - forceVector.x;
- floatingObject1.currentSpeed.y = floatingObject1.currentSpeed.y - forceVector.y;
-
- }
-
- }
-
- }
-
- function colliding(floatingObject1, floatingObject2) {
- /* This function detects weather 2 floatingObjects collide with each other. */
-
- var r1 = floatingObject1.currentRadius;
- var r2 = floatingObject2.currentRadius;
-
- var distance = Math.sqrt(Math.pow(floatingObject2.currentPosition.x - floatingObject1.currentPosition.x, 2) + Math.pow(floatingObject2.currentPosition.y - floatingObject1.currentPosition.y, 2));
-
- if (distance > (r1 + r2)) {
- // No solutions, the circles are too far apart.
- return false;
- }
- else if (distance <= r1 + r2) {
- // One circle contains the other.
- return true;
- }
- else if ((distance === 0) && (r1 === r2)) {
- // the circles coincide.
- return true;
- }
- else return true;
- }
-
- function isInside(x, y) {
-
- /* This function detects weather the point x,y is inside any of the floatingObjects. */
-
- for (var i = 0; i < thisObject.floatingObjects.length; i++) {
- var floatingObject = thisObject.floatingObjects[i];
- var distance = Math.sqrt(Math.pow(floatingObject.currentPosition.x - x, 2) + Math.pow(floatingObject.currentPosition.y - y, 2));
-
- if (distance < floatingObject.currentRadius) {
- return i;
- }
- }
- return -1;
-
- }
-
- function isInsideFloatingObject(floatingObjectIndex, x, y) {
-
- /* This function detects weather the point x,y is inside one particular floatingObjects. */
-
-
- var floatingObject = thisObject.floatingObjects[floatingObjectIndex];
- var distance = Math.sqrt(Math.pow(floatingObject.currentPosition.x - x, 2) + Math.pow(floatingObject.currentPosition.y - y, 2));
-
- if (distance < floatingObject.currentRadius) {
- return true;
- }
-
- return false;
-
- }
-
- function distance(x1, y1, x2, y2) {
- return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
- }
-
- function resolveCollision(floatingObject1, floatingObject2) {
-
- /* This function changes speed and position of floatingObjects that are in collision */
-
- var collisionision_angle = Math.atan2((floatingObject2.currentPosition.y - floatingObject1.currentPosition.y), (floatingObject2.currentPosition.x - floatingObject1.currentPosition.x));
-
- var speed1 = Math.sqrt(floatingObject1.currentSpeed.x * floatingObject1.currentSpeed.x + floatingObject1.currentSpeed.y * floatingObject1.currentSpeed.y); // Magnitude of Speed Vector for floatingObject 1
- var speed2 = Math.sqrt(floatingObject2.currentSpeed.x * floatingObject2.currentSpeed.x + floatingObject2.currentSpeed.y * floatingObject2.currentSpeed.y); // Magnitude of Speed Vector for floatingObject 2
-
- var direction_1 = Math.atan2(floatingObject1.currentSpeed.y, floatingObject1.currentSpeed.x);
- var direction_2 = Math.atan2(floatingObject2.currentSpeed.y, floatingObject2.currentSpeed.x);
-
- var new_xspeed_1 = speed1 * Math.cos(direction_1 - collisionision_angle);
- var new_yspeed_1 = speed1 * Math.sin(direction_1 - collisionision_angle);
- var new_xspeed_2 = speed2 * Math.cos(direction_2 - collisionision_angle);
- var new_yspeed_2 = speed2 * Math.sin(direction_2 - collisionision_angle);
-
- var final_xspeed_1 = ((floatingObject1.currentMass - floatingObject2.currentMass) * new_xspeed_1 + (floatingObject2.currentMass + floatingObject2.currentMass) * new_xspeed_2) / (floatingObject1.currentMass + floatingObject2.currentMass);
- var final_xspeed_2 = ((floatingObject1.currentMass + floatingObject1.currentMass) * new_xspeed_1 + (floatingObject2.currentMass - floatingObject1.currentMass) * new_xspeed_2) / (floatingObject1.currentMass + floatingObject2.currentMass);
- var final_yspeed_1 = new_yspeed_1;
- var final_yspeed_2 = new_yspeed_2;
-
- var cosAngle = Math.cos(collisionision_angle);
- var sinAngle = Math.sin(collisionision_angle);
-
- floatingObject1.currentSpeed.x = cosAngle * final_xspeed_1 - sinAngle * final_yspeed_1;
- floatingObject1.currentSpeed.y = sinAngle * final_xspeed_1 + cosAngle * final_yspeed_1;
-
- floatingObject2.currentSpeed.x = cosAngle * final_xspeed_2 - sinAngle * final_yspeed_2;
- floatingObject2.currentSpeed.y = sinAngle * final_xspeed_2 + cosAngle * final_yspeed_2;
-
- var pos1 = {
- x: floatingObject1.currentPosition.x,
- y: floatingObject1.currentPosition.y
- };
-
- var pos2 = {
- x: floatingObject2.currentPosition.x,
- y: floatingObject2.currentPosition.y
- };
-
- // get the mtd
- var posDiff = {
- x: pos1.x - pos2.x,
- y: pos1.y - pos2.y
- };
-
- var d = Math.sqrt(Math.pow(floatingObject2.currentPosition.x - floatingObject1.currentPosition.x, 2) + Math.pow(floatingObject2.currentPosition.y - floatingObject1.currentPosition.y, 2));
-
- // minimum translation distance to push floatingObjects apart after intersecting
- var scalar = (((floatingObject1.currentRadius + floatingObject2.currentRadius) - d) / d);
-
- var minTD = {
- x: posDiff.x * scalar,
- y: posDiff.y * scalar
- };
-
- // resolve intersection --
- // computing inverse mass quantities
- var im1 = 1 / floatingObject1.currentMass;
- var im2 = 1 / floatingObject2.currentMass;
-
- // push-pull them apart based off their mass
-
- pos1.x = pos1.x + minTD.x * (im1 / (im1 + im2));
- pos1.y = pos1.y + minTD.y * (im1 / (im1 + im2));
- pos2.x = pos2.x - minTD.x * (im2 / (im1 + im2));
- pos2.y = pos2.y - minTD.y * (im2 / (im1 + im2));
-
- floatingObject1.currentPosition = pos1;
- floatingObject2.currentPosition = pos2;
}
}
diff --git a/TimelineChart.js b/TimelineChart.js
index 9cbdf41e6..e02aac988 100644
--- a/TimelineChart.js
+++ b/TimelineChart.js
@@ -315,13 +315,18 @@
productPlotter.plotter.profile.downLabel = pProductCard.bot.displayName;
productPlotter.plotter.profile.imageId = imageId;
- productPlotter.profile = canvas.floatingSpace.createNewFloatingObject(productPlotter.plotter.profile, thisObject.container)
+ canvas.floatingSpace.profileBalls.createNewProfileBall(productPlotter.plotter.profile, thisObject.container, onProfileBallCreated)
+ function onProfileBallCreated(err, pProfileHandle) {
+
+ productPlotter.profile = pProfileHandle;
+
+ }
}
/* Create the Text Bubbles */
- productPlotter.bubbleSet = canvas.floatingSpace.createBubbleSet(productPlotter.plotter.bubbles);
+ productPlotter.bubbleSet = canvas.floatingSpace.bubbleSets.createBubbleSet(productPlotter.plotter.bubbles);
/* Add the new Active Protter to the Array */
@@ -369,13 +374,13 @@
if (productPlotters[i].profile !== undefined) {
- canvas.floatingSpace.destroyFloatingObject(productPlotters[i].profile);
+ canvas.floatingSpace.profileBalls.destroyProfileBall(productPlotters[i].profile);
}
/* Destroyd the Bubble Set */
- canvas.floatingSpace.destroyBubbleSet(productPlotters[i].bubbleSet);
+ canvas.floatingSpace.bubbleSets.destroyBubbleSet(productPlotters[i].bubbleSet);
/* Finally the panels. */
diff --git a/index.html b/index.html
index 12c98c8c1..e26d9397b 100644
--- a/index.html
+++ b/index.html
@@ -27,7 +27,6 @@
-
@@ -44,6 +43,12 @@
+
+
+
+
+
+
diff --git a/server.js b/server.js
index 1cf8bb361..626140bfd 100644
--- a/server.js
+++ b/server.js
@@ -6,7 +6,7 @@ if (CONSOLE_LOG === true) {
}
-const DEBUG_MODE = false; // This forces the server to read Plotters from the local drive.
+const DEBUG_MODE = true; // This forces the server to read Plotters from the local drive.
if (CONSOLE_LOG === true && DEBUG_MODE === true) {
@@ -851,6 +851,12 @@ function onBrowserRequest(request, response) {
}
break;
+ case "FloatingSpace":
+ {
+ respondWithFile('./' + requestParameters[1] + '/' + requestParameters[2], response);
+ }
+ break;
+
default:
if (requestParameters[1] === "") {