Skip to content

Commit 5d4ea69

Browse files
add
1 parent bc3789b commit 5d4ea69

File tree

2 files changed

+56
-18
lines changed

2 files changed

+56
-18
lines changed

index.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
<!DOCTYPE html>
22
<html lang="en">
3+
34
<head>
45
<meta charset="UTF-8">
56
<meta name="viewport" content="width=device-width, initial-scale=1.0">
67
<title>Kirov Airship Showcase</title>
78
<link rel="stylesheet" href="style.css">
89
</head>
10+
911
<body>
1012
<canvas id="bg"></canvas>
1113

@@ -37,6 +39,17 @@ <h2>Helium optimal.</h2>
3739
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/ScrollTrigger.min.js"></script>
3840
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/loaders/GLTFLoader.js"></script>
3941

42+
<!-- ... các thẻ script khác ... -->
43+
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/loaders/GLTFLoader.js"></script>
44+
45+
<!-- ***** THÊM DÒNG NÀY ***** -->
46+
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.js"></script>
47+
48+
<!-- Tệp JavaScript của chúng ta -->
4049
<script src="script.js"></script>
4150
</body>
51+
52+
</html>
53+
</body>
54+
4255
</html>

script.js

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22
gsap.registerPlugin(ScrollTrigger);
33

44
// --------------------------------------------------------------------
5-
// 1. THIẾT LẬP CẢNH 3D CƠ BẢN
5+
// 1. THIẾT LẬP CẢNH 3D
66
// --------------------------------------------------------------------
77
const scene = new THREE.Scene();
88
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
9-
// Vẫn giữ camera ở xa để đảm bảo thấy mô hình lúc đầu
109
camera.position.set(0, 5, 30);
1110

1211
const renderer = new THREE.WebGLRenderer({
@@ -17,31 +16,30 @@ const renderer = new THREE.WebGLRenderer({
1716
renderer.setSize(window.innerWidth, window.innerHeight);
1817
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
1918

19+
// ***** KHỞI TẠO ORBIT CONTROLS *****
20+
// Truyền vào camera và canvas để nó biết cần điều khiển cái gì và lắng nghe sự kiện ở đâu
21+
const controls = new THREE.OrbitControls(camera, renderer.domElement);
22+
controls.enableDamping = true; // Tạo ra hiệu ứng "quán tính" mượt mà khi xoay
23+
controls.enablePan = false; // Tắt tính năng kéo (pan) để người dùng không kéo Kirov ra khỏi màn hình
24+
controls.minDistance = 10; // Ngăn người dùng zoom quá gần
25+
controls.maxDistance = 150; // Ngăn người dùng zoom quá xa
26+
27+
// Ánh sáng và Skybox (giữ nguyên)
2028
const ambientLight = new THREE.AmbientLight(0xffffff, 0.8);
2129
scene.add(ambientLight);
2230
const directionalLight = new THREE.DirectionalLight(0xffffff, 1.5);
23-
directionalLight.position.set(10, 10, 5); // Thay đổi hướng sáng một chút
31+
directionalLight.position.set(10, 10, 5);
2432
scene.add(directionalLight);
2533

26-
// --------------------------------------------------------------------
27-
// THÊM SKYBOX
28-
// --------------------------------------------------------------------
2934
const cubeTextureLoader = new THREE.CubeTextureLoader();
3035
cubeTextureLoader.setPath('air-skybox/');
31-
32-
// ***** THAY ĐỔI DUY NHẤT: CẬP NHẬT TÊN FILE SKYBOX MỚI *****
33-
// Chúng ta thay đổi tên file để khớp với bộ ảnh bạn vừa tải về.
3436
const textureCube = cubeTextureLoader.load([
3537
'px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png'
3638
]);
37-
38-
// Đặt skybox làm background cho scene
3939
scene.background = textureCube;
40-
// ***** KẾT THÚC THAY ĐỔI *****
41-
4240

4341
// --------------------------------------------------------------------
44-
// 2. TẢI MÔ HÌNH 3D MỚI
42+
// 2. TẢI MÔ HÌNH (Giữ nguyên)
4543
// --------------------------------------------------------------------
4644
const loader = new THREE.GLTFLoader();
4745
let newModel;
@@ -50,11 +48,9 @@ loader.load(
5048
'models/air_ship_1K.glb',
5149
function (gltf) {
5250
newModel = gltf.scene;
53-
5451
newModel.position.set(0, -2, 0);
5552
newModel.scale.set(1, 1, 1);
5653
newModel.rotation.set(0, Math.PI / 2, 0);
57-
5854
scene.add(newModel);
5955
setupScrollAnimation();
6056
},
@@ -63,10 +59,12 @@ loader.load(
6359
);
6460

6561
// --------------------------------------------------------------------
66-
// 3. THIẾT LẬP LẠI HIỆU ỨNG CUỘN (GIỮ NGUYÊN)
62+
// 3. THIẾT LẬP HIỆU ỨNG CUỘN (CÓ THAY ĐỔI NHỎ)
6763
// --------------------------------------------------------------------
6864
function setupScrollAnimation() {
65+
// ***** THÊM ID CHO TIMELINE ĐỂ CÓ THỂ ĐIỀU KHIỂN NÓ *****
6966
const tl = gsap.timeline({
67+
id: "main-timeline", // Đặt một cái tên cho timeline
7068
scrollTrigger: {
7169
trigger: 'main',
7270
start: 'top top',
@@ -76,6 +74,7 @@ function setupScrollAnimation() {
7674
}
7775
});
7876

77+
// Các animation giữ nguyên
7978
tl
8079
.to(camera.position, { z: 20, y: 3 })
8180
.to(camera.position, { x: -15 })
@@ -88,14 +87,40 @@ function setupScrollAnimation() {
8887
.to(camera.rotation, { x: 0 }, "<");
8988
}
9089

90+
// ***** GIẢI QUYẾT XUNG ĐỘT GIỮA SCROLL VÀ KÉO CHUỘT *****
91+
controls.addEventListener('start', () => {
92+
// Khi người dùng bắt đầu kéo chuột, vô hiệu hóa animation cuộn
93+
console.log("OrbitControls started, ScrollTrigger disabled.");
94+
const mainTimeline = ScrollTrigger.getById("main-timeline");
95+
if (mainTimeline) {
96+
mainTimeline.disable();
97+
}
98+
});
99+
100+
controls.addEventListener('end', () => {
101+
// Khi người dùng thả chuột, kích hoạt lại animation cuộn
102+
console.log("OrbitControls ended, ScrollTrigger enabled.");
103+
const mainTimeline = ScrollTrigger.getById("main-timeline");
104+
if (mainTimeline) {
105+
mainTimeline.enable();
106+
}
107+
});
108+
109+
91110
// --------------------------------------------------------------------
92-
// 4. VÒNG LẶP RENDER VÀ RESIZE (GIỮ NGUYÊN)
111+
// 4. VÒNG LẶP RENDER (CÓ THAY ĐỔI)
93112
// --------------------------------------------------------------------
94113
function animate() {
95114
requestAnimationFrame(animate);
115+
116+
// ***** CẬP NHẬT ORBIT CONTROLS TRONG MỖI FRAME *****
117+
// Điều này là bắt buộc nếu bạn bật `enableDamping`
118+
controls.update();
119+
96120
renderer.render(scene, camera);
97121
}
98122

123+
// Các hàm còn lại giữ nguyên
99124
window.addEventListener('resize', () => {
100125
camera.aspect = window.innerWidth / window.innerHeight;
101126
camera.updateProjectionMatrix();

0 commit comments

Comments
 (0)