Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Organize Sample List #358

Merged
merged 22 commits into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d51dc45
Merge pull request #1 from webgpu/main
cmhhelgeson Oct 18, 2023
766427d
Merge pull request #2 from webgpu/main
cmhhelgeson Oct 27, 2023
415bd67
Merge pull request #3 from webgpu/main
cmhhelgeson Oct 31, 2023
ff38128
Merge pull request #4 from webgpu/main
cmhhelgeson Nov 15, 2023
c4f73a1
Merge branch 'main' of https://github.com/cmhhelgeson/webgpu-samples
cmhhelgeson Nov 30, 2023
c5a9982
Merge pull request #5 from webgpu/main
cmhhelgeson Dec 4, 2023
08d811d
Merge branch 'main' of https://github.com/cmhhelgeson/webgpu-samples
cmhhelgeson Dec 4, 2023
1db2e10
Merge branch 'webgpu:main' into main
cmhhelgeson Feb 21, 2024
ebbb389
Encapsulated sample page link logic into its own component, which wil…
cmhhelgeson Feb 28, 2024
73f26d7
Test
cmhhelgeson Feb 28, 2024
5419898
New sidebar layout
cmhhelgeson Feb 28, 2024
970f069
First draft
cmhhelgeson Feb 28, 2024
12e1770
Sketch dropdown before merging main into this branch
cmhhelgeson Feb 28, 2024
8bfa289
Merge branch 'webgpu:main' into main
cmhhelgeson Feb 28, 2024
1879c54
merge main into sample_organize_branch
cmhhelgeson Feb 28, 2024
f3c618c
Dropdowns complete. Note that dropdowns can easily be removed if they…
cmhhelgeson Feb 28, 2024
bc57254
fix build errors
cmhhelgeson Feb 28, 2024
8a980a8
Implemented most suggested changes, will have further discussions abo…
cmhhelgeson Feb 28, 2024
95334d3
Moved stuffed around, added comments justifying each category
cmhhelgeson Feb 29, 2024
f05a846
Capitalize GPGPU
cmhhelgeson Feb 29, 2024
40ee507
Added more specific comments to gpgpu section
cmhhelgeson Feb 29, 2024
14c55f8
Cambios pequenos
cmhhelgeson Feb 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions src/components/SampleCategory.module.css
cmhhelgeson marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
@keyframes openTriangle {
from { transform: rotate(0deg); }
to { transform: rotate(180deg); }
}

@keyframes closeTriangle {
from { transform: rotate(180deg); }
to { transform: rotate(0deg); }
}
cmhhelgeson marked this conversation as resolved.
Show resolved Hide resolved

.sampleCategory {
display: flex;
cursor: pointer;
}

.dropdown {
margin-left: 8px;
margin-top: 7px;
margin-bottom: 5px;
}

li.selected a {
cmhhelgeson marked this conversation as resolved.
Show resolved Hide resolved
color: #ff0000;
}

.dropdown[data-collapsed=false] {
cmhhelgeson marked this conversation as resolved.
Show resolved Hide resolved
animation: closeTriangle 0.3s forwards ease-in-out;
}

.dropdown[data-collapsed=true] {
animation: openTriangle 0.3s forwards ease-in-out;
}
93 changes: 93 additions & 0 deletions src/components/SampleCategory.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { useState } from 'react';
import styles from './SampleCategory.module.css';

import { NextRouter } from 'next/router';
import Link from 'next/link';
import { PageCategory } from '../pages/samples/[slug]';

type PageType = {
[key: string]: React.ComponentType & { render: { preload: () => void } };
};

type PageComponentType = {
[key: string]: React.ComponentType;
};

interface SampleCategoryProps {
category: PageCategory;
router: NextRouter;
onClickPageLink: () => void;
}

export const SampleCategory = ({
category,
onClickPageLink,
router,
}: SampleCategoryProps) => {
const { title, pages, sampleNames } = category;
const [open, setOpen] = useState<boolean>(true);
return (
<div>
<div className={styles.sampleCategory} onClick={() => setOpen(!open)}>
<h3
style={{
marginTop: '5px',
}}
>
{title}
</h3>
<div className={`${styles.dropdown}`} data-collapsed={open}>
<svg width="15" height="15" viewBox="0 0 20 20">
<path d="M0 7 L 20 7 L 10 16" fill="black" />
</svg>
</div>
</div>
{open
? sampleNames.map((slug) => {
return (
<SampleLink
key={`samples/${slug}`}
slug={slug}
router={router}
pages={pages}
onClick={() => onClickPageLink()}
/>
);
})
: null}
</div>
);
};

