simple Three.js site
This commit is contained in:
parent
e33031c071
commit
830af4ac9b
11 changed files with 2306 additions and 1 deletions
|
@ -93,6 +93,13 @@ services:
|
||||||
secrets:
|
secrets:
|
||||||
- db_password
|
- db_password
|
||||||
env_file: .env
|
env_file: .env
|
||||||
|
site:
|
||||||
|
restart: on-failure
|
||||||
|
build:
|
||||||
|
context: ./requirements/bonus/site
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
networks:
|
||||||
|
- inception
|
||||||
|
|
||||||
secrets:
|
secrets:
|
||||||
db_password:
|
db_password:
|
||||||
|
|
16
srcs/requirements/bonus/site/Dockerfile
Normal file
16
srcs/requirements/bonus/site/Dockerfile
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
FROM alpine:3.21.2
|
||||||
|
|
||||||
|
LABEL org.opencontainers.image.authors="alier@student.42mulhouse.fr"
|
||||||
|
|
||||||
|
RUN apk add nodejs curl npm
|
||||||
|
|
||||||
|
COPY app/ /app
|
||||||
|
|
||||||
|
RUN cd /app && npm install && npm run build
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
HEALTHCHECK --start-period=5s \
|
||||||
|
CMD curl "http://site:3000/site/index.html" --fail || exit 1
|
||||||
|
|
||||||
|
ENTRYPOINT ["node", "/app/index.mjs"]
|
20
srcs/requirements/bonus/site/app/index.mjs
Normal file
20
srcs/requirements/bonus/site/app/index.mjs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import Fastify from 'fastify';
|
||||||
|
import path from 'node:path';
|
||||||
|
import * as staticPlugin from '@fastify/static';
|
||||||
|
|
||||||
|
const fastify = Fastify({
|
||||||
|
logger: true
|
||||||
|
});
|
||||||
|
|
||||||
|
fastify.register(staticPlugin, {
|
||||||
|
root: path.join(import.meta.dirname, 'dist'),
|
||||||
|
prefix: '/site/',
|
||||||
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
await fastify.listen({ port: 3000, host: 'site' });
|
||||||
|
} catch (err) {
|
||||||
|
fastify.log.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
};
|
||||||
|
|
2103
srcs/requirements/bonus/site/app/package-lock.json
generated
Normal file
2103
srcs/requirements/bonus/site/app/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
14
srcs/requirements/bonus/site/app/package.json
Normal file
14
srcs/requirements/bonus/site/app/package.json
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build src --outDir ../dist --emptyOutDir --base /site"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@fastify/static": "^8.1.1",
|
||||||
|
"fastify": "^5.2.1",
|
||||||
|
"lil-gui": "^0.20.0",
|
||||||
|
"three": "^0.173.0",
|
||||||
|
"vite": "^6.1.0"
|
||||||
|
}
|
||||||
|
}
|
115
srcs/requirements/bonus/site/app/src/app.mjs
Normal file
115
srcs/requirements/bonus/site/app/src/app.mjs
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
import * as THREE from 'three';
|
||||||
|
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
|
||||||
|
import { TextGeometry } from 'three/addons/geometries/TextGeometry.js';
|
||||||
|
import { FontLoader } from 'three/addons/loaders/FontLoader.js';
|
||||||
|
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
|
||||||
|
import GUI from 'lil-gui';
|
||||||
|
|
||||||
|
const gui = new GUI();
|
||||||
|
|
||||||
|
const sizes = {
|
||||||
|
width: window.innerWidth,
|
||||||
|
height: window.innerHeight
|
||||||
|
};
|
||||||
|
|
||||||
|
const scene = new THREE.Scene();
|
||||||
|
const fontLoader = new FontLoader();
|
||||||
|
const textureLoader = new THREE.TextureLoader();
|
||||||
|
const gltfLoader = new GLTFLoader();
|
||||||
|
|
||||||
|
scene.add(new THREE.AmbientLight());
|
||||||
|
|
||||||
|
const light = new THREE.PointLight();
|
||||||
|
light.intensity = 50;
|
||||||
|
light.position.y = 6;
|
||||||
|
scene.add(light);
|
||||||
|
|
||||||
|
const matcapTexture = textureLoader.load('/site/textures/matcaps/gold.png');
|
||||||
|
matcapTexture.colorSpace = THREE.SRGBColorSpace;
|
||||||
|
|
||||||
|
const material = new THREE.MeshMatcapMaterial({ matcap: matcapTexture });
|
||||||
|
|
||||||
|
fontLoader.load('/site/fonts/helvetiker_regular.typeface.json', function (font) {
|
||||||
|
const textGeometry = new TextGeometry('oui oui baguette', {
|
||||||
|
font,
|
||||||
|
size: 1,
|
||||||
|
depth: 0.5
|
||||||
|
});
|
||||||
|
|
||||||
|
textGeometry.center();
|
||||||
|
|
||||||
|
const cubeMesh = new THREE.Mesh(textGeometry, material);
|
||||||
|
scene.add(cubeMesh);
|
||||||
|
|
||||||
|
cubeMesh.position.x = 0;
|
||||||
|
cubeMesh.position.y = 0;
|
||||||
|
|
||||||
|
gui.add(cubeMesh.position, 'y', -3, 3, 0.01);
|
||||||
|
gui.add(cubeMesh, 'visible');
|
||||||
|
gui.add(cubeMat, 'wireframe');
|
||||||
|
gui.addColor(cubeMat, 'color');
|
||||||
|
});
|
||||||
|
|
||||||
|
gltfLoader.load('/site/models/baguette.glb', function (gltf) {
|
||||||
|
for (let i = 0; i < 100; i++) {
|
||||||
|
const baguette = gltf.scene.clone();
|
||||||
|
baguette.position.x = (Math.random() - 0.5) * 10;
|
||||||
|
baguette.position.y = (Math.random() - 0.5) * 10;
|
||||||
|
baguette.position.z = (Math.random() - 0.5) * 10;
|
||||||
|
baguette.rotation.x = Math.random() * Math.PI;
|
||||||
|
baguette.rotation.y = Math.random() * Math.PI;
|
||||||
|
const scale = Math.random();
|
||||||
|
baguette.scale.set(scale, scale, scale);
|
||||||
|
scene.add(baguette);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height);
|
||||||
|
camera.position.z = 5;
|
||||||
|
|
||||||
|
//const axesHelper = new THREE.AxesHelper(1);
|
||||||
|
//scene.add(axesHelper);
|
||||||
|
|
||||||
|
const canvas = document.getElementById('three');
|
||||||
|
|
||||||
|
function updateSize() {
|
||||||
|
sizes.width = window.innerWidth;
|
||||||
|
sizes.height = window.innerHeight;
|
||||||
|
|
||||||
|
camera.aspect = sizes.width / sizes.height;
|
||||||
|
camera.updateProjectionMatrix();
|
||||||
|
|
||||||
|
renderer.setSize(sizes.width, sizes.height);
|
||||||
|
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderer = new THREE.WebGLRenderer({ canvas });
|
||||||
|
|
||||||
|
updateSize();
|
||||||
|
|
||||||
|
const clock = new THREE.Clock();
|
||||||
|
|
||||||
|
const controls = new OrbitControls(camera, canvas);
|
||||||
|
|
||||||
|
function render() {
|
||||||
|
const elapsedTime = clock.getElapsedTime();
|
||||||
|
|
||||||
|
renderer.render(scene, camera);
|
||||||
|
|
||||||
|
requestAnimationFrame(render);
|
||||||
|
}
|
||||||
|
|
||||||
|
requestAnimationFrame(render);
|
||||||
|
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
updateSize();
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener('dblclick', () => {
|
||||||
|
if (!document.fullscreenElement) {
|
||||||
|
canvas.requestFullscreen();
|
||||||
|
} else {
|
||||||
|
document.exitFullscreen();
|
||||||
|
}
|
||||||
|
});
|
25
srcs/requirements/bonus/site/app/src/index.html
Normal file
25
srcs/requirements/bonus/site/app/src/index.html
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Baguette Land</title>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#three {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<canvas id="three"></canvas>
|
||||||
|
<script src="app.mjs" type="module"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
File diff suppressed because one or more lines are too long
BIN
srcs/requirements/bonus/site/app/src/public/models/baguette.glb
Normal file
BIN
srcs/requirements/bonus/site/app/src/public/models/baguette.glb
Normal file
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 68 KiB |
|
@ -31,4 +31,8 @@ server {
|
||||||
include fastcgi_params;
|
include fastcgi_params;
|
||||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
location /site {
|
||||||
|
proxy_pass http://site:3000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue