Skip to content

Commit

Permalink
Merge pull request #14 from readyplayerme/feature/suspense-loader
Browse files Browse the repository at this point in the history
Feature/suspense loader
  • Loading branch information
BDenysovets authored Aug 18, 2022
2 parents 390104b + c9a9344 commit 0418313
Show file tree
Hide file tree
Showing 12 changed files with 157 additions and 76 deletions.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<div id="root" style="height: 100%"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
Expand Down
File renamed without changes.
16 changes: 8 additions & 8 deletions src/App/App.component.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import React from 'react';
import { Avatar } from 'src/components/Avatar';
import './App.scss';
import styles from './App.module.scss';

function App() {
return (
<div className="App">
<div className="settings">
<div className="wrapper">
<h3 className="title">localhost playground</h3>
<div className="content">
<div className={styles.app}>
<div className={styles.settings}>
<div className={styles.wrapper}>
<h3 className={styles.title}>localhost playground</h3>
<div className={styles.content}>
Paste your content in there to test the avatar props without shrinking the canvas
</div>
</div>
</div>
<div className="container">
<div className="card" style={{ width: '100%' }}>
<div className={styles.container}>
<div className={styles.card}>
<Avatar modelUrl="/male.glb" poseUrl="/male-pose-standing.glb" backgroundColor="#fafafa" shadows={false} />
</div>
</div>
Expand Down
62 changes: 62 additions & 0 deletions src/App/App.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
html,
body,
#root,
.app {
margin: 0;
height: 100%;
width: 100%;
}

.app {
position: relative;
margin: 0;
height: 100%;
width: 100%;
}

.container {
display: flex;
height: 100%;
}

.card {
width: 100%;
}

.settings {
z-index: 2;
position: fixed;
top: 24px;
right: 24px;
width: 100%;
max-width: 320px;
background-color: rgba(243, 243, 243, 0.9);
border: 1px solid #b9b9b9;
border-radius: 4px;
overflow: hidden;
}

.wrapper {
position: relative;
height: 100%;
width: 100%;
}

.title {
font-size: 18px;
font-weight: 600;
font-family: Arial, sans-serif;
color: black;
display: block;
padding: 8px;
margin: 0;
border-bottom: 1px solid #b9b9b9;
}

.content {
position: relative;
padding: 8px;
display: flex;
flex-direction: column;
gap: 12px;
}
59 changes: 0 additions & 59 deletions src/App/App.scss

This file was deleted.

18 changes: 12 additions & 6 deletions src/components/Avatar/Avatar.component.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { Suspense, FC, useMemo, CSSProperties } from 'react';
import React, { Suspense, FC, useMemo, CSSProperties, ReactNode } from 'react';
import { Environment } from '@react-three/drei';
import { PresetsType } from '@react-three/drei/helpers/environment-assets';
import { Vector3 } from 'three';
Expand All @@ -11,6 +11,7 @@ import { isValidGlbUrl } from 'src/services';
import Capture, { CaptureType } from '../Capture/Capture.component';
import Box, { Background } from '../Background/Box/Box.component';
import Shadow from '../Shadow/Shadow.components';
import Loader from '../Loader';

export const CAMERA = {
TARGET: {
Expand Down Expand Up @@ -99,6 +100,10 @@ export interface AvatarProps extends LightingProps {
* Return base64 image after making screenshot of the canvas.
*/
capture?: CaptureType;
/**
* Pass custom fallback component
*/
loader?: ReactNode;
}

/**
Expand Down Expand Up @@ -127,7 +132,8 @@ export const Avatar: FC<AvatarProps> = ({
emotion,
idleRotation = false,
capture,
background
background,
loader
}) => {
const AvatarModel = useMemo(() => {
if (!isValidGlbUrl(modelUrl)) {
Expand All @@ -152,8 +158,8 @@ export const Avatar: FC<AvatarProps> = ({
}, [halfBody, animationUrl, modelUrl, scale, poseUrl, idleRotation, emotion]);

return (
<BaseCanvas background={backgroundColor} position={new Vector3(0, 0, 3)} fov={50} style={style}>
<Suspense fallback={null}>
<Suspense fallback={loader ?? <Loader />}>
<BaseCanvas background={backgroundColor} position={new Vector3(0, 0, 3)} fov={50} style={style}>
<Environment preset={environment} />
<CameraLighting
cameraTarget={cameraTarget}
Expand All @@ -178,7 +184,7 @@ export const Avatar: FC<AvatarProps> = ({
{shadows && <Shadow />}
{background?.src && <Box {...background} />}
{capture && <Capture {...capture} />}
</Suspense>
</BaseCanvas>
</BaseCanvas>
</Suspense>
);
};
4 changes: 2 additions & 2 deletions src/components/Avatar/Avatar.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ export const Animated = Template.bind({});
Animated.args = {
...Static.args,
modelUrl: getStoryAssetPath('male.glb'),
animationUrl: getStoryAssetPath('maleIdle.glb'),
animationUrl: getStoryAssetPath('male-idle.glb'),
cameraTarget: CAMERA.TARGET.FULL_BODY,
cameraInitialDistance: CAMERA.CONTROLS.FULL_BODY.MAX_DISTANCE
};

export const HalfBody = Template.bind({});
HalfBody.args = {
...Static.args,
modelUrl: getStoryAssetPath('halfBody.glb'),
modelUrl: getStoryAssetPath('half-body.glb'),
halfBody: true,
cameraTarget: CAMERA.TARGET.HALF_BODY,
cameraInitialDistance: CAMERA.INITIAL_DISTANCE.HALF_BODY
Expand Down
15 changes: 15 additions & 0 deletions src/components/Loader/Loader.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React, { FC } from 'react';

import styles from './Loader.module.scss';

const Loader: FC = () => (
<div className={styles.loader}>
<div className={styles.dots}>
{[1, 2, 3].map((it) => (
<div key={it} className={styles.dot} />
))}
</div>
</div>
);

export { Loader };
54 changes: 54 additions & 0 deletions src/components/Loader/Loader.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
.loader {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
}

.dots {
display: flex;
align-items: center;
justify-content: center;
}

.dot {
background-color: rgb(236, 236, 236);
width: 8px;
height: 8px;
margin: 2px;
border-radius: 100%;
display: inline-block;

&:nth-child(1) {
animation: 0.75s cubic-bezier(0.2, 0.68, 0.18, 1.08) 0.12s infinite normal both running glowing;
}

&:nth-child(2) {
animation: 0.75s cubic-bezier(0.2, 0.68, 0.18, 1.08) 0.24s infinite normal both running glowing;
}

&:nth-child(3) {
animation: 0.75s cubic-bezier(0.2, 0.68, 0.18, 1.08) 0.36s infinite normal both running glowing;
}
}

@keyframes glowing {
0% {
transform: scale(1);
opacity: 1;
}

45% {
transform: scale(0.1);
opacity: 0.7;
}

80% {
transform: scale(1);
opacity: 1;
}
}


3 changes: 3 additions & 0 deletions src/components/Loader/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { Loader } from './Loader.component';

export default Loader;

0 comments on commit 0418313

Please sign in to comment.