<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<title>3d台式机小屋</title>
<style>
*,
*::after,
*::before {
margin: 0;
padding: 0;
box-sizing: border-box;
outline: none;
font-family: monospace;
}
body {
overflow: hidden;
background-color: #d2cfc8;
cursor: grab;
}
.webgl,
#loader {
position: fixed;
top: 0;
left: 0;
}
#loader {
display: grid;
place-content: center;
width: 100%;
height: 100%;
background-color: #faedcd;
}
</style>
</head>
<body>
<canvas class="webgl"></canvas>
<div id="loader">
<h1>Loading</h1>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r124/three.min.js"></script>
<script src="https://unpkg.com/three@0.126.0/examples/js/loaders/GLTFLoader.js"></script>
<script src="https://unpkg.com/three@0.126.0/examples/js/controls/OrbitControls.js"></script>
<script>
const loading = document.querySelector('#loader');
const canvas = document.querySelector('.webgl');
const scene = new THREE.Scene();
const textureLoader = new THREE.TextureLoader();
const sizes = { width: window.innerWidth, height: window.innerHeight };
const camera = new THREE.PerspectiveCamera(
10,
sizes.width / sizes.height,
0.1,
100
);
camera.position.x = 8;
camera.position.y = 4;
camera.position.z = 15;
scene.add(camera);
const controls = new THREE.OrbitControls(camera, canvas);
controls.enableDamping = true;
controls.enableZoom = true;
controls.enablePan = true;
controls.minDistance = 21;
controls.maxDistance = 50;
controls.minPolarAngle = Math.PI / 5;
controls.maxPolarAngle = Math.PI / 2;
const renderer = new THREE.WebGLRenderer({
canvas: canvas,
antialias: true,
alpha: true,
});
renderer.setSize(sizes.width, sizes.height);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.outputEncoding = THREE.sRGBEncoding;
const bakedTexture = textureLoader.load(
'https://www.fecoder.cn/code-fun/baked.jpg'
);
bakedTexture.flipY = false;
bakedTexture.encoding = THREE.sRGBEncoding;
const bakedMaterial = new THREE.MeshBasicMaterial({ map: bakedTexture });
const loader = new THREE.GLTFLoader();
loader.load(
'https://www.fecoder.cn/code-fun/model.glb',
(gltf) => {
const model = gltf.scene;
model.traverse((child) => (child.material = bakedMaterial));
scene.add(model);
scene.position.set(0, 0.2, 0);
loading.style.display = 'none';
},
(xhr) => {
console.log((xhr.loaded / xhr.total) * 100 + '% loaded');
}
);
window.addEventListener('resize', () => {
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));
});
var minPan = new THREE.Vector3(-2, -0.5, -2);
var maxPan = new THREE.Vector3(2, 0.5, 2);
const tick = () => {
controls.update();
controls.target.clamp(minPan, maxPan);
renderer.render(scene, camera);
window.requestAnimationFrame(tick);
};
tick();
</script>
</body>
</html>