mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-11 12:23:20 +00:00
Merge branch 'test' of github.com:storytold/GottaGoFast into test
This commit is contained in:
commit
96604f35a3
15 files changed
+198
-110
No files matched your search
@@ -0,0 +1,7 @@
|
||||
import { Button } from "./Button";
|
||||
import { ButtonLink } from "./ButtonLink";
|
||||
|
||||
export {
|
||||
Button,
|
||||
ButtonLink
|
||||
};
|
||||
@@ -1,18 +1,16 @@
|
||||
import {
|
||||
Fragment,
|
||||
useCallback,
|
||||
useLayoutEffect,
|
||||
useState
|
||||
} from 'react'
|
||||
import { Dialog, Transition } from '@headlessui/react'
|
||||
import {
|
||||
faXmark,
|
||||
faGears,
|
||||
} from '@fortawesome/free-solid-svg-icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
|
||||
import { Button } from '~/components/Button';
|
||||
import { TOP_BAR_HEIGHT } from '~/constants';
|
||||
|
||||
import { SidePanelInner } from './SidePanelInner';
|
||||
|
||||
interface SidePanelPropsI{
|
||||
title?: string;
|
||||
@@ -23,21 +21,10 @@ export const SidePanel =({
|
||||
title,
|
||||
children,
|
||||
}:SidePanelPropsI)=>{
|
||||
const [height, setHeight] = useState<number>(0);
|
||||
|
||||
const [open, setOpen] = useState<boolean>(false);
|
||||
const handleOpen = ()=> setOpen(true);
|
||||
|
||||
const handleWindowResize = useCallback(()=>{
|
||||
setHeight((window.innerHeight * 3 / 4) - TOP_BAR_HEIGHT);
|
||||
},[])
|
||||
|
||||
useLayoutEffect(()=>{
|
||||
handleWindowResize();
|
||||
window.addEventListener("resize", handleWindowResize);
|
||||
return () => {
|
||||
window.removeEventListener("resize", handleWindowResize);
|
||||
};
|
||||
}, [handleWindowResize])
|
||||
const handleClose = ()=>setOpen(false);
|
||||
|
||||
return (<>
|
||||
<Button
|
||||
@@ -63,39 +50,12 @@ export const SidePanel =({
|
||||
leaveTo="translate-x-full"
|
||||
>
|
||||
<Dialog.Panel className="pointer-events-auto w-screen lg:max-w-md">
|
||||
<div
|
||||
className="flex flex-col overflow-y-scroll bg-ui-panel py-6 shadow-xl border-y border-l border-ui-panel-border"
|
||||
style={{height:height+'px'}}
|
||||
<SidePanelInner
|
||||
title={title}
|
||||
closeCallback={handleClose}
|
||||
>
|
||||
<div className="px-4 sm:px-6">
|
||||
<div className="flex items-start justify-between">
|
||||
{!title && <span/>}
|
||||
{title &&
|
||||
<Dialog.Title className="text-base font-semibold leading-6 text-white">
|
||||
{title}
|
||||
</Dialog.Title>
|
||||
}
|
||||
<div className="ml-3 flex h-7 items-center">
|
||||
<button
|
||||
type="button"
|
||||
className="relative rounded-md bg-brand-primary text-white hover:bg-brand-primary-400 focus:outline-none focus:ring-brand-primary-500"
|
||||
onClick={() => setOpen(false)}
|
||||
>
|
||||
{/* <span className="absolute -inset-2.5" /> */}
|
||||
<span className="sr-only">Close panel</span>
|
||||
<FontAwesomeIcon
|
||||
className="h-6 w-6 mt-1 mx-1"
|
||||
aria-hidden="true"
|
||||
icon={faXmark}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative mt-6 flex-1 px-4 sm:px-6">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
{children}
|
||||
</SidePanelInner>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
import {
|
||||
useCallback,
|
||||
useLayoutEffect,
|
||||
useState
|
||||
} from 'react';
|
||||
import { Dialog } from '@headlessui/react'
|
||||
|
||||
import {
|
||||
faXmark,
|
||||
} from '@fortawesome/free-solid-svg-icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
|
||||
import { TOP_BAR_HEIGHT } from '~/constants';
|
||||
|
||||
export const SidePanelInner = ({
|
||||
title,
|
||||
children,
|
||||
closeCallback
|
||||
}:{
|
||||
title?: string;
|
||||
children: React.ReactNode;
|
||||
closeCallback: ()=>void;
|
||||
})=>{
|
||||
const [height, setHeight] = useState(0);
|
||||
const handleWindowResize = useCallback(()=>{
|
||||
if(window){
|
||||
setHeight (Math.ceil(window.innerHeight * 3 / 4) - TOP_BAR_HEIGHT);
|
||||
}
|
||||
return 0;
|
||||
},[])
|
||||
|
||||
useLayoutEffect(()=>{
|
||||
handleWindowResize();
|
||||
window.addEventListener("resize", handleWindowResize);
|
||||
return () => {
|
||||
window.removeEventListener("resize", handleWindowResize);
|
||||
};
|
||||
}, [handleWindowResize]);
|
||||
|
||||
return(
|
||||
<div
|
||||
className="flex flex-col overflow-y-scroll bg-ui-panel py-6 shadow-xl border-y border-l border-ui-panel-border"
|
||||
style={{height:height+'px'}}
|
||||
>
|
||||
<div className="px-4 sm:px-6">
|
||||
<div className="flex items-start justify-between">
|
||||
{!title && <span/>}
|
||||
{title &&
|
||||
<Dialog.Title className="text-base font-semibold leading-6 text-white">
|
||||
{title}
|
||||
</Dialog.Title>
|
||||
}
|
||||
<div className="ml-3 flex h-7 items-center">
|
||||
<button
|
||||
type="button"
|
||||
className="relative rounded-md bg-brand-primary text-white hover:bg-brand-primary-400 focus:outline-none focus:ring-brand-primary-500"
|
||||
onClick={closeCallback}
|
||||
>
|
||||
{/* <span className="absolute -inset-2.5" /> */}
|
||||
<span className="sr-only">Close panel</span>
|
||||
<FontAwesomeIcon
|
||||
className="h-6 w-6 mt-1 mx-1"
|
||||
aria-hidden="true"
|
||||
icon={faXmark}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative mt-6 flex-1 px-4 sm:px-6">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import {
|
||||
useContext,
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { TopBarInnerContext } from "~/contexts/TopBarInner";
|
||||
|
||||
|
||||
export const TopBarHelmet = (props:{
|
||||
children: JSX.Element | null;
|
||||
})=>{
|
||||
const [showChild, setShowChild] = useState(false);
|
||||
// Wait until after client-side hydration to show
|
||||
useEffect(() => {
|
||||
setShowChild(true);
|
||||
}, []);
|
||||
if (!showChild) {
|
||||
// You can show some kind of placeholder UI here
|
||||
return null;
|
||||
}
|
||||
|
||||
return <LazyLoadTopBarInnerContent {...props} />;
|
||||
}
|
||||
|
||||
const LazyLoadTopBarInnerContent = (props:{
|
||||
children: JSX.Element | null;
|
||||
})=>{
|
||||
const { setTopBarInner } = useContext(TopBarInnerContext) || {};
|
||||
|
||||
useLayoutEffect(()=>{
|
||||
if(setTopBarInner){
|
||||
setTopBarInner(props.children);
|
||||
}
|
||||
},[setTopBarInner]);
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { TopBarHelmet } from "./TopBarHelmet";
|
||||
@@ -2,7 +2,6 @@ import {
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
@@ -13,15 +12,13 @@ import {
|
||||
|
||||
import { Button } from '~/components/Button';
|
||||
import { ButtonLink } from '~/components/ButtonLink';
|
||||
import { TopBarInnerContext } from "~/contexts/TopBarInner";
|
||||
import { TopBarHelmet } from '~/modules/TopBarHelmet';
|
||||
|
||||
import { SidePanel } from '~/modules/SidePanel';
|
||||
|
||||
import { SceneWithCube } from './SceneWithCube';
|
||||
|
||||
export const PageCube = () => {
|
||||
|
||||
const { setTopBarInner } = useContext(TopBarInnerContext) || {};
|
||||
|
||||
const mountRef = useRef<HTMLDivElement | null>(null);
|
||||
const sceneRef = useRef<SceneWithCube | null>(null);
|
||||
@@ -63,9 +60,9 @@ export const PageCube = () => {
|
||||
};
|
||||
}, []);
|
||||
|
||||
useLayoutEffect(()=>{
|
||||
if(setTopBarInner){
|
||||
const BackButton = (
|
||||
return (
|
||||
<div className="grid grid-cols-12 gap-2 ">
|
||||
<TopBarHelmet>
|
||||
<ButtonLink
|
||||
to={"/"}
|
||||
variant='secondary'
|
||||
@@ -73,13 +70,7 @@ export const PageCube = () => {
|
||||
>
|
||||
Back to Dashboard
|
||||
</ButtonLink>
|
||||
);
|
||||
setTopBarInner(BackButton);
|
||||
}
|
||||
},[setTopBarInner]);
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-12 gap-2 ">
|
||||
</TopBarHelmet>
|
||||
<div className="col-span-6 ">
|
||||
<div className="MountingPoint" ref={mountRef} />
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import {
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useRef,
|
||||
// useState,
|
||||
} from 'react';
|
||||
|
||||
import {
|
||||
@@ -13,17 +10,21 @@ import {
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
|
||||
|
||||
import { Button } from '~/components/Button';
|
||||
import { ButtonLink } from '~/components/ButtonLink';
|
||||
import {
|
||||
Button,
|
||||
ButtonLink,
|
||||
} from '~/components';
|
||||
import { ButtonDialogue } from '~/modules/ButtonDialogue';
|
||||
import { TopBarInnerContext } from "~/contexts/TopBarInner";
|
||||
import { TopBarHelmet } from '~/modules/TopBarHelmet/TopBarHelmet';
|
||||
import { SidePanel } from '~/modules/SidePanel';
|
||||
import { LowerPanel } from '~/modules/LowerPanel';
|
||||
import { Controls3D } from './comps/Controls3D';
|
||||
import { ControlsVideo } from './comps/ControlsVideo';
|
||||
import { Timeline } from './comps/Timeline';
|
||||
|
||||
import Editor from './js/editor';
|
||||
|
||||
export const PageEnigma = () => {
|
||||
const { setTopBarInner } = useContext(TopBarInnerContext) || {};
|
||||
// const { setTopBarInner } = useContext(TopBarInnerContext) || {};
|
||||
|
||||
const canvasRef = useRef<HTMLCanvasElement | null>(null);
|
||||
const editorRef = useRef<Editor | null>(null);
|
||||
@@ -50,29 +51,6 @@ export const PageEnigma = () => {
|
||||
}
|
||||
}, []);
|
||||
|
||||
useLayoutEffect(()=>{
|
||||
if(setTopBarInner){
|
||||
const TopBarInnerButtons = (
|
||||
<div className="flex grow justify-between">
|
||||
<ButtonLink
|
||||
to={"/"}
|
||||
variant='secondary'
|
||||
icon={faChevronLeft}
|
||||
>
|
||||
Back to Dashboard
|
||||
</ButtonLink>
|
||||
<Button
|
||||
icon={faWandSparkles}
|
||||
>
|
||||
Generate Movie
|
||||
</Button>
|
||||
<span className="w-8"/>
|
||||
</div>
|
||||
);
|
||||
setTopBarInner(TopBarInnerButtons);
|
||||
}
|
||||
},[setTopBarInner]);
|
||||
|
||||
const handleButtonSave = ()=>{
|
||||
editorRef.current?.save();
|
||||
}
|
||||
@@ -88,6 +66,23 @@ export const PageEnigma = () => {
|
||||
|
||||
return(
|
||||
<div>
|
||||
<TopBarHelmet>
|
||||
<div className="flex grow justify-between">
|
||||
<ButtonLink
|
||||
to={"/"}
|
||||
variant='secondary'
|
||||
icon={faChevronLeft}
|
||||
>
|
||||
Back to Dashboard
|
||||
</ButtonLink>
|
||||
<Button
|
||||
icon={faWandSparkles}
|
||||
>
|
||||
Generate Movie
|
||||
</Button>
|
||||
<span className="w-8"/>
|
||||
</div>
|
||||
</TopBarHelmet>
|
||||
<canvas ref={canvasRef} id="video-scene" width="1280px" height="720px" />
|
||||
<div className='fixed top-20 left-4'>
|
||||
<div className="flex mt-2 gap-2">
|
||||
@@ -105,6 +100,8 @@ export const PageEnigma = () => {
|
||||
<p>Ask Miles about ThreeJS</p>
|
||||
<p>Ask Wil about React</p>
|
||||
</ButtonDialogue>
|
||||
<Controls3D/>
|
||||
<ControlsVideo/>
|
||||
</div>
|
||||
</div>
|
||||
<SidePanel>
|
||||
@@ -112,10 +109,7 @@ export const PageEnigma = () => {
|
||||
<Button onClick={handleButtonRender}>Render</Button>
|
||||
<Button onClick={handleButtonPlay}>Play</Button>
|
||||
</SidePanel>
|
||||
<LowerPanel>
|
||||
<div className='h-10 w-full border-b border-ui-panel-border'></div>
|
||||
<input style={{ display: 'none' }} type="file" id="load-upload" name="load-upload"></input>
|
||||
</LowerPanel>
|
||||
<Timeline />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
export const Controls3D = ()=>{
|
||||
return(
|
||||
<div
|
||||
className="fixed left-1/2 -translate-x-1/2 bg-ui-panel border-b border-x border-ui-panel-border rounded-b-md p-2 text-white"
|
||||
style={{top: "72px"}}
|
||||
>
|
||||
Controls for the 3D scene
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { Controls3D } from './Controls3D';
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
export const ControlsVideo = ()=>{
|
||||
return(
|
||||
<div className="fixed top-3/4 left-1/2 -translate-x-1/2 -mt-10 bg-ui-panel border-t border-x border-ui-panel-border rounded-t-md p-2 text-white">Video Controls</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export { ControlsVideo } from './ControlsVideo';
|
||||
@@ -0,0 +1,10 @@
|
||||
import { LowerPanel } from "~/modules/LowerPanel";
|
||||
|
||||
export const Timeline = ()=>{
|
||||
return(
|
||||
<LowerPanel>
|
||||
<div className='h-10 w-full border-b border-ui-panel-border'></div>
|
||||
<input style={{ display: 'none' }} type="file" id="load-upload" name="load-upload"></input>
|
||||
</LowerPanel>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { Timeline } from './Timeline';
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
import { useState } from 'react';
|
||||
import { PageCube } from "../pages/PageCube";
|
||||
import { Button } from '~/components/Button';
|
||||
import { Button } from '~/components';
|
||||
|
||||
export default function Cube(){
|
||||
const pausedRiddle = true;
|
||||
const [riddle, setRiddle] = useState<string>("");
|
||||
|
||||
+3
-11
@@ -1,9 +1,6 @@
|
||||
import {
|
||||
useContext,
|
||||
useLayoutEffect,
|
||||
} from "react";
|
||||
|
||||
import type { MetaFunction } from "@remix-run/deno";
|
||||
import { TopBarInnerContext } from "~/contexts/TopBarInner";
|
||||
import { TopBarHelmet } from "~/modules/TopBarHelmet";
|
||||
|
||||
import sonic from "./_assets/sonic-the-hedgehog-classic-sonic.gif";
|
||||
|
||||
@@ -15,14 +12,9 @@ export const meta: MetaFunction = () => {
|
||||
};
|
||||
|
||||
export default function Index() {
|
||||
const { setTopBarInner } = useContext(TopBarInnerContext) || {};
|
||||
useLayoutEffect(()=>{
|
||||
if(setTopBarInner){
|
||||
setTopBarInner(null);
|
||||
}
|
||||
},[setTopBarInner]);
|
||||
return (
|
||||
<div className="size-full">
|
||||
<TopBarHelmet>{null}</TopBarHelmet>
|
||||
<img
|
||||
alt="sonic"
|
||||
src={sonic}
|
||||
|
||||
Reference in new issue
Block a user