-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.js
More file actions
268 lines (206 loc) · 6.65 KB
/
main.js
File metadata and controls
268 lines (206 loc) · 6.65 KB
1
;(function() { var colors = ["red", "purple","blue", "black", "pink","yellow"]; var radiusArr = [10, 15 , 5, 12, 20, 8]; var myColor ; var myRadius = 10; var myAngleRadian; function start() { var canvas = document.getElementById('myCanvas') var ctx = canvas.getContext('2d'); var entities = { circles: [], lines: [ makeLine({ x: 140, y: 140 }), makeLine({ x: 270, y: 140 }), makeLine({ x: 210, y: 210 }), makeLine({ x: 140, y: 270 }), makeLine({ x: 300, y: 270 }), ], dimensions: { x: ctx.canvas.width, y: ctx.canvas.height }, timeLastCircleMade: 0 }; function tick() { update(entities); draw(entities, ctx); requestAnimationFrame(tick); }; tick(); }; function update(entities) { updateCircles(entities) createNewCircleIfDue(entities); updateLines(entities); }; function updateCircles(entities) { for (var i = entities.circles.length - 1; i >= 0; i--) { var circle = entities.circles[i]; for (var j = 0; j < entities.lines.length; j++) { var line = entities.lines[j]; if (trig.isLineIntersectingCircle(circle, line)) { physics.bounceCircle(circle, line); } } physics.applyGravity(circle); physics.moveCircle(circle); if (!isOutOfBorder(circle, entities.dimensions)) { entities.circles.splice(i, 1); } } }; function createNewCircleIfDue(entities) { var now = new Date().getTime(); if (now - entities.timeLastCircleMade > 400) { entities.circles.push(makeCircle({ x: entities.dimensions.x / 2, y: -5 })); entities.timeLastCircleMade = now; } }; function updateLines(entities) { for (var i = 0; i < entities.lines.length; i++) { entities.lines[i].angle += entities.lines[i].rotateSpeed; } }; function draw(entities, ctx) { ctx.clearRect(0, 0, entities.dimensions.x, entities.dimensions.y); var bodies = entities.circles.concat(entities.lines); for (var i = 0; i < bodies.length; i++) { bodies[i].draw(ctx); } }; function makeCircle(center) { return { center: center, velocity: { x: 0, y: 0 }, radius: myRadius, draw: function(ctx) { ctx.beginPath(); ctx.arc(this.center.x, this.center.y, this.radius, 0, Math.PI * 2, true); ctx.closePath(); ctx.fillStyle = myColor; ctx.fill(); } }; }; function makeLine(center) { return { center: center, len: 200, angle: 0, rotateSpeed: 0.9, draw: function(ctx) { var end1 = trig.lineEndPoints(this)[0]; var end2 = trig.lineEndPoints(this)[1]; ctx.beginPath(); ctx.lineWidth = 10; ctx.moveTo(end1.x, end1.y); ctx.lineTo(end2.x, end2.y); ctx.closePath(); ctx.strokeStyle = "black"; ctx.stroke(); } }; }; function isOutOfBorder(circle, entitiesDimensions) { return circle.center.x > -circle.radius && circle.center.x < entitiesDimensions.x + circle.radius && circle.center.y > -circle.radius && circle.center.y < entitiesDimensions.y + circle.radius; }; var trig = { distance: function(point1, point2) { var x = point1.x - point2.x; var y = point1.y - point2.y; return Math.sqrt(x * x + y * y); }, magnitude: function(vector) { return Math.sqrt(vector.x * vector.x + vector.y * vector.y); }, unitVector: function(vector) { return { x: vector.x / trig.magnitude(vector), y: vector.y / trig.magnitude(vector) }; }, dotProduct: function(vector1, vector2) { return vector1.x * vector2.x + vector1.y * vector2.y; }, vectorBetween: function(startPoint, endPoint) { return { x: endPoint.x - startPoint.x, y: endPoint.y - startPoint.y }; }, lineEndPoints: function(line) { angleRadians = line.angle* 0.015; var lineUnitVector = trig.unitVector({ x: Math.cos(angleRadians), y: Math.sin(angleRadians) }); var endOffsetFromCenterVector = { x: lineUnitVector.x * line.len / 2, y: lineUnitVector.y * line.len / 2 }; return [ { x: line.center.x + endOffsetFromCenterVector.x, y: line.center.y + endOffsetFromCenterVector.y }, { x: line.center.x - endOffsetFromCenterVector.x, y: line.center.y - endOffsetFromCenterVector.y } ]; }, pointOnLineClosestToCircle: function(circle, line) { var lineEndPoint1 = trig.lineEndPoints(line)[0]; var lineEndPoint2 = trig.lineEndPoints(line)[1]; var lineUnitVector = trig.unitVector( trig.vectorBetween(lineEndPoint1, lineEndPoint2)); var lineEndToCircleVector = trig.vectorBetween(lineEndPoint1, circle.center); var projection = trig.dotProduct(lineEndToCircleVector, lineUnitVector); if (projection <= 0) { return lineEndPoint1; } else if (projection >= line.len) { return lineEndPoint2; } else { return { x: lineEndPoint1.x + lineUnitVector.x * projection, y: lineEndPoint1.y + lineUnitVector.y * projection }; } }, isLineIntersectingCircle: function(circle, line) { var closest = trig.pointOnLineClosestToCircle(circle, line); var circleToLineDistance = trig.distance(circle.center, closest); return circleToLineDistance < circle.radius; } } var physics = { applyGravity: function(circle) { circle.velocity.y += 0.06; }, moveCircle: function(circle) { circle.center.x += circle.velocity.x; circle.center.y += circle.velocity.y; }, bounceCircle: function(circle, line) { var bounceLineNormal = physics.bounceLineNormal(circle, line); var dot = trig.dotProduct(circle.velocity, bounceLineNormal); circle.velocity.x -= 2 * dot * bounceLineNormal.x; circle.velocity.y -= 2 * dot * bounceLineNormal.y; myColor = colors[Math.floor(Math.random()*colors.length)]; myRadius += .15; if(myRadius > 40){ myRadius = 10; } while (trig.isLineIntersectingCircle(circle, line)) { physics.moveCircle(circle); circle.color = 'white'; } }, bounceLineNormal: function(circle, line) { var circleToClosestPointOnLineVector = trig.vectorBetween(trig.pointOnLineClosestToCircle(circle, line),circle.center); return trig.unitVector(circleToClosestPointOnLineVector); } }; window.addEventListener('load', start);})(this);