diff --git a/apps/website/package.json b/apps/website/package.json index fa1d86beb..6d4d518ce 100644 --- a/apps/website/package.json +++ b/apps/website/package.json @@ -28,6 +28,8 @@ "@trpc/client": "next", "@trpc/react-query": "next", "@trpc/server": "next", + "@tsparticles/basic": "^3.5.0", + "@tsparticles/react": "^3.0.0", "@twemoji/api": "^15.1.0", "@uidotdev/usehooks": "^2.4.1", "accept-language": "^3.0.18", diff --git a/apps/website/src/app/components/LandingPage/Background.tsx b/apps/website/src/app/components/LandingPage/Background.tsx new file mode 100644 index 000000000..a355c6455 --- /dev/null +++ b/apps/website/src/app/components/LandingPage/Background.tsx @@ -0,0 +1,535 @@ +import type { ISourceOptions } from "@tsparticles/engine"; +import { memo, useEffect, useMemo, useState } from "react"; +import { loadBasic } from "@tsparticles/basic"; // if you are going to use `loadAll`, install the "@tsparticles/all" package too. +import Particles, { initParticlesEngine } from "@tsparticles/react"; + +import { cn } from "@mc/ui"; + +export const Background = memo(function Background({ + className, +}: { + className?: string; +}) { + const [init, setInit] = useState(false); + + useEffect(() => { + void initParticlesEngine(async (engine) => { + await loadBasic(engine); + }).then(() => { + setInit(true); + }); + }, []); + + const options: ISourceOptions = useMemo( + () => ({ + autoPlay: true, + background: { + color: { + value: "#0c0a09", + }, + image: "", + position: "", + repeat: "", + size: "", + opacity: 1, + }, + backgroundMask: { + composite: "destination-out", + cover: { + color: { + value: "#fff", + }, + opacity: 1, + }, + enable: false, + }, + clear: true, + defaultThemes: {}, + delay: 0, + fullScreen: { + enable: true, + zIndex: -1, + }, + detectRetina: true, + duration: 0, + fpsLimit: 15, + interactivity: { + detectsOn: "window", + events: { + onClick: { + enable: false, + mode: [], + }, + onDiv: { + selectors: [], + enable: false, + mode: [], + type: "circle", + }, + onHover: { + enable: false, + mode: [], + parallax: { + enable: false, + force: 2, + smooth: 10, + }, + }, + resize: { + delay: 0.5, + enable: true, + }, + }, + modes: { + trail: { + delay: 1, + pauseOnStop: false, + quantity: 1, + }, + attract: { + distance: 200, + duration: 0.4, + easing: "ease-out-quad", + factor: 1, + maxSpeed: 50, + speed: 1, + }, + bounce: { + distance: 200, + }, + bubble: { + distance: 200, + duration: 0.4, + mix: false, + divs: { + distance: 200, + duration: 0.4, + mix: false, + selectors: [], + }, + }, + connect: { + distance: 80, + links: { + opacity: 0.5, + }, + radius: 60, + }, + grab: { + distance: 100, + links: { + blink: false, + consent: false, + opacity: 1, + }, + }, + push: { + default: true, + groups: [], + quantity: 4, + }, + remove: { + quantity: 2, + }, + repulse: { + distance: 200, + duration: 0.4, + factor: 100, + speed: 1, + maxSpeed: 50, + easing: "ease-out-quad", + divs: { + distance: 200, + duration: 0.4, + factor: 100, + speed: 1, + maxSpeed: 50, + easing: "ease-out-quad", + selectors: [], + }, + }, + slow: { + factor: 3, + radius: 200, + }, + light: { + area: { + gradient: { + start: { + value: "#ffffff", + }, + stop: { + value: "#000000", + }, + }, + radius: 1000, + }, + shadow: { + color: { + value: "#000000", + }, + length: 2000, + }, + }, + }, + }, + manualParticles: [], + particles: { + bounce: { + horizontal: { + value: 1, + }, + vertical: { + value: 1, + }, + }, + collisions: { + absorb: { + speed: 2, + }, + bounce: { + horizontal: { + value: 1, + }, + vertical: { + value: 1, + }, + }, + enable: false, + maxSpeed: 50, + mode: "bounce", + overlap: { + enable: true, + retries: 0, + }, + }, + color: { + value: "#fff", + animation: { + h: { + count: 0, + enable: false, + speed: 1, + decay: 0, + delay: 0, + sync: true, + offset: 0, + }, + s: { + count: 0, + enable: false, + speed: 1, + decay: 0, + delay: 0, + sync: true, + offset: 0, + }, + l: { + count: 0, + enable: false, + speed: 1, + decay: 0, + delay: 0, + sync: true, + offset: 0, + }, + }, + }, + effect: { + close: true, + fill: true, + options: {}, + type: [], + }, + groups: {}, + move: { + angle: { + offset: 0, + value: 90, + }, + attract: { + distance: 200, + enable: false, + rotate: { + x: 3000, + y: 3000, + }, + }, + center: { + x: 50, + y: 50, + mode: "percent", + radius: 0, + }, + decay: 0, + distance: {}, + direction: "none", + drift: 0, + enable: false, + gravity: { + acceleration: 9.81, + enable: false, + inverse: false, + maxSpeed: 50, + }, + path: { + clamp: true, + delay: { + value: 0, + }, + enable: false, + options: {}, + }, + outModes: { + default: "out", + bottom: "out", + left: "out", + right: "out", + top: "out", + }, + random: false, + size: false, + speed: 2, + spin: { + acceleration: 0, + enable: false, + }, + straight: false, + trail: { + enable: false, + length: 10, + fill: {}, + }, + vibrate: false, + warp: false, + }, + number: { + density: { + enable: true, + width: 1920, + height: 1080, + }, + limit: { + mode: "delete", + value: 0, + }, + value: 200, + }, + opacity: { + value: { + min: 0.1, + max: 1, + }, + animation: { + count: 0, + enable: true, + speed: 0.25, + decay: 0, + delay: 0, + sync: false, + mode: "auto", + startValue: "random", + destroy: "none", + }, + }, + reduceDuplicates: false, + shadow: { + blur: 0, + color: { + value: "#000", + }, + enable: false, + offset: { + x: 0, + y: 0, + }, + }, + shape: { + close: true, + fill: true, + options: {}, + type: "circle", + }, + size: { + value: 1, + animation: { + count: 0, + enable: false, + speed: 5, + decay: 0, + delay: 0, + sync: false, + mode: "auto", + startValue: "random", + destroy: "none", + }, + }, + stroke: { + width: 0, + }, + zIndex: { + value: 0, + opacityRate: 1, + sizeRate: 1, + velocityRate: 1, + }, + destroy: { + bounds: {}, + mode: "none", + split: { + count: 1, + factor: { + value: 3, + }, + rate: { + value: { + min: 4, + max: 9, + }, + }, + sizeOffset: true, + particles: {}, + }, + }, + roll: { + darken: { + enable: false, + value: 0, + }, + enable: false, + enlighten: { + enable: false, + value: 0, + }, + mode: "vertical", + speed: 25, + }, + tilt: { + value: 0, + animation: { + enable: false, + speed: 0, + decay: 0, + sync: false, + }, + direction: "clockwise", + enable: false, + }, + twinkle: { + lines: { + enable: false, + frequency: 0.05, + opacity: 1, + }, + particles: { + enable: false, + frequency: 0.05, + opacity: 1, + }, + }, + wobble: { + distance: 5, + enable: false, + speed: { + angle: 50, + move: 10, + }, + }, + life: { + count: 0, + delay: { + value: 0, + sync: false, + }, + duration: { + value: 0, + sync: false, + }, + }, + rotate: { + value: 0, + animation: { + enable: false, + speed: 0, + decay: 0, + sync: false, + }, + direction: "clockwise", + path: false, + }, + orbit: { + animation: { + count: 0, + enable: false, + speed: 1, + decay: 0, + delay: 0, + sync: false, + }, + enable: false, + opacity: 1, + rotation: { + value: 45, + }, + width: 1, + }, + links: { + blink: false, + color: { + value: "#fff", + }, + consent: false, + distance: 100, + enable: false, + frequency: 1, + opacity: 1, + shadow: { + blur: 5, + color: { + value: "#000", + }, + enable: false, + }, + triangles: { + enable: false, + frequency: 1, + }, + width: 1, + warp: false, + }, + repulse: { + value: 0, + enabled: false, + distance: 1, + duration: 1, + factor: 1, + speed: 1, + }, + }, + pauseOnBlur: true, + pauseOnOutsideViewport: true, + responsive: [], + smooth: false, + style: {}, + themes: [], + zLayers: 100, + emitters: [], + motion: { + disable: false, + reduce: { + factor: 4, + value: true, + }, + }, + }), + [], + ); + + if (init) { + return ( + + ); + } + + return <>; +}); diff --git a/apps/website/src/app/components/LandingPage/index.tsx b/apps/website/src/app/components/LandingPage/index.tsx index f650f6193..a9900e481 100644 --- a/apps/website/src/app/components/LandingPage/index.tsx +++ b/apps/website/src/app/components/LandingPage/index.tsx @@ -16,7 +16,7 @@ import { Button } from "@mc/ui/button"; import { BotIcon } from "../BotIcon"; import { DiscordIcon } from "../DiscordIcon"; -import bgImage from "./bg.png"; +import { Background } from "./Background"; import { DiscordDemo } from "./DiscordDemo"; import { SupportedCounters } from "./SupportedCounters"; @@ -60,12 +60,7 @@ export default function LandingPage() { return (
- +
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dfaf212ad..359e68ab6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -146,13 +146,19 @@ importers: version: 5.59.0(react@18.3.1) '@trpc/client': specifier: next - version: 11.0.0-rc.553(@trpc/server@11.0.0-rc.553) + version: 11.0.0-rc.580(@trpc/server@11.0.0-rc.580) '@trpc/react-query': specifier: next - version: 11.0.0-rc.553(@tanstack/react-query@5.59.0(react@18.3.1))(@trpc/client@11.0.0-rc.553(@trpc/server@11.0.0-rc.553))(@trpc/server@11.0.0-rc.553)(react-dom@18.2.0(react@18.3.1))(react@18.3.1) + version: 11.0.0-rc.580(@tanstack/react-query@5.59.0(react@18.3.1))(@trpc/client@11.0.0-rc.580(@trpc/server@11.0.0-rc.580))(@trpc/server@11.0.0-rc.580)(react-dom@18.2.0(react@18.3.1))(react@18.3.1) '@trpc/server': specifier: next - version: 11.0.0-rc.553 + version: 11.0.0-rc.580 + '@tsparticles/basic': + specifier: ^3.5.0 + version: 3.5.0 + '@tsparticles/react': + specifier: ^3.0.0 + version: 3.0.0(@tsparticles/engine@3.5.0)(react-dom@18.2.0(react@18.3.1))(react@18.3.1) '@twemoji/api': specifier: ^15.1.0 version: 15.1.0 @@ -315,10 +321,10 @@ importers: version: 1.2.1(ioredis@5.4.1) '@trpc/client': specifier: next - version: 11.0.0-rc.553(@trpc/server@11.0.0-rc.553) + version: 11.0.0-rc.580(@trpc/server@11.0.0-rc.580) '@trpc/server': specifier: next - version: 11.0.0-rc.553 + version: 11.0.0-rc.580 discord.js: specifier: ^14.15.2 version: 14.15.2(bufferutil@4.0.8)(utf-8-validate@6.0.3) @@ -533,7 +539,7 @@ importers: version: 11.0.0-next-beta.216 '@trpc/server': specifier: next - version: 11.0.0-rc.553 + version: 11.0.0-rc.580 ioredis: specifier: ^5.4.1 version: 5.4.1 @@ -2230,25 +2236,25 @@ packages: '@total-typescript/ts-reset@0.5.1': resolution: {integrity: sha512-AqlrT8YA1o7Ff5wPfMOL0pvL+1X+sw60NN6CcOCqs658emD6RfiXhF7Gu9QcfKBH7ELY2nInLhKSCWVoNL70MQ==} - '@trpc/client@11.0.0-rc.553': - resolution: {integrity: sha512-ICgziilbuAslRgHIVJZ162KaHQRpHXA1C1LPRsNpxPa9aStPF7eThAjn4V3JmDyJsuDLQgAmqLVRImlLPMYR5Q==} + '@trpc/client@11.0.0-rc.580': + resolution: {integrity: sha512-lQ2iRZyUprtyrcIS9388ZIgxhPp/j9632FqDPcKO8LrFgPshT+hbQtS+vSJh7eGv8QlsNDyxLRSIgGhoR4NcDA==} peerDependencies: - '@trpc/server': 11.0.0-rc.553+9b629cc67 + '@trpc/server': 11.0.0-rc.580+26ac97c0e '@trpc/core@11.0.0-next-beta.216': resolution: {integrity: sha512-dmdSFeSzArkmdZvnymoQwAju0QBODC3PhLgBKTYgVIj0HATE/OJsPAKOxiqdcgm3YyN/zABm+ntiYmjLBJzTCA==} - '@trpc/react-query@11.0.0-rc.553': - resolution: {integrity: sha512-m88HBhpfIDJccJCXycHtkGS82RG2TVPsZUFIWswR8m6ip5eFNmqWASanu7DiiFbY6sufLT1S8ee28towrPUgoA==} + '@trpc/react-query@11.0.0-rc.580': + resolution: {integrity: sha512-dVUuQVzFWLLqjgvLtlqQ+gSnsdIdqvkR3/Fh0aV2mzTIKxIspqk9AQwcIyEy/0HlV7EV4S7xpvOSQ5SDD9qplw==} peerDependencies: - '@tanstack/react-query': ^5.54.1 - '@trpc/client': 11.0.0-rc.553+9b629cc67 - '@trpc/server': 11.0.0-rc.553+9b629cc67 + '@tanstack/react-query': ^5.59.15 + '@trpc/client': 11.0.0-rc.580+26ac97c0e + '@trpc/server': 11.0.0-rc.580+26ac97c0e react: '>=18.2.0' react-dom: '>=18.2.0' - '@trpc/server@11.0.0-rc.553': - resolution: {integrity: sha512-pYUhxV3QU834jP1ugJk1uhtPwwaY1ymIuupb4DiWOhNCl68syuXPlUdD8IYsYKd3BjLkmnjlsOUMoyd/aoOF/Q==} + '@trpc/server@11.0.0-rc.580': + resolution: {integrity: sha512-2XYvKJlfWQqO8m20iWlUWuh/65HTPAo/r/zekCIt/uHGDXuUp7EQPxuyqzjcC8TG70W0Cw5cTZs1OK71E7Hbjg==} '@tsconfig/node10@1.0.11': resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} @@ -2262,6 +2268,37 @@ packages: '@tsconfig/node16@1.0.4': resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + '@tsparticles/basic@3.5.0': + resolution: {integrity: sha512-oty33TxM2aHWrzcwWRic1bQ04KBCdpnvzv8JXEkx5Uyp70vgVegUbtKmwGki3shqKZIt3v2qE4I8NsK6onhLrA==} + + '@tsparticles/engine@3.5.0': + resolution: {integrity: sha512-RCwrJ2SvSYdhXJ24oUCjSUKEZQ9lXwObOWMvfMC9vS6/bk+Qo0N7Xx8AfumqzP/LebB1YJdlCvuoJMauAon0Pg==} + + '@tsparticles/move-base@3.5.0': + resolution: {integrity: sha512-9oDk7zTxyhUCstj3lHTNTiWAgqIBzWa2o1tVQFK63Qwq+/WxzJCSwZOocC9PAHGM1IP6nA4zYJSfjbMBTrUocA==} + + '@tsparticles/react@3.0.0': + resolution: {integrity: sha512-hjGEtTT1cwv6BcjL+GcVgH++KYs52bIuQGW3PWv7z3tMa8g0bd6RI/vWSLj7p//NZ3uTjEIeilYIUPBh7Jfq/Q==} + peerDependencies: + '@tsparticles/engine': ^3.0.2 + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@tsparticles/shape-circle@3.5.0': + resolution: {integrity: sha512-59TmXkeeI6Jzv5vt/D3TkclglabaoEXQi2kbDjSCBK68SXRHzlQu29mSAL41Y5S0Ft5ZJKkAQHX1IqEnm8Hyjg==} + + '@tsparticles/updater-color@3.5.0': + resolution: {integrity: sha512-TGGgiLixIg37sst2Fj9IV4XbdMwkT6PYanM7qEqyfmv4hJ/RHMQlCznEe6b7OhChQVBg5ov5EMl/BT4/fIWEYw==} + + '@tsparticles/updater-opacity@3.5.0': + resolution: {integrity: sha512-T2YfqdIFV/f5VOg1JQsXu6/owdi9g9K2wrJlBfgteo+IboVp6Lcuo4PGAfilWVkWrTdp1Nz4mz39NrLHfOce2g==} + + '@tsparticles/updater-out-modes@3.5.0': + resolution: {integrity: sha512-y6NZe2OSk5SrYdaLwUIQnHICsNEDIdPPJHQ2nAWSvAuPJphlSKjUknc7OaGiFwle6l0OkhWoZZe1rV1ktbw/lA==} + + '@tsparticles/updater-size@3.5.0': + resolution: {integrity: sha512-TnWlOChBsVZffT2uO0S4ALGSzxT6UAMIVlhGMGFgSeIlktKMqM+dxDGAPrYa1n8IS2dkVGisiXzsV0Ss6Ceu1A==} + '@turbo/gen@2.0.6': resolution: {integrity: sha512-Epv3tt40mrNCzL6XKELdHvM1KSYvY7bg4uRZAjS0SuYYY5E0gGjpeZPqqUNZl7fwmTHZLEZH5qqoKxbGWZsKXQ==} hasBin: true @@ -6638,21 +6675,21 @@ snapshots: '@total-typescript/ts-reset@0.5.1': {} - '@trpc/client@11.0.0-rc.553(@trpc/server@11.0.0-rc.553)': + '@trpc/client@11.0.0-rc.580(@trpc/server@11.0.0-rc.580)': dependencies: - '@trpc/server': 11.0.0-rc.553 + '@trpc/server': 11.0.0-rc.580 '@trpc/core@11.0.0-next-beta.216': {} - '@trpc/react-query@11.0.0-rc.553(@tanstack/react-query@5.59.0(react@18.3.1))(@trpc/client@11.0.0-rc.553(@trpc/server@11.0.0-rc.553))(@trpc/server@11.0.0-rc.553)(react-dom@18.2.0(react@18.3.1))(react@18.3.1)': + '@trpc/react-query@11.0.0-rc.580(@tanstack/react-query@5.59.0(react@18.3.1))(@trpc/client@11.0.0-rc.580(@trpc/server@11.0.0-rc.580))(@trpc/server@11.0.0-rc.580)(react-dom@18.2.0(react@18.3.1))(react@18.3.1)': dependencies: '@tanstack/react-query': 5.59.0(react@18.3.1) - '@trpc/client': 11.0.0-rc.553(@trpc/server@11.0.0-rc.553) - '@trpc/server': 11.0.0-rc.553 + '@trpc/client': 11.0.0-rc.580(@trpc/server@11.0.0-rc.580) + '@trpc/server': 11.0.0-rc.580 react: 18.3.1 react-dom: 18.2.0(react@18.3.1) - '@trpc/server@11.0.0-rc.553': {} + '@trpc/server@11.0.0-rc.580': {} '@tsconfig/node10@1.0.11': {} @@ -6662,6 +6699,48 @@ snapshots: '@tsconfig/node16@1.0.4': {} + '@tsparticles/basic@3.5.0': + dependencies: + '@tsparticles/engine': 3.5.0 + '@tsparticles/move-base': 3.5.0 + '@tsparticles/shape-circle': 3.5.0 + '@tsparticles/updater-color': 3.5.0 + '@tsparticles/updater-opacity': 3.5.0 + '@tsparticles/updater-out-modes': 3.5.0 + '@tsparticles/updater-size': 3.5.0 + + '@tsparticles/engine@3.5.0': {} + + '@tsparticles/move-base@3.5.0': + dependencies: + '@tsparticles/engine': 3.5.0 + + '@tsparticles/react@3.0.0(@tsparticles/engine@3.5.0)(react-dom@18.2.0(react@18.3.1))(react@18.3.1)': + dependencies: + '@tsparticles/engine': 3.5.0 + react: 18.3.1 + react-dom: 18.2.0(react@18.3.1) + + '@tsparticles/shape-circle@3.5.0': + dependencies: + '@tsparticles/engine': 3.5.0 + + '@tsparticles/updater-color@3.5.0': + dependencies: + '@tsparticles/engine': 3.5.0 + + '@tsparticles/updater-opacity@3.5.0': + dependencies: + '@tsparticles/engine': 3.5.0 + + '@tsparticles/updater-out-modes@3.5.0': + dependencies: + '@tsparticles/engine': 3.5.0 + + '@tsparticles/updater-size@3.5.0': + dependencies: + '@tsparticles/engine': 3.5.0 + '@turbo/gen@2.0.6(@types/node@20.12.13)(typescript@5.4.5)': dependencies: '@turbo/workspaces': 2.0.6