From b6ef4f8a3b7fc9463482120de3910071a8514450 Mon Sep 17 00:00:00 2001 From: Max Wofford Date: Thu, 9 Nov 2023 11:19:15 -0500 Subject: [PATCH] Create initial OnBoard page for FIRST Co-Authored-By: Lexi Mattick --- pages/onboard/first.js | 1193 ++++++++++++++++++++++++ pages/{onboard.js => onboard/index.js} | 14 +- 2 files changed, 1200 insertions(+), 7 deletions(-) create mode 100644 pages/onboard/first.js rename pages/{onboard.js => onboard/index.js} (99%) diff --git a/pages/onboard/first.js b/pages/onboard/first.js new file mode 100644 index 000000000..98ebd6651 --- /dev/null +++ b/pages/onboard/first.js @@ -0,0 +1,1193 @@ +import { Box, Button, Flex, Grid, Heading, Image, Link, Text } from "theme-ui"; +import Balancer from "react-wrap-balancer"; +import Head from "next/head"; +import Meta from "@hackclub/meta"; +import Nav from "../../components/nav"; +import Footer from "../../components/footer"; +import FadeIn from "../../components/fade-in"; +import Sparkles from "../../components/sparkles"; +import Tilt from "../../components/tilt"; +import usePrefersReducedMotion from "../../lib/use-prefers-reduced-motion"; +import { useEffect, useRef, useState } from "react"; + +/** + * @type {import('theme-ui').ThemeUIStyleObject} + */ +const traceSx = { + width: 6, + bg: '#e2b747', + alignSelf: 'stretch', + mr: 100, + position: 'relative' +} + +const dimBg = '#151515' + +// Beloved classic utility function :3 +const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)) + +// "LET'S RECAP" pixel art (exported from Piskel) +// Original: https://doggo.ninja/fiK0nk.piskel +const recapWidth = 71 +const recapHeight = 10 +const recapPixels = [ + 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, + 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, + 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, + 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, + 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, + 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, + 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, + 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, + 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, + 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, + 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, + 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, + 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, + 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, + 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, + 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, + 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, + 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, + 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, + 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, + 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, + 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, + 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, + 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, + 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, + 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, + 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, + 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, + 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, + 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, + 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, + 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, + 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, + 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xffffffff, 0xffffffff +] + +const slackLink = '/slack/?event=onboard' + +const stickerButtonText = 'Click 4 Stickers' +const stickerButtonFont = 'Oleo Script' +const stickerButtonFontStylesheet = `https://fonts.googleapis.com/css2?family=${encodeURIComponent( + stickerButtonFont +)}&display=swap&text=${encodeURIComponent(stickerButtonText)}` + +const wandImgTraced = + 'https://cloud-gcy8oasci-hack-club-bot.vercel.app/0back.svg' +const wandImgRendered = + 'https://cloud-kg2rvjz19-hack-club-bot.vercel.app/0front.svg' + +const ShipPage = () => { + const prefersReducedMotion = usePrefersReducedMotion() + + // Wand flicker animation + const [wandImg, setWandImg] = useState(wandImgTraced) + const wandAnimated = useRef(false) + useEffect(() => { + let canceled = false + + const flicker = async () => { + if (canceled) return + setWandImg(wandImgTraced) + await sleep(Math.random() * 80 + 10) + if (canceled) return + setWandImg(wandImgRendered) + setTimeout(flicker, Math.random() * 4000 + 500) + } + + const animate = async () => { + if (wandAnimated.current) return + wandAnimated.current = true + + await sleep(1500) + if (canceled) return + + setWandImg(wandImgRendered) + await sleep(60) + if (canceled) return + setWandImg(wandImgTraced) + await sleep(340) + if (canceled) return + + setWandImg(wandImgRendered) + await sleep(14) + if (canceled) return + setWandImg(wandImgTraced) + await sleep(55) + if (canceled) return + + setWandImg(wandImgRendered) + await sleep(10) + if (canceled) return + setWandImg(wandImgTraced) + await sleep(150) + if (canceled) return + + setWandImg(wandImgRendered) + setTimeout(flicker, 1200) + } + + if (prefersReducedMotion) { + setWandImg(wandImgRendered) + } else { + animate() + } + + return () => (canceled = true) + }, [prefersReducedMotion]) + + // Spotlight effect + const spotlightRef = useRef() + useEffect(() => { + const handler = event => { + spotlightRef.current.style.background = `radial-gradient( + circle at ${event.pageX}px ${event.pageY}px, + rgba(0, 0, 0, 0) 10px, + rgba(0, 0, 0, 0.8) 80px + )` + } + window.addEventListener('mousemove', handler) + return () => window.removeEventListener('mousemove', handler) + }, []) + + // Calculating the bus height to match the bottom left of the first connector. + const [busHeight, setBusHeight] = useState(null) + const containerRef = useRef() // For ResizeObserver + const connectorRef = useRef() // To get bottom left position + const busRef = useRef() // To calculate height differential + + useEffect(() => { + const observer = new ResizeObserver(() => { + const connectorRect = connectorRef.current.getBoundingClientRect() + const busRect = busRef.current.getBoundingClientRect() + setBusHeight(busRect.bottom - connectorRect.bottom + 4.5) + }) + + observer.observe(containerRef.current) + return () => observer.disconnect() + }, []) + + // Fancy lights animation + const lightsScrollTrigger = useRef() + const lightsAnimated = useRef(false) + useEffect(() => { + let canceled = false + + const setAtIndex = (i, color) => { + if (canceled) return + + // Going outside of React for performance + const el = document.getElementById(`pixel-${i}`) + if (!el) return + + if (recapPixels[i]) { + el.style.background = color + el.style.boxShadow = `0 0 10px ${color}` + } else { + el.style.background = dimBg + el.style.boxShadow = 'none' + } + } + const setAll = color => { + for (let i = 0; i < recapPixels.length; i++) setAtIndex(i, color) + } + + const animate = async () => { + if (lightsAnimated.current) return + lightsAnimated.current = true + + // Illuminate lights in diagonal lines starting with only top left. + for ( + let curColumn = 0; + curColumn < recapWidth + recapHeight; + curColumn++ + ) { + for ( + let offset = curColumn; + offset >= Math.max(0, curColumn - recapHeight); + offset-- + ) { + const i = curColumn * recapWidth + offset - offset * recapWidth + setAtIndex(i, '#ffffff') + if (!recapPixels[i]) await sleep(4) + if (canceled) return + } + // await sleep(2); if (canceled) return + } + + // Flash the lights twice + await sleep(600) + if (canceled) return + + setAll(dimBg) + await sleep(80) + if (canceled) return + + setAll('#aaaaaa') + await sleep(20) + if (canceled) return + + setAll(dimBg) + await sleep(30) + if (canceled) return + + setAll('#aaaaaa') + await sleep(100) + if (canceled) return + + setAll(dimBg) + await sleep(200) + if (canceled) return + + // Animate rainbow 2-column increments + for (let x = 0; x < recapWidth; x++) { + const color = `hsl(${(x * 360) / recapWidth}, 100%, 65%)` + for (let y = 0; y < recapHeight; y++) { + const i = y * recapWidth + x + setAtIndex(i, color) + } + if (x % 2 === 1) await sleep(35) + } + } + + if (prefersReducedMotion) { + if (!lightsAnimated.current) setAll('#ffffff') + return () => (canceled = true) + } else { + const observer = new IntersectionObserver( + ([entry]) => { + if (entry.isIntersecting) animate() + }, + { threshold: 0.5 } + ) + observer.observe(lightsScrollTrigger.current) + return () => { + canceled = true + observer.disconnect() + } + } + }, [prefersReducedMotion]) + + return ( + <> + + + + + + + + +