commit
c96824c702
6 changed files with 389 additions and 0 deletions
20
Random.js
Normal file
20
Random.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* Bounded random number generator. Has 3 forms:
|
||||
*
|
||||
** Form 1 **
|
||||
* @param {number} a The minimum value.
|
||||
* @param {number} b The maximum value.
|
||||
* @param {boolean} c Whether the resulting number should be a float. [optional]
|
||||
* @return {number} A random number.
|
||||
*
|
||||
** Form 2 **
|
||||
* @param {number} a The maximum value.
|
||||
* @param {boolean} b Whether the resulting number should be a float. [optional]
|
||||
* @return {number} A random number.
|
||||
*
|
||||
** Form 3 **
|
||||
* @return {number} A random number.
|
||||
*/
|
||||
function random(a,b,c,d)
|
||||
{d=Math.random();if(typeof a!="number")return d;a=typeof b=="number"?d*(a-b)+b:d*a;a=(typeof b!="number"?b:c)?a:Math.floor(a);return a;}
|
||||
|
30
Star.js
Normal file
30
Star.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
"use strict";
|
||||
|
||||
class Star
|
||||
{
|
||||
constructor(inCanvas, inPosition, inSize)
|
||||
{
|
||||
this.canvas = inCanvas;
|
||||
|
||||
this.position = inPosition;
|
||||
this.size = inSize;
|
||||
|
||||
this.colour = "white";
|
||||
}
|
||||
|
||||
update(dt)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
render(context)
|
||||
{
|
||||
context.save();
|
||||
context.translate(this.position.x, this.position.y);
|
||||
|
||||
context.fillStyle = this.colour;
|
||||
context.fillRect(-5, -5, 10, 10);
|
||||
|
||||
context.restore();
|
||||
}
|
||||
}
|
88
Starilght-Renderer.js
Normal file
88
Starilght-Renderer.js
Normal file
|
@ -0,0 +1,88 @@
|
|||
"use strict";
|
||||
|
||||
class StarlightRenderer
|
||||
{
|
||||
constructor(canvas)
|
||||
{
|
||||
// The colour of the sky in the background.
|
||||
this.skyColour = "hsla(248, 100%, 23%, 1)";
|
||||
|
||||
// ~~~
|
||||
|
||||
this.canvas = canvas;
|
||||
this.context = canvas.getContext("2d");
|
||||
this.trackWindowSize();
|
||||
|
||||
this.lastFrame = new Date();
|
||||
|
||||
// ~~~
|
||||
|
||||
this.stars = [];
|
||||
for(let i = 0; i < 100; i++)
|
||||
{
|
||||
this.stars.push(new Star(
|
||||
this.canvas,
|
||||
new Vector(
|
||||
random(0, this.canvas.width),
|
||||
random(0, this.canvas.height)
|
||||
),
|
||||
random(0, 10)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
nextFrame()
|
||||
{
|
||||
this.update();
|
||||
this.render(this.canvas, this.context);
|
||||
requestAnimationFrame(this.nextFrame.bind(this));
|
||||
}
|
||||
|
||||
update()
|
||||
{
|
||||
// Calculate the time between this frame and the last one
|
||||
this.currentFrame = new Date();
|
||||
this.currentDt = this.currentFrame - this.lastFrame;
|
||||
|
||||
|
||||
// Stars
|
||||
for(let star of this.stars)
|
||||
star.update(this.currentDt);
|
||||
}
|
||||
|
||||
render(canvas, context)
|
||||
{
|
||||
// Background
|
||||
context.fillStyle = this.skyColour;
|
||||
context.fillRect(0, 0, this.canvas.width, this.canvas.height);
|
||||
|
||||
// Stars
|
||||
for(let star of this.stars)
|
||||
star.render(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the canvas size to match the current viewport size.
|
||||
*/
|
||||
matchWindowSize() {
|
||||
this.canvas.width = window.innerWidth;
|
||||
this.canvas.height = window.innerHeight;
|
||||
|
||||
//this.render(this.context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the canvas size track the window size.
|
||||
*/
|
||||
trackWindowSize() {
|
||||
this.matchWindowSize();
|
||||
window.addEventListener("resize", this.matchWindowSize.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("load", function (event) {
|
||||
var canvas = document.getElementById("canvas-main"),
|
||||
renderer = new StarlightRenderer(canvas);
|
||||
renderer.nextFrame();
|
||||
window.renderer = renderer;
|
||||
});
|
218
Vector.js
Normal file
218
Vector.js
Normal file
|
@ -0,0 +1,218 @@
|
|||
"use strict";
|
||||
|
||||
/******************************************************
|
||||
************** Simple ES6 Vector Class **************
|
||||
******************************************************
|
||||
* Author: Starbeamrainbowlabs
|
||||
* Twitter: @SBRLabs
|
||||
* Email: feedback at starbeamrainbowlabs dot com
|
||||
*
|
||||
* From https://gist.github.com/sbrl/69a8fa588865cacef9c0
|
||||
******************************************************
|
||||
* Originally written for my 2D Graphics ACW at Hull
|
||||
* University.
|
||||
******************************************************
|
||||
* Changelog
|
||||
******************************************************
|
||||
* 19th December 2015:
|
||||
* Added this changelog.
|
||||
* 28th December 2015:
|
||||
* Rewrite tests with klud.js + Node.js
|
||||
* 30th January 2016:
|
||||
* Tweak angleFrom function to make it work properly.
|
||||
* 31st January 2016:
|
||||
* Add the moveTowards function.
|
||||
* Add the minComponent getter.
|
||||
* Add the maxComponent getter.
|
||||
* Add the equalTo function.
|
||||
* Tests still need to be written for all of the above.
|
||||
* 19th September 2016:
|
||||
* Added Vector support to the multiply method.
|
||||
*/
|
||||
|
||||
class Vector {
|
||||
// Constructor
|
||||
constructor(inX, inY) {
|
||||
if (typeof inX != "number") throw new Error("Invalid x value.");
|
||||
if (typeof inY != "number") throw new Error("Invalid y value.");
|
||||
|
||||
// Store the (x, y) coordinates
|
||||
this.x = inX;
|
||||
this.y = inY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add another vector to this vector.
|
||||
* @param {Vector} v The vector to add.
|
||||
* @return {Vector} The current vector. useful for daisy-chaining calls.
|
||||
*/
|
||||
add(v) {
|
||||
this.x += v.x;
|
||||
this.y += v.y;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take another vector from this vector.
|
||||
* @param {Vector} v The vector to subtrace from this one.
|
||||
* @return {Vector} The current vector. useful for daisy-chaining calls.
|
||||
*/
|
||||
subtract(v) {
|
||||
this.x -= v.x;
|
||||
this.y -= v.y;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide the current vector by a given value.
|
||||
* @param {number} value The value to divide by.
|
||||
* @return {Vector} The current vector. Useful for daisy-chaining calls.
|
||||
*/
|
||||
divide(value) {
|
||||
if (typeof value != "number") throw new Error("Can't divide by non-number value.");
|
||||
|
||||
this.x /= value;
|
||||
this.y /= value;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply the current vector by a given value.
|
||||
* @param {(number|Vector)} value The number (or Vector) to multiply the current vector by.
|
||||
* @return {Vector} The current vector. useful for daisy-chaining calls.
|
||||
*/
|
||||
multiply(value) {
|
||||
if (value instanceof Vector) {
|
||||
this.x *= value.x;
|
||||
this.y *= value.y;
|
||||
} else if (typeof value == "number") {
|
||||
this.x *= value;
|
||||
this.y *= value;
|
||||
} else throw new Error("Can't multiply by non-number value.");
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the vector towards the given vector by the given amount.
|
||||
* @param {Vector} v The vector to move towards.
|
||||
* @param {number} amount The distance to move towards the given vector.
|
||||
*/
|
||||
moveTowards(v, amount) {
|
||||
// From http://stackoverflow.com/a/2625107/1460422
|
||||
var dir = new Vector(
|
||||
v.x - this.x,
|
||||
v.y - this.y).limitTo(amount);
|
||||
this.x += dir.x;
|
||||
this.y += dir.y;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Limit the length of the current vector to value without changing the
|
||||
* direction in which the vector is pointing.
|
||||
* @param {number} value The number to limit the current vector's length to.
|
||||
* @return {Vector} The current vector. useful for daisy-chaining calls.
|
||||
*/
|
||||
limitTo(value) {
|
||||
if (typeof value != "number") throw new Error("Can't limit to non-number value.");
|
||||
|
||||
this.divide(this.length);
|
||||
this.multiply(value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the dot product of the current vector and another vector.
|
||||
* @param {Vector} v The other vector we should calculate the dot product with.
|
||||
* @return {Vector} The current vector. useful for daisy-chaining calls.
|
||||
*/
|
||||
dotProduct(v) {
|
||||
return (this.x * v.x) + (this.y * v.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the angle, in radians, from north to another vector.
|
||||
* @param {Vector} v The other vector to which to calculate the angle.
|
||||
* @return {Vector} The current vector. useful for daisy-chaining calls.
|
||||
*/
|
||||
angleFrom(v) {
|
||||
// From http://stackoverflow.com/a/16340752/1460422
|
||||
var angle = Math.atan2(v.y - this.y, v.x - this.x) - (Math.PI / 2);
|
||||
angle += Math.PI / 2;
|
||||
if (angle < 0) angle += Math.PI * 2;
|
||||
return angle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones the current vector.
|
||||
* @return {Vector} A clone of the current vector. Very useful for passing around copies of a vector if you don't want the original to be altered.
|
||||
*/
|
||||
clone() {
|
||||
return new Vector(this.x, this.y);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a representation of the current vector as a string.
|
||||
* @returns {string} A representation of the current vector as a string.
|
||||
*/
|
||||
toString() {
|
||||
return` ($ {
|
||||
this.x
|
||||
}, $ {
|
||||
this.y
|
||||
})`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the vector is equal to another vector.
|
||||
* @param {Vector} v The vector to compare to.
|
||||
* @return {boolean} Whether the current vector is equal to the given vector.
|
||||
*/
|
||||
equalTo(v) {
|
||||
if (this.x == v.x && this.y == v.y) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unit vector of the current vector - that is a vector poiting in the same direction with a length of 1. Note that this does *not* alter the original vector.
|
||||
* @return {Vector} The current vector's unit form.
|
||||
*/
|
||||
get unitVector() {
|
||||
var length = this.length;
|
||||
return new Vector(
|
||||
this.x / length,
|
||||
this.y / length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the length of the current vector.
|
||||
* @return {number} The length of the current vector.
|
||||
*/
|
||||
get length() {
|
||||
return Math.sqrt((this.x * this.x) + (this.y * this.y));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the minimum component of the vector.
|
||||
* @return {number} The minimum component of the vector.
|
||||
*/
|
||||
get minComponent() {
|
||||
return Math.min(this.x, this.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the maximum component of the vector.
|
||||
* @return {number} The maximum component of the vector.
|
||||
*/
|
||||
get maxComponent() {
|
||||
return Math.min(this.x, this.y);
|
||||
}
|
||||
}
|
||||
// Make Vector.js Node.js friendly
|
||||
if (typeof module != "undefined" && module.exports) module.exports = Vector;
|
12
index.css
Normal file
12
index.css
Normal file
|
@ -0,0 +1,12 @@
|
|||
html, body { font-size: 100%; }
|
||||
|
||||
body
|
||||
{
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
#canvas-main
|
||||
{
|
||||
position: absolute;
|
||||
top: 0; left: 0;
|
||||
}
|
21
index.html
Normal file
21
index.html
Normal file
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Starlight</title>
|
||||
|
||||
<link href="index.css" rel="stylesheet" />
|
||||
|
||||
<!-- Libraries -->
|
||||
<script src="Vector.js"></script>
|
||||
<script src="Random.js"></script>
|
||||
|
||||
<!-- Local Code -->
|
||||
<script src="Starlight-Renderer.js"></script>
|
||||
<script src="Star.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="canvas-main"></canvas>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in a new issue