Repository: brunosimon/threejs-template-simple Branch: main Commit: 239c9bb9e6fd Files: 10 Total size: 9.6 KB Directory structure: gitextract_bl9z94ew/ ├── .gitignore ├── bundler/ │ ├── webpack.common.js │ ├── webpack.dev.js │ └── webpack.prod.js ├── package.json ├── readme.md ├── src/ │ ├── index.html │ ├── script.js │ └── style.css └── static/ └── .gitkeep ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # Created by https://www.toptal.com/developers/gitignore/api/macos,node # Edit at https://www.toptal.com/developers/gitignore?templates=macos,node ### macOS ### # General .DS_Store .AppleDouble .LSOverride # Icon must end with two \r Icon # Thumbnails ._* # Files that might appear in the root of a volume .DocumentRevisions-V100 .fseventsd .Spotlight-V100 .TemporaryItems .Trashes .VolumeIcon.icns .com.apple.timemachine.donotpresent # Directories potentially created on remote AFP share .AppleDB .AppleDesktop Network Trash Folder Temporary Items .apdisk ### Node ### # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* lerna-debug.log* .pnpm-debug.log* # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json # Runtime data pids *.pid *.seed *.pid.lock # Directory for instrumented libs generated by jscoverage/JSCover lib-cov # Coverage directory used by tools like istanbul coverage *.lcov # nyc test coverage .nyc_output # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) .grunt # Bower dependency directory (https://bower.io/) bower_components # node-waf configuration .lock-wscript # Compiled binary addons (https://nodejs.org/api/addons.html) build/Release # Dependency directories node_modules/ jspm_packages/ # Snowpack dependency directory (https://snowpack.dev/) web_modules/ # TypeScript cache *.tsbuildinfo # Optional npm cache directory .npm # Optional eslint cache .eslintcache # Microbundle cache .rpt2_cache/ .rts2_cache_cjs/ .rts2_cache_es/ .rts2_cache_umd/ # Optional REPL history .node_repl_history # Output of 'npm pack' *.tgz # Yarn Integrity file .yarn-integrity # dotenv environment variables file .env .env.test .env.production # parcel-bundler cache (https://parceljs.org/) .cache .parcel-cache # Next.js build output .next out # Nuxt.js build / generate output .nuxt dist # Gatsby files .cache/ # Comment in the public line in if your project uses Gatsby and not Next.js # https://nextjs.org/blog/next-9-1#public-directory-support # public # vuepress build output .vuepress/dist # Serverless directories .serverless/ # FuseBox cache .fusebox/ # DynamoDB Local files .dynamodb/ # TernJS port file .tern-port # Stores VSCode versions used for testing VSCode extensions .vscode-test # yarn v2 .yarn/cache .yarn/unplugged .yarn/build-state.yml .yarn/install-state.gz .pnp.* # End of https://www.toptal.com/developers/gitignore/api/macos,node ================================================ FILE: bundler/webpack.common.js ================================================ const CopyWebpackPlugin = require('copy-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') const MiniCSSExtractPlugin = require('mini-css-extract-plugin') const path = require('path') module.exports = { entry: path.resolve(__dirname, '../src/script.js'), output: { filename: 'bundle.[contenthash].js', path: path.resolve(__dirname, '../dist') }, devtool: 'source-map', plugins: [ new CopyWebpackPlugin({ patterns: [ { from: path.resolve(__dirname, '../static') } ] }), new HtmlWebpackPlugin({ template: path.resolve(__dirname, '../src/index.html'), minify: true }), new MiniCSSExtractPlugin() ], module: { rules: [ // HTML { test: /\.(html)$/, use: ['html-loader'] }, // JS { test: /\.js$/, exclude: /node_modules/, use: [ 'babel-loader' ] }, // CSS { test: /\.css$/, use: [ MiniCSSExtractPlugin.loader, 'css-loader' ] }, // Images { test: /\.(jpg|png|gif|svg)$/, use: [ { loader: 'file-loader', options: { outputPath: 'assets/images/' } } ] }, // Fonts { test: /\.(ttf|eot|woff|woff2)$/, use: [ { loader: 'file-loader', options: { outputPath: 'assets/fonts/' } } ] }, // Shaders { test: /\.(glsl|vs|fs|vert|frag)$/, exclude: /node_modules/, use: [ 'raw-loader', 'glslify-loader' ] } ] } } ================================================ FILE: bundler/webpack.dev.js ================================================ const { merge } = require('webpack-merge') const commonConfiguration = require('./webpack.common.js') const ip = require('internal-ip') const portFinderSync = require('portfinder-sync') const infoColor = (_message) => { return `\u001b[1m\u001b[34m${_message}\u001b[39m\u001b[22m` } module.exports = merge( commonConfiguration, { mode: 'development', devServer: { host: '0.0.0.0', port: portFinderSync.getPort(8080), contentBase: './dist', watchContentBase: true, open: true, https: false, useLocalIp: true, disableHostCheck: true, overlay: true, noInfo: true, after: function(app, server, compiler) { const port = server.options.port const https = server.options.https ? 's' : '' const localIp = ip.v4.sync() const domain1 = `http${https}://${localIp}:${port}` const domain2 = `http${https}://localhost:${port}` console.log(`Project running at:\n - ${infoColor(domain1)}\n - ${infoColor(domain2)}`) } } } ) ================================================ FILE: bundler/webpack.prod.js ================================================ const { merge } = require('webpack-merge') const commonConfiguration = require('./webpack.common.js') const { CleanWebpackPlugin } = require('clean-webpack-plugin') module.exports = merge( commonConfiguration, { mode: 'production', plugins: [ new CleanWebpackPlugin() ] } ) ================================================ FILE: package.json ================================================ { "repository": "#", "license": "UNLICENSED", "scripts": { "build": "webpack --config ./bundler/webpack.prod.js", "dev": "webpack serve --config ./bundler/webpack.dev.js" }, "dependencies": { "@babel/core": "^7.14.6", "@babel/preset-env": "^7.14.7", "babel-loader": "^8.2.2", "clean-webpack-plugin": "^3.0.0", "copy-webpack-plugin": "^9.0.1", "css-loader": "^5.2.6", "file-loader": "^6.2.0", "glslify-loader": "^2.0.0", "html-loader": "^2.1.2", "html-webpack-plugin": "^5.3.2", "mini-css-extract-plugin": "^2.1.0", "portfinder-sync": "0.0.2", "raw-loader": "^4.0.2", "style-loader": "^3.0.0", "three": "^0.130.1", "webpack": "^5.42.1", "webpack-cli": "^4.7.2", "webpack-dev-server": "^3.11.2", "webpack-merge": "^5.8.0" } } ================================================ FILE: readme.md ================================================ # Three.js - Template - Simple ## Setup Download [Node.js](https://nodejs.org/en/download/). Run this followed commands: ``` bash # Install dependencies (only the first time) npm install # Run the local server at localhost:8080 npm run dev # Build for production in the dist/ directory npm run build ``` ================================================ FILE: src/index.html ================================================ Three.js - Template - Simple ================================================ FILE: src/script.js ================================================ import './style.css' import * as THREE from 'three' import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js' /** * Base */ // Canvas const canvas = document.querySelector('canvas.webgl') // Scene const scene = new THREE.Scene() /** * Sizes */ const sizes = { width: window.innerWidth, height: window.innerHeight } window.addEventListener('resize', () => { // Update sizes sizes.width = window.innerWidth sizes.height = window.innerHeight // Update camera camera.aspect = sizes.width / sizes.height camera.updateProjectionMatrix() // Update renderer renderer.setSize(sizes.width, sizes.height) renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)) }) /** * Camera */ // Base camera const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.1, 100) camera.position.x = 1 camera.position.y = 1 camera.position.z = 1 scene.add(camera) // Controls const controls = new OrbitControls(camera, canvas) controls.enableDamping = true /** * Cube */ const cube = new THREE.Mesh( new THREE.BoxGeometry(1, 1, 1), new THREE.MeshBasicMaterial({ color: 0xff0000 }) ) scene.add(cube) /** * Renderer */ const renderer = new THREE.WebGLRenderer({ canvas: canvas, antialias: true, }) renderer.setSize(sizes.width, sizes.height) renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)) /** * Animate */ const clock = new THREE.Clock() let lastElapsedTime = 0 const tick = () => { const elapsedTime = clock.getElapsedTime() const deltaTime = elapsedTime - lastElapsedTime lastElapsedTime = elapsedTime // Update controls controls.update() // Render renderer.render(scene, camera) // Call tick again on the next frame window.requestAnimationFrame(tick) } tick() ================================================ FILE: src/style.css ================================================ * { margin: 0; padding: 0; } html, body { overflow: hidden; } .webgl { position: fixed; top: 0; left: 0; outline: none; } ================================================ FILE: static/.gitkeep ================================================