├── static
└── .gitkeep
├── .gitignore
├── src
├── style
│ └── main.css
├── index.html
└── index.js
├── bundler
├── webpack.prod.js
├── webpack.dev.js
└── webpack.common.js
├── readme.md
└── package.json
/static/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 | .cache
5 |
6 | # Editor directories and files
7 | .idea
8 | .vscode
9 | *.suo
10 | *.ntvs*
11 | *.njsproj
12 | *.sln
13 | *.sw?
14 |
--------------------------------------------------------------------------------
/src/style/main.css:
--------------------------------------------------------------------------------
1 | *
2 | {
3 | padding: 0;
4 | margin: 0;
5 | }
6 |
7 | body,
8 | html
9 | {
10 | overflow: hidden;
11 | }
12 |
13 | .webgl
14 | {
15 | position: fixed;
16 | top: 0;
17 | left: 0;
18 | width: 100%;
19 | height: 100%;
20 | background: #000000;
21 | }
22 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Webpack THREE.js Template
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/bundler/webpack.prod.js:
--------------------------------------------------------------------------------
1 | const webpackMerge = require('webpack-merge')
2 | const commonConfiguration = require('./webpack.common.js')
3 | const { CleanWebpackPlugin } = require('clean-webpack-plugin')
4 |
5 | module.exports = webpackMerge(
6 | commonConfiguration,
7 | {
8 | mode: 'production',
9 | plugins:
10 | [
11 | new CleanWebpackPlugin()
12 | ]
13 | }
14 | )
15 |
--------------------------------------------------------------------------------
/bundler/webpack.dev.js:
--------------------------------------------------------------------------------
1 | const webpackMerge = require('webpack-merge')
2 | const commonConfiguration = require('./webpack.common.js')
3 |
4 | module.exports = webpackMerge(
5 | commonConfiguration,
6 | {
7 | mode: 'development',
8 | devServer:
9 | {
10 | host: '0.0.0.0',
11 | contentBase: './dist',
12 | open: true,
13 | https: false,
14 | useLocalIp: true
15 | }
16 | }
17 | )
18 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Three.js Template / Boilerplate
2 |
3 | *Get started with Three.js to render 3d Web Experience*
4 |
5 | .png)
6 |
7 | [Youtube Setup Video](https://youtu.be/MmjZG-UX30g)
8 |
9 | [Demo](https://threejs-template.netlify.app/)
10 |
11 |
12 | ## Installation
13 |
14 | Install dependencies (only for first time) :
15 |
16 | ```
17 | yarn
18 | ```
19 |
20 | Compile the code for development and start a local server:
21 |
22 | ```
23 | yarn dev
24 | ```
25 |
26 | Local Server will open on:
27 |
28 | ```
29 | http://localhost:8080/
30 | ```
31 |
32 | Create the build:
33 |
34 | ```
35 | yarn build
36 | ```
37 |
38 | ## Credits
39 |
40 | - [Webpack THREE.js Template](https://github.com/brunosimon/webpack-three-js-template)
41 |
42 | ## Misc
43 |
44 | Follow *@iviixio*: [Twitter](https://twitter.com/iviixio), [Instagram](https://www.instagram.com/iviixio/)
45 |
46 | Youtube Video: [Twitter](https://youtu.be/MmjZG-UX30g)
47 |
48 | ## License
49 | [MIT](LICENSE)
50 |
51 | Made with :blue_heart: by [Mohnish Landge](http://mohnishlandge.me)
52 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "threejs-starter",
3 | "version": "1.0.0",
4 | "description": "*Get started with Three.js to render 3d Web Experience*",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "webpack --config ./bundler/webpack.prod.js",
8 | "dev": "webpack-dev-server --config ./bundler/webpack.dev.js"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git+https://github.com/mohnishlandge/threejs-template.git"
13 | },
14 | "keywords": [],
15 | "author": "Mohnish Landge",
16 | "license": "ISC",
17 | "bugs": {
18 | "url": "https://github.com/mohnishlandge/threejs-template/issues"
19 | },
20 | "homepage": "https://github.com/mohnishlandge/threejs-template#readme",
21 | "devDependencies": {
22 | "@babel/core": "^7.9.6",
23 | "@babel/preset-env": "^7.9.6",
24 | "babel-loader": "^8.1.0",
25 | "clean-webpack-plugin": "^3.0.0",
26 | "copy-webpack-plugin": "^5.1.1",
27 | "css-loader": "^3.5.3",
28 | "file-loader": "^6.0.0",
29 | "glslify-loader": "^2.0.0",
30 | "html-loader": "^1.1.0",
31 | "html-webpack-plugin": "^4.3.0",
32 | "raw-loader": "^4.0.1",
33 | "style-loader": "^1.2.1",
34 | "three": "^0.116.1",
35 | "webpack": "^4.43.0",
36 | "webpack-cli": "^3.3.11",
37 | "webpack-dev-server": "^3.11.0",
38 | "webpack-merge": "^4.2.2"
39 | },
40 | "dependencies": {
41 | "dat.gui": "^0.7.7"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/bundler/webpack.common.js:
--------------------------------------------------------------------------------
1 | const CopyWebpackPlugin = require('copy-webpack-plugin')
2 | const HtmlWebpackPlugin = require('html-webpack-plugin')
3 | const path = require('path')
4 |
5 | module.exports = {
6 | entry: path.resolve(__dirname, '../src/index.js'),
7 | output:
8 | {
9 | filename: 'bundle.[hash].js',
10 | path: path.resolve(__dirname, '../dist')
11 | },
12 | devtool: 'source-map',
13 | plugins:
14 | [
15 | new CopyWebpackPlugin([ { from: path.resolve(__dirname, '../static') } ]),
16 | new HtmlWebpackPlugin({
17 | template: path.resolve(__dirname, '../src/index.html'),
18 | minify: true
19 | })
20 | ],
21 | module:
22 | {
23 | rules:
24 | [
25 | // HTML
26 | {
27 | test: /\.(html)$/,
28 | use: ['html-loader']
29 | },
30 |
31 | // JS
32 | {
33 | test: /\.js$/,
34 | exclude: /node_modules/,
35 | use:
36 | [
37 | 'babel-loader'
38 | ]
39 | },
40 |
41 | // CSS
42 | {
43 | test: /\.css$/,
44 | use:
45 | [
46 | 'style-loader',
47 | 'css-loader'
48 | ]
49 | },
50 |
51 | // Images
52 | {
53 | test: /\.(jpg|png|gif|svg)$/,
54 | use:
55 | [
56 | {
57 | loader: 'file-loader',
58 | options:
59 | {
60 | outputPath: 'assets/images/'
61 | }
62 | }
63 | ]
64 | },
65 |
66 | // Shaders
67 | {
68 | test: /\.(glsl|vs|fs|vert|frag)$/,
69 | exclude: /node_modules/,
70 | use: [
71 | 'raw-loader',
72 | 'glslify-loader'
73 | ]
74 | }
75 | ]
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import './style/main.css'
2 | import * as THREE from 'three'
3 | import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
4 | /**
5 | * GUI Controls
6 | */
7 | import * as dat from 'dat.gui'
8 | const gui = new dat.GUI()
9 |
10 | /**
11 | * Base
12 | */
13 | // Canvas
14 | const canvas = document.querySelector('canvas.webgl')
15 |
16 | // Scene
17 | const scene = new THREE.Scene()
18 |
19 | /**
20 | * Object
21 | */
22 | const geometry = new THREE.IcosahedronGeometry(20, 1)
23 | const material = new THREE.MeshNormalMaterial()
24 | // Material Props.
25 | material.wireframe = true
26 | // Create Mesh & Add To Scene
27 | const mesh = new THREE.Mesh(geometry, material)
28 | scene.add(mesh)
29 |
30 | /**
31 | * Sizes
32 | */
33 | const sizes = {
34 | width: window.innerWidth,
35 | height: window.innerHeight,
36 | }
37 |
38 | window.addEventListener('resize', () => {
39 | // Update sizes
40 | sizes.width = window.innerWidth
41 | sizes.height = window.innerHeight
42 |
43 | // Update camera
44 | camera.aspect = sizes.width / sizes.height
45 | camera.updateProjectionMatrix()
46 |
47 | // Update renderer
48 | renderer.setSize(sizes.width, sizes.height)
49 | renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
50 | })
51 |
52 | /**
53 | * Camera
54 | */
55 | // Base camera
56 | const camera = new THREE.PerspectiveCamera(
57 | 75,
58 | sizes.width / sizes.height,
59 | 0.001,
60 | 5000
61 | )
62 | camera.position.x = 1
63 | camera.position.y = 1
64 | camera.position.z = 50
65 | scene.add(camera)
66 |
67 | // Controls
68 | const controls = new OrbitControls(camera, canvas)
69 | controls.enableDamping = true
70 | controls.autoRotate = true
71 | // controls.enableZoom = false
72 | controls.enablePan = false
73 | controls.dampingFactor = 0.05
74 | controls.maxDistance = 1000
75 | controls.minDistance = 30
76 | controls.touches = {
77 | ONE: THREE.TOUCH.ROTATE,
78 | TWO: THREE.TOUCH.DOLLY_PAN,
79 | }
80 | /**
81 | * Renderer
82 | */
83 | const renderer = new THREE.WebGLRenderer({
84 | canvas: canvas,
85 | antialias: true,
86 | })
87 | renderer.setSize(sizes.width, sizes.height)
88 | renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
89 |
90 | /**
91 | * Animate
92 | */
93 | const clock = new THREE.Clock()
94 | const tick = () => {
95 | const elapsedTime = clock.getElapsedTime()
96 |
97 | //mesh.rotation.y += 0.01 * Math.sin(1)
98 | //mesh.rotation.y += 0.01 * Math.sin(1)
99 | mesh.rotation.z += 0.01 * Math.sin(1)
100 |
101 | // Update controls
102 | controls.update()
103 | // Render
104 | renderer.render(scene, camera)
105 |
106 | // Call tick again on the next frame
107 | window.requestAnimationFrame(tick)
108 | }
109 |
110 | tick()
111 |
--------------------------------------------------------------------------------