From b8bf51093439eb72cbeb316e9164dd7a2e725303 Mon Sep 17 00:00:00 2001 From: Noman Dhoni Date: Tue, 19 Nov 2024 15:21:24 +0600 Subject: [PATCH 1/7] Added shooting meteor background --- src/components/ReminderStyles.tsx | 4 +- src/components/backgrounds/ShootingMeteor.tsx | 99 +++++++++++++++++++ src/components/window/Reminder.tsx | 3 + .../window/ReminderPreviewWindow.tsx | 3 + tailwind.config.js | 9 ++ 5 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 src/components/backgrounds/ShootingMeteor.tsx diff --git a/src/components/ReminderStyles.tsx b/src/components/ReminderStyles.tsx index e4ffa3f..edaebc8 100644 --- a/src/components/ReminderStyles.tsx +++ b/src/components/ReminderStyles.tsx @@ -4,6 +4,7 @@ import { WebviewWindow } from "@tauri-apps/api/webviewWindow"; import { Flame, Loader2 } from "lucide-react"; import { usePremiumFeatures } from "../contexts/PremiumFeaturesContext"; import { Button } from "./ui/button"; +import ShootingMeteor from "./backgrounds/ShootingMeteor"; const styles = [ { value: "default", label: "Default" }, @@ -12,6 +13,7 @@ const styles = [ { value: "canvasShapes", label: "Bouncy Balls" }, { value: "particleBackground", label: "Infinite Wave Background" }, { value: "starryBackground", label: "Starry Background" }, + { value: "shootingmeteor", label: "Shooting Meteor" }, ]; export default function ReminderStyles() { @@ -130,7 +132,7 @@ export default function ReminderStyles() { ? "bg-primary/20" : "bg-secondary" }`} - /> + > ))} diff --git a/src/components/backgrounds/ShootingMeteor.tsx b/src/components/backgrounds/ShootingMeteor.tsx new file mode 100644 index 0000000..82edb52 --- /dev/null +++ b/src/components/backgrounds/ShootingMeteor.tsx @@ -0,0 +1,99 @@ +import React, { useEffect, useRef } from "react"; + +const ShootingMeteor: React.FC<{ number?: number }> = ({ number = 20 }) => { + const canvasRef = useRef(null); + + useEffect(() => { + const canvas = canvasRef.current; + if (!canvas) return; + + const ctx = canvas.getContext("2d"); + if (!ctx) return; + + // Generate meteor data + const meteors = Array.from({ length: number }, () => ({ + x: Math.random() * canvas.width, + y: (Math.random() * canvas.height) / 2, // Start in the upper half + length: Math.random() * 50 + 30, + speedX: Math.random() * 1.5 + 0.5, // Slower horizontal speed + speedY: Math.random() * 1.5 + 0.5, // Slower vertical speed + opacity: Math.random() * 0.5 + 0.5, + })); + + const updateCanvasSize = () => { + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; + }; + + const drawMeteor = (meteor: (typeof meteors)[0]) => { + ctx.save(); + ctx.globalAlpha = meteor.opacity; + + // Create gradient for the meteor trail + const gradient = ctx.createLinearGradient( + meteor.x, + meteor.y, + meteor.x + meteor.length, + meteor.y + meteor.length + ); + gradient.addColorStop(0, "transparent"); + gradient.addColorStop(1, "#64748b"); + + ctx.strokeStyle = gradient; + ctx.lineWidth = 3; + + // Draw the meteor + ctx.beginPath(); + ctx.moveTo(meteor.x, meteor.y); + ctx.lineTo(meteor.x + meteor.length, meteor.y + meteor.length); + ctx.stroke(); + ctx.restore(); + }; + + const updateMeteor = (meteor: (typeof meteors)[0]) => { + meteor.x += meteor.speedX; + meteor.y += meteor.speedY; + + // Reset meteor if it moves off screen + if (meteor.x > canvas.width || meteor.y > canvas.height) { + meteor.x = Math.random() * canvas.width; + meteor.y = (Math.random() * canvas.height) / 2; + meteor.length = Math.random() * 50 + 30; + meteor.speedX = Math.random() * 1.5 + 0.5; // Reset slower speed + meteor.speedY = Math.random() * 1.5 + 0.5; + meteor.opacity = Math.random() * 0.5 + 0.5; + } + }; + + const animate = () => { + ctx.clearRect(0, 0, canvas.width, canvas.height); + meteors.forEach((meteor) => { + drawMeteor(meteor); + updateMeteor(meteor); + }); + requestAnimationFrame(animate); + }; + + updateCanvasSize(); + animate(); + + const handleResize = () => { + updateCanvasSize(); + }; + window.addEventListener("resize", handleResize); + + return () => { + window.removeEventListener("resize", handleResize); + }; + }, [number]); + + return ( +