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

With threejs example #10301

Merged
merged 5 commits into from Feb 7, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 28 additions & 0 deletions examples/with-three-js/.gitignore
@@ -0,0 +1,28 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
Timer marked this conversation as resolved.
Show resolved Hide resolved

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
.env*

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

.next
yarn.lock
52 changes: 52 additions & 0 deletions examples/with-three-js/README.md
@@ -0,0 +1,52 @@
# Example Name
Timer marked this conversation as resolved.
Show resolved Hide resolved

This example uses:


`threejs`: A lightweight, 3D library with a default WebGL renderer. The library also provides Canvas 2D, SVG and CSS3D renderers in the examples.
`react-three-fiber`: A React renderer for Threejs on the web and react-native.



## Deploy your own

Deploy the example using [ZEIT Now](https://zeit.co/now):

[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/next.js/tree/canary/examples/with-three-js)

## How to use

### Using `create-next-app`

Execute [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:

```bash
npx create-next-app --example with-three-js
# or
yarn create next-app --example with-three-js
```

### Download manually

Download the example:

```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/with-three-js
cd with-three-js
```

Install it and run:

```bash
npm install
npm run dev
# or
yarn
yarn dev
```

Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download)):

```bash
now
```
4 changes: 4 additions & 0 deletions examples/with-three-js/next.config.js
@@ -0,0 +1,4 @@
const withCSS = require('@zeit/next-css');
module.exports = withCSS({
cssModules: true
});
20 changes: 20 additions & 0 deletions examples/with-three-js/package.json
@@ -0,0 +1,20 @@
{
"name": "with-three-js",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
},
"dependencies": {
"next": "9.2.1",
"react": "16.12.0",
"react-dom": "16.12.0",
"react-three-fiber": "4.0.12",
"three": "0.112.1"
},
"devDependencies": {
"@zeit/next-css": "1.0.1"
Timer marked this conversation as resolved.
Show resolved Hide resolved
}
}
83 changes: 83 additions & 0 deletions examples/with-three-js/pages/birds.js
@@ -0,0 +1,83 @@
import React, { useRef, useState, useEffect, Suspense } from "react";
import * as THREE from "three";
import { Canvas, useFrame, useLoader } from "react-three-fiber";
import './index.css';

let GLTFLoader;

const Bird = ({ speed, factor, url, ...props }) => {
const gltf = useLoader(GLTFLoader, url);
const group = useRef();
const [mixer] = useState(() => new THREE.AnimationMixer());
useEffect(
() => void mixer.clipAction(gltf.animations[0], group.current).play(),
[]
);
useFrame((state, delta) => {
group.current.rotation.y +=
Math.sin((delta * factor) / 2) * Math.cos((delta * factor) / 2) * 1.5;
mixer.update(delta * speed);
});
return (
<group ref={group}>
<scene name="Scene" {...props}>
<mesh
name="Object_0"
morphTargetDictionary={gltf.__$[1].morphTargetDictionary}
morphTargetInfluences={gltf.__$[1].morphTargetInfluences}
rotation={[1.5707964611537577, 0, 0]}
>
<bufferGeometry attach="geometry" {...gltf.__$[1].geometry} />
<meshStandardMaterial
attach="material"
{...gltf.__$[1].material}
name="Material_0_COLOR_0"
/>
</mesh>
</scene>
</group>
);
}

const Birds = () => {
return new Array(5).fill().map((_, i) => {
const x = (15 + Math.random() * 30) * (Math.round(Math.random()) ? -1 : 1);
const y = -10 + Math.random() * 20;
const z = -5 + Math.random() * 10;
const bird = ["stork", "parrot", "flamingo"][Math.round(Math.random() * 2)];
let speed = bird === "stork" ? 0.5 : bird === "flamingo" ? 2 : 5;
let factor =
bird === "stork"
? 0.5 + Math.random()
: bird === "flamingo"
? 0.25 + Math.random()
: 1 + Math.random() - 0.5;
return (
<Bird
key={i}
position={[x, y, z]}
rotation={[0, x > 0 ? Math.PI : 0, 0]}
speed={speed}
factor={factor}
url={`/static/glb/${bird}.glb`}
/>
);
});
}

const BirdsPage = props => {
useEffect(() => {
GLTFLoader = require("three/examples/jsm/loaders/GLTFLoader").GLTFLoader;
}, []);
return (
<Canvas camera={{ position: [0, 0, 35] }}>
<ambientLight intensity={2} />
<pointLight position={[40, 40, 40]} />
<Suspense fallback={null}>
<Birds />
</Suspense>
</Canvas>
);
};

export default BirdsPage;
47 changes: 47 additions & 0 deletions examples/with-three-js/pages/boxes.js
@@ -0,0 +1,47 @@
import React, { useRef, useState, Suspense } from "react";
import { Canvas, useFrame } from "react-three-fiber";
import './index.css';

const Box = (props) => {
const mesh = useRef();

const [hovered, setHover] = useState(false);
const [active, setActive] = useState(false);

useFrame(() => (mesh.current.rotation.x = mesh.current.rotation.y += 0.01));

return (
<mesh
{...props}
ref={mesh}
scale={active ? [6, 6, 6] : [5, 5, 5]}
onClick={e => setActive(!active)}
onPointerOver={e => setHover(true)}
onPointerOut={e => setHover(false)}
>
<boxBufferGeometry attach="geometry" args={[1, 1, 1]} />
<meshStandardMaterial
attach="material"
color={hovered ? "#2b6c76" : "#720b23"}
/>
</mesh>
);
};

const BirdsPage = props => {
return[
<h1>Click on me - Hover me :)</h1>,
<Canvas camera={{ position: [0, 0, 35] }}>
<ambientLight intensity={2} />
<pointLight position={[40, 40, 40]} />
<Suspense fallback={null}>
<Box position={[10, 0, 0]} />
<Box position={[-10, 0, 0]} />
<Box position={[0, 10, 0]} />
<Box position={[0, -10, 0]} />
</Suspense>
</Canvas>,
]
};

export default BirdsPage;
43 changes: 43 additions & 0 deletions examples/with-three-js/pages/index.css
@@ -0,0 +1,43 @@
body {
margin: 0;
padding: 0;
width: 100%;
height: 100vh;
background: lavender;
}

canvas {
width: 100%;
height: 100vh;
}

.main {
background: hotpink;
padding: 50px;
border-radius: 4px;
display: flex;
margin: 200px;
flex-direction: column;
justify-content: center;
align-items: center;
color: white;
}

a {
color: white;
display: block;
text-decoration: unset;
font-size: 20px;
margin: 5px 0;
}

a:hover {
color: #3f51b5;
}

h1 {
display: flex;
justify-content: center;
align-content: center;
color: hotpink;
}
14 changes: 14 additions & 0 deletions examples/with-three-js/pages/index.js
@@ -0,0 +1,14 @@
import React from 'react';
import Link from "next/link";
import style from './index.css';

const Index = () => {
return (
<div className={style.main}>
<Link href="/birds"><a>Birds Example</a></Link>
<Link href="/boxes"><a>Boxes Example</a></Link>
</div>
);
};

export default Index;
Binary file added examples/with-three-js/static/glb/flamingo.glb
Binary file not shown.
Binary file added examples/with-three-js/static/glb/parrot.glb
Binary file not shown.
Binary file added examples/with-three-js/static/glb/stork.glb
Binary file not shown.