diff --git a/package-lock.json b/package-lock.json index 6f1743e95..218ff5719 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "threejs-first-proj", + "name": "threejs-webpack-starter", "lockfileVersion": 2, "requires": true, "packages": { diff --git a/src/index.html b/src/index.html index 30ed75a7d..4b0d88488 100644 --- a/src/index.html +++ b/src/index.html @@ -4,8 +4,32 @@ ThreeJS Starter + + +
+
+

The next
Dimension

+

the journey into the next dimension with this crazy particle effect

+
+
+ + + + \ No newline at end of file diff --git a/src/script.js b/src/script.js index 9d86927ca..3ff862f2a 100644 --- a/src/script.js +++ b/src/script.js @@ -1,69 +1,102 @@ -import './style.css' -import * as THREE from 'three' -import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js' -import * as dat from 'dat.gui' +import "./style.css"; +import * as THREE from "three"; +import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"; +import * as dat from "dat.gui"; + +//Texture Loader +const loader = new THREE.TextureLoader(); +const cross = loader.load("./cross.svg"); // Debug -const gui = new dat.GUI() +const gui = new dat.GUI(); // Canvas -const canvas = document.querySelector('canvas.webgl') +const canvas = document.querySelector("canvas.webgl"); // Scene -const scene = new THREE.Scene() +const scene = new THREE.Scene(); // Objects -const geometry = new THREE.TorusGeometry( .7, .2, 16, 100 ); +const geometry = new THREE.TorusGeometry(0.7, 0.2, 16, 100); + +const particlesGeometry = new THREE.BufferGeometry(); +const particlesCnt = 15000; + +const posArray = new Float32Array(particlesCnt * 3); +// xyz, xyz, xyz, xyz + +for (let i = 0; i < particlesCnt * 3; i++) { + // posArray[i] = Math.random(); + // posArray[i] = Math.random() - 0.5; + // posArray[i] = (Math.random() - 0.5) * 5; + posArray[i] = (Math.random() - 0.5) * (Math.random() * 5); +} + +particlesGeometry.setAttribute( + "position", + new THREE.BufferAttribute(posArray, 3) +); // Materials -const material = new THREE.MeshBasicMaterial() -material.color = new THREE.Color(0xff0000) +const material = new THREE.PointsMaterial({ + size: 0.005, +}); + +const particlesMaterial = new THREE.PointsMaterial({ + size: 0.005, + map: cross, +}); // Mesh -const sphere = new THREE.Mesh(geometry,material) -scene.add(sphere) +const sphere = new THREE.Points(geometry, material); +const particlesMesh = new THREE.Points(particlesGeometry, particlesMaterial); +scene.add(sphere, particlesMesh); // Lights -const pointLight = new THREE.PointLight(0xffffff, 0.1) -pointLight.position.x = 2 -pointLight.position.y = 3 -pointLight.position.z = 4 -scene.add(pointLight) +const pointLight = new THREE.PointLight(0xffffff, 0.1); +pointLight.position.x = 2; +pointLight.position.y = 3; +pointLight.position.z = 4; +scene.add(pointLight); /** * Sizes */ const sizes = { - width: window.innerWidth, - height: window.innerHeight -} + width: window.innerWidth, + height: window.innerHeight, +}; -window.addEventListener('resize', () => -{ - // Update sizes - sizes.width = window.innerWidth - sizes.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 camera + camera.aspect = sizes.width / sizes.height; + camera.updateProjectionMatrix(); - // Update renderer - renderer.setSize(sizes.width, sizes.height) - renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)) -}) + // 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 = 0 -camera.position.y = 0 -camera.position.z = 2 -scene.add(camera) +const camera = new THREE.PerspectiveCamera( + 75, + sizes.width / sizes.height, + 0.1, + 100 +); +camera.position.x = 0; +camera.position.y = 0; +camera.position.z = 2; +scene.add(camera); // Controls // const controls = new OrbitControls(camera, canvas) @@ -73,33 +106,49 @@ scene.add(camera) * Renderer */ const renderer = new THREE.WebGLRenderer({ - canvas: canvas -}) -renderer.setSize(sizes.width, sizes.height) -renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)) + canvas: canvas, + alpha: true, +}); +renderer.setSize(sizes.width, sizes.height); +renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); + +// Mouse + +document.addEventListener("mousemove", animateParticles); + +let mouseX = 0; +let mouseY = 0; + +function animateParticles(event) { + mouseY = event.clientY; + mouseX = event.clientY; +} /** * Animate */ -const clock = new THREE.Clock() - -const tick = () => -{ +const clock = new THREE.Clock(); - const elapsedTime = clock.getElapsedTime() +const tick = () => { + const elapsedTime = clock.getElapsedTime(); - // Update objects - sphere.rotation.y = .5 * elapsedTime + // Update objects + sphere.rotation.y = 0.5 * elapsedTime; + particlesMesh.rotation.x = -0.005 * elapsedTime; - // Update Orbital Controls - // controls.update() + if (mouseX > 0) { + particlesMesh.rotation.y = -mouseY * (elapsedTime * 0.000008); + particlesMesh.rotation.y = mouseY * (elapsedTime * 0.00004); + } + // Update Orbital Controls + // controls.update() - // Render - renderer.render(scene, camera) + // Render + renderer.render(scene, camera); - // Call tick again on the next frame - window.requestAnimationFrame(tick) -} + // Call tick again on the next frame + window.requestAnimationFrame(tick); +}; -tick() \ No newline at end of file +tick(); diff --git a/src/style.css b/src/style.css index 70e4e1afa..d2287dad3 100644 --- a/src/style.css +++ b/src/style.css @@ -1,20 +1,65 @@ -* -{ - margin: 0; - padding: 0; +* { + margin: 0; + padding: 0; } html, -body -{ - height: 100vh; - font-family: 'Poppins'; -} - -.webgl -{ - position: fixed; - top: 0; - left: 0; - outline: none; +body { + height: 100vh; + font-family: "Poppins"; + background-color: #21282a; + color: white; +} + +.webgl { + position: fixed; + top: 0; + left: 0; + outline: none; +} + +.container { + position: absolute; + z-index: 1; + width: 100%; + height: 100vh; + display: grid; + place-items: center; +} + +.content { + display: flex; + gap: 5em; + width: 90%; + padding-top: 3em; + position: relative; +} + +.content:before { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + border-bottom: 1px solid white; + transform: scale(1); +} + +h1 { + font-size: 4em; + width: 50vw; + line-height: 97%; + text-align: right; +} + +h1, +p { + flex-basis: 0; + flex-grow: 1; + clip-path: polygon(0 0, 100% 0, 100% 0, 0 0); +} + +p { + font-size: 1.3rem; + width: 40vw; } diff --git a/static/cross.png b/static/cross.png new file mode 100644 index 000000000..c9f635ef5 Binary files /dev/null and b/static/cross.png differ diff --git a/static/cross.svg b/static/cross.svg new file mode 100644 index 000000000..437b84609 --- /dev/null +++ b/static/cross.svg @@ -0,0 +1,4 @@ + + + +