New effects, refactor
This commit is contained in:
parent
4ac45367e5
commit
c0d6bee9c3
14 changed files with 1620 additions and 215 deletions
166
static/js/button-generator/effects/background-starfield.js
Normal file
166
static/js/button-generator/effects/background-starfield.js
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
import { ButtonEffect } from "../effect-base.js";
|
||||
|
||||
/**
|
||||
* Starfield background effect
|
||||
* Twinkling stars with optional shooting stars
|
||||
*/
|
||||
export class StarfieldEffect extends ButtonEffect {
|
||||
constructor() {
|
||||
super({
|
||||
id: "bg-starfield",
|
||||
name: "Starfield",
|
||||
type: "general",
|
||||
category: "Background Animations",
|
||||
renderOrder: 55,
|
||||
});
|
||||
|
||||
this.stars = [];
|
||||
this.shootingStars = [];
|
||||
this.initialized = false;
|
||||
}
|
||||
|
||||
defineControls() {
|
||||
return [
|
||||
{
|
||||
id: "animate-starfield",
|
||||
type: "checkbox",
|
||||
label: "Starfield Effect",
|
||||
description:
|
||||
"This might look a bit different when exported, work in progress!",
|
||||
defaultValue: false,
|
||||
},
|
||||
{
|
||||
id: "star-density",
|
||||
type: "range",
|
||||
label: "Star Density",
|
||||
defaultValue: 30,
|
||||
min: 10,
|
||||
max: 80,
|
||||
step: 5,
|
||||
showWhen: "animate-starfield",
|
||||
description: "Number of stars",
|
||||
},
|
||||
{
|
||||
id: "star-twinkle-speed",
|
||||
type: "range",
|
||||
label: "Twinkle Speed",
|
||||
defaultValue: 1,
|
||||
min: 0.1,
|
||||
max: 3,
|
||||
step: 0.1,
|
||||
showWhen: "animate-starfield",
|
||||
description: "Speed of twinkling",
|
||||
},
|
||||
{
|
||||
id: "star-shooting-enabled",
|
||||
type: "checkbox",
|
||||
label: "Shooting Stars",
|
||||
defaultValue: true,
|
||||
showWhen: "animate-starfield",
|
||||
description: "Enable shooting stars",
|
||||
},
|
||||
{
|
||||
id: "star-color",
|
||||
type: "color",
|
||||
label: "Star Color",
|
||||
defaultValue: "#ffffff",
|
||||
showWhen: "animate-starfield",
|
||||
description: "Color of stars",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
isEnabled(controlValues) {
|
||||
return controlValues["animate-starfield"] === true;
|
||||
}
|
||||
|
||||
apply(context, controlValues, animState, renderData) {
|
||||
if (!animState) return;
|
||||
|
||||
const density = controlValues["star-density"] || 30;
|
||||
const twinkleSpeed = controlValues["star-twinkle-speed"] || 1;
|
||||
const shootingEnabled = controlValues["star-shooting-enabled"] !== false;
|
||||
const starColor = controlValues["star-color"] || "#ffffff";
|
||||
|
||||
// Initialize stars on first frame or density change
|
||||
if (!this.initialized || this.stars.length !== density) {
|
||||
this.stars = [];
|
||||
for (let i = 0; i < density; i++) {
|
||||
this.stars.push({
|
||||
x: Math.random() * renderData.width,
|
||||
y: Math.random() * renderData.height,
|
||||
size: 0.5 + Math.random() * 1.5,
|
||||
twinkleOffset: Math.random() * Math.PI * 2,
|
||||
twinkleSpeed: 0.5 + Math.random() * 1.5,
|
||||
});
|
||||
}
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
// Draw twinkling stars
|
||||
this.stars.forEach((star) => {
|
||||
const twinkle =
|
||||
Math.sin(
|
||||
animState.getPhase(twinkleSpeed * star.twinkleSpeed) +
|
||||
star.twinkleOffset,
|
||||
) *
|
||||
0.5 +
|
||||
0.5;
|
||||
const opacity = 0.3 + twinkle * 0.7;
|
||||
|
||||
context.fillStyle = starColor;
|
||||
context.globalAlpha = opacity;
|
||||
context.beginPath();
|
||||
context.arc(star.x, star.y, star.size, 0, Math.PI * 2);
|
||||
context.fill();
|
||||
context.globalAlpha = 1.0;
|
||||
});
|
||||
|
||||
// Shooting stars
|
||||
if (shootingEnabled) {
|
||||
// Randomly spawn shooting stars
|
||||
if (Math.random() < 0.02 && this.shootingStars.length < 3) {
|
||||
this.shootingStars.push({
|
||||
x: Math.random() * renderData.width,
|
||||
y: -10,
|
||||
vx: (Math.random() - 0.5) * 2,
|
||||
vy: 3 + Math.random() * 2,
|
||||
life: 1.0,
|
||||
});
|
||||
}
|
||||
|
||||
// Update and draw shooting stars
|
||||
this.shootingStars = this.shootingStars.filter((star) => {
|
||||
star.x += star.vx;
|
||||
star.y += star.vy;
|
||||
star.life -= 0.02;
|
||||
|
||||
if (star.life > 0) {
|
||||
// Draw shooting star trail
|
||||
const gradient = context.createLinearGradient(
|
||||
star.x,
|
||||
star.y,
|
||||
star.x - star.vx * 5,
|
||||
star.y - star.vy * 5,
|
||||
);
|
||||
gradient.addColorStop(0, `rgba(255, 255, 255, ${star.life * 0.8})`);
|
||||
gradient.addColorStop(1, "rgba(255, 255, 255, 0)");
|
||||
|
||||
context.strokeStyle = gradient;
|
||||
context.lineWidth = 2;
|
||||
context.beginPath();
|
||||
context.moveTo(star.x, star.y);
|
||||
context.lineTo(star.x - star.vx * 5, star.y - star.vy * 5);
|
||||
context.stroke();
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function register(generator) {
|
||||
generator.registerEffect(new StarfieldEffect());
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue