• Что бы вступить в ряды "Принятый кодер" Вам нужно:
    Написать 10 полезных сообщений или тем и Получить 10 симпатий.
    Для того кто не хочет терять время,может пожертвовать средства для поддержки сервеса, и вступить в ряды VIP на месяц, дополнительная информация в лс.

  • Пользаватели которые будут спамить, уходят в бан без предупреждения. Спам сообщения определяется администрацией и модератором.

  • Гость, Что бы Вы хотели увидеть на нашем Форуме? Изложить свои идеи и пожелания по улучшению форума Вы можете поделиться с нами здесь. ----> Перейдите сюда
  • Все пользователи не прошедшие проверку электронной почты будут заблокированы. Все вопросы с разблокировкой обращайтесь по адресу электронной почте : info@guardianelinks.com . Не пришло сообщение о проверке или о сбросе также сообщите нам.

HarmonyOS NEXT Development Case: Garbage Classification

Lomanu4 Оффлайн

Lomanu4

Команда форума
Администратор
Регистрация
1 Мар 2015
Сообщения
1,481
Баллы
155

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.




import { curves } from '@kit.ArkUI'; // Import curve module from ArkUI toolkit

// Define Garbage Item Class
class GarbageItem {
name: string; // Item name
type: number; // Category type
description?: string; // Optional description

// Constructor for initializing garbage item
constructor(name: string, type: number, description?: string) {
this.name = name; // Set item name
this.type = type; // Set category type
this.description = description || ""; // Set description with default empty string
}
}

// Define Garbage Category Class
class GarbageCategory {
name: string; // Category name
type: number; // Category type
color: string; // Display color
description: string; // Category description

// Constructor for initializing garbage category
constructor(name: string, type: number, color: string, description: string) {
this.name = name; // Set category name
this.type = type; // Set category type
this.color = color; // Set display color
this.description = description; // Set category description
}
}

