Skip to content

Commit

Permalink
Add basic embed mode
Browse files Browse the repository at this point in the history
  • Loading branch information
davidar committed Aug 15, 2024
1 parent e0b7758 commit 7c74be5
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 162 deletions.
12 changes: 12 additions & 0 deletions components/wgputoycontroller.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useTransientAtom } from 'jotai-game';
import {
codeAtom,
dbLoadedAtom,
embedModeAtom,
entryPointsAtom,
float32EnabledAtom,
halfResolutionAtom,
Expand Down Expand Up @@ -86,6 +87,7 @@ const WgpuToyController = props => {
const [scale, setScale] = useTransientAtom(scaleAtom);

const [requestFullscreenSignal, setRequestFullscreenSignal] = useAtom(requestFullscreenAtom);
const embedMode = useAtomValue(embedModeAtom);
const float32Enabled = useAtomValue(float32EnabledAtom);
const halfResolution = useAtomValue(halfResolutionAtom);

Expand Down Expand Up @@ -497,6 +499,16 @@ const WgpuToyController = props => {
canvas.height = dimensions.y;
canvas.style.width = `${dimensions.x / window.devicePixelRatio}px`;
canvas.style.height = `${dimensions.y / window.devicePixelRatio}px`;
if (embedMode) {
canvas.style.width = '100vw';
canvas.style.height = '100vh';
canvas.style.zIndex = '9999';
canvas.style.position = 'fixed';
canvas.style.top = '0';
canvas.style.left = '0';
document.body.style.overflow = 'hidden';
document.body.style.display = 'block';
}
}
}
};
Expand Down
1 change: 1 addition & 0 deletions lib/atoms/atoms.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const resetAtom = atom<boolean>(false);
export const hotReloadAtom = atom<boolean>(false);
export const manualReloadAtom = atom<boolean>(false);
export const requestFullscreenAtom = atom<boolean>(false);
export const embedModeAtom = atom<boolean>(false);
export const parseErrorAtom = atom<ParseError>({
summary: '',
position: { row: 0, col: 0 },
Expand Down
161 changes: 161 additions & 0 deletions lib/view.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import { fromUniformActiveSettings } from 'components/editor/uniformsliders';
import { useSetAtom } from 'jotai';
import { SUPABASE_SHADERTHUMB_BUCKET_NAME } from 'lib/db/supabaseclient';
import { getFullyQualifiedSupabaseBucketURL } from 'lib/util/urlutils';
import Head from 'next/head';
import { useRouter } from 'next/router';
import { useEffect } from 'react';
import { definitions } from 'types/supabase';
import {
authorProfileAtom,
codeAtom,
codeNeedSaveAtom,
customTexturesAtom,
dbLoadedAtom,
descriptionAtom,
float32EnabledAtom,
loadedTexturesAtom,
manualReloadAtom,
shaderIDAtom,
sliderRefMapAtom,
sliderSerDeNeedsUpdateAtom,
Texture,
titleAtom,
visibilityAtom
} from './atoms/atoms';
import { ShaderActiveSettings, useResetShaderData } from './db/serializeshader';
import { supabase, SUPABASE_SHADER_TABLE_NAME } from './db/supabaseclient';
import { fixup_shader_code } from './util/fixup';
import { defaultTextures } from './util/textureutils';

export async function fetchShader(id: number) {
const { data, error, status } = await supabase
.from<definitions['shader']>(SUPABASE_SHADER_TABLE_NAME)
.select(
`
name,
description,
thumb_url,
visibility,
body,
profile:author (
username,
avatar_url,
id
)
`
)
.eq('id', id)
.single();

if (error && status !== 406) {
console.error(error.message);
}

return data;
}

export function buildHead(shader) {
const image = getFullyQualifiedSupabaseBucketURL(
SUPABASE_SHADERTHUMB_BUCKET_NAME,
shader.thumb_url
);
return (
<Head>
<title>{shader.name}</title>
<meta property="og:type" content="image" />
<meta property="og:site_name" content="@compute.toys" />
<meta property="og:title" content={shader.name} />
<meta property="og:description" content={shader.description} />
<meta property="og:image" content={image} />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site:id" content="@compute_toys" />
<meta name="twitter:title" content={shader.name} />
<meta name="twitter:description" content={shader.description} />
<meta name="twitter:image" content={image} />
</Head>
);
}

export function useShader(props) {
const reset = useResetShaderData();
const setManualReload = useSetAtom(manualReloadAtom);
const setShaderID = useSetAtom(shaderIDAtom);
const setDBLoaded = useSetAtom(dbLoadedAtom);
const setCodeNeedSave = useSetAtom(codeNeedSaveAtom);

const setCode = useSetAtom(codeAtom);
const setLoadedTextures = useSetAtom(loadedTexturesAtom);
const setCustomTextures = useSetAtom(customTexturesAtom);
const setSliderSerDeNeedsUpdate = useSetAtom(sliderSerDeNeedsUpdateAtom);
const setSliderRefMap = useSetAtom(sliderRefMapAtom);
const setTitle = useSetAtom(titleAtom);
const setDescription = useSetAtom(descriptionAtom);
const setVisibility = useSetAtom(visibilityAtom);
const setAuthorProfile = useSetAtom(authorProfileAtom);
const setFloat32Enabled = useSetAtom(float32EnabledAtom);

const router = useRouter();

const loadShader = shader => {
if (!shader) router.push('/404');

setDBLoaded(false);
reset();
setTitle(shader.name);
setDescription(shader.description);
setVisibility(shader.visibility);

const body = JSON.parse(shader.body);
const float32Enabled = 'float32Enabled' in body ? body.float32Enabled : false;

const shaderActiveSettings: ShaderActiveSettings = {
code: fixup_shader_code(JSON.parse(body.code)),
uniforms: body.uniforms,
textures: body.textures,
float32Enabled: float32Enabled
};
setCode(shaderActiveSettings.code);
setLoadedTextures(shaderActiveSettings.textures);
// see if the shaders requires any textures that aren't part of the default set
// if it does, check if that custom texture is already in the custom texture list
// and if it's not, add it to the list
setCustomTextures(existingCustomTextures => {
const newCustomTextures: Texture[] = [];
for (const requiredTexture of shaderActiveSettings.textures) {
const isDefault = defaultTextures.find(dt => dt.img === requiredTexture.img);

if (!isDefault) {
const isNew = !existingCustomTextures.find(
ect => ect.img === requiredTexture.img
);
if (isNew) {
newCustomTextures.push({ img: requiredTexture.img });
}
}
}

return [...existingCustomTextures, ...newCustomTextures];
});
setSliderRefMap(fromUniformActiveSettings(shaderActiveSettings.uniforms));
// need to inform the slider component of a change so it can get a count of all the enabled sliders
setSliderSerDeNeedsUpdate(true);
setFloat32Enabled(float32Enabled);
// @ts-ignore
setAuthorProfile(shader.profile);
setShaderID(props.id);
setManualReload(true);
setDBLoaded(true);
setCodeNeedSave(false);
};

useEffect(() => {
if (props.shader) {
// public/unlisted shaders are fetched server-side
loadShader(props.shader);
} else if (router.isReady) {
// private shaders need to be fetched client-side
fetchShader(props.id).then(loadShader);
}
}, [router.isReady]);
}
25 changes: 25 additions & 0 deletions pages/embed/[id].tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use client';
import Editor from 'components/editor/editor';
import { useSetAtom } from 'jotai';
import { embedModeAtom } from 'lib/atoms/atoms';
import { fetchShader, useShader } from 'lib/view';

export async function getServerSideProps(context) {
const id = Number(context.params.id);
if (Number.isNaN(id)) return { notFound: true };
return { props: { id, shader: await fetchShader(id) } };
}

export default function Index(props) {
useShader(props);
const setEmbedMode = useSetAtom(embedModeAtom);
setEmbedMode(true);
return (
<div>
<style>{`
body { display: none; }
`}</style>
<Editor />
</div>
);
}
Loading

0 comments on commit 7c74be5

Please sign in to comment.