Last active
October 16, 2015 10:24
-
-
Save adambowles/73cb5052fbcfbb95d737 to your computer and use it in GitHub Desktop.
Solar system model and graphical view in HTML canvas / JS. Live demo: http://jsfiddle.net/cwshg3qh/3/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<body> | |
<canvas id="canvas" width="512" height="512"></canvas> | |
<script> | |
/** | |
* Celestial body class | |
*/ | |
var CelestialBody = function (name, x, y, radius, bodyColour, strokeColour) { | |
this.name = name; | |
this.x = x; | |
this.y = y; | |
this.radius = radius; // in km | |
this.bodyColour = bodyColour; | |
this.strokeColour = strokeColour; | |
bodies.push(this); | |
}; | |
CelestialBody.prototype.render = function (context) { | |
// Orbit path | |
if(this.orbitRadius) { | |
x = this.primary.x; | |
y = this.primary.y; | |
radius = this.orbitRadius + this.radius + this.primary.radius; | |
context.beginPath(); | |
context.lineWidth = 1; | |
context.arc(x, y, radius, 0, 2 * Math.PI); | |
context.strokeStyle = "#656D78"; // Light grey | |
context.stroke(); | |
} | |
// Body | |
x = this.x; | |
y = this.y; | |
radius = this.radius; | |
//console.log(x, y, radius); | |
context.beginPath(); | |
context.arc(x, y, radius, 0, 2 * Math.PI); | |
context.fillStyle = this.bodyColour; | |
context.fill(); | |
context.strokeStyle = this.strokeColour; | |
context.lineWidth = this.radius/8; | |
context.stroke(); | |
}; | |
CelestialBody.prototype.toString = function () { | |
return JSON.stringify(this); | |
}; | |
/** | |
* Star class | |
*/ | |
var Star = function (name, radius, bodyColour, strokeColour) { | |
CelestialBody.call(this, name, canvas.width/2, canvas.height/2, radius, bodyColour, strokeColour); | |
}; | |
Star.prototype = Object.create(CelestialBody.prototype); | |
Star.prototype.constructor = Star; | |
Star.prototype.toString = function () { | |
return JSON.stringify(this); | |
}; | |
/** | |
* Satellite class (planets, moons) | |
*/ | |
var Satellite = function (name, primary, orbitRadius, orbitPeriod, radius, bodyColour, strokeColour) { | |
CelestialBody.call(this, name, 0, 0, radius, bodyColour, strokeColour); | |
this.currentAngle = 0; | |
this.primary = primary; | |
this.orbitRadius = orbitRadius; // in km | |
this.orbitPeriod = orbitPeriod; // in earth days | |
satellites.push(this); | |
}; | |
Satellite.prototype = Object.create(CelestialBody.prototype); | |
Satellite.prototype.constructor = Satellite; | |
Satellite.prototype.updateLocation = function (delta) { | |
this.currentAngle = (this.currentAngle + (delta/(this.orbitPeriod * (16 * Math.PI/2)))) % (Math.PI*2); | |
this.x = this.primary.x + ((this.orbitRadius + this.primary.radius + this.radius) * Math.sin(this.currentAngle)); | |
this.y = this.primary.y - ((this.orbitRadius + this.primary.radius + this.radius) * Math.cos(this.currentAngle)); | |
}; | |
Satellite.prototype.toString = function () { | |
return JSON.stringify(this); | |
}; | |
var canvas; | |
var context; | |
var currentFrame; // Unix ms time of current frame | |
var bodies; // Holds all bodies | |
var satellites; // Holds all moving bodies (satellites) | |
var init = function() | |
{ | |
canvas = document.getElementById('canvas'); | |
context = canvas.getContext('2d'); | |
currentFrame = Date.now(); | |
bodies = []; | |
satellites = []; | |
var sun = new Star("The Sun", 24, '#FFCE54', '#F6BB42'); | |
// Inner planets | |
// i.e. new Satellite(name, primary, orbit radius, orbit period, radius, colour, border colour): | |
var mercury = new Satellite("Mercury", sun, 32, 87.9691, 4, '#CCD1D9', '#AAB2BD'); | |
var venus = new Satellite("Venus", sun, 64, 224.701, 12, '#5D9CEC', '#4A89DC'); | |
var earth = new Satellite("Earth", sun, 128, 365.256363004, 12, '#4FC1E9', '#3BAFDA'); | |
var moon = new Satellite("The Moon", earth, 8, 27.321582, 2, '#CCD1D9', '#AAB2BD'); | |
var mars = new Satellite("Mars", sun, 192, 686.971, 6, '#FC6E51', '#E9573F'); | |
var phobos = new Satellite("Phobos", mars, 3, 0.31891023, 1.5, '#CCD1D9', '#AAB2BD'); | |
var deimos = new Satellite("Deimos", mars, 9, 1.263, 0.75, '#CCD1D9', '#AAB2BD'); | |
window.requestAnimationFrame(draw); | |
}(); //IIFE | |
function draw() | |
{ | |
/* Update model */ | |
// Calculate elapsed milliseconds since last frame | |
previousFrame = currentFrame; | |
currentFrame = Date.now(); | |
delta = currentFrame - previousFrame; | |
// Calculate satellites new positions | |
satellites.forEach(function(item){ | |
item.updateLocation(delta); | |
}); | |
/* Update view */ | |
// Clear canvas | |
canvas.width = canvas.width; | |
// Draw background | |
context.fillStyle = '#434A54'; // Dark grey | |
context.fillRect(0, 0, canvas.width, canvas.height); | |
// Draw the celestial bodies | |
bodies.forEach(function(item){ | |
item.render(context); | |
}); | |
/* Re-call controller on next frame */ | |
window.requestAnimationFrame(draw); | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment