tooling overhaul

This commit is contained in:
itsMapleLeaf
2023-08-16 19:32:28 -05:00
parent 7ac1a9cdce
commit e9e5a1617b
111 changed files with 6758 additions and 6156 deletions

View File

@@ -5,191 +5,191 @@ import cursorIbeamUrl from "~/assets/cursor-ibeam.png"
import cursorUrl from "~/assets/cursor.png"
const defaultState = {
chatInputText: "",
chatInputCursorVisible: true,
messageVisible: false,
count: 0,
cursorLeft: "25%",
cursorBottom: "-15px",
chatInputText: "",
chatInputCursorVisible: true,
messageVisible: false,
count: 0,
cursorLeft: "25%",
cursorBottom: "-15px",
}
const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))
const animationFrame = () =>
new Promise((resolve) => requestAnimationFrame(resolve))
new Promise((resolve) => requestAnimationFrame(resolve))
export function LandingAnimation() {
const [state, setState] = useState(defaultState)
const chatInputRef = useRef<HTMLDivElement>(null)
const addRef = useRef<HTMLDivElement>(null)
const deleteRef = useRef<HTMLDivElement>(null)
const cursorRef = useRef<HTMLImageElement>(null)
const [state, setState] = useState(defaultState)
const chatInputRef = useRef<HTMLDivElement>(null)
const addRef = useRef<HTMLDivElement>(null)
const deleteRef = useRef<HTMLDivElement>(null)
const cursorRef = useRef<HTMLImageElement>(null)
useEffect(() => {
const animateClick = (element: HTMLElement) =>
element.animate(
[{ transform: `translateY(2px)` }, { transform: `translateY(0px)` }],
300,
)
useEffect(() => {
const animateClick = (element: HTMLElement) =>
element.animate(
[{ transform: `translateY(2px)` }, { transform: `translateY(0px)` }],
300,
)
let running = true
let running = true
void (async () => {
while (running) {
setState(defaultState)
await delay(700)
void (async () => {
while (running) {
setState(defaultState)
await delay(700)
for (const letter of "/counter") {
setState((state) => ({
...state,
chatInputText: state.chatInputText + letter,
}))
await delay(100)
}
for (const letter of "/counter") {
setState((state) => ({
...state,
chatInputText: state.chatInputText + letter,
}))
await delay(100)
}
await delay(1000)
await delay(1000)
setState((state) => ({
...state,
messageVisible: true,
chatInputText: "",
}))
await delay(1000)
setState((state) => ({
...state,
messageVisible: true,
chatInputText: "",
}))
await delay(1000)
setState((state) => ({
...state,
cursorLeft: "70px",
cursorBottom: "40px",
}))
await delay(1500)
setState((state) => ({
...state,
cursorLeft: "70px",
cursorBottom: "40px",
}))
await delay(1500)
for (let i = 0; i < 3; i++) {
setState((state) => ({
...state,
count: state.count + 1,
chatInputCursorVisible: false,
}))
animateClick(addRef.current!)
await delay(700)
}
for (let i = 0; i < 3; i++) {
setState((state) => ({
...state,
count: state.count + 1,
chatInputCursorVisible: false,
}))
animateClick(addRef.current!)
await delay(700)
}
await delay(500)
await delay(500)
setState((state) => ({
...state,
cursorLeft: "140px",
}))
await delay(1000)
setState((state) => ({
...state,
cursorLeft: "140px",
}))
await delay(1000)
animateClick(deleteRef.current!)
setState((state) => ({ ...state, messageVisible: false }))
await delay(1000)
animateClick(deleteRef.current!)
setState((state) => ({ ...state, messageVisible: false }))
await delay(1000)
setState(() => ({
...defaultState,
chatInputCursorVisible: false,
}))
await delay(500)
}
})()
setState(() => ({
...defaultState,
chatInputCursorVisible: false,
}))
await delay(500)
}
})()
return () => {
running = false
}
}, [])
return () => {
running = false
}
}, [])
useEffect(() => {
let running = true
useEffect(() => {
let running = true
void (async () => {
while (running) {
// check if the cursor is in the input
const cursorRect = cursorRef.current!.getBoundingClientRect()
const chatInputRect = chatInputRef.current!.getBoundingClientRect()
void (async () => {
while (running) {
// check if the cursor is in the input
const cursorRect = cursorRef.current!.getBoundingClientRect()
const chatInputRect = chatInputRef.current!.getBoundingClientRect()
const isOverInput =
cursorRef.current &&
chatInputRef.current &&
cursorRect.top + cursorRect.height / 2 > chatInputRect.top
const isOverInput =
cursorRef.current &&
chatInputRef.current &&
cursorRect.top + cursorRect.height / 2 > chatInputRect.top
cursorRef.current!.src = isOverInput ? cursorIbeamUrl : cursorUrl
cursorRef.current!.src = isOverInput ? cursorIbeamUrl : cursorUrl
await animationFrame()
}
})()
await animationFrame()
}
})()
return () => {
running = false
}
})
return () => {
running = false
}
})
return (
<div
className="grid gap-2 relative pointer-events-none select-none"
role="presentation"
>
<div
className={clsx(
"bg-slate-800 p-4 rounded-lg shadow transition",
state.messageVisible ? "opacity-100" : "opacity-0 -translate-y-2",
)}
>
<div className="flex items-start gap-4">
<div className="w-12 h-12 p-2 rounded-full bg-no-repeat bg-contain bg-black/25">
<img
src={blobComfyUrl}
alt=""
className="object-contain scale-90 w-full h-full"
/>
</div>
<div>
<p className="font-bold">comfybot</p>
<p>this button was clicked {state.count} times</p>
<div className="mt-2 flex flex-row gap-3">
<div
ref={addRef}
className="bg-emerald-700 text-white py-1.5 px-3 text-sm rounded"
>
+1
</div>
<div
ref={deleteRef}
className="bg-red-700 text-white py-1.5 px-3 text-sm rounded"
>
🗑 delete
</div>
</div>
</div>
</div>
</div>
<div
className="bg-slate-700 pb-2 pt-1.5 px-4 rounded-lg shadow"
ref={chatInputRef}
>
<span
className={clsx(
"text-sm after:content-[attr(data-after)] after:relative after:-top-px after:-left-[2px]",
state.chatInputCursorVisible
? "after:opacity-100"
: "after:opacity-0",
)}
data-after="|"
>
{state.chatInputText || (
<span className="opacity-50 block absolute translate-y-1">
Message #showing-off-reacord
</span>
)}
</span>
</div>
return (
<div
className="pointer-events-none relative grid select-none gap-2"
role="presentation"
>
<div
className={clsx(
"rounded-lg bg-slate-800 p-4 shadow transition",
state.messageVisible ? "opacity-100" : "-translate-y-2 opacity-0",
)}
>
<div className="flex items-start gap-4">
<div className="h-12 w-12 rounded-full bg-black/25 bg-contain bg-no-repeat p-2">
<img
src={blobComfyUrl}
alt=""
className="h-full w-full scale-90 object-contain"
/>
</div>
<div>
<p className="font-bold">comfybot</p>
<p>this button was clicked {state.count} times</p>
<div className="mt-2 flex flex-row gap-3">
<div
ref={addRef}
className="rounded bg-emerald-700 px-3 py-1.5 text-sm text-white"
>
+1
</div>
<div
ref={deleteRef}
className="rounded bg-red-700 px-3 py-1.5 text-sm text-white"
>
🗑 delete
</div>
</div>
</div>
</div>
</div>
<div
className="rounded-lg bg-slate-700 px-4 pb-2 pt-1.5 shadow"
ref={chatInputRef}
>
<span
className={clsx(
"text-sm after:relative after:-left-[2px] after:-top-px after:content-[attr(data-after)]",
state.chatInputCursorVisible
? "after:opacity-100"
: "after:opacity-0",
)}
data-after="|"
>
{state.chatInputText || (
<span className="absolute block translate-y-1 opacity-50">
Message #showing-off-reacord
</span>
)}
</span>
</div>
<img
src={cursorUrl}
alt=""
className="transition-all duration-500 absolute scale-75 bg-transparent"
style={{ left: state.cursorLeft, bottom: state.cursorBottom }}
ref={cursorRef}
/>
</div>
)
<img
src={cursorUrl}
alt=""
className="absolute scale-75 bg-transparent transition-all duration-500"
style={{ left: state.cursorLeft, bottom: state.cursorBottom }}
ref={cursorRef}
/>
</div>
)
}

