Skip to content

Commit

Permalink
Merge pull request #87 from opherlabs/main
Browse files Browse the repository at this point in the history
fix countdown component
  • Loading branch information
mitch1009 authored Sep 19, 2024
2 parents eec6958 + 8e4a379 commit 277487a
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 41 deletions.
2 changes: 1 addition & 1 deletion components/src/app/coming/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {CountdownComponent} from '@/components'
function page() {
return (
<div>
<CountdownComponent targetDate={'2024-09-26T12:00:00'} />
<CountdownComponent url='/api/auth/signin' targetDate={'2024-09-26T12:00:00'} />
</div>
)
}
Expand Down
15 changes: 6 additions & 9 deletions components/src/components/CountDown/AnimatedBackground.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
'use client';

import React, { useState, useEffect, useRef } from 'react';
import { ParticleComponent } from './ParticleComponent';
import dynamic from 'next/dynamic';

const DynamicParticleComponent = dynamic(() => import('./ParticleComponent'), {
ssr: false,
});

export const AnimatedBackground: React.FC = () => {
const canvasRef = useRef<HTMLCanvasElement | null>(null);
Expand Down Expand Up @@ -51,14 +55,7 @@ export const AnimatedBackground: React.FC = () => {
height={dimensions.height}
className="fixed inset-0 pointer-events-none"
/>
{canvasRef.current && Array.from({ length: 100 }).map((_, index) => (
<ParticleComponent
key={index}
context={canvasRef.current?.getContext('2d') ?? null}
width={dimensions.width}
height={dimensions.height}
/>
))}
{canvasRef.current && <DynamicParticleComponent count={100} />}
</>
);
};
111 changes: 80 additions & 31 deletions components/src/components/CountDown/ParticleComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,48 +1,97 @@
'use client';

import React, { useRef, useEffect } from 'react';
import React, { useRef, useEffect, useState } from 'react';

interface Particle {
x: number;
y: number;
dx: number;
dy: number;
size: number;
color: string;
}

interface ParticleProps {
context: CanvasRenderingContext2D | null;
width: number;
height: number;
count: number;
}

export const ParticleComponent: React.FC<ParticleProps> = ({ count }) => {
const canvasRef = useRef<HTMLCanvasElement>(null);
const [isClient, setIsClient] = useState(false);

export const ParticleComponent: React.FC<ParticleProps> = ({ context, width, height }) => {
const x = useRef(Math.random() * width);
const y = useRef(Math.random() * height);
const dx = useRef((Math.random() - 0.5) * 0.5);
const dy = useRef((Math.random() - 0.5) * 0.5);
const color = `hsl(${Math.random() * 360}, 50%, 50%)`;
const size = Math.random() * 3 + 1;
useEffect(() => {
setIsClient(true);
}, []);

const animate = () => {
if (!context) return;
useEffect(() => {
if (!isClient) return;

x.current += dx.current;
if (x.current < 0 || x.current > width) {
dx.current = -dx.current;
x.current = Math.max(0, Math.min(x.current, width));
}
const canvas = canvasRef.current;
if (!canvas) return;

const ctx = canvas.getContext('2d');
if (!ctx) return;

const resizeCanvas = () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
};

resizeCanvas();
window.addEventListener('resize', resizeCanvas);

const particles: Particle[] = [];

y.current += dy.current;
if (y.current < 0 || y.current > height) {
dy.current = -dy.current;
y.current = Math.max(0, Math.min(y.current, height));
for (let i = 0; i < count; i++) {
particles.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
dx: (Math.random() - 0.5) * 2,
dy: (Math.random() - 0.5) * 2,
size: Math.random() * 5 + 1,
color: `hsl(${Math.random() * 360}, 50%, 50%)`,
});
}

context.beginPath();
context.arc(x.current, y.current, size, 0, Math.PI * 2);
context.fillStyle = color;
context.fill();
let animationFrameId: number;

requestAnimationFrame(animate);
};
const animate = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);

particles.forEach((particle) => {
particle.x += particle.dx;
particle.y += particle.dy;

if (particle.x < 0 || particle.x > canvas.width) {
particle.dx = -particle.dx;
}

if (particle.y < 0 || particle.y > canvas.height) {
particle.dy = -particle.dy;
}

ctx.beginPath();
ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2);
ctx.fillStyle = particle.color;
ctx.fill();
});

animationFrameId = requestAnimationFrame(animate);
};

useEffect(() => {
animate();
}, [context, width, height]);

return null;
return () => {
window.removeEventListener('resize', resizeCanvas);
cancelAnimationFrame(animationFrameId);
};
}, [count, isClient]);

if (!isClient) {
return <div className="absolute inset-0 bg-gray-900" />;
}

return <canvas ref={canvasRef} className="absolute inset-0 bg-gray-900" />;
};

export default ParticleComponent;
12 changes: 12 additions & 0 deletions components/tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@ const config: Config = {
],
theme: {
extend: {
keyframes: {
float: {
'0%, 100%': { transform: 'translate(0, 0) rotate(0deg)' },
'25%': { transform: 'translate(150px, -100px) rotate(90deg)' },
'50%': { transform: 'translate(-100px, 200px) rotate(180deg)' },
'75%': { transform: 'translate(-150px, -150px) rotate(270deg)' },
}
},
animation: {
'float': 'float 40s ease-in-out infinite',
},

colors: {
background: "var(--background)",
foreground: "var(--foreground)",
Expand Down

0 comments on commit 277487a

Please sign in to comment.