欢迎光临
我们一直在努力

HarmonyOS 应用开发《掌上英语》第46篇:单词卡片翻转——从旋转动画到用户交互

单词卡片翻转——从旋转动画到用户交互

在这里插入图片描述

一、卡片翻转的应用场景

在英语学习 App 中,单词卡片是核心的学习交互方式。用户看到单词正面(英文),思考释义后翻转卡片看到背面(中文释义 + 例句),这是一个自然的学习流程。

本项目中,CourseHomePage 实现了完整的单词卡片翻转功能,包含 3D 旋转动画、正反面交叉淡入淡出、分类筛选、发音播放、掌握程度标记等交互。

二、核心翻转动画

2.1 状态变量

@Local isFlipped: boolean = false; // 翻转状态
@Local rotateY: number = 0; // Y 轴旋转角度
@Local frontOpacity: number = 1; // 正面透明度
@Local backOpacity: number = 0; // 背面透明度

四个变量共同控制卡片的视觉效果:

  • isFlipped 用作文本状态标志
  • rotateY 控制 3D 旋转角度
  • frontOpacity / backOpacity 控制两面淡入淡出

2.2 flipCard 方法

private flipCard(): void {
animateTo({ duration: 400, curve: Curve.EaseInOut }, () => {
if (this.isFlipped) {
// 翻回正面
this.rotateY = 0;
this.frontOpacity = 1;
this.backOpacity = 0;
} else {
// 翻到背面
this.rotateY = 180;
this.frontOpacity = 0;
this.backOpacity = 1;
}
this.isFlipped = !this.isFlipped;
});
}

animateTo API:这是 ArkUI 的显式动画接口。第一个参数是动画配置(400ms 时长、EaseInOut 缓动曲线),第二个参数是状态变更闭包。框架自动插值计算中间帧的 rotateY 值,产生平滑的过渡效果。

2.3 正反面 UI 结构

Stack() {
// 正面 – 显示单词
Column() {
Text(currentWord().word) // 英文单词
.fontSize(34).fontWeight(FontWeight.Bold);
Text(currentWord().phonetic) // 音标
Text(currentWord().translation) // 中文释义
Text(currentWord().example) // 例句
}
.rotate({ x: 0, y: this.rotateY, z: 0, centerX: '50%', centerY: '50%', perspective: 1200 })
.opacity(this.frontOpacity)
.onClick(() => this.flipCard());

// 背面 – 显示详细释义
Column() {
Text('详细释义')
Text(currentWord().translation)
Text(currentWord().example)
Text(currentWord().exampleTranslation)
// 分类标签
}
.rotate({ x: 0, y: this.rotateY 180, z: 0, centerX: '50%', centerY: '50%', perspective: 1200 })
.opacity(this.backOpacity)
.onClick(() => this.flipCard());
}

正反两面通过 Stack 堆叠在一起。翻转到背面时,rotateY 变为 180 度,同时背面的 rotation 为 rotateY – 180(即 -180→0 度),这样在视觉上始终以正面朝向用户。

perspective(透视):perspective: 1200 设置了 3D 透视的视距。值越小,3D 效果越明显;值越大,效果越平缓。1200 是一个较为自然的数值。

三、前后翻页导航

3.1 上一张 / 下一张

private nextCard(): void {
if (this.currentIndex < this.totalCount 1) {
// 翻页时重置翻转状态到正面
this.isFlipped = false;
this.rotateY = 0;
this.frontOpacity = 1;
this.backOpacity = 0;
this.isFavorite = false;
this.currentIndex++;
}
}

private prevCard(): void {
if (this.currentIndex > 0) {
this.isFlipped = false;
this.rotateY = 0;
this.frontOpacity = 1;
this.backOpacity = 0;
this.isFavorite = false;
this.currentIndex;
}
}

每次切换卡片时,都重置翻转状态为正面(未翻转)。这确保了用户每次看到新卡片时都是熟悉的"正面朝上"状态。

四、掌握程度标记

4.1 用户交互

Row({ space: 10 }) {
Button('左滑 待复习')
.backgroundColor('#FFc000')
.onClick(() => this.markUnfamiliar());

Button('右滑 已掌握')
.backgroundColor('#165DFF')
.onClick(() => this.markMastered());
}

4.2 标记逻辑

private markMastered(): void {
const word = this.currentWord();
GlobalContextUtils.showToast({ message: `已掌握: ${word.word}` });
this.masteredCount++;
this.learnedCount++;
this.nextCard();
}

private markUnfamiliar(): void {
const word = this.currentWord();
GlobalContextUtils.showToast({ message: `已加入生词本: ${word.word}` });
this.learnedCount++;
this.nextCard();
}

两个按钮的共同点:

  • 都通过 showToast 给用户即时反馈
  • 都增加 learnedCount(今日学习计数)
  • 都自动跳到下一张卡片

不同点:

  • markMastered 增加 masteredCount(已掌握计数)
  • markUnfamiliar 实际调用 NewWordManager 将单词加入生词本(后续复习使用)

五、分类筛选

卡片页支持按词汇分类筛选:

Tabs({ barPosition: BarPosition.Start }) {
TabContent() { this.cardArea(); }
.tabBar(this.tabBuilder('全部', 'all'));

ForEach(WORD_CATEGORIES, (cat: WordCategory) => {
TabContent() { this.cardArea(); }
.tabBar(this.tabBuilder(cat.label, cat.key));
});
}
.barMode(BarMode.Scrollable)
.onTabBarClick((index: number) => {
if (index === 0) {
this.currentCategory = 'all';
} else {
this.currentCategory = WORD_CATEGORIES[index 1].key;
}
this.currentIndex = 0;
this.resetCardState();
});

BarMode.Scrollable 使 Tab 在分类较多时可滚动,通过 onTabBarClick 切换分类时重置卡片状态。分类筛选通过 getFilteredWords() 方法实现:

private getFilteredWords(): WordCard[] {
if (this.currentCategory === 'all') {
return DEFAULT_WORD_CARDS; // 500 词全量
}
return DEFAULT_WORD_CARDS.filter(w => w.category === this.currentCategory);
}

六、发音功能

private playPronunciation(): void {
const word = this.currentWord();
if (word.audioUrl && word.audioUrl !== '') {
this.audioPlayer.play(word.audioUrl);
} else {
this.audioPlayer.play(''); // 播放系统默认提示音
}
}

用户点击单词或音标旁的播放按钮时触发,使用 AudioPlayer 单例播放当前单词的音频。

七、动画性能优化

卡片翻转动画涉及每一帧的旋转和透明度变化,以下要点有助于保证动画流畅:

  • 避免重复计算:currentWord() 在模板中多次调用,ArkTS 的响应式系统会缓存结果
  • 使用 GPU 加速属性:rotate 和 opacity 是 GPU 加速属性,不会触发 Layout 重排
  • 合理时长:400ms 的动画时长经过实践验证,既不会太快看不清,也不会慢到让人等
  • EaseInOut 缓动:缓动曲线让动画在开始和结束时减速,更加自然
  • 八、总结

    CourseHomePage 的卡片翻转实现,是 ArkTS 动画系统的一个典型应用。通过 animateTo 驱动状态变更,配合 rotate 和 opacity 实现立体的翻转效果。再加上分类筛选、发音播放、掌握标记等功能,构成了一个完整的单词学习交互闭环。这个模式可以扩展到其他需要"查看详情"的场景——例如闪卡学习、选择题的答案解析等。

    赞(0)
    未经允许不得转载:171主机测评 » HarmonyOS 应用开发《掌上英语》第46篇:单词卡片翻转——从旋转动画到用户交互
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址