Skip to content

Commit

Permalink
web site: improvements to examples page
Browse files Browse the repository at this point in the history
  • Loading branch information
WesUnwin committed Mar 9, 2024
1 parent 552185e commit 2005582
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 24 deletions.
2 changes: 1 addition & 1 deletion web_site/src/AppRoutes.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
import About from './about/About.jsx';
import Docs from "./docs/Docs.jsx";
import Editor from './Editor.jsx';
import Examples from './Examples.jsx';
import Examples from './examples/Examples.jsx';

const AppRoutes = () => {
return (
Expand Down
23 changes: 0 additions & 23 deletions web_site/src/Examples.jsx

This file was deleted.

69 changes: 69 additions & 0 deletions web_site/src/examples/CurrentExample.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React, { useEffect, useRef, useState } from 'react'
import CodeMirror from '@uiw/react-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { vscodeDark } from '@uiw/codemirror-theme-vscode';

const CurrentExample = ({ currentExample }) => {
const iframeRef= useRef();

const [showCode, setShowCode] = useState(false);
const [code, setCode] = useState('');

const iframeSrc = `https://wesunwin.github.io/three-game-engine/examples/${currentExample.name}.html`;

const reloadIframe = () => {
iframeRef.current.src = iframeRef.current.src + '';
};

useEffect(() => {
if (currentExample?.code) {
setCode('Loading...')
window.fetch(currentExample.code)
.then(response => response.text())
.then(code => setCode(code))
}
}, [currentExample?.code])

return (
<div className="current-example">
<h4>{currentExample.label}</h4>

<div className="current-example-content">
<div className="current-example-preview">
<p>
{currentExample.description}
</p>

<iframe
ref={iframeRef}
className="current-example-iframe"
src={iframeSrc}
/>
</div>

{currentExample.footer}

<button onClick={() => setShowCode(!showCode)}>
{showCode ? 'Hide Code' : 'Show Code'}
</button>
&nbsp;
<button onClick={reloadIframe}>
Restart Demo
</button>

{showCode &&
<div className="current-example-code">
<CodeMirror
theme={vscodeDark}
value={code}
extensions={[javascript({ jsx: true })]}
onChange={() => {}}
/>
</div>
}
</div>
</div>
);
};

export default CurrentExample
50 changes: 50 additions & 0 deletions web_site/src/examples/Examples.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React, { useEffect, useState } from 'react';
import ExamplesSidebar from './ExamplesSidebar.jsx';
import CurrentExample from './CurrentExample.jsx';

const Examples = () => {
const [currentExample, setCurrentExample] = useState(null)

const examples = [
{
thumbnail: 'https://raw.githubusercontent.com/WesUnwin/three-game-engine/main/docs/images/first_person_kinematic_character_controller_example_thumbnail.png',
name: 'first_person_kinematic_character_controller_example',
label: 'First-Person Kinematic Character Controller',
description: 'Demonstrates using the KinematicCharacterController class to create a first-person controlled character game object.',
code: 'https://raw.githubusercontent.com/WesUnwin/three-game-engine/main/examples/first_person_kinematic_character_controller/index.js',
footer: (
<div className="current-example-footer">
<h6 style={{ textAlign: 'center' }}>Controls:</h6>
<ul>
<li>Click on the iframe to allow the game to capture your mouse (ESC to escape).</li>
<li>Move your mouse to look around.</li>
<li>Use WSAD (or arrow keys) to move relative to the direction your facing.</li>
<li>Hold shift to run.</li>
</ul>
</div>
)
}
];

useEffect(() => {
if (!currentExample) {
setCurrentExample(examples[0])
}
}, [currentExample?.name])

return (
<div className="examples">
<ExamplesSidebar
examples={examples}
currentExample={currentExample}
setCurrentExample={setCurrentExample}
/>

{currentExample &&
<CurrentExample currentExample={currentExample} />
}
</div>
);
};

export default Examples;
22 changes: 22 additions & 0 deletions web_site/src/examples/ExamplesSidebar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react'

const ExamplesSidebar = ({ examples, currentExample, setCurrentExample }) => {
return (
<div className="examples-sidebar">
{examples.map(example => (
<div
key={example.name}
className={`examples-sidebar__example ${currentExample?.name === example.name ? 'active' : ''}`}
onClick={() => setCurrentExample(example)}
>
<img src={example.thumbnail} />
<p className='examples-sidebar__example-label'>
{example.label}
</p>
</div>
))}
</div>
)
}

export default ExamplesSidebar
64 changes: 64 additions & 0 deletions web_site/src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,70 @@ body {
margin: 0 auto;
}

.examples {
display: flex;
flex-direction: row;
align-items: stretch;
}

.examples-sidebar {
border-right: 1px solid lightslategray;
flex-grow: 1;

display: flex;
flex-direction: column;
}

.examples-sidebar__example {
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
}

.examples-sidebar__example-label {
text-align: center;
font-size: small;
}

.examples-sidebar__example.active .examples-sidebar__example-label {
font-weight: 600;
}

.examples-sidebar__example img {
object-fit: cover;
height: 180px;
margin: 10px auto;
max-width: 300px;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
}

.examples-sidebar__example.active img {
box-shadow: rgb(80 115 63) 0px 3px 8px;
}

.current-example {
text-align: center;
flex-grow: 5;
}

.current-example-iframe {
height: 55vh;
width: 50vw;
}

.current-example-footer {
text-align: left;
width: 50%;
margin: 5px auto;
}

.current-example-code {
margin: 1em;
text-align: left;
font-size: small;
}

.markdown pre {
padding: 10px;
background-color: rgba(230, 230, 230, 0.699);
Expand Down

0 comments on commit 2005582

Please sign in to comment.