HTML5 Canvas : Amazing Star Orbital
After learning the calculation of circular motion, I suddenly got a flash of inspiration
I have a hobby, that is photography! Why don't I use this way to achieve a star orbit effect!!!
<html>
<body>
<div id="canvas-container" style="width: 600px; height: 400px; position: relative; background: linear-gradient(#040e47,#040e47,#051355,#07256b,#444a82, #c8966e);">
<canvas id="myCanvas" style="width: 600px; height: 400px; ">
Your browser does not support canvas, please upgrade your browser
</canvas>
<div id="skyline" style="width: 100%; height: 135px; bottom: 0; left: 0; position: absolute; background: url(/upload/post/7208a351-7359-4d26-868c-0376d9286f9c.png) repeat-x 50% 0;"></div>
</div>
</body>
</html>
<script>
window.requestAnimFrame = (function () {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
function random(min, max) {
return Math.random() * (max - min) + min;
}
function setupCanvas(canvas) {
// Get the device pixel ratio, falling back to 1.
var dpr = window.devicePixelRatio || 1;
// Get the size of the canvas in CSS pixels.
var rect = canvas.getBoundingClientRect();
// Give the canvas pixel dimensions of their CSS
// size * the device pixel ratio.
canvas.width = rect.width * dpr;
canvas.height = rect.height * dpr;
var ctx = canvas.getContext('2d');
// Scale all drawing operations by the dpr, so you
// don't have to worry about the difference.
ctx.scale(dpr, dpr);
return ctx;
}
var canvas = document.getElementById("myCanvas"),
ctx = setupCanvas(canvas),
w = canvas.clientWidth,
h = canvas.clientHeight,
//Center point of rotation
centerX = w * 2 / 3,
centerY = h * 2 / 3,
//
starCount = 720,
stars = [];
function Star(x, y, cx, cy) {
this.x = x;
this.y = y;
this.cx = cx;
this.cy = cy;
var angle = - 1;
var dx = cx - x,
dy = cy - y;
//Calculate the initial radius of rotation
this.radius = Math.sqrt(dx * dx + dy * dy);
//Color value control
this.hue = random(0, 1) > .5 ? random(0, 80) : random(160, 260);
//Transparency control
this.alpha = - 1;
this.alphaDecay = random(0.001, 0.015);
this.alphaMax = random(0, 1)
//Track the past coordinates of each star to create a track effect, increase the coordinate count to create a more obvious track
this.coordinates = [];
this.coordinateCount = 15;
while (this.coordinateCount--) {
this.coordinates.push([this.x, this.y]);
}
this.draw = function () {
ctx.strokeStyle = 'hsla(' + this.hue + ', 80%, ' + random(80, 100) + '%, ' + this.alpha + ')';
ctx.lineWidth = 0.5
//Draw highlights
ctx.beginPath();
ctx.moveTo(this.coordinates[this.coordinates.length - 1][0], this.coordinates[this.coordinates.length - 1][1]);
ctx.lineTo(this.x, this.y);
ctx.stroke();
//Draw star anise
if (this.radius > 100) {
this.createPolygonalStar(this.x, this.y, 8, 1, 12, 45, 0, this.hue, this.alpha);
}
}
// x : central coordinate x value
// y : center coordinate y value
// n : number of star angles
// r : distance from center to concave point
// R : Center to vertex distance
// rotation : pre rotation angle
// borderWidth : edge width
// hue : color value
// alpha : transparency
// isFilled : fill or not
this.createPolygonalStar = function (x, y, n, r, R, rotation, borderWidth, hue, alpha, isFilled = true) {
ctx.save();
ctx.fillStyle = 'hsla(' + hue + ', 80%, 60%, ' + alpha + ')';
ctx.lineWidth = borderWidth;
ctx.beginPath();
for (var i = 0; i < n; i++) {
var perDeg = 360 / n;
var degA = perDeg / 2 / 2;
var degB = 360 / (n - 1) / 2 - degA / 2 + degA;
ctx.lineTo(Math.cos((degA + perDeg * i - rotation) / 180 * Math.PI) * R + (x - R) + borderWidth + R * Math.cos(degA / 180 * Math.PI),
-Math.sin((degA + perDeg * i - rotation) / 180 * Math.PI) * R + (y - R) + borderWidth + R);
ctx.lineTo(Math.cos((degB + perDeg * i - rotation) / 180 * Math.PI) * r + (x - R) + borderWidth + R * Math.cos(degA / 180 * Math.PI),
-Math.sin((degB + perDeg * i - rotation) / 180 * Math.PI) * r + (y - R) + borderWidth + R);
}
ctx.closePath();
if (!!isFilled) {
ctx.fill();
} else {
ctx.stroke();
}
ctx.restore();
}
this.update = function () {
this.coordinates.pop();
this.coordinates.unshift([this.x, this.y]);
//Coordinate calculation after rotation
this.x = this.cx + Math.sin(angle) * this.radius;
this.y = this.cy + Math.cos(angle) * this.radius;
//Increasing radius of rotation
this.radius += 0.05;
//Stop transparency at random
if (this.alpha <= this.alphaMax) {
this.alpha += this.alphaDecay;
}
//Increasing rotation angle
angle += 0.01;
}
}
function loop() {
requestAnimFrame(loop);
ctx.save();
ctx.globalCompositeOperation = "destination-in";
ctx.fillStyle = 'rgba(0,0,0,.8)';
ctx.fillRect(0, 0, w, h);
ctx.restore();
if (stars.length < starCount) {
stars.push(new Star(random(0, w), centerY, centerX, centerY));
}
var i = stars.length;
while (i--) {
stars[i].draw();
stars[i].update();
if (stars[i].radius > 400) {
stars.splice(i, 1);
}
}
}
loop();
</script>
- Link : https://www.zdyla.com/en/post/html5-canvas-amazing-star-orbital.html
- Copyright Notice : Unless otherwise stated, please contact the author for authorization and indicate the source!