interface SampleLinkProps {
router: NextRouter;
slug: string;
pages: PageComponentType;
onClick: () => void;
}

export const SampleLink = ({
router,
slug,
pages,
onClick,
}: SampleLinkProps) => {
const className =
router.pathname === `/samples/[slug]` && router.query['slug'] === slug
? styles.selected
: undefined;

return (
<li
key={slug}
className={className}
onMouseOver={() => {
(pages as PageType)[slug].render.preload();
}}
>
<Link href={`/samples/${slug}`} onClick={() => onClick()}>
{slug}
</Link>
</li>
);
};
9 changes: 8 additions & 1 deletion src/pages/MainLayout.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
margin-block-end: 16px;
}

.exampleList h3 {
color: rgb(43, 126, 171);
}

.exampleList li {
list-style: none;
padding: 0.3em 0;
Expand All @@ -49,6 +53,8 @@
max-height: 100vh;
}



@media only screen and (max-width: 768px) {
/* More padding on mobile for easier touch screen use */
.exampleLink {
Expand All @@ -67,12 +73,13 @@
.panel .panelContents {
display: block;
transition: max-height 0.3s ease-out;
overflow: hidden;
overflow: none;
cmhhelgeson marked this conversation as resolved.
Show resolved Hide resolved
max-height: 0px;
}

.panel[data-expanded='false'] .panelContents {
max-height: 0vh;
overflow: hidden;
}

.panel[data-expanded='true'] .panelContents {
Expand Down
56 changes: 21 additions & 35 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,16 @@ import { useMemo, memo, useState } from 'react';
import './styles.css';
import styles from './MainLayout.module.css';

import { pages } from './samples/[slug]';
import { pageCategories } from './samples/[slug]';
import { SampleCategory } from '../components/SampleCategory';

const title = 'WebGPU Samples';

type PageType = {
[key: string]: React.ComponentType & { render: { preload: () => void } };
};

const MainLayout: React.FunctionComponent<AppProps> = ({
Component,
pageProps,
}) => {
const router = useRouter();
const samplesNames = Object.keys(pages);
const [listExpanded, setListExpanded] = useState<boolean>(false);

const ComponentMemo = useMemo(() => {
Expand Down Expand Up @@ -66,36 +62,26 @@ const MainLayout: React.FunctionComponent<AppProps> = ({
Github
</a>
<hr />
<ul className={styles.exampleList}>
{samplesNames.map((slug) => {
const className =
router.pathname === `/samples/[slug]` &&
router.query['slug'] === slug
? styles.selected
: undefined;
return (
<li
key={slug}
className={className}
onMouseOver={() => {
(pages as PageType)[slug].render.preload();
}}
>
<Link
href={`/samples/${slug}`}
onClick={() => {
setListExpanded(false);
}}
>
{slug}
</Link>
</li>
);
})}
</ul>
{pageCategories.map((category) => {
return (
<ul
className={styles.exampleList}
key={`/categories/${category.title}`}
>
<SampleCategory
category={category}
router={router}
onClickPageLink={() => setListExpanded(false)}
/>
</ul>
);
})}
<hr />
<h3>Other Pages</h3>
<ul className={styles.exampleList}>
<h3 style={{ marginBottom: '5px' }}>Other Pages</h3>
<ul
style={{ margin: '0px', paddingBottom: '20px' }}
className={styles.exampleList}
>
<li>
<a
rel="noreferrer"
Expand Down
91 changes: 71 additions & 20 deletions src/pages/samples/[slug].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,55 +13,106 @@ type PageComponentType = {
[key: string]: React.ComponentType;
};

export const pages: PageComponentType = {
const webGPUBasicsPages: PageComponentType = {
helloTriangle: dynamic(() => import('../../sample/helloTriangle/main')),
helloTriangleMSAA: dynamic(
() => import('../../sample/helloTriangleMSAA/main')
),
resizeCanvas: dynamic(() => import('../../sample/resizeCanvas/main')),
rotatingCube: dynamic(() => import('../../sample/rotatingCube/main')),
twoCubes: dynamic(() => import('../../sample/twoCubes/main')),
texturedCube: dynamic(() => import('../../sample/texturedCube/main')),
instancedCube: dynamic(() => import('../../sample/instancedCube/main')),
fractalCube: dynamic(() => import('../../sample/fractalCube/main')),
cameras: dynamic(() => import('../../sample/cameras/main')),
cubemap: dynamic(() => import('../../sample/cubemap/main')),
computeBoids: dynamic(() => import('../../sample/computeBoids/main')),
animometer: dynamic(() => import('../../sample/animometer/main')),
videoUploading: dynamic(() => import('../../sample/videoUploading/main')),
videoUploadingWebCodecs: dynamic(
() => import('../../sample/videoUploadingWebCodecs/main')
),
};

const featureDemoPages: PageComponentType = {
cameras: dynamic(() => import('../../sample/cameras/main')),
samplerParameters: dynamic(
() => import('../../sample/samplerParameters/main')
),
imageBlur: dynamic(() => import('../../sample/imageBlur/main')),
shadowMapping: dynamic(() => import('../../sample/shadowMapping/main')),
reversedZ: dynamic(() => import('../../sample/reversedZ/main')),
normalMap: dynamic(() => import('../../sample/normalMap/main')),
renderBundles: dynamic(() => import('../../sample/renderBundles/main')),
skinnedMesh: dynamic(() => import('../../sample/skinnedMesh/main')),
};

const renderPassDemoPages: PageComponentType = {
shadowMapping: dynamic(() => import('../../sample/shadowMapping/main')),
deferredRendering: dynamic(
() => import('../../sample/deferredRendering/main')
),
particles: dynamic(() => import('../../sample/particles/main')),
cornell: dynamic(() => import('../../sample/cornell/main')),
gameOfLife: dynamic(() => import('../../sample/gameOfLife/main')),
renderBundles: dynamic(() => import('../../sample/renderBundles/main')),
worker: dynamic(() => import('../../sample/worker/main')),
'A-buffer': dynamic(() => import('../../sample/a-buffer/main')),
};

const gpuComputeDemoPages: PageComponentType = {
imageBlur: dynamic(() => import('../../sample/imageBlur/main')),
computeBoids: dynamic(() => import('../../sample/computeBoids/main')),
particles: dynamic(() => import('../../sample/particles/main')),
gameOfLife: dynamic(() => import('../../sample/gameOfLife/main')),
bitonicSort: dynamic(() => import('../../sample/bitonicSort/main')),
normalMap: dynamic(() => import('../../sample/normalMap/main')),
skinnedMesh: dynamic(() => import('../../sample/skinnedMesh/main')),
};

const webPlatformPages: PageComponentType = {
resizeCanvas: dynamic(() => import('../../sample/resizeCanvas/main')),
videoUploading: dynamic(() => import('../../sample/videoUploading/main')),
videoUploadingWebCodecs: dynamic(
() => import('../../sample/videoUploadingWebCodecs/main')
),
worker: dynamic(() => import('../../sample/worker/main')),
};

const benchmarkPages: PageComponentType = {
animometer: dynamic(() => import('../../sample/animometer/main')),
};

const pages: PageComponentType = {
...webGPUBasicsPages,
...featureDemoPages,
...renderPassDemoPages,
...gpuComputeDemoPages,
...webPlatformPages,
...benchmarkPages,
};

export interface PageCategory {
title: string;
pages: PageComponentType;
sampleNames: string[];
}

const createPageCategory = (
title: string,
pages: PageComponentType
): PageCategory => {
return {
title,
pages,
sampleNames: Object.keys(pages),
};
};

export const pageCategories: PageCategory[] = [
createPageCategory('WebGPU Basics', webGPUBasicsPages),
createPageCategory('Feature Demos', featureDemoPages),
createPageCategory('Render Pass Demos', renderPassDemoPages),
createPageCategory('GPU Compute Demos', gpuComputeDemoPages),
createPageCategory('Web Platform Demos', webPlatformPages),
cmhhelgeson marked this conversation as resolved.
Show resolved Hide resolved
createPageCategory('Benchmarks', benchmarkPages),
kainino0x marked this conversation as resolved.
Show resolved Hide resolved
];

function Page({ slug }: Props): JSX.Element {
const PageComponent = pages[slug];
return <PageComponent />;
}

export const getStaticPaths: GetStaticPaths<PathParams> = async () => {
const paths = Object.keys(pages).map((p) => ({
params: { slug: p },
}));
return {
paths: Object.keys(pages).map((p) => {
return { params: { slug: p } };
}),
paths,
fallback: false,
};
};
Expand Down
5 changes: 5 additions & 0 deletions src/pages/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ a:hover {
text-decoration: underline;
}

h3 {
margin-bottom: 5px;
margin-top: 5px;
}

main {
position: relative;
flex: 1;
Expand Down
Loading