last try with the generative banner

This commit is contained in:
nvrl committed 2026-02-18 08:39:22 +01:00
1 parent 1653a5e448
commit 93961aa309
3 files changed
+47 -45

No files matched your search

+24 -38
View File
@@ -30,9 +30,8 @@ const GenerativeBanner: React.FC<GenerativeBannerProps> = ({ username, palette,
let animationFrameId: number;
const seed = getSeed(username);
const nodeCount = Math.min(25 + Math.floor(ratingsCount / 2), 60);
const speedMultiplier = 0.3 + (Math.min(followersCount, 50) / 80);
const nodeCount = Math.min(20 + Math.floor(ratingsCount / 2), 50);
const speedMultiplier = 0.25 + (Math.min(followersCount, 50) / 80);
const colors = palette.length >= 2 ? palette : [theme.palette.primary.main, theme.palette.secondary.main, theme.palette.info.main];
interface Node {
@@ -82,7 +81,6 @@ const GenerativeBanner: React.FC<GenerativeBannerProps> = ({ username, palette,
const resizeObserver = new ResizeObserver(() => resize());
if (canvas.parentElement) resizeObserver.observe(canvas.parentElement);
resize();
let mouse = { x: -1000, y: -1000, down: false };
@@ -104,12 +102,14 @@ const GenerativeBanner: React.FC<GenerativeBannerProps> = ({ username, palette,
const handleMouseDown = () => { mouse.down = true; };
const handleMouseUp = () => { mouse.down = false; };
// Event listeners on canvas for local coordinates
canvas.addEventListener('mousemove', handleMouseMove);
canvas.addEventListener('touchmove', handleTouchMove);
canvas.addEventListener('mousedown', handleMouseDown);
canvas.addEventListener('mouseup', handleMouseUp);
canvas.addEventListener('mouseleave', () => { mouse.x = -1000; mouse.y = -1000; mouse.down = false; });
// Attach listeners to parent to ensure they work even if canvas has issues
const parent = canvas.parentElement;
if (parent) {
parent.addEventListener('mousemove', handleMouseMove);
parent.addEventListener('touchmove', handleTouchMove);
parent.addEventListener('mousedown', handleMouseDown);
parent.addEventListener('mouseup', handleMouseUp);
}
const draw = () => {
const width = canvas.width / (window.devicePixelRatio || 1);
@@ -147,38 +147,22 @@ const GenerativeBanner: React.FC<GenerativeBannerProps> = ({ username, palette,
}
});
// Draw mesh
ctx.lineWidth = 1;
// Mesh
ctx.lineWidth = 1.2;
for (let i = 0; i < nodes.length; i++) {
for (let j = i + 1; j < nodes.length; j++) {
const ddist = Math.sqrt(Math.pow(nodes[i].x - nodes[j].x, 2) + Math.pow(nodes[i].y - nodes[j].y, 2));
if (ddist < 120) {
if (ddist < 130) {
ctx.beginPath();
ctx.moveTo(nodes[i].x, nodes[i].y);
ctx.lineTo(nodes[j].x, nodes[j].y);
ctx.strokeStyle = alpha(nodes[i].color, (1 - ddist / 120) * 0.4);
ctx.strokeStyle = alpha(nodes[i].color, (1 - ddist / 130) * 0.4);
ctx.stroke();
for (let k = j + 1; k < nodes.length; k++) {
const ddist2 = Math.sqrt(Math.pow(nodes[j].x - nodes[k].x, 2) + Math.pow(nodes[j].y - nodes[k].y, 2));
const ddist3 = Math.sqrt(Math.pow(nodes[i].x - nodes[k].x, 2) + Math.pow(nodes[i].y - nodes[k].y, 2));
if (ddist2 < 120 && ddist3 < 120) {
ctx.beginPath();
ctx.moveTo(nodes[i].x, nodes[i].y);
ctx.lineTo(nodes[j].x, nodes[j].y);
ctx.lineTo(nodes[k].x, nodes[k].y);
ctx.closePath();
ctx.fillStyle = alpha(nodes[i].color, 0.1);
ctx.fill();
}
}
}
}
}
// Draw nodes
// Points
nodes.forEach(node => {
ctx.beginPath();
ctx.arc(node.x, node.y, node.size, 0, Math.PI * 2);
@@ -187,7 +171,7 @@ const GenerativeBanner: React.FC<GenerativeBannerProps> = ({ username, palette,
ctx.beginPath();
ctx.arc(node.x, node.y, node.size * 2.5, 0, Math.PI * 2);
ctx.fillStyle = alpha(node.color, 0.15);
ctx.fillStyle = alpha(node.color, 0.2);
ctx.fill();
});
@@ -198,10 +182,12 @@ const GenerativeBanner: React.FC<GenerativeBannerProps> = ({ username, palette,
return () => {
resizeObserver.disconnect();
canvas.removeEventListener('mousemove', handleMouseMove);
canvas.removeEventListener('touchmove', handleTouchMove);
canvas.removeEventListener('mousedown', handleMouseDown);
canvas.removeEventListener('mouseup', handleMouseUp);
if (parent) {
parent.removeEventListener('mousemove', handleMouseMove);
parent.removeEventListener('touchmove', handleTouchMove);
parent.removeEventListener('mousedown', handleMouseDown);
parent.removeEventListener('mouseup', handleMouseUp);
}
cancelAnimationFrame(animationFrameId);
};
}, [username, palette, ratingsCount, followersCount, theme]);
@@ -215,9 +201,9 @@ const GenerativeBanner: React.FC<GenerativeBannerProps> = ({ username, palette,
left: 0,
width: '100%',
height: '100%',
pointerEvents: 'auto', // Enable direct interaction
pointerEvents: 'none',
zIndex: 5,
cursor: 'pointer'
mixBlendMode: 'plus-lighter'
}}
/>
);
+14 -6
View File
@@ -264,15 +264,23 @@ const Dashboard: React.FC = () => {
}}>
<Box sx={{
height: { xs: 100, sm: 140 },
background: `
radial-gradient(at 0% 0%, ${alpha(palette[0] || theme.palette.primary.main, 0.6)} 0px, transparent 55%),
radial-gradient(at 100% 0%, ${alpha(palette[1] || theme.palette.secondary.main, 0.5)} 0px, transparent 55%),
radial-gradient(at 50% 100%, ${alpha(theme.palette.primary.main, 0.3)} 0px, transparent 55%),
linear-gradient(135deg, ${alpha(palette[0] || theme.palette.primary.main, 0.1)} 0%, ${alpha(palette[1] || theme.palette.secondary.main, 0.1)} 100%)
`,
position: 'relative',
overflow: 'hidden'
}}>
{/* Layer 1: Abstract Mesh Background */}
<Box sx={{
position: 'absolute',
top: 0, left: 0, right: 0, bottom: 0,
background: `
radial-gradient(at 0% 0%, ${alpha(palette[0] || theme.palette.primary.main, 0.6)} 0px, transparent 55%),
radial-gradient(at 100% 0%, ${alpha(palette[1] || theme.palette.secondary.main, 0.5)} 0px, transparent 55%),
radial-gradient(at 50% 100%, ${alpha(theme.palette.primary.main, 0.3)} 0px, transparent 55%),
linear-gradient(135deg, ${alpha(palette[0] || theme.palette.primary.main, 0.1)} 0%, ${alpha(palette[1] || theme.palette.secondary.main, 0.1)} 100%)
`,
zIndex: 0
}} />
{/* Layer 2: Interactive Generative Art */}
<GenerativeBanner
username={data.user.username}
palette={palette}
+9 -1
View File
@@ -271,10 +271,18 @@ const PublicProfile: React.FC<PublicProfileProps> = ({ adminMode }) => {
}}>
<Box sx={{
height: { xs: 120, sm: 180 },
background: abstractBanner,
position: 'relative',
overflow: 'hidden'
}}>
{/* Layer 1: Abstract Mesh Background */}
<Box sx={{
position: 'absolute',
top: 0, left: 0, right: 0, bottom: 0,
background: abstractBanner,
zIndex: 0
}} />
{/* Layer 2: Interactive Generative Art */}
<GenerativeBanner
username={data.username}
palette={palette}