// Application entry component with decorators
@Entry
@Component
struct Index {
// State management variables
@State currentQuestionIndex: number = 0; // Current question index
@State quizResults: string[] = []; // Quiz result records
@State totalScore: number = 0; // Total score
@State showAnimation: boolean = false; // Animation control flag
@State scaleOptions: ScaleOptions = { x: 1, y: 1 }; // Scaling parameters
@State itemXPosition: number = 0; // Item X-axis position
@State itemOpacity: number = 1.0; // Item opacity

// Predefined garbage categories
@State garbageCategories: GarbageCategory[] = [
new GarbageCategory("Hazardous", 0, "#e2413f", "Waste harmful to human health or environment"),
new GarbageCategory("Recyclable", 1, "#1c6bb5", "Reusable and recyclable materials"),
new GarbageCategory("Kitchen", 2, "#4ca84e", "Biodegradable organic waste"),
new GarbageCategory("Other", 3, "#5f5f5f", "Non-classifiable residual waste"),
];

// Predefined garbage items
@State garbageItems: GarbageItem[] = [
// Kitchen waste examples
new GarbageItem("Vegetable leaves", 2),
new GarbageItem("Leftovers", 2),
// ... (other items remain similar with English translations)
new GarbageItem("Toilet paper", 3, "Water-soluble paper products cannot be recycled")
];

// Lifecycle hook for initializing quiz
aboutToAppear(): void {
this.resetQuiz();
}

// Quiz initialization logic
resetQuiz() {
this.quizResults = [];
this.totalScore = 0;
this.currentQuestionIndex = 0;
this.shuffleItems();
}

// Fisher-Yates shuffle algorithm implementation
shuffleItems() {
for (let i = this.garbageItems.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[this.garbageItems, this.garbageItems[j]] = [this.garbageItems[j], this.garbageItems];
}
}

// Answer validation logic
checkAnswer(categoryType: number) {
const currentItem = this.garbageItems[this.currentQuestionIndex];
const isCorrect = currentItem.type === categoryType;

this.quizResults.push(
`${currentItem.name} (${this.garbageCategories[categoryType].name}) ` +
`[${isCorrect ? "✓" : this.garbageCategories[currentItem.type].name}]`
);

if (isCorrect) this.totalScore += 10;
this.currentQuestionIndex++;

if (this.currentQuestionIndex >= 10) {
this.displayResults();
this.resetQuiz();
}
}

// Results display implementation
displayResults() {
const resultSheets = this.quizResults.map(result => ({
title: result,
action: () => {}
}));

this.getUIContext().showActionSheet({
title: 'Score Report',
message: `Total Score: ${this.totalScore}`,
confirm: {
defaultFocus: true,
value: 'OK',
action: () => {}
},
alignment: DialogAlignment.Center,
sheets: resultSheets
});
}

// UI construction using ArkUI declarative syntax
build() {
Column() {
Text(`Question: ${this.currentQuestionIndex + 1}/10`)
.fontSize(30)
.margin(20);

Stack() {
// Animated item display
Text(this.garbageItems[this.currentQuestionIndex].name)
.size(130)
.style({
border: { width: 1 },
borderRadius: 5,
backgroundColor: Color.Orange,
textAlign: TextAlign.Center,
fontSize: 20,
padding: 2
})
.scale(this.scaleOptions);

// Particle animation implementation
if (this.showAnimation) {
Particle({
particles: [{
emitter: {
particle: { type: ParticleType.POINT, config: { radius: 5 }},
emitRate: 100,
position: ['25%', 0],
shape: ParticleEmitterShape.RECTANGLE
},
// ... (particle configuration remains similar)
}]
}).size('100%');
}
}
.size(150, 300)
.translate({ x: `${this.itemXPosition}px` });

// Category selection buttons
Row() {
ForEach(this.garbageCategories, (category) => {
Column() {
Text(category.name).style(categoryTextStyle);
Divider();
Text(category.description).style(descTextStyle);
}
.clickEffect({ scale: 0.8 })
.onClick(() => this.handleCategoryClick(category))
});
}

Button('Restart')
.onClick(() => this.resetQuiz())
.margin(50);
}
.width('100%');
}

// Animation handling logic
private handleCategoryClick(category: GarbageCategory) {
if (this.showAnimation) return;

this.showAnimation = true;
const positions = [-270, -90, 90, 270];

animateToImmediately({
duration: 200,
onFinish: this.handleAnimationComplete.bind(this, category)
}, () => {
this.itemXPosition = positions[category.type];
});
}

private handleAnimationComplete(category: GarbageCategory) {
animateToImmediately({
duration: 800,
curve: curves.springCurve(0, 20, 90, 20),
onFinish: this.finalizeAnswerCheck.bind(this, category)
}, () => {
this.scaleOptions = { x: 1.3, y: 1.3 };
});
}

private finalizeAnswerCheck(category: GarbageCategory) {
animateToImmediately({
duration: 200,
onFinish: () => {
this.resetAnimationState();
this.checkAnswer(category.type);
}
}, () => {
this.itemXPosition = 0;
this.scaleOptions = { x: 1.0, y: 1.0 };
});
}

private resetAnimationState() {
this.itemXPosition = 0;
this.showAnimation = false;
}
}

// Style constants
const categoryTextStyle = {
fontSize: 30,
color: Color.White,
padding: 5
};

const descTextStyle = {
fontSize: 28,
color: Color.White,
padding: 5
};
Technical Highlights


  1. State Management:

    Utilizes ArkUI's @State decorator for reactive UI updates. The component maintains multiple state variables including current question index, user score, and animation parameters.


  2. Dynamic Shuffling:

    Implements Fisher-Yates algorithm for randomizing question order, ensuring varied quiz experiences.


  3. Particle Animation:

    Creates engaging visual feedback using HarmonyOS's Particle system with configurable:
    • Emission rates
    • Particle trajectories
    • Color transitions
    • Scaling effects

  4. Gesture Interactions:

    Features spring-based animations with curves.springCurve for smooth category selection feedback.


  5. Responsive Layout:

    Implements adaptive UI using:
    • Percentage-based dimensions
    • Flexbox layout (Row/Column)
    • Stack positioning
    • Dynamic translation transforms

  6. Result Visualization:

    Uses ActionSheet component to display detailed score breakdown with scrollable history.
Development Considerations


  1. Performance Optimization:
    • Animation frame synchronization
    • Object pooling for particle effects
    • Memoization of static resources

  2. Localization Support:

    The architecture supports easy translation through centralized string management in class definitions.


  3. Accessibility:

    Built-in contrast ratios and click effect visual feedback enhance usability.

This implementation demonstrates HarmonyOS's capabilities in building engaging, interactive applications while maintaining clean code organization and smooth performance.


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

 
Вверх Снизу