├── .gitignore ├── README.md ├── config-overrides.js ├── package.json ├── public ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── apple-touch-icon.png ├── browserconfig.xml ├── bump.jpg ├── cube │ ├── nx.png │ ├── ny.png │ ├── nz.png │ ├── px.png │ ├── py.png │ └── pz.png ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── index.html ├── manifest.json ├── mstile-150x150.png ├── robots.txt └── site.webmanifest ├── screenshot.jpg ├── src ├── App.js ├── index.js └── styles.css └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | # Logs 25 | logs 26 | *.log 27 | npm-debug.log* 28 | yarn-debug.log* 29 | yarn-error.log* 30 | lerna-debug.log* 31 | 32 | # Diagnostic reports (https://nodejs.org/api/report.html) 33 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 34 | 35 | # Runtime data 36 | pids 37 | *.pid 38 | *.seed 39 | *.pid.lock 40 | 41 | # Directory for instrumented libs generated by jscoverage/JSCover 42 | lib-cov 43 | 44 | # Coverage directory used by tools like istanbul 45 | coverage 46 | *.lcov 47 | 48 | # nyc test coverage 49 | .nyc_output 50 | 51 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 52 | .grunt 53 | 54 | # Bower dependency directory (https://bower.io/) 55 | bower_components 56 | 57 | # node-waf configuration 58 | .lock-wscript 59 | 60 | # Compiled binary addons (https://nodejs.org/api/addons.html) 61 | build/Release 62 | 63 | # Dependency directories 64 | node_modules/ 65 | jspm_packages/ 66 | 67 | # Snowpack dependency directory (https://snowpack.dev/) 68 | web_modules/ 69 | 70 | # TypeScript cache 71 | *.tsbuildinfo 72 | 73 | # Optional npm cache directory 74 | .npm 75 | 76 | # Optional eslint cache 77 | .eslintcache 78 | 79 | # Microbundle cache 80 | .rpt2_cache/ 81 | .rts2_cache_cjs/ 82 | .rts2_cache_es/ 83 | .rts2_cache_umd/ 84 | 85 | # Optional REPL history 86 | .node_repl_history 87 | 88 | # Output of 'npm pack' 89 | *.tgz 90 | 91 | # Yarn Integrity file 92 | .yarn-integrity 93 | 94 | # dotenv environment variables file 95 | .env 96 | .env.test 97 | 98 | # parcel-bundler cache (https://parceljs.org/) 99 | .cache 100 | .parcel-cache 101 | 102 | # Next.js build output 103 | .next 104 | out 105 | 106 | # Nuxt.js build / generate output 107 | .nuxt 108 | dist 109 | 110 | # Gatsby files 111 | .cache/ 112 | # Comment in the public line in if your project uses Gatsby and not Next.js 113 | # https://nextjs.org/blog/next-9-1#public-directory-support 114 | # public 115 | 116 | # vuepress build output 117 | .vuepress/dist 118 | 119 | # Serverless directories 120 | .serverless/ 121 | 122 | # FuseBox cache 123 | .fusebox/ 124 | 125 | # DynamoDB Local files 126 | .dynamodb/ 127 | 128 | # TernJS port file 129 | .tern-port 130 | 131 | # Stores VSCode versions used for testing VSCode extensions 132 | .vscode-test 133 | 134 | # yarn v2 135 | .yarn/cache 136 | .yarn/unplugged 137 | .yarn/build-state.yml 138 | .yarn/install-state.gz 139 | .pnp.* 140 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Preview 🧼 https://r3f-bubbles.netlify.app 🧼 2 | 3 | ### Featuring [react-postprocessing](https://github.com/react-spring/react-postprocessing) 4 | 5 | ![](https://raw.githubusercontent.com/gsimone/r3f-bubbles/master/screenshot.jpg) 6 | 7 | To run locally: 8 | ```bash 9 | # using npm 10 | npm install 11 | npm run start 12 | 13 | # using yarn 14 | yarn 15 | yarn start 16 | ``` 17 | -------------------------------------------------------------------------------- /config-overrides.js: -------------------------------------------------------------------------------- 1 | const { override } = require('customize-cra') 2 | const { addReactRefresh } = require('customize-cra-react-refresh') 3 | 4 | module.exports = (config, env) => override(addReactRefresh())(config, env) 5 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "r3f-starter", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "drei": "^1.5.6", 7 | "glsl-noise": "^0.0.0", 8 | "merge-refs": "^1.0.0", 9 | "postprocessing": "^6.17.3", 10 | "react": "^17.0.0-rc.0", 11 | "react-dom": "^17.0.0-rc.0", 12 | "react-postprocessing": "^1.3.2", 13 | "react-scripts": "3.4.3", 14 | "react-three-fiber": "^5.0.0-beta.11", 15 | "three": "^0.120.1" 16 | }, 17 | "devDependencies": { 18 | "@react-spring/three": "^9.0.0-rc.3", 19 | "@testing-library/jest-dom": "^5.11.4", 20 | "@testing-library/react": "^11.0.4", 21 | "@testing-library/user-event": "^12.1.4", 22 | "customize-cra": "^1.0.0", 23 | "customize-cra-react-refresh": "^1.1.0", 24 | "glslify-loader": "^2.0.0", 25 | "husky": "^4.3.0", 26 | "prettier": "^2.1.1", 27 | "pretty-quick": "^3.0.2", 28 | "raw-loader": "^4.0.1", 29 | "react-app-rewired": "^2.1.6" 30 | }, 31 | "scripts": { 32 | "start": "react-app-rewired start", 33 | "build": "react-app-rewired build", 34 | "test": "react-app-rewired test", 35 | "eject": "react-app-rewired eject" 36 | }, 37 | "husky": { 38 | "hooks": { 39 | "pre-commit": "pretty-quick --staged --pattern \"**/*.*(js)\"" 40 | } 41 | }, 42 | "prettier": { 43 | "semi": false, 44 | "trailingComma": "es5", 45 | "singleQuote": true, 46 | "jsxBracketSameLine": true, 47 | "tabWidth": 2, 48 | "printWidth": 120 49 | }, 50 | "eslintConfig": { 51 | "extends": "react-app" 52 | }, 53 | "browserslist": { 54 | "production": [ 55 | ">0.2%", 56 | "not dead", 57 | "not op_mini all" 58 | ], 59 | "development": [ 60 | "last 1 chrome version", 61 | "last 1 firefox version", 62 | "last 1 safari version" 63 | ] 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsimone/r3f-bubbles/dd72cbca6e22320ac8c218298531ae894b66d94e/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsimone/r3f-bubbles/dd72cbca6e22320ac8c218298531ae894b66d94e/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsimone/r3f-bubbles/dd72cbca6e22320ac8c218298531ae894b66d94e/public/apple-touch-icon.png -------------------------------------------------------------------------------- /public/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #da532c 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /public/bump.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsimone/r3f-bubbles/dd72cbca6e22320ac8c218298531ae894b66d94e/public/bump.jpg -------------------------------------------------------------------------------- /public/cube/nx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsimone/r3f-bubbles/dd72cbca6e22320ac8c218298531ae894b66d94e/public/cube/nx.png -------------------------------------------------------------------------------- /public/cube/ny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsimone/r3f-bubbles/dd72cbca6e22320ac8c218298531ae894b66d94e/public/cube/ny.png -------------------------------------------------------------------------------- /public/cube/nz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsimone/r3f-bubbles/dd72cbca6e22320ac8c218298531ae894b66d94e/public/cube/nz.png -------------------------------------------------------------------------------- /public/cube/px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsimone/r3f-bubbles/dd72cbca6e22320ac8c218298531ae894b66d94e/public/cube/px.png -------------------------------------------------------------------------------- /public/cube/py.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsimone/r3f-bubbles/dd72cbca6e22320ac8c218298531ae894b66d94e/public/cube/py.png -------------------------------------------------------------------------------- /public/cube/pz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsimone/r3f-bubbles/dd72cbca6e22320ac8c218298531ae894b66d94e/public/cube/pz.png -------------------------------------------------------------------------------- /public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsimone/r3f-bubbles/dd72cbca6e22320ac8c218298531ae894b66d94e/public/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsimone/r3f-bubbles/dd72cbca6e22320ac8c218298531ae894b66d94e/public/favicon-32x32.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsimone/r3f-bubbles/dd72cbca6e22320ac8c218298531ae894b66d94e/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 23 | 24 | 33 | Bubbles • A React Three Fiber & Drei demo 34 | 35 | 36 | 37 |
38 | 48 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /public/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsimone/r3f-bubbles/dd72cbca6e22320ac8c218298531ae894b66d94e/public/mstile-150x150.png -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /public/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "short_name": "", 4 | "icons": [ 5 | { 6 | "src": "/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "theme_color": "#ffffff", 17 | "background_color": "#ffffff", 18 | "display": "standalone" 19 | } 20 | -------------------------------------------------------------------------------- /screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsimone/r3f-bubbles/dd72cbca6e22320ac8c218298531ae894b66d94e/screenshot.jpg -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three' 2 | import React, { Suspense, useRef, useState } from 'react' 3 | import { Canvas, useFrame, useResource } from 'react-three-fiber' 4 | import { EffectComposer, DepthOfField, Bloom, Noise, Vignette } from 'react-postprocessing' 5 | import { Html, Icosahedron, useTextureLoader, useCubeTextureLoader, MeshDistortMaterial } from 'drei' 6 | 7 | function MainSphere({ material }) { 8 | const main = useRef() 9 | // main sphere rotates following the mouse position 10 | useFrame(({ clock, mouse }) => { 11 | main.current.rotation.z = clock.getElapsedTime() 12 | main.current.rotation.y = THREE.MathUtils.lerp(main.current.rotation.y, mouse.x * Math.PI, 0.1) 13 | main.current.rotation.x = THREE.MathUtils.lerp(main.current.rotation.x, mouse.y * Math.PI, 0.1) 14 | }) 15 | return 16 | } 17 | 18 | function Instances({ material }) { 19 | // we use this array ref to store the spheres after creating them 20 | const [sphereRefs] = useState(() => []) 21 | // we use this array to initialize the background spheres 22 | const initialPositions = [ 23 | [-4, 20, -12], 24 | [-10, 12, -4], 25 | [-11, -12, -23], 26 | [-16, -6, -10], 27 | [12, -2, -3], 28 | [13, 4, -12], 29 | [14, -2, -23], 30 | [8, 10, -20], 31 | ] 32 | // smaller spheres movement 33 | useFrame(() => { 34 | // animate each sphere in the array 35 | sphereRefs.forEach((el) => { 36 | el.position.y += 0.02 37 | if (el.position.y > 19) el.position.y = -18 38 | el.rotation.x += 0.06 39 | el.rotation.y += 0.06 40 | el.rotation.z += 0.02 41 | }) 42 | }) 43 | return ( 44 | <> 45 | 46 | {initialPositions.map((pos, i) => ( 47 | (sphereRefs[i] = ref)} 53 | /> 54 | ))} 55 | 56 | ) 57 | } 58 | 59 | function Scene() { 60 | const bumpMap = useTextureLoader('/bump.jpg') 61 | const envMap = useCubeTextureLoader(['px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png'], { path: '/cube/' }) 62 | // We use `useResource` to be able to delay rendering the spheres until the material is ready 63 | const [matRef, material] = useResource() 64 | return ( 65 | <> 66 | 79 | {material && } 80 | 81 | ) 82 | } 83 | 84 | export default function App() { 85 | return ( 86 | 89 | 90 | 91 | Loading.}> 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | ) 102 | } 103 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import App from './App' 4 | import './styles.css' 5 | 6 | ReactDOM.render(, document.getElementById('root')) 7 | -------------------------------------------------------------------------------- /src/styles.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | outline: none; 4 | } 5 | 6 | html, 7 | body, 8 | #root { 9 | width: 100%; 10 | height: 100%; 11 | margin: 0; 12 | padding: 0; 13 | } 14 | 15 | body { 16 | font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, helvetica neue, helvetica, ubuntu, roboto, noto, 17 | segoe ui, arial, sans-serif; 18 | color: white; 19 | font-size: 14px; 20 | } 21 | 22 | #root:focus { 23 | outline: none; 24 | } 25 | --------------------------------------------------------------------------------