mirror of
https://github.com/krahets/hello-algo.git
synced 2026-01-12 00:04:24 +08:00
Add starfield.js in the landing page. (#1833)
This commit is contained in:
@@ -1,7 +1,10 @@
|
|||||||
<!-- Section: hero -->
|
<!-- Section: hero -->
|
||||||
<section data-md-color-scheme="slate" data-md-color-primary="grey" class="home-div" style="height: min(100vh, 120vw); position: relative; margin-top:-2.4rem; padding: 0; overflow: hidden;">
|
<section data-md-color-scheme="slate" data-md-color-primary="grey" class="home-div" style="height: min(100vh, 120vw); position: relative; margin-top:-2.4rem; padding: 0; overflow: hidden;">
|
||||||
<!-- hero image -->
|
<!-- hero image -->
|
||||||
<img src="assets/hero/universe_bg.png" class="hero-bg" alt="">
|
<!-- <img alt="" class="hero-bg" src="assets/hero/universe_bg.png" /> -->
|
||||||
|
<div class="starfield">
|
||||||
|
<div class="starfield-origin"></div>
|
||||||
|
</div>
|
||||||
<div class="hero-div">
|
<div class="hero-div">
|
||||||
<img src="assets/hero/ground.png" alt="" style="position: absolute; width: auto; height: 26.445%; left: 28.211%; top: 54.145%;">
|
<img src="assets/hero/ground.png" alt="" style="position: absolute; width: auto; height: 26.445%; left: 28.211%; top: 54.145%;">
|
||||||
<img src="assets/hero/links.png" alt="" style="position: absolute; width: auto; height: 78.751%; left: 10.545%; top: 7.326%;">
|
<img src="assets/hero/links.png" alt="" style="position: absolute; width: auto; height: 78.751%; left: 10.545%; top: 7.326%;">
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
<!-- Section: hero -->
|
<!-- Section: hero -->
|
||||||
<section data-md-color-scheme="slate" data-md-color-primary="grey" class="home-div" style="height: min(100vh, 120vw); position: relative; margin-top:-2.4rem; padding: 0; overflow: hidden;">
|
<section data-md-color-scheme="slate" data-md-color-primary="grey" class="home-div" style="height: min(100vh, 120vw); position: relative; margin-top:-2.4rem; padding: 0; overflow: hidden;">
|
||||||
<!-- hero image -->
|
<!-- hero image -->
|
||||||
<img src="../assets/hero/universe_bg.png" class="hero-bg" alt="">
|
<!-- <img alt="" class="hero-bg" src="assets/hero/universe_bg.png" /> -->
|
||||||
|
<div class="starfield">
|
||||||
|
<div class="starfield-origin"></div>
|
||||||
|
</div>
|
||||||
<div class="hero-div">
|
<div class="hero-div">
|
||||||
<img src="../assets/hero/ground.png" alt="" style="position: absolute; width: auto; height: 26.445%; left: 28.211%; top: 54.145%;">
|
<img src="../assets/hero/ground.png" alt="" style="position: absolute; width: auto; height: 26.445%; left: 28.211%; top: 54.145%;">
|
||||||
<img src="../assets/hero/links.png" alt="" style="position: absolute; width: auto; height: 78.751%; left: 10.545%; top: 7.326%;">
|
<img src="../assets/hero/links.png" alt="" style="position: absolute; width: auto; height: 78.751%; left: 10.545%; top: 7.326%;">
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
<!-- Section: hero -->
|
<!-- Section: hero -->
|
||||||
<section data-md-color-scheme="slate" data-md-color-primary="grey" class="home-div" style="height: min(100vh, 120vw); position: relative; margin-top:-2.4rem; padding: 0; overflow: hidden;">
|
<section data-md-color-scheme="slate" data-md-color-primary="grey" class="home-div" style="height: min(100vh, 120vw); position: relative; margin-top:-2.4rem; padding: 0; overflow: hidden;">
|
||||||
<!-- hero image -->
|
<!-- hero image -->
|
||||||
<img src="../assets/hero/universe_bg.png" class="hero-bg" alt="">
|
<!-- <img alt="" class="hero-bg" src="assets/hero/universe_bg.png" /> -->
|
||||||
|
<div class="starfield">
|
||||||
|
<div class="starfield-origin"></div>
|
||||||
|
</div>
|
||||||
<div class="hero-div">
|
<div class="hero-div">
|
||||||
<img src="../assets/hero/ground.png" alt="" style="position: absolute; width: auto; height: 26.445%; left: 28.211%; top: 54.145%;">
|
<img src="../assets/hero/ground.png" alt="" style="position: absolute; width: auto; height: 26.445%; left: 28.211%; top: 54.145%;">
|
||||||
<img src="../assets/hero/links.png" alt="" style="position: absolute; width: auto; height: 78.751%; left: 10.545%; top: 7.326%;">
|
<img src="../assets/hero/links.png" alt="" style="position: absolute; width: auto; height: 78.751%; left: 10.545%; top: 7.326%;">
|
||||||
|
|||||||
471
overrides/javascripts/starfield.js
Normal file
471
overrides/javascripts/starfield.js
Normal file
@@ -0,0 +1,471 @@
|
|||||||
|
/*
|
||||||
|
* starfield.js
|
||||||
|
*
|
||||||
|
* Version: 1.5.0
|
||||||
|
* Description: Interactive starfield background
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* Starfield.setup({
|
||||||
|
* // options
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
(function (root, factory) {
|
||||||
|
if (typeof define === "function" && define.amd) {
|
||||||
|
define([], factory);
|
||||||
|
} else if (typeof module === "object" && module.exports) {
|
||||||
|
module.exports = factory();
|
||||||
|
} else {
|
||||||
|
root.Starfield = factory();
|
||||||
|
}
|
||||||
|
})(this, function () {
|
||||||
|
const Starfield = {};
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
numStars: 250, // Number of stars
|
||||||
|
baseSpeed: 1, // Base speed of stars (will affect acceleration)
|
||||||
|
trailLength: 0.8, // Length of star trail (0-1)
|
||||||
|
starColor: "rgb(255, 255, 255)", // Color of stars (only rgb)
|
||||||
|
canvasColor: "rgb(0, 0, 0)", // Canvas background color (only rgb)
|
||||||
|
hueJitter: 0, // Maximum hue variation in degrees (0-360)
|
||||||
|
maxAcceleration: 10, // Maximum acceleration
|
||||||
|
accelerationRate: 0.2, // Rate of acceleration
|
||||||
|
decelerationRate: 0.2, // Rate of deceleration
|
||||||
|
minSpawnRadius: 80, // Minimum spawn distance from origin
|
||||||
|
maxSpawnRadius: 500, // Maximum spawn distance from origin
|
||||||
|
auto: true,
|
||||||
|
originX: null,
|
||||||
|
originY: null,
|
||||||
|
container: null,
|
||||||
|
originElement: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
let stars = [];
|
||||||
|
let accelerate = false;
|
||||||
|
let accelerationFactor = 0;
|
||||||
|
let originX = 0;
|
||||||
|
let originY = 0;
|
||||||
|
let prevOriginX = 0;
|
||||||
|
let prevOriginY = 0;
|
||||||
|
|
||||||
|
let canvas, ctx;
|
||||||
|
let width, height;
|
||||||
|
let lastTimestamp = 0;
|
||||||
|
let canvasRGB = [0, 0, 0];
|
||||||
|
let lastCanvasColor = config.canvasColor;
|
||||||
|
|
||||||
|
let origin;
|
||||||
|
let container;
|
||||||
|
|
||||||
|
const mouseEnterHandler = () => (accelerate = true);
|
||||||
|
const mouseLeaveHandler = () => (accelerate = false);
|
||||||
|
const resizeHandler = () => windowResized(container, origin);
|
||||||
|
|
||||||
|
function visibilityHandler() {
|
||||||
|
if (document.visibilityState === "visible") {
|
||||||
|
lastTimestamp = performance.now();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOriginY(origin, container) {
|
||||||
|
const originRect = origin.getBoundingClientRect();
|
||||||
|
const containerRect = container.getBoundingClientRect();
|
||||||
|
return originRect.top - containerRect.top + originRect.height / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOriginX(origin, container) {
|
||||||
|
const originRect = origin.getBoundingClientRect();
|
||||||
|
const containerRect = container.getBoundingClientRect();
|
||||||
|
return originRect.left - containerRect.left + originRect.width / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up and start the starfield animation.
|
||||||
|
* @param {Object} userConfig Configuration options.
|
||||||
|
*/
|
||||||
|
function setup(userConfig = {}) {
|
||||||
|
Object.assign(config, userConfig);
|
||||||
|
|
||||||
|
container = config.container || document.querySelector(".starfield");
|
||||||
|
if (!container) {
|
||||||
|
throw new Error("Starfield: No container element found.");
|
||||||
|
}
|
||||||
|
// container.style.position = "relative";
|
||||||
|
|
||||||
|
width = container.clientWidth;
|
||||||
|
height = container.clientHeight;
|
||||||
|
|
||||||
|
canvas = document.createElement("canvas");
|
||||||
|
canvas.width = width;
|
||||||
|
canvas.height = height;
|
||||||
|
|
||||||
|
canvas.style.position = "absolute";
|
||||||
|
canvas.style.top = "0";
|
||||||
|
canvas.style.left = "0";
|
||||||
|
canvas.style.width = "100%";
|
||||||
|
canvas.style.height = "100%";
|
||||||
|
canvas.style.zIndex = "-1";
|
||||||
|
canvasRGB = parseRGBA(config.canvasColor);
|
||||||
|
|
||||||
|
container.appendChild(canvas);
|
||||||
|
|
||||||
|
ctx = canvas.getContext("2d");
|
||||||
|
|
||||||
|
if (config.auto) {
|
||||||
|
origin =
|
||||||
|
config.originElement || document.querySelector(".starfield-origin");
|
||||||
|
if (!origin) {
|
||||||
|
throw new Error("Starfield: No origin element found.");
|
||||||
|
}
|
||||||
|
originX = getOriginX(origin, container);
|
||||||
|
originY = getOriginY(origin, container);
|
||||||
|
|
||||||
|
origin.addEventListener("mouseenter", mouseEnterHandler);
|
||||||
|
origin.addEventListener("mouseleave", mouseLeaveHandler);
|
||||||
|
|
||||||
|
window.addEventListener("resize", resizeHandler);
|
||||||
|
} else {
|
||||||
|
originX = config.originX !== null ? config.originX : width / 2;
|
||||||
|
originY = config.originY !== null ? config.originY : height / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < config.numStars; i++) {
|
||||||
|
const star = createRandomStar();
|
||||||
|
stars.push(star);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("visibilitychange", visibilityHandler);
|
||||||
|
|
||||||
|
requestAnimationFrame(draw);
|
||||||
|
}
|
||||||
|
|
||||||
|
function windowResized(container, origin) {
|
||||||
|
width = container.clientWidth;
|
||||||
|
height = container.clientHeight;
|
||||||
|
canvas.width = width;
|
||||||
|
canvas.height = height;
|
||||||
|
|
||||||
|
originX = getOriginX(origin, container);
|
||||||
|
originY = getOriginY(origin, container);
|
||||||
|
|
||||||
|
stars.forEach((star) => star.reset());
|
||||||
|
}
|
||||||
|
|
||||||
|
function createRandomStar() {
|
||||||
|
const angle = random(0, Math.PI * 2);
|
||||||
|
const radius = random(config.minSpawnRadius, config.maxSpawnRadius);
|
||||||
|
|
||||||
|
const x = originX + Math.cos(angle) * radius;
|
||||||
|
const y = originY + Math.sin(angle) * radius;
|
||||||
|
|
||||||
|
return new Star(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Star {
|
||||||
|
constructor(x, y) {
|
||||||
|
this.pos = {
|
||||||
|
x: x,
|
||||||
|
y: y,
|
||||||
|
};
|
||||||
|
this.prevpos = {
|
||||||
|
x: x,
|
||||||
|
y: y,
|
||||||
|
};
|
||||||
|
this.vel = {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
};
|
||||||
|
this.angle = Math.atan2(y - originY, x - originX);
|
||||||
|
this.baseSpeed = random(config.baseSpeed * 0.5, config.baseSpeed * 1.5);
|
||||||
|
this.hueOffset = random(-config.hueJitter, config.hueJitter);
|
||||||
|
}
|
||||||
|
|
||||||
|
reset() {
|
||||||
|
const newStar = createRandomStar();
|
||||||
|
this.pos.x = newStar.pos.x;
|
||||||
|
this.pos.y = newStar.pos.y;
|
||||||
|
this.prevpos.x = this.pos.x;
|
||||||
|
this.prevpos.y = this.pos.y;
|
||||||
|
this.vel.x = 0;
|
||||||
|
this.vel.y = 0;
|
||||||
|
this.angle = Math.atan2(this.pos.y - originY, this.pos.x - originX);
|
||||||
|
this.baseSpeed = random(config.baseSpeed * 0.5, config.baseSpeed * 1.5);
|
||||||
|
this.hueOffset = random(-config.hueJitter, config.hueJitter);
|
||||||
|
}
|
||||||
|
|
||||||
|
update(acc, deltaTime) {
|
||||||
|
const adjustedAcc = acc * this.baseSpeed;
|
||||||
|
|
||||||
|
this.vel.x += Math.cos(this.angle) * adjustedAcc * deltaTime;
|
||||||
|
this.vel.y += Math.sin(this.angle) * adjustedAcc * deltaTime;
|
||||||
|
|
||||||
|
this.prevpos.x = this.pos.x;
|
||||||
|
this.prevpos.y = this.pos.y;
|
||||||
|
this.pos.x += this.vel.x * deltaTime;
|
||||||
|
this.pos.y += this.vel.y * deltaTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
draw() {
|
||||||
|
let velMag = Math.sqrt(
|
||||||
|
this.vel.x * this.vel.x + this.vel.y * this.vel.y
|
||||||
|
);
|
||||||
|
velMag = velMag * 3;
|
||||||
|
const alpha = map(velMag, 0, 10, 0, 1);
|
||||||
|
const weight = map(velMag, 0, 10, 1, 3);
|
||||||
|
|
||||||
|
ctx.lineWidth = weight;
|
||||||
|
|
||||||
|
const [r, g, b] = parseRGBA(config.starColor);
|
||||||
|
const [h, s, l] = rgbToHsl(r, g, b);
|
||||||
|
const adjustedH = (h + this.hueOffset + 360) % 360;
|
||||||
|
const [newR, newG, newB] = hslToRgb(adjustedH, s, l).map((v) =>
|
||||||
|
Math.round(v)
|
||||||
|
);
|
||||||
|
ctx.strokeStyle = `rgba(${newR}, ${newG}, ${newB}, ${alpha})`;
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(this.prevpos.x, this.prevpos.y);
|
||||||
|
ctx.lineTo(this.pos.x, this.pos.y);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
isActive() {
|
||||||
|
return onScreen(this.pos.x, this.pos.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateAngle() {
|
||||||
|
this.angle = Math.atan2(this.pos.y - originY, this.pos.x - originX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw(timestamp) {
|
||||||
|
if (!lastTimestamp) lastTimestamp = timestamp;
|
||||||
|
const deltaTime = (timestamp - lastTimestamp) / 16.67;
|
||||||
|
lastTimestamp = timestamp;
|
||||||
|
|
||||||
|
if (config.auto) {
|
||||||
|
originX = getOriginX(origin, container);
|
||||||
|
originY = getOriginY(origin, container);
|
||||||
|
if (originX !== prevOriginX || originY !== prevOriginY) {
|
||||||
|
stars.forEach((star) => {
|
||||||
|
star.updateAngle();
|
||||||
|
});
|
||||||
|
prevOriginX = originX;
|
||||||
|
prevOriginY = originY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastCanvasColor !== config.canvasColor) {
|
||||||
|
canvasRGB = parseRGBA(config.canvasColor);
|
||||||
|
lastCanvasColor = config.canvasColor;
|
||||||
|
}
|
||||||
|
const [bgR, bgG, bgB] = canvasRGB;
|
||||||
|
ctx.fillStyle = `rgba(${bgR}, ${bgG}, ${bgB}, ${1 - config.trailLength})`;
|
||||||
|
ctx.fillRect(0, 0, width, height);
|
||||||
|
|
||||||
|
if (accelerate) {
|
||||||
|
accelerationFactor = Math.min(
|
||||||
|
accelerationFactor + config.accelerationRate * deltaTime,
|
||||||
|
config.maxAcceleration
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
accelerationFactor = Math.max(
|
||||||
|
accelerationFactor - config.decelerationRate * deltaTime,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const baseAcc = 0.01;
|
||||||
|
const currentAcc = baseAcc * (1 + accelerationFactor * 10);
|
||||||
|
|
||||||
|
for (let star of stars) {
|
||||||
|
star.update(currentAcc, deltaTime);
|
||||||
|
star.draw();
|
||||||
|
if (!star.isActive()) {
|
||||||
|
star.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
requestAnimationFrame(draw);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onScreen(x, y) {
|
||||||
|
return x >= 0 && x <= width && y >= 0 && y <= height;
|
||||||
|
}
|
||||||
|
|
||||||
|
function random(min, max) {
|
||||||
|
return Math.random() * (max - min) + min;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://gist.github.com/mjackson/5311256
|
||||||
|
function rgbToHsl(r, g, b) {
|
||||||
|
r /= 255;
|
||||||
|
g /= 255;
|
||||||
|
b /= 255;
|
||||||
|
const max = Math.max(r, g, b),
|
||||||
|
min = Math.min(r, g, b);
|
||||||
|
let h,
|
||||||
|
s,
|
||||||
|
l = (max + min) / 2;
|
||||||
|
|
||||||
|
if (max === min) {
|
||||||
|
h = s = 0;
|
||||||
|
} else {
|
||||||
|
const d = max - min;
|
||||||
|
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||||||
|
switch (max) {
|
||||||
|
case r:
|
||||||
|
h = (g - b) / d + (g < b ? 6 : 0);
|
||||||
|
break;
|
||||||
|
case g:
|
||||||
|
h = (b - r) / d + 2;
|
||||||
|
break;
|
||||||
|
case b:
|
||||||
|
h = (r - g) / d + 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
h /= 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [h * 360, s, l];
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://gist.github.com/mjackson/5311256
|
||||||
|
function hslToRgb(h, s, l) {
|
||||||
|
let r, g, b;
|
||||||
|
h = h / 360;
|
||||||
|
|
||||||
|
if (s === 0) {
|
||||||
|
r = g = b = l;
|
||||||
|
} else {
|
||||||
|
const hue2rgb = (p, q, t) => {
|
||||||
|
if (t < 0) t += 1;
|
||||||
|
if (t > 1) t -= 1;
|
||||||
|
if (t < 1 / 6) return p + (q - p) * 6 * t;
|
||||||
|
if (t < 1 / 2) return q;
|
||||||
|
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
|
||||||
|
return p;
|
||||||
|
};
|
||||||
|
|
||||||
|
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||||
|
const p = 2 * l - q;
|
||||||
|
r = hue2rgb(p, q, h + 1 / 3);
|
||||||
|
g = hue2rgb(p, q, h);
|
||||||
|
b = hue2rgb(p, q, h - 1 / 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [r * 255, g * 255, b * 255];
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseRGBA(color) {
|
||||||
|
const rgbaRegex = /rgba?\((\d+),\s*(\d+),\s*(\d+)/;
|
||||||
|
const match = color.match(rgbaRegex);
|
||||||
|
if (match) {
|
||||||
|
return [
|
||||||
|
parseInt(match[1], 10),
|
||||||
|
parseInt(match[2], 10),
|
||||||
|
parseInt(match[3], 10),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return [255, 255, 255];
|
||||||
|
}
|
||||||
|
|
||||||
|
function map(value, start1, stop1, start2, stop2) {
|
||||||
|
return ((value - start1) / (stop1 - start1)) * (stop2 - start2) + start2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the acceleration state of the starfield.
|
||||||
|
* @param {boolean} state The acceleration state.
|
||||||
|
*/
|
||||||
|
function setAccelerate(state) {
|
||||||
|
accelerate = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the x-coordinate of the origin of the starfield.
|
||||||
|
* @param {number} x The x-coordinate of the origin.
|
||||||
|
*/
|
||||||
|
function setOriginX(x) {
|
||||||
|
originX = x;
|
||||||
|
stars.forEach((star) => {
|
||||||
|
star.angle = Math.atan2(star.pos.y - originY, star.pos.x - originX);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the y-coordinate of the origin of the starfield.
|
||||||
|
* @param {number} y The y-coordinate of the origin.
|
||||||
|
*/
|
||||||
|
function setOriginY(y) {
|
||||||
|
originY = y;
|
||||||
|
stars.forEach((star) => {
|
||||||
|
star.angle = Math.atan2(star.pos.y - originY, star.pos.x - originX);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the origin of the starfield to a specific point.
|
||||||
|
* @param {number} x The x-coordinate of the origin.
|
||||||
|
* @param {number} y The y-coordinate of the origin.
|
||||||
|
*/
|
||||||
|
function setOrigin(x, y) {
|
||||||
|
originX = x;
|
||||||
|
originY = y;
|
||||||
|
stars.forEach((star) => {
|
||||||
|
star.angle = Math.atan2(star.pos.y - originY, star.pos.x - originX);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resize the starfield to a new width and height.
|
||||||
|
* @param {number} newWidth The new width of the starfield.
|
||||||
|
* @param {number} newHeight The new height of the starfield.
|
||||||
|
*/
|
||||||
|
function resize(newWidth, newHeight) {
|
||||||
|
width = newWidth;
|
||||||
|
height = newHeight;
|
||||||
|
canvas.width = width;
|
||||||
|
canvas.height = height;
|
||||||
|
|
||||||
|
if (config.originY !== null) {
|
||||||
|
originY = config.originY;
|
||||||
|
} else {
|
||||||
|
originY = height / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
stars.forEach((star) => star.reset());
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanup() {
|
||||||
|
if (origin) {
|
||||||
|
origin.removeEventListener("mouseenter", mouseEnterHandler);
|
||||||
|
origin.removeEventListener("mouseleave", mouseLeaveHandler);
|
||||||
|
}
|
||||||
|
window.removeEventListener("resize", resizeHandler);
|
||||||
|
document.removeEventListener("visibilitychange", visibilityHandler);
|
||||||
|
|
||||||
|
if (canvas && canvas.parentNode) {
|
||||||
|
canvas.parentNode.removeChild(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
stars = [];
|
||||||
|
accelerate = false;
|
||||||
|
accelerationFactor = 0;
|
||||||
|
originX = 0;
|
||||||
|
originY = 0;
|
||||||
|
prevOriginX = 0;
|
||||||
|
prevOriginY = 0;
|
||||||
|
lastTimestamp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Starfield.setup = setup;
|
||||||
|
Starfield.setAccelerate = setAccelerate;
|
||||||
|
Starfield.setOrigin = setOrigin;
|
||||||
|
Starfield.setOriginX = setOriginX;
|
||||||
|
Starfield.setOriginY = setOriginY;
|
||||||
|
Starfield.resize = resize;
|
||||||
|
Starfield.config = config;
|
||||||
|
Starfield.cleanup = cleanup;
|
||||||
|
|
||||||
|
return Starfield;
|
||||||
|
});
|
||||||
@@ -551,4 +551,19 @@ a:hover .text-button span {
|
|||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* starfield */
|
||||||
|
.starfield {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.starfield-origin {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
<!-- Section: hero -->
|
<!-- Section: hero -->
|
||||||
<section data-md-color-scheme="slate" data-md-color-primary="grey" class="home-div" style="height: min(100vh, 120vw); position: relative; margin-top:-2.4rem; padding: 0; overflow: hidden;">
|
<section data-md-color-scheme="slate" data-md-color-primary="grey" class="home-div" style="height: min(100vh, 120vw); position: relative; margin-top:-2.4rem; padding: 0; overflow: hidden;">
|
||||||
<!-- hero image -->
|
<!-- hero image -->
|
||||||
<img src="../assets/hero/universe_bg.png" class="hero-bg" alt="">
|
<!-- <img alt="" class="hero-bg" src="assets/hero/universe_bg.png" /> -->
|
||||||
|
<div class="starfield">
|
||||||
|
<div class="starfield-origin"></div>
|
||||||
|
</div>
|
||||||
<div class="hero-div">
|
<div class="hero-div">
|
||||||
<img src="../assets/hero/ground.png" alt="" style="position: absolute; width: auto; height: 26.445%; left: 28.211%; top: 54.145%;">
|
<img src="../assets/hero/ground.png" alt="" style="position: absolute; width: auto; height: 26.445%; left: 28.211%; top: 54.145%;">
|
||||||
<img src="../assets/hero/links.png" alt="" style="position: absolute; width: auto; height: 78.751%; left: 10.545%; top: 7.326%;">
|
<img src="../assets/hero/links.png" alt="" style="position: absolute; width: auto; height: 78.751%; left: 10.545%; top: 7.326%;">
|
||||||
|
|||||||
Reference in New Issue
Block a user