<head> <script type="text/javascript" src="star.js"> </script> <script type="text/javascript" src="UI.js"> </script> </head> <body> <canvas id="canvas" width=500 height=500 style="border:2px solid"></canvas> <p> <ul> </ul> <script> 'use strict' var canvas = document.getElementById('canvas'); canvas.tabIndex=0; canvas.addEventListener("keypress", Keypress); var items = []; items.push(new Star(canvas.width/2, canvas.height/2)); items.push(new Star(canvas.width/4, canvas.height/4)); items.push(new Star(3*canvas.width/4, canvas.height/4)); items.push(new Star(3*canvas.width/4, 3*canvas.height/4)); items.push(new Star(canvas.width/4, 3*canvas.height/4)); var animation = false; var rotation = 0; var doRotation = false; var ctx = canvas.getContext('2d'); ctx.transform(1,0,0,-1,0,canvas.height); DrawScene(items); </script> <ul> <li> <b>b</b> toggles boing for center star <lI> <b>w</b> toggles whir for center star <lI> <b>p</b> toggles phase for center star <li> <b>G</b> go <li> <b>S</b> stop <lI> <b>A</b> copy center to all <lI> <b>R</b> reset All <li> <b>W</b> toggle whir for entire scene. </ul> </body>
'use strict' function Keypress(evnt) { switch(event.key) { case 'A': for (let i=1;i<items.length;i++) { items[i].Copy(items[0]); } break; case 'G': // don't want to start a second one if we are already animating if (animation != true) { animation = true; setTimeout(DoAnimation, 20); } break; case 'S': animation = false; break; case 'R': for (let i=0;i<items.length;i++) { items[i].Reset(); } animation = false; break; case 'W': doRotation = !doRotation; break; case 'b': items[0].FlipScale() break; case 'p': items[0].FlipPhase(); break; case 'w': items[0].FlipSpin(); break; } DrawScene(); } function DoAnimation() { if (doRotation) { rotation -= 1; rotation %= 360; } DrawScene(); if (animation) { setTimeout(DoAnimation, 20); } } function DrawScene(){ ctx.clearRect(0,0, canvas.height, canvas.width); ctx.save(); ctx.translate(canvas.width/2, canvas.height/2); ctx.rotate(rotation*Math.PI/180); ctx.translate(-canvas.width/2, -canvas.height/2); for(let i = 0; i < items.length; i++) { items[i].Next(); items[i].Display(ctx); } ctx.restore(); }
'use strict' const SCALE_MIN = 20; const SCALE_MAX = 100; function MakePoints() { let pts = []; for(let i = 0; i < 5; i++) { let angle = i*Math.PI*2/5; let x = Math.cos(angle); let y = Math.sin(angle); pts.push([x,y]); } return pts; } class Star{ constructor(cx = 0, cy = 0 ){ this.points = MakePoints(); this.orderB = [0,1,2,3,4]; this.orderA = [3,1,4,2,0]; this.cx = cx; this.cy = cy; this.Reset(); } Copy (master) { this.scale = master.scale; this.scaling = master.scaling; this.scaleDir = master.scaleDir; this.rotation = master.rotation; this.spinning = master.spinning; this.spinDown = master.spinDown; this.phasing = master.phasing; this.phaseDir = master.phaseDir; this.phaseStep = master.phaseStep; } Reset() { this.scale = SCALE_MIN; this.scaling = false; this.scaleDir = 1; this.rotation = 0; this.spinning = false; this.spinDown = false; this.phasing = false; this.phaseDir = 1; this.phaseStep = 0; } FlipSpin() { this.spinning = !this.spinning; if (this.spinning == false ) { this.spinDown = true; } else { this.spinDown = false; } } FlipScale() { this.scaling = !this.scaling; } FlipPhase() { this.phasing = !this.phasing; } Next() { if (this.spinning || (this.spinDown && this.rotation != 0)) { this.rotation += 1; this.rotation %= 360; } if(this.spinDown && this.rotation == 0) { this.spinDown = false; } if (this.scaling) { this.scale += this.scaleDir; if (this.scale <= SCALE_MIN) { this.scaleDir = 1; } if (this.scale >= SCALE_MAX) { this.scaleDir = -1; } } if (this.phasing) { this.phaseStep += .01 * this.phaseDir; if (this.phaseStep <= 0) { this.phaseDir = 1; } if (this.phaseStep >= 1) { this.phaseDir = -1; } } } TruePoint(pt) { let idx1 = this.orderA[pt]; let idx2 = this.orderB[pt]; let x = this.points[idx1][0] * (1-this.phaseStep) + this.points[idx2][0]*this.phaseStep; let y = this.points[idx1][1] * (1-this.phaseStep) + this.points[idx2][1]*this.phaseStep; return [x,y]; } Display(ctx) { let scale = this.scale; ctx.save(); ctx.translate(this.cx, this.cy) ctx.rotate(this.rotation*Math.PI/180); let last = this.points.length-1; ctx.beginPath(); let pt = this.TruePoint(last); ctx.fillStyle = "red"; ctx.arc(pt[0]*scale,pt[1]*scale, 4, 0, Math.PI*2); ctx.fill(); ctx.strokeStyle = "blue"; ctx.moveTo(pt[0]*scale,pt[1]*scale); for(let i=0; i<=last; i++) { let pt = this.TruePoint(i); ctx.lineTo(pt[0]*scale,pt[1]*scale); } ctx.stroke(); ctx.closePath(); ctx.restore(); } }