mirror of
https://github.com/sussy-code/smov.git
synced 2024-12-29 16:07:40 +01:00
This commit is contained in:
parent
21656e6606
commit
cf24ddc71f
3 changed files with 103 additions and 10 deletions
Before Width: | Height: | Size: 314 B After Width: | Height: | Size: 314 B |
45
public/lightbar-images/snowflake.svg
Normal file
45
public/lightbar-images/snowflake.svg
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg fill="#fff" height="800px" width="800px" version="1.1" id="Capa_1"
|
||||||
|
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
viewBox="0 0 298 298" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<path d="M289.5,140.5h-24.606l11.031-11.03c2.93-2.929,2.93-7.678,0.001-10.606c-2.929-2.929-7.678-2.93-10.606-0.001
|
||||||
|
L243.681,140.5h-36.369l16.182-17.392c2.821-3.032,2.65-7.777-0.383-10.6c-1.243-1.156-2.775-1.802-4.345-1.961
|
||||||
|
c-0.952-0.047-21.495-0.003-21.495-0.003L221.315,86.5H251.5c4.143,0,7.5-3.357,7.5-7.5s-3.357-7.5-7.5-7.5h-15.186l17.69-17.69
|
||||||
|
c2.929-2.93,2.929-7.678,0-10.608c-2.93-2.928-7.844-2.928-10.774,0L225.167,61.1V45.5c0-4.143-3.357-7.5-7.5-7.5
|
||||||
|
c-4.143,0-7.5,3.357-7.5,7.5v30.601l-24.837,25.004l-0.415-22.645c-0.001-0.036,0.035-0.07,0.034-0.106
|
||||||
|
c-0.035-1.824-0.704-3.641-2.07-5.059c-2.873-2.982-7.778-3.07-10.761-0.194l-15.951,15.226V53.107l21.47-21.304
|
||||||
|
c2.929-2.93,3.012-7.678,0.083-10.607c-2.93-2.928-7.803-2.928-10.732,0l-10.821,10.696V7.5c0-4.143-3.357-7.5-7.5-7.5
|
||||||
|
c-4.143,0-7.5,3.357-7.5,7.5v24.393l-10.53-10.696c-2.93-2.928-7.594-2.928-10.524,0c-2.929,2.93-3.054,7.678-0.125,10.607
|
||||||
|
l21.179,21.304v35.421l-16.176-15.475c-3.009-2.847-7.67-2.718-10.52,0.289c-1.075,1.136-1.683,2.52-1.914,3.955
|
||||||
|
c-0.142,0.583-0.203,1.188-0.201,1.811l-0.088,21.229l-25.1-24.944V45.5c0-4.143-3.357-7.5-7.5-7.5s-7.5,3.357-7.5,7.5v14.894
|
||||||
|
L55.142,43.202c-2.93-2.928-7.594-2.928-10.524,0c-2.929,2.93-2.887,7.678,0.042,10.608L62.392,71.5H46.5
|
||||||
|
c-4.143,0-7.5,3.357-7.5,7.5s3.357,7.5,7.5,7.5h30.892l24.744,24.744l-23.057,0.831c-4.021,0.146-7.524,3.435-7.563,7.418
|
||||||
|
c-0.004,0.112-0.349,0.225-0.349,0.337c0,0.003,0,0.007,0,0.011c0,0.008,0.345,0.017,0.345,0.024
|
||||||
|
c0.045,1.875,0.955,3.736,2.395,5.158L89.748,140.5H55.025l-21.638-21.638c-2.93-2.928-7.678-2.928-10.607,0
|
||||||
|
c-2.929,2.93-2.929,7.678,0,10.607l11.03,11.03H8.5c-4.143,0-7.5,3.357-7.5,7.5s3.357,7.5,7.5,7.5h25.02L22.78,166.239
|
||||||
|
c-2.929,2.93-2.929,7.678,0,10.607c1.465,1.464,3.385,2.196,5.304,2.196c1.919,0,3.839-0.732,5.304-2.196L54.734,155.5h35.027
|
||||||
|
l-15.253,16.394c-2.821,3.032-2.65,7.777,0.383,10.6c1.444,1.344,3.277,2.009,5.106,2.009c0.034,0,0.068-0.005,0.103-0.005
|
||||||
|
c0.022,0,0.044,0.003,0.065,0.003c0.018,0,0.037,0,0.055,0l22.005-0.125L77.101,209.5H46.5c-4.143,0-7.5,3.357-7.5,7.5
|
||||||
|
s3.357,7.5,7.5,7.5h15.601l-17.399,17.399c-2.929,2.93-2.929,7.678,0,10.607c1.465,1.464,3.385,2.196,5.304,2.196
|
||||||
|
c1.919,0,3.672-0.732,5.137-2.196l17.025-17.191V250.5c0,4.143,3.357,7.5,7.5,7.5s7.5-3.357,7.5-7.5v-30.185l25.445-25.278
|
||||||
|
l0.977,24.39c0.148,4.046,3.517,7.306,7.532,7.225c1.364-0.027,2.844-0.465,4.312-1.543c1.063-0.781,15.734-15.812,15.734-15.812
|
||||||
|
v35.385l-20.971,21.137c-2.93,2.929-2.846,7.678,0.082,10.607c1.465,1.465,3.425,2.197,5.345,2.197
|
||||||
|
c1.919,0,3.693-0.732,5.157-2.196l10.387-10.532V290.5c0,4.143,3.357,7.5,7.5,7.5c4.143,0,7.5-3.357,7.5-7.5v-25.31l11.404,11.237
|
||||||
|
c1.465,1.464,3.468,2.196,5.387,2.196c1.919,0,3.881-0.732,5.345-2.196c2.929-2.93,2.783-7.678-0.146-10.607l-21.99-21.845v-35.7
|
||||||
|
c0,0,13.729,12.896,15.896,14.976c2.167,2.08,3.942,3.25,6.525,3.25c0.015,0,0.03,0,0.046,0c4.142,0,7.48-3.604,7.455-7.746
|
||||||
|
l-0.306-23.696l24.384,24.551V250.5c0,4.143,3.357,7.5,7.5,7.5c4.143,0,7.5-3.357,7.5-7.5v-15.891l18.064,17.897
|
||||||
|
c1.465,1.464,3.467,2.196,5.387,2.196c1.919,0,3.88-0.732,5.345-2.196c2.929-2.93,2.95-7.678,0.021-10.607L236.605,224.5H251.5
|
||||||
|
c4.143,0,7.5-3.357,7.5-7.5s-3.357-7.5-7.5-7.5h-29.894l-25.742-25.742l23.059-0.831c0.082-0.003,0.162-0.016,0.243-0.021
|
||||||
|
c0.03-0.002,0.06-0.005,0.09-0.008c3.977-0.319,7.037-3.709,6.892-7.736c-0.087-2.424-1.32-4.531-3.155-5.837L209.138,155.5h34.835
|
||||||
|
l21.345,21.346c1.465,1.465,3.384,2.197,5.304,2.197c1.919,0,3.839-0.732,5.303-2.196c2.93-2.929,2.93-7.678,0.001-10.606
|
||||||
|
l-10.74-10.74H289.5c4.143,0,7.5-3.357,7.5-7.5S293.643,140.5,289.5,140.5z M200.795,125.483L186.823,140.5h-19.507l15.002-15.002
|
||||||
|
L200.795,125.483z M170.21,95.784l0.356,20.002l-14.399,14.315V109.16L170.21,95.784z M127.263,95.865l13.904,13.323v20.205
|
||||||
|
l-13.925-14.008L127.263,95.865z M96.862,126.444l19.762-0.712l14.768,14.768h-20.299L96.862,126.444z M97.246,169.477
|
||||||
|
L110.25,155.5h20.851l-13.841,13.841L97.246,169.477z M127.863,201.599l-0.854-21.042l14.158-14.241v21.604L127.863,201.599z
|
||||||
|
M170.819,201.264l-14.652-13.478v-22.179l14.442,14.359L170.819,201.264z M200.991,168.564l-19.614,0.706l-13.77-13.77h20.292
|
||||||
|
L200.991,168.564z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.5 KiB |
|
@ -1,6 +1,12 @@
|
||||||
import { useEffect, useRef } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
import "./Lightbar.css";
|
import "./Lightbar.css";
|
||||||
|
|
||||||
|
interface LightbarOptions {
|
||||||
|
imgSrc?: string;
|
||||||
|
horizontalMotion?: boolean;
|
||||||
|
sizeRange?: [number, number];
|
||||||
|
}
|
||||||
|
|
||||||
class Particle {
|
class Particle {
|
||||||
x = 0;
|
x = 0;
|
||||||
|
|
||||||
|
@ -18,11 +24,23 @@ class Particle {
|
||||||
|
|
||||||
image: null | HTMLImageElement = null;
|
image: null | HTMLImageElement = null;
|
||||||
|
|
||||||
constructor(canvas: HTMLCanvasElement, { doFish } = { doFish: false }) {
|
size = 10;
|
||||||
if (doFish) {
|
|
||||||
this.image = new Image();
|
options: LightbarOptions;
|
||||||
if (this.image) this.image.src = "/fishie.png";
|
|
||||||
|
constructor(
|
||||||
|
canvas: HTMLCanvasElement,
|
||||||
|
options: LightbarOptions = {
|
||||||
|
horizontalMotion: false,
|
||||||
|
sizeRange: [10, 10],
|
||||||
}
|
}
|
||||||
|
) {
|
||||||
|
if (options.imgSrc) {
|
||||||
|
this.image = new Image();
|
||||||
|
this.image.src = options.imgSrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.options = options;
|
||||||
|
|
||||||
this.reset(canvas);
|
this.reset(canvas);
|
||||||
this.initialize(canvas);
|
this.initialize(canvas);
|
||||||
|
@ -39,7 +57,13 @@ class Particle {
|
||||||
const second = 60;
|
const second = 60;
|
||||||
this.lifetime = second * 3 + Math.random() * (second * 30);
|
this.lifetime = second * 3 + Math.random() * (second * 30);
|
||||||
|
|
||||||
if (this.image) {
|
this.size = this.options.sizeRange
|
||||||
|
? Math.random() *
|
||||||
|
(this.options.sizeRange[1] - this.options.sizeRange[0]) +
|
||||||
|
this.options.sizeRange[0]
|
||||||
|
: 10;
|
||||||
|
|
||||||
|
if (this.options.horizontalMotion) {
|
||||||
this.direction = Math.random() <= 0.5 ? 0 : Math.PI;
|
this.direction = Math.random() <= 0.5 ? 0 : Math.PI;
|
||||||
this.lifetime = 30 * second;
|
this.lifetime = 30 * second;
|
||||||
}
|
}
|
||||||
|
@ -81,7 +105,7 @@ class Particle {
|
||||||
|
|
||||||
if (this.image) {
|
if (this.image) {
|
||||||
ctx.translate(this.x, this.y);
|
ctx.translate(this.x, this.y);
|
||||||
const w = 10;
|
const w = this.size;
|
||||||
const h = (this.image.naturalWidth / this.image.naturalHeight) * w;
|
const h = (this.image.naturalWidth / this.image.naturalHeight) * w;
|
||||||
ctx.rotate(this.direction - Math.PI);
|
ctx.rotate(this.direction - Math.PI);
|
||||||
ctx.drawImage(this.image, -w / 2, h, h, w);
|
ctx.drawImage(this.image, -w / 2, h, h, w);
|
||||||
|
@ -113,12 +137,36 @@ function ParticlesCanvas() {
|
||||||
canvas.width = canvas.scrollWidth;
|
canvas.width = canvas.scrollWidth;
|
||||||
canvas.height = canvas.scrollHeight;
|
canvas.height = canvas.scrollHeight;
|
||||||
|
|
||||||
const shouldShowFishie = Math.floor(Math.random() * 600) === 1;
|
// Basic particle config
|
||||||
const particleCount = 20;
|
const particleCount = 20;
|
||||||
|
let imageParticleCount = particleCount;
|
||||||
|
|
||||||
|
// Holiday overrides
|
||||||
|
let imageOverride;
|
||||||
|
let sizeRange;
|
||||||
|
const date = new Date();
|
||||||
|
const month = date.getMonth();
|
||||||
|
const day = date.getDate();
|
||||||
|
if (month === 11 && day >= 24 && day <= 26) {
|
||||||
|
imageOverride = "/lightbar-images/snowflake.svg";
|
||||||
|
sizeRange = [4, 15] as [number, number];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fish easter egg
|
||||||
|
const shouldShowFishie = Math.floor(Math.random() * 600) === 1;
|
||||||
|
if (shouldShowFishie) {
|
||||||
|
imageOverride = "/lightbar-images/fishie.png";
|
||||||
|
imageParticleCount = particleCount / 2;
|
||||||
|
sizeRange = [10, 11] as [number, number];
|
||||||
|
}
|
||||||
|
|
||||||
|
// HOIST THE SAIL (of particles)!
|
||||||
for (let i = 0; i < particleCount; i += 1) {
|
for (let i = 0; i < particleCount; i += 1) {
|
||||||
|
const isImageParticle = imageOverride && i <= imageParticleCount;
|
||||||
const particle = new Particle(canvas, {
|
const particle = new Particle(canvas, {
|
||||||
doFish: shouldShowFishie && i <= particleCount / 2,
|
imgSrc: isImageParticle ? imageOverride : undefined,
|
||||||
|
horizontalMotion: imageOverride?.includes("fishie"),
|
||||||
|
sizeRange,
|
||||||
});
|
});
|
||||||
particles.push(particle);
|
particles.push(particle);
|
||||||
}
|
}
|
||||||
|
@ -161,8 +209,8 @@ function ParticlesCanvas() {
|
||||||
|
|
||||||
export function Lightbar(props: { className?: string }) {
|
export function Lightbar(props: { className?: string }) {
|
||||||
return (
|
return (
|
||||||
<div className="absolute inset-0 w-full h-[calc(680px)] overflow-hidden pointer-events-none -mt-64">
|
<div className="absolute inset-0 w-full h-[680px] overflow-hidden pointer-events-none -mt-64">
|
||||||
<div className="max-w-screen w-full h-[calc(680px)] relative pt-64">
|
<div className="max-w-screen w-full h-[680px] relative pt-64">
|
||||||
<div className={props.className}>
|
<div className={props.className}>
|
||||||
<div className="lightbar">
|
<div className="lightbar">
|
||||||
<ParticlesCanvas />
|
<ParticlesCanvas />
|
||||||
|
|
Loading…
Reference in a new issue