|
1 | | -# My Personal Portfolio Website (v2.0.0) |
| 1 | +# Dự án Trình diễn 3D với Hiệu ứng Cuộn Chuột |
2 | 2 |
|
3 | | - |
4 | | -<!-- QUAN TRỌNG: Hãy chụp một bức ảnh đẹp của trang web mới và lưu nó với tên là "screenshot.png" trong thư mục "assets" của bạn --> |
| 3 | +Đây là một dự án web demo, trình diễn cách sử dụng các công nghệ web hiện đại để tạo ra một trang web tương tác, nơi người dùng có thể điều khiển một hoạt cảnh 3D bằng cách cuộn chuột. Dự án này lấy cảm hứng từ các trang giới thiệu sản phẩm của Apple hoặc các trang web portfolio sáng tạo. |
5 | 4 |
|
6 | | -Welcome to the repository for my personal portfolio. This is a completely redesigned and rebuilt version focusing on a modern interface, smooth user experience, and unique interactive features. |
7 | 5 |
|
8 | | -**✨ [View Live Version!](https://tranhuudat2004.github.io/) ✨** |
| 6 | + |
9 | 7 |
|
10 | | ---- |
| 8 | +## Công nghệ sử dụng |
11 | 9 |
|
12 | | -<details> |
13 | | -<summary><strong>🇻🇳 Tiếng Việt (Vietnamese)</strong></summary> |
| 10 | +* **HTML5 / CSS3:** Cấu trúc và giao diện cơ bản của trang web. |
| 11 | +* **Three.js:** Một thư viện JavaScript mạnh mẽ để tạo và hiển thị đồ họa 3D trong trình duyệt. |
| 12 | +* **GSAP (GreenSock Animation Platform):** "Tiêu chuẩn vàng" trong ngành cho các hiệu ứng chuyển động (animation) hiệu suất cao trên web. |
| 13 | +* **ScrollTrigger:** Một plugin của GSAP, dùng để kích hoạt các animation dựa trên vị trí của thanh cuộn. |
14 | 14 |
|
15 | | -## 🚀 Giới thiệu |
| 15 | +## Hướng dẫn Cài đặt và Chạy |
16 | 16 |
|
17 | | -Dự án này là phiên bản nâng cấp toàn diện từ portfolio cũ của tôi. Mục tiêu là tạo ra một không gian trực tuyến không chỉ để trưng bày các dự án và kỹ năng, mà còn để thể hiện đam mê của tôi đối với thiết kế đẹp, code hiệu quả và các công nghệ web hiện đại. |
| 17 | +Để chạy dự án này trên máy của bạn, bạn cần một máy chủ web cục bộ (local server) để trình duyệt có thể tải tệp mô hình 3D (`.glb`). |
18 | 18 |
|
19 | | -Trang web được xây dựng với triết lý "dark mode" chủ đạo, kết hợp hiệu ứng "glassmorphism" để tạo chiều sâu và sự tinh tế. |
| 19 | +**Cách đơn giản nhất là sử dụng Visual Studio Code và tiện ích "Live Server":** |
20 | 20 |
|
21 | | ---- |
| 21 | +1. **Clone hoặc tải về** toàn bộ mã nguồn của dự án này. |
| 22 | +2. Mở thư mục dự án bằng **Visual Studio Code**. |
| 23 | +3. Trong VS Code, vào tab Tiện ích (Extensions) và tìm kiếm `Live Server`, sau đó cài đặt nó. |
| 24 | +4. Sau khi cài đặt xong, chuột phải vào tệp `index.html` trong cây thư mục và chọn **"Open with Live Server"**. |
| 25 | +5. Trang web sẽ tự động mở trong trình duyệt của bạn và mọi thứ sẽ hoạt động! |
22 | 26 |
|
23 | | -## 🎨 Các tính năng chính |
| 27 | +## Giải thích chi tiết `script.js` |
24 | 28 |
|
25 | | -- **Thiết kế Hiện đại & Responsive:** Giao diện tối (dark theme) thân thiện với mắt, tự động điều chỉnh hoàn hảo trên mọi thiết bị từ desktop, tablet đến mobile. |
26 | | -- **Animation Tương tác:** Các phần tử sẽ xuất hiện và biến mất mượt mà khi người dùng cuộn trang, tạo ra một trải nghiệm sống động và tập trung. |
27 | | -- **Kỹ năng động từ GitHub API:** Phần "Technical Stack" không phải là dữ liệu tĩnh. Nó tự động lấy các ngôn ngữ lập trình tôi sử dụng nhiều nhất trực tiếp từ tài khoản GitHub của tôi thông qua API, đảm bảo danh sách kỹ năng luôn được cập nhật. |
28 | | -- **Thanh điều hướng thông minh:** Vạch chỉ báo (indicator) di chuyển mượt mà theo từng mục khi người dùng cuộn hoặc nhấp chuột. |
29 | | -- **Trình phát nhạc:** Một widget nhỏ cho phép khách truy cập nghe những bản nhạc yêu thích của tôi, thể hiện một chút cá tính cá nhân. |
30 | | -- **Hiệu ứng Glassmorphism:** Các thẻ (card) được thiết kế với hiệu ứng kính mờ, tạo cảm giác hiện đại và có chiều sâu. |
| 29 | +Tệp `script.js` là "bộ não" của toàn bộ dự án. Nó được chia thành 4 phần chính: |
31 | 30 |
|
32 | | ---- |
| 31 | +### 1. Thiết lập Cảnh 3D (Three.js) |
33 | 32 |
|
34 | | -## 🛠️ Ngăn xếp Công nghệ |
| 33 | +Phần này khởi tạo các thành phần cơ bản để có thể hiển thị một vật thể 3D: |
35 | 34 |
|
36 | | -Dự án này được xây dựng hoàn toàn từ gốc với các công nghệ web cốt lõi: |
| 35 | +* `const scene = new THREE.Scene();`: Tạo ra một "sân khấu" để chứa tất cả các đối tượng, mô hình, và ánh sáng. |
| 36 | +* `const camera = new THREE.PerspectiveCamera(...)`: Tạo ra một "máy quay" ảo. Đây là góc nhìn của người dùng vào sân khấu. |
| 37 | + * **`camera.position.set(x, y, z)`**: Đặt vị trí ban đầu của máy quay. **Đây là thuộc tính quan trọng nhất để điều chỉnh góc nhìn ban đầu (ra xa, lại gần, cao, thấp).** |
| 38 | +* `const renderer = new THREE.WebGLRenderer(...)`: Tạo ra "họa sĩ", người sẽ lấy hình ảnh từ `camera` và vẽ nó lên thẻ `<canvas>` trong HTML. |
| 39 | +* `const ambientLight = ...`, `const directionalLight = ...`: Tạo ra các nguồn "ánh sáng" ảo. Nếu không có ánh sáng, mô hình sẽ có màu đen kịt. |
37 | 40 |
|
38 | | -- **HTML5:** Cấu trúc ngữ nghĩa và chuẩn SEO. |
39 | | -- **CSS3:** |
40 | | - - Sử dụng biến CSS (CSS Variables) để quản lý màu sắc và theme một cách nhất quán. |
41 | | - - Layout hiện đại với **CSS Grid** và **Flexbox**. |
42 | | - - Animations và Transitions mượt mà. |
43 | | -- **JavaScript (ES6+):** |
44 | | - - Thao tác với DOM để tạo các tính năng tương tác. |
45 | | - - Sử dụng **`fetch` API** để gọi dữ liệu từ GitHub. |
46 | | - - **`IntersectionObserver`** để tối ưu hóa hiệu năng cho các animation khi cuộn. |
47 | | -- **API:** GitHub API |
48 | | -- **Thư viện:** Font Awesome (cho các icon). |
49 | | -- **Deployment:** GitHub Pages. |
| 41 | +### 2. Tải Mô hình 3D |
50 | 42 |
|
51 | | ---- |
| 43 | +Phần này sử dụng `GLTFLoader` của Three.js để tải tệp mô hình `.glb` vào sân khấu: |
52 | 44 |
|
53 | | -## ⚙️ Thiết lập và Chạy cục bộ |
| 45 | +```javascript |
| 46 | +loader.load( |
| 47 | + 'path/to/your/model.glb', // Đường dẫn tới tệp |
| 48 | + function (gltf) { |
| 49 | + // Hàm này sẽ được gọi KHI mô hình tải XONG |
| 50 | + model = gltf.scene; |
| 51 | + scene.add(model); // Thêm mô hình vào sân khấu |
| 52 | + setupScrollAnimation(); // QUAN TRỌNG: Chỉ chạy animation sau khi mô hình đã sẵn sàng |
| 53 | + } |
| 54 | +); |
| 55 | +``` |
| 56 | +Trong hàm callback này, chúng ta có thể điều chỉnh vị trí, kích thước, và hướng xoay ban đầu của mô hình bằng các thuộc tính: |
| 57 | +* `model.position.set(x, y, z)` |
| 58 | +* `model.scale.set(x, y, z)` |
| 59 | +* `model.rotation.set(x, y, z)` |
54 | 60 |
|
55 | | -Nếu bạn muốn xem hoặc thử nghiệm trang web này trên máy của mình: |
| 61 | +### 3. "Phép thuật" của GSAP và ScrollTrigger |
56 | 62 |
|
57 | | -1. **Clone a repository:** |
58 | | - ```bash |
59 | | - git clone https://github.com/TranHuuDat2004/TranHuuDat2004.github.io.git |
60 | | - ``` |
| 63 | +Đây là trái tim của hiệu ứng. Chúng ta tạo ra một chuỗi các animation và "gắn" nó vào thanh cuộn. |
61 | 64 |
|
62 | | -2. **Điều hướng đến thư mục dự án:** |
63 | | - ```bash |
64 | | - cd TranHuuDat2004.github.io |
65 | | - ``` |
| 65 | +* `gsap.registerPlugin(ScrollTrigger);`: Đăng ký để có thể sử dụng plugin ScrollTrigger. |
| 66 | +* `const tl = gsap.timeline({...});`: Tạo một **Timeline**, là một chuỗi các animation sẽ diễn ra tuần tự. |
66 | 67 |
|
67 | | -3. **Mở file `index.html`:** |
68 | | - - Bạn có thể mở trực tiếp bằng trình duyệt. |
69 | | - - **Gợi ý:** Để có trải nghiệm tốt nhất, hãy sử dụng một tiện ích mở rộng máy chủ trực tiếp (live server) trong trình soạn thảo code của bạn (ví dụ: **Live Server** cho Visual Studio Code). |
| 68 | +Phần quan trọng nhất là đối tượng cấu hình `scrollTrigger`: |
70 | 69 |
|
71 | | ---- |
| 70 | +```javascript |
| 71 | +scrollTrigger: { |
| 72 | + trigger: 'main', // Kích hoạt khi phần tử <main> vào màn hình |
| 73 | + start: 'top top', // Bắt đầu animation khi đỉnh của <main> chạm đỉnh màn hình |
| 74 | + end: 'bottom bottom', // Kết thúc animation khi đáy của <main> chạm đáy màn hình |
| 75 | + scrub: 1, // Điểm mấu chốt! |
| 76 | + markers: false // Đặt là `true` để hiện các vạch đánh dấu khi debug |
| 77 | +} |
| 78 | +``` |
72 | 79 |
|
73 | | -## 📫 Liên hệ |
| 80 | +**`scrub` là gì?** Đây là thuộc tính kỳ diệu nhất: |
| 81 | +* Nếu không có `scrub`, animation sẽ chạy một lần duy nhất khi bạn cuộn đến điểm `start`. |
| 82 | +* Khi có `scrub: true` (hoặc một con số như `1` để mượt hơn), tiến trình của animation sẽ được **kết nối trực tiếp** với vị trí của thanh cuộn. Bạn cuộn xuống, animation chạy tới. Bạn cuộn lên, animation chạy ngược lại. |
74 | 83 |
|
75 | | -Nếu bạn có bất kỳ câu hỏi nào hoặc muốn kết nối, đừng ngần ngại liên hệ với tôi qua: |
| 84 | +Sau khi tạo timeline, chúng ta thêm các animation vào đó bằng phương thức `.to()`: |
76 | 85 |
|
77 | | -- **LinkedIn:** [linkedin.com/in/tranhuudat2004](https://linkedin.com/in/tranhuudat2004) |
78 | | -- **Email:** [tranhuudat.cv@gmail.com](mailto:tranhuudat.cv@gmail.com) |
| 86 | +```javascript |
| 87 | +// .to(đối_tượng, { thuộc_tính_muốn_thay_đổi }) |
| 88 | +tl |
| 89 | + .to(camera.position, { z: 30, y: 10 }) |
| 90 | + .to(camera.position, { x: -25 }) |
| 91 | + .to(airshipModel.rotation, { y: Math.PI }, "<"); // "<" có nghĩa là chạy CÙNG LÚC với animation trước đó |
| 92 | +``` |
| 93 | +Mỗi dòng `.to()` là một bước trong chuỗi animation. GSAP sẽ tự động tính toán và làm cho các chuyển động trở nên mượt mà. |
79 | 94 |
|
80 | | -Cảm ơn bạn đã ghé thăm! |
| 95 | +### 4. Vòng lặp Render |
81 | 96 |
|
82 | | -</details> |
| 97 | +Hàm `animate()` là một vòng lặp vô tận, được gọi liên tục khoảng 60 lần mỗi giây. |
83 | 98 |
|
84 | | ---- |
| 99 | +```javascript |
| 100 | +function animate() { |
| 101 | + requestAnimationFrame(animate); |
| 102 | + renderer.render(scene, camera); |
| 103 | +} |
| 104 | +``` |
| 105 | +Nhiệm vụ của nó rất đơn giản: "Mỗi frame, hãy vẽ lại sân khấu (`scene`) từ góc nhìn của máy quay (`camera`)". Điều này đảm bảo rằng mọi thay đổi về vị trí/xoay của camera hoặc mô hình (do GSAP điều khiển) sẽ được hiển thị ngay lập tức trên màn hình. |
85 | 106 |
|
86 | | -<details> |
87 | | -<summary><strong>🇬🇧 English (Tiếng Anh)</strong></summary> |
| 107 | +## Tùy chỉnh Dự án |
88 | 108 |
|
89 | | -## 🚀 About This Project |
| 109 | +Bạn có thể dễ dàng biến dự án này thành của riêng mình: |
90 | 110 |
|
91 | | -This project is a complete overhaul of my old portfolio. The goal was to create an online space not only to showcase my projects and skills but also to express my passion for beautiful design, efficient code, and modern web technologies. |
| 111 | +1. **Để thay đổi mô hình 3D:** |
| 112 | + * Đặt tệp `.glb` của bạn vào thư mục dự án (hoặc thư mục con `models`). |
| 113 | + * Thay đổi đường dẫn trong hàm `loader.load(...)`. |
| 114 | + * Tinh chỉnh `position`, `scale`, `rotation` của mô hình mới trong hàm callback để có góc nhìn ban đầu đẹp nhất. |
92 | 115 |
|
93 | | -The website is built with a "dark mode" philosophy, incorporating the "glassmorphism" effect to create depth and sophistication. |
94 | | - |
95 | | ---- |
96 | | - |
97 | | -## 🎨 Key Features |
98 | | - |
99 | | -- **Modern & Responsive Design:** A user-friendly dark theme that adapts perfectly to all devices, from desktops and tablets to mobile phones. |
100 | | -- **Interactive Animations:** Elements smoothly appear and disappear as the user scrolls, creating a dynamic and focused experience. |
101 | | -- **Dynamic Skills from GitHub API:** The "Technical Stack" section is not static. It automatically fetches my most-used programming languages directly from my GitHub account via the API, ensuring the skill list is always up-to-date. |
102 | | -- **Smart Navigation Bar:** The active indicator smoothly follows each menu item as the user scrolls or clicks. |
103 | | -- **Music Player:** A small widget that allows visitors to listen to my favorite music, adding a personal touch. |
104 | | -- **Glassmorphism Effect:** Cards are designed with a frosted-glass effect, giving a modern and layered feel. |
105 | | - |
106 | | ---- |
107 | | - |
108 | | -## 🛠️ Tech Stack |
109 | | - |
110 | | -This project was built from scratch with core web technologies: |
111 | | - |
112 | | -- **HTML5:** Semantic structure and SEO standards. |
113 | | -- **CSS3:** |
114 | | - - Utilizes CSS Variables for consistent color and theme management. |
115 | | - - Modern layouts with **CSS Grid** and **Flexbox**. |
116 | | - - Smooth Animations and Transitions. |
117 | | -- **JavaScript (ES6+):** |
118 | | - - DOM manipulation for interactive features. |
119 | | - - Uses the **`fetch` API** to call data from GitHub. |
120 | | - - **`IntersectionObserver`** to optimize performance for scroll-based animations. |
121 | | -- **API:** GitHub API |
122 | | -- **Library:** Font Awesome (for icons). |
123 | | -- **Deployment:** GitHub Pages. |
124 | | - |
125 | | ---- |
126 | | - |
127 | | -## ⚙️ Local Setup |
128 | | - |
129 | | -If you want to view or test this website on your local machine: |
130 | | - |
131 | | -1. **Clone the repository:** |
132 | | - ```bash |
133 | | - git clone https://github.com/TranHuuDat2004/TranHuuDat2004.github.io.git |
134 | | - ``` |
135 | | - |
136 | | -2. **Navigate to the project directory:** |
137 | | - ```bash |
138 | | - cd TranHuuDat2004.github.io |
139 | | - ``` |
140 | | - |
141 | | -3. **Open the `index.html` file:** |
142 | | - - You can open it directly with your browser. |
143 | | - - **Tip:** For the best experience, use a live server extension in your code editor (e.g., **Live Server** for Visual Studio Code). |
144 | | - |
145 | | ---- |
146 | | - |
147 | | -## 📫 Connect with Me |
148 | | - |
149 | | -If you have any questions or would like to connect, feel free to reach out to me via: |
150 | | - |
151 | | -- **LinkedIn:** [linkedin.com/in/tranhuudat2004](https://linkedin.com/in/tranhuudat2004) |
152 | | -- **Email:** [tranhuudat.cv@gmail.com](mailto:tranhuudat.cv@gmail.com) |
153 | | - |
154 | | -Thank you for visiting! |
155 | | - |
156 | | -</details> |
157 | | - |
158 | | ---- |
159 | | - |
160 | | -### Topics |
161 | | - |
162 | | -`portfolio` `personal-website` `front-end` `web-developer` `javascript` `dark-theme` `responsive-design` `css-animations` `github-api` `glassmorphism` |
| 116 | +2. **Để thay đổi kịch bản animation:** |
| 117 | + * Chỉnh sửa các giá trị trong các dòng `.to(...)` bên trong hàm `setupScrollAnimation()`. |
| 118 | + * Thêm hoặc bớt các dòng `.to(...)` để tạo ra một câu chuyện chuyển động hoàn toàn mới. Thỏa sức sáng tạo |
0 commit comments