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] === "") {