View File

@@ -1,13 +1,13 @@
---
export type Props = {
icon: (props: { class?: string; className?: string }) => any
label: string
export interface Props {
icon: (props: { class?: string; className?: string }) => unknown
label: string
}
---
<div
class="px-3 py-2 transition text-left font-medium block w-full opacity-50 inline-flex gap-1 items-center hover:opacity-100 hover:text-emerald-500"
class="flex w-full items-center gap-1 px-3 py-2 text-left font-medium opacity-50 transition hover:text-emerald-500 hover:opacity-100"
>
<Astro.props.icon class="inline-icon" className="inline-icon" />
<span class="flex-1">{Astro.props.label}</span>
<Astro.props.icon class="inline-icon" className="inline-icon" />
<span class="flex-1">{Astro.props.label}</span>
</div>

View File

@@ -1,6 +1,6 @@
---
export type Props = astroHTML.JSX.AnchorHTMLAttributes & {
href: string
href: string
}
const removeTrailingSlash = (str: string) => str.replace(/\/$/, "")
@@ -8,10 +8,10 @@ const removeTrailingSlash = (str: string) => str.replace(/\/$/, "")
const linkUrl = new URL(Astro.props.href, Astro.url)
const isActive =
removeTrailingSlash(Astro.url.pathname) ===
removeTrailingSlash(linkUrl.pathname)
removeTrailingSlash(Astro.url.pathname) ===
removeTrailingSlash(linkUrl.pathname)
---
<a {...Astro.props} data-active={isActive || undefined}>
<slot />
<slot />
</a>