diff --git a/with-three/App.tsx b/with-three/App.tsx new file mode 100644 index 0000000..9738b68 --- /dev/null +++ b/with-three/App.tsx @@ -0,0 +1,86 @@ +import { ExpoWebGLRenderingContext, GLView } from "expo-gl"; +import { Renderer, TextureLoader } from "expo-three"; +import * as React from "react"; +import { + AmbientLight, + BoxBufferGeometry, + Fog, + GridHelper, + Mesh, + MeshStandardMaterial, + PerspectiveCamera, + PointLight, + Scene, + SpotLight, +} from "three"; + +export default function App() { + let timeout; + + React.useEffect(() => { + // Clear the animation loop when the component unmounts + return () => clearTimeout(timeout); + }, []); + + const onContextCreate = async (gl: ExpoWebGLRenderingContext) => { + const { drawingBufferWidth: width, drawingBufferHeight: height } = gl; + const sceneColor = 0x6ad6f0; + + // Create a WebGLRenderer without a DOM element + const renderer = new Renderer({ gl }); + renderer.setSize(width, height); + renderer.setClearColor(sceneColor); + + const camera = new PerspectiveCamera(70, width / height, 0.01, 1000); + camera.position.set(2, 5, 5); + + const scene = new Scene(); + scene.fog = new Fog(sceneColor, 1, 10000); + scene.add(new GridHelper(10, 10)); + + const ambientLight = new AmbientLight(0x101010); + scene.add(ambientLight); + + const pointLight = new PointLight(0xffffff, 2, 1000, 1); + pointLight.position.set(0, 200, 200); + scene.add(pointLight); + + const spotLight = new SpotLight(0xffffff, 0.5); + spotLight.position.set(0, 500, 100); + spotLight.lookAt(scene.position); + scene.add(spotLight); + + const cube = new IconMesh(); + scene.add(cube); + + camera.lookAt(cube.position); + + function update() { + cube.rotation.y += 0.05; + cube.rotation.x += 0.025; + } + + // Setup an animation loop + const render = () => { + timeout = requestAnimationFrame(render); + update(); + renderer.render(scene, camera); + gl.endFrameEXP(); + }; + render(); + }; + + return ; +} + +class IconMesh extends Mesh { + constructor() { + super( + new BoxBufferGeometry(1.0, 1.0, 1.0), + new MeshStandardMaterial({ + map: new TextureLoader().load(require("./icon.jpg")), + // color: 0xff0000 + }) + ); + } +} diff --git a/with-three/README.md b/with-three/README.md new file mode 100644 index 0000000..824aa4d --- /dev/null +++ b/with-three/README.md @@ -0,0 +1,20 @@ +# Three.js Example + +

+ + Supports Expo iOS + + Supports Expo Android + + Supports Expo Web +

+ +## 🚀 How to use + +- Install with `yarn` or `npm install`. +- Run [`expo start`](https://docs.expo.io/versions/latest/workflow/expo-cli/), try it out. + +## 📝 Notes + +- [Expo GL docs](https://docs.expo.io/versions/latest/sdk/gl-view/) +- [Three.js docs](https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene) diff --git a/with-three/babel.config.js b/with-three/babel.config.js new file mode 100644 index 0000000..2900afe --- /dev/null +++ b/with-three/babel.config.js @@ -0,0 +1,6 @@ +module.exports = function(api) { + api.cache(true); + return { + presets: ['babel-preset-expo'], + }; +}; diff --git a/with-three/icon.jpg b/with-three/icon.jpg new file mode 100644 index 0000000..e6c0d5f Binary files /dev/null and b/with-three/icon.jpg differ diff --git a/with-three/package.json b/with-three/package.json new file mode 100644 index 0000000..457c1c2 --- /dev/null +++ b/with-three/package.json @@ -0,0 +1,20 @@ +{ + "dependencies": { + "expo": "37.0.7", + "expo-gl": "^8.0.0", + "expo-three": "^5.4.0", + "expo-auth-session": "^1.2.1", + "jwt-decode": "2.2.0", + "react": "16.9.0", + "react-native": "https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz", + "react-native-web": "^0.11", + "react-dom": "16.9.0", + "three": "^0.108.0" + }, + "devDependencies": { + "@babel/core": "7.9.0", + "@types/react": "^16.8.23", + "@types/react-native": "^0.57.65", + "typescript": "^3.4.5" + } +} diff --git a/with-three/tsconfig.json b/with-three/tsconfig.json new file mode 100644 index 0000000..2ee1a98 --- /dev/null +++ b/with-three/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "allowSyntheticDefaultImports": true, + "jsx": "react-native", + "lib": ["dom", "esnext"], + "moduleResolution": "node", + "noEmit": true, + "skipLibCheck": true, + "resolveJsonModule": true + } +}