"use strict"; import Vector from './Vector'; import random from './Random'; class Star { constructor(inCanvas, inPosition, inSize) { this.canvas = inCanvas; this.position = inPosition; // The position this.rotation = 0; // The rotation this.rotationStep = 0; // The amount (in rads / sec) the star turns by this.scale = 1; this.alpha = 1; // The opacity this.pointCount = 5; // The number of points this.startSize = inSize; // The initial radius this.size = this.startSize; // The current radius this.innerRingRatio = 0.5; // The radius of the inner ring (for the inner points) this.twinkleSize = 2; // The size multiplier when twinkling this.twinkling = false; // Whether we're twinkling this.twinkleDuration = 1; // The duration of a twinkle (in seconds) this.twinkleTimer = 0; // The current point along the twinkle we are at now this.colour = "white"; // The colour of the star } /** * The step around a circle (in radians) between each point (both inner and * outer) on the star. * Used by recalculatePoints(). * @return {number} The step around a circle between each point on the star. */ get pointStep() { return (Math.PI * 2) / (this.pointCount * 2); } get innerRingSize() { return this.innerRingRatio * this.size; } recalculatePoints() { this.points = []; for (let n = 0, i = 0; n < Math.PI * 2; n += this.pointStep, i++) { let currentSize = i % 2 == 0 ? this.size : this.innerRingSize; this.points.push(new Vector( currentSize * Math.cos(Math.PI * 2 * (n / (Math.PI * 2)) - Math.PI / 2), currentSize * Math.sin(Math.PI * 2 * (n / (Math.PI * 2)) - Math.PI / 2) )); } } update(dt) { // Rotate (slowly I hope) this.rotation += this.rotationStep * dt; if(this.rotation > Math.PI * 2) this.rotation -= Math.PI * 2; if(this.rotation < 0) this.rotation += Math.PI * 2; // Randomly begin a twinkle if(!this.twinkling && dt != 0 && Math.floor(random(0, 50000)*dt) == 0) this.twinkling = true; if(this.twinkling) { // Calculate the new size quadratically let sizeMultiplier = (1 - Math.pow(2*(this.twinkleTimer / this.twinkleDuration) - 1, 2)); sizeMultiplier *= this.twinkleSize; // Go from 0 - size to 1 - (size + 1) (because a size of 0 makes things disappear) sizeMultiplier += 1; this.scale = sizeMultiplier; this.twinkleTimer += dt; if(this.twinkleTimer >= this.twinkleDuration) this.twinkling = false, this.twinkleTimer = 0; } } render(context) { if(!(this.points instanceof Array)) this.recalculatePoints(); context.save(); context.translate(this.position.x, this.position.y); context.rotate(this.rotation); context.scale(this.scale, this.scale); context.beginPath(); context.moveTo(this.points[0].x, this.points[0].y); for (let point of this.points) { context.lineTo(point.x, point.y); } context.closePath(); context.globalAlpha = this.alpha; context.fillStyle = this.colour; context.fill(); context.restore(); } } export default Star;