From 49e6152c288280fe1dd42f50e5d8a1e5317f9d71 Mon Sep 17 00:00:00 2001 From: Nikolaj Frey Date: Tue, 4 Jul 2023 19:16:41 +1000 Subject: [PATCH] feat: main Progress --- remix/app/components/Rainbow/Rainbow.tsx | 145 ++++++++++++++++++++++- remix/app/routes/index.tsx | 2 +- 2 files changed, 143 insertions(+), 4 deletions(-) diff --git a/remix/app/components/Rainbow/Rainbow.tsx b/remix/app/components/Rainbow/Rainbow.tsx index 1846589..de9fb16 100644 --- a/remix/app/components/Rainbow/Rainbow.tsx +++ b/remix/app/components/Rainbow/Rainbow.tsx @@ -1,14 +1,153 @@ import React from "react" -import { Box } from "@chakra-ui/react" +import { Box, Center } from "@chakra-ui/react" +import { GradientPath } from "gradient-path" export const Rainbow = (props: any): JSX.Element => { const rainbow = ["#f34a4a", "#ffbc48", "#58ca70", "#47b5e6", "#a555e8"] const [colors, setColors] = React.useState(props?.colors || rainbow) + const repeatedColours = React.useMemo(() => { + return [...colors, colors[0]] + }, [colors]) + + // make SVG that takes makes path in the shape of a box + // which adjusts to the parent containers size + + const [strokeWidth, setStrokeWidth] = React.useState(1) + + const [extraStroke, setExtraStroke] = React.useState(0) + + const [width, setWidth] = React.useState(props?.width || "105%") + const [height, setHeight] = React.useState(props?.height || "105%") + + const pathString = React.useMemo(() => { + const startPoint = 0 + strokeWidth / 2 + const endPoint = 100 - strokeWidth / 2 + + return `M -${4} ${startPoint} H ${endPoint} V ${endPoint} H ${startPoint} V ${startPoint}` + }, [strokeWidth]) + + const viewBox = React.useMemo(() => { + return `0 0 100 100` + }, []) + + const svgRef = React.useRef(null) + + const svg = React.useMemo(() => { + return ( + + + + {/* */} + + + ) + }, [pathString, strokeWidth, extraStroke, viewBox]) + + React.useEffect(() => { + const path = svgRef.current.querySelector("rect") + + if (path) { + const gp = new GradientPath({ + path, + segments: props?.segments || 2000, + samples: props?.samples || 10, + precision: props?.precision || 10, + }) + + const colors = repeatedColours?.map((color, idx) => { + return { + color, + pos: idx / (repeatedColours.length - 1), + } + }) + + gp.render({ + type: "path", + width: 10, + fill: colors, + strokeWidth: 1, + stroke: colors, + }) + + let prevColours = colors + + const interval = setInterval(() => { + // pop first colour and append new first colour to end + const prevColoursClone = prevColours.map((colour) => { + return { + ...colour, + } + }) + const newColoursStart = prevColoursClone.slice(1) + const newColours = [...newColoursStart, { ...newColoursStart[0] }] + + const adjustedPosition = newColours.map((colour, idx) => { + return { + ...colour, + pos: idx / (newColours.length - 1), + } + }) + + prevColours = adjustedPosition + + gp.render({ + type: "path", + width: 10, + fill: adjustedPosition, + strokeWidth: 1, + stroke: adjustedPosition, + }) + }, 1000) + + return () => { + clearInterval(interval) + } + } + }, []) + return ( - +
{props?.children} - +
+ + {svg} + +
+
) } diff --git a/remix/app/routes/index.tsx b/remix/app/routes/index.tsx index aba5941..ec82d63 100644 --- a/remix/app/routes/index.tsx +++ b/remix/app/routes/index.tsx @@ -19,7 +19,7 @@ export default function Index() { > - +