📘 Giới Thiệu
Việc tạo ra các thành phần tương tác và hoạt hình trong HarmonyOS có thể cải thiện đáng kể sự tương tác của người dùng — đặc biệt là trong các trò chơi giải trí hoặc ứng dụng dự thưởng. Trong bài viết này, tôi sẽ hướng dẫn bạn cách xây dựng một bánh xe “Lucky Spin” đơn giản nhưng mượt mà bằng HarmonyOS và ArkTS.
Chúng ta sẽ sử dụng PieChartModel từ @ohos/mpchart, hoạt hình cơ bản với @ohos/animator, và một số mẹo bố trí để làm cho giao diện người dùng trở nên thú vị và phản hồi tốt.
📊 Lucky Spin Là Gì?
Lucky Spin là một bánh xe giải thưởng hình tròn được chia thành các phân khúc, mỗi phân khúc đại diện cho một phần thưởng như “Điện thoại thông minh”, “Laptop” hoặc “Tai nghe VR”. Người dùng nhấn nút Spin, và bánh xe sẽ quay — cuối cùng dừng lại ở một phần thưởng ngẫu nhiên.
Nó thường được sử dụng trong các trò chơi, ứng dụng khách hàng trung thành hoặc sự kiện khuyến mãi để tăng thêm sự hồi hộp và cung cấp phản hồi ngẫu nhiên.
🛠️ Bước 1: Nhập Các Thành Phần PieChart Cần Thiết
Trước khi xây dựng biểu đồ, chúng ta cần nhập các lớp cần thiết từ gói @ohos/mpchart.
javascript
import {
ColorTemplate,
JArrayList,
MPPointF,
PieChart,
PieChartModel,
PieData,
PieDataSet,
PieEntry
} from '@ohos/mpchart';
PieChartModel: Logic chính và trình xử lý dữ liệu cho biểu đồPieChart: Thành phần giao diện người dùng hiển thị bánh xePieEntry: Đại diện cho một phân khúc duy nhất của bánh xePieDataSet: Một tập hợp các mục với kiểu dángColorTemplate: Một bộ màu sắc đã được định nghĩa sẵnJArrayList: Dùng để xây dựng danh sách các mục và màu sắc của biểu đồMPPointF: Dùng để định nghĩa vị trí biểu tượng/văn bản
🛠️ Bước 2: Khởi Tạo Biểu Đồ Bánh
Tôi đã sử dụng PieChartModel để xây dựng bánh xe hình tròn. Tôi đã tắt lỗ, chú thích, và tương tác chạm, vì vậy nó hoạt động như một biểu đồ tĩnh — chỉ quay khi có lệnh.
🎨 Bước 3: Thiết Lập Dữ Liệu Giải Thưởng và Màu Sắc
Để đại diện cho từng phân khúc phần thưởng, tôi đã sử dụng các đối tượng PieEntry với giá trị bằng nhau, và sau đó tạo kiểu cho biểu đồ bằng các lát màu sắc từ ColorTemplate.
javascript
private async setData(range: number): Promise<void> {
let entries: JArrayList<PieEntry> = new JArrayList<PieEntry>();
for (let i = 0; i < this.count; i++) {
entries.add(new PieEntry(range, this.parties[i % this.parties.length]));
}
let dataSet: PieDataSet = new PieDataSet(entries, "Giải Thưởng");
dataSet.setSliceSpace(1); // Khoảng cách nhỏ giữa các lát
dataSet.setIconsOffset(new MPPointF(0, 40)); // Vị trí lệch cho biểu tượng có thể có
dataSet.setSelectionShift(5); // Di chuyển hình ảnh khi chọn
dataSet.setValueTextColor(Color.White); // Màu chữ giá trị
dataSet.setDrawValues(false); // Ẩn giá trị trong các lát
let colors: JArrayList<number> = new JArrayList();
for (let index = 0; index < ColorTemplate.COLORFUL_COLORS.length; index++) {
colors.add(ColorTemplate.COLORFUL_COLORS[index]);
}
colors.add(ColorTemplate.getHoloBlue()); // Thêm màu sắc bổ sung
dataSet.setColorsByList(colors);
let data: PieData = new PieData(dataSet);
this.onePartAngle = 360 / this.count;
this.model.setRotationAngle(-90 - this.onePartAngle / 2); // Căn chỉnh mũi tên
this.model.setData(data);
}
📌 range ở đây xác định giá trị được gán cho mỗi lát. Vì tất cả các phần thưởng đều bằng nhau, chúng ta sử dụng cùng một giá trị cho tất cả.
🌀 Bước 4: Hoạt Hình Quay Bánh Xe
Để quay bánh xe, tôi đã tạo một hàm startGun() mà:
- Tính toán một góc ngẫu nhiên.
- Thêm một giá trị cơ sở lớn (
7200 độ) để tạo ra một vòng quay dài thú vị. - Điều chỉnh góc cuối cùng để căn chỉnh với đỉnh (mũi tên).
- Xác định phân khúc giải thưởng mà mũi tên dừng lại.
Dưới đây là hàm đầy đủ:
javascript
startGun() {
let currentAngle = this.model.getRotationAngle();
let randomExtraRotation = Math.random() * 360;
let end = 7200 + currentAngle + randomExtraRotation;
let options: AnimatorOptions = {
duration: 8000,
easing: "ease",
delay: 0,
fill: "forwards",
direction: "normal",
begin: currentAngle,
end: end,
iterations: 1
};
this.animatorResult = animator.create(options);
this.animatorResult.onframe = (value) => {
this.model.setRotationAngle(value);
this.model.invalidate();
};
this.animatorResult.onfinish = () => {
const finalRotation = end % 360;
let adjustedAngle = finalRotation - 90;
if (adjustedAngle < 0) adjustedAngle += 360;
let index = Math.floor(adjustedAngle / this.onePartAngle);
this.currentIndex = index;
};
this.animatorResult.play();
}
📌 Lưu ý: Việc điều chỉnh -90 tính đến độ quay ban đầu của biểu đồ, đảm bảo rằng mũi tên chính xác nằm trên phân khúc mong muốn.
✅ Kết Luận
Việc xây dựng giao diện Lucky Spin trong HarmonyOS dễ hơn bạn nghĩ — chỉ với một sự kết hợp giữa PieChartModel và animator, chúng ta có thể mô phỏng một trải nghiệm quay bánh xe hoàn chỉnh. Từ việc tùy chỉnh giải thưởng cho đến tính toán góc dừng chính xác, toàn bộ quy trình đều cảm thấy phản hồi và hấp dẫn.
Thành phần này có thể dễ dàng được mở rộng với hiệu ứng âm thanh, cảm ứng, hoặc thậm chí tích hợp backend cho các giải thưởng thực.
Nếu bạn đang xây dựng một ứng dụng gamified hoặc muốn tăng cường sự tương tác của người dùng, hãy thử ngay! 🎯
📚 Tài Liệu Tham Khảo
- Hướng dẫn chính thức về việc sử dụng PieChart trong HarmonyOS
- Tài liệu API cho các tính năng hoạt hình được sử dụng trong logic quay
- Hình ảnh và mã từ triển khai cá nhân Dự án được xây dựng và thử nghiệm bằng DevEco Studio.