HarmonyOS 6.1 实战:鸿蒙滚动容器性能优化:隐藏滚动条与约束尺寸视图裁剪方案
糖果街机一爪入魂:基于HarmonyOS ArkTS声明式UI的CLAW CITY娃都,从葡萄紫深底马卡龙电玩风到8Tab导航7弹框的潮流娃娃机夹娃娃电玩城全栈实战解析
本文深度解析 CLAW CITY 娃都——一款融合糖果街机质感与马卡龙电玩美学的潮流娃娃机·夹娃娃电玩城应用。项目采用 HarmonyOS ArkTS 声明式 UI 框架,单文件架构,无外部依赖,通过 8 大 Tab 页面、7 套弹框组件、约 10 组属性动画和约 25 个全局纯函数,完整实现机台预约、潮玩收藏、币值充值、夹神排行、换物交易、夹友动态、每日任务、个人中心等核心业务闭环。全文约 8 万字,含 8 张应用截图。
引言:当夹娃娃遇上鸿蒙生态
夹娃娃机作为电玩城的经典项目,早已超越了单纯的娱乐范畴,成为一种集收藏、社交、竞技、交易于一体的亚文化现象。从三丽鸥系列的库洛米、玉桂狗,到潮玩IP的星之卡比、Loopy,再到盲盒、挂件等周边产品,娃娃机里的每一只玩偶都承载着玩家的期待、欧气和收藏欲。
CLAW CITY 娃都正是在这一背景下诞生的概念性应用。它以"糖果街机 × 马卡龙电玩"为视觉基调,用深邃的葡萄紫(#1A1030)铺陈底色,用甜美的马卡龙粉(#FF8FB8)、梦幻紫(#9B6BFF)、薄荷绿(#5FE3C0)、柠檬金(#FFC93C)点亮界面,构建出一个沉浸式的线上电玩城空间。
技术层面,项目选择 HarmonyOS ArkTS 作为开发框架,通过声明式 UI 语法、@State 状态管理、@Builder 自定义构建函数和 animateTo 属性动画,用单文件约 1700 行代码实现了 8 个 Tab 页面和 7 套弹框组件的完整交互。
本文将从设计理念、色彩系统、架构设计、数据模型、页面实现、弹框组件、动画交互、业务逻辑、性能优化等十四个维度,对 CLAW CITY 娃都进行全方位深度解析。
第一章 项目概述与设计理念
1.1 项目定位
CLAW CITY 娃都定位为"潮流娃娃机·夹娃娃电玩城"一体化数字平台,核心用户为 16-30 岁的潮玩收藏爱好者和电玩城常客。应用融合机台状态、潮玩收藏、币值充值、夹神排行、换物交易、夹友动态、每日任务、个人中心八大业务模块,形成从"发现机台→查看概率→充值开夹→收藏图鉴→换物交易→分享动态→冲击排行"的完整用户旅程闭环。
与传统电玩城会员卡 App 不同,CLAW CITY 娃都更强调"收藏感"和"社区感"——玩家可以在这里建立自己的潮玩收藏册、查看每只娃娃的稀有度和人气、在换物街与其他玩家交换重复娃娃、在动态广场分享夹中喜报、在夹神榜比拼月度夹中数和成功率。
1.2 设计理念:糖果街机 × 马卡龙电玩
项目的视觉设计灵感来源于糖果色街机厅和马卡龙色系的碰撞。走进一家潮流电玩城,首先映入眼帘的是霓虹闪烁的机台、五颜六色的玩偶、粉色紫色的灯光和甜美的马卡龙色调。CLAW CITY 娃都将这些电玩城元素抽象为数字化的视觉语言:
- 葡萄紫深底(#1A1030):作为应用主背景色,模拟电玩城昏暗的环境,让彩色机台和玩偶如舞台上的表演般脱颖而出。
- 马卡龙粉(#FF8FB8):作为主强调色,用于按钮、选中态、价格高亮,如同娃娃机里最受欢迎的粉色玩偶。
- 梦幻紫(#9B6BFF):作为辅助强调色,用于段位、分类、渐变,营造梦幻的电玩氛围。
- 薄荷绿(#5FE3C0):用于成功状态、畅玩标识、到账提示,如同电玩城里清新的薄荷糖。
- 柠檬金(#FFC93C):用于币值、奖励、热销标识,如同街机里投下的金色硬币。
这种"电玩感"设计不仅仅停留在色彩层面,更贯穿到交互细节中——机械爪上下移动动画、金币脉动缩放动画、星星闪烁动画、娃娃摇摆动画、皇冠呼吸动画,每一处动画都在模拟电玩城的光影和机械变化,让用户在使用 App 时仿佛置身于一个真实的潮流电玩城。
1.3 得物 App 风格借鉴
项目在电商化运营和社区化交互方面借鉴了得物 App 的设计风格:商品卡片式布局(机台、娃娃、礼包)、标签化分类(三丽鸥风/潮玩IP/毛绒/挂件)、热度榜单(夹神榜/热门娃娃)、弹幕式互动(沾欧气/夹中喜报横滚)、限时礼包(新人首充/周末疯狂/深夜快乐/段位冲刺)。
1.4 技术选型
| 维度 | 选型 | 说明 |
|---|---|---|
| 开发框架 | HarmonyOS ArkTS | 声明式 UI,原生性能 |
| 架构模式 | 单文件组件化 | 所有代码在一个 .ets 文件中 |
| 状态管理 | @State + 组件回调 | 轻量级,无需额外库 |
| 动画方案 | 属性动画(animateTo) | 约10组无限循环,零定时器 |
| 外部依赖 | 无 | 纯 ArkTS 内置组件 |
| Tab 数量 | 8 个 | 娃都/潮玩库/补币/夹神榜/换物街/动态/每日/我的 |
| 弹框数量 | 7 套 | 机台详情/发布换物/编辑换物/删除确认/充值确认/娃娃图鉴/领取奖励 |
第二章 色彩系统与视觉风格
2.1 色彩体系总览
CLAW CITY 娃都的色彩体系由 15 个核心色值构成,通过 CCColorPalette 接口定义,以 CC_COLORS 常量对象全局引用:
const CC_COLORS = {
bg: '#1A1030', // 葡萄紫深底 - 主背景
card: '#241840', // 深紫卡片 - 内容容器
deep: '#120A22', // 极深黑 - 头部/输入框
line: '#3A2B5C', // 暗紫线 - 分割线/边框
pink: '#FF8FB8', // 马卡龙粉 - 主强调色
pinkDeep: '#E85D93',// 深粉 - 按钮/渐变
purple: '#9B6BFF', // 梦幻紫 - 辅助强调色
gold: '#FFC93C', // 柠檬金 - 币值/奖励
mint: '#5FE3C0', // 薄荷绿 - 成功/畅玩
textMain: '#F6F1FF',// 主文字
textSub: '#A99BC4', // 次文字
textHint: '#6F5F8C',// 提示文字
white: '#FFFFFF', // 纯白
blueR: '#5FA8FF', // 蓝 - R稀有度
grayTag: '#6F5F8C' // 灰标签
}
2.2 色彩层级与对比度
深色主题通过四级背景深度和三级文字明度构建清晰的视觉层级:
背景深度四级:
deep #120A22(极深黑)—— 顶部标题栏、输入框、弹框内次级容器bg #1A1030(葡萄紫深底)—— 页面主背景card #241840(深紫卡片)—— 内容卡片、列表项deep #120A22(极深黑)—— 输入框、标签背景,形成凹陷感
文字明度三级:textMain #F6F1FF(近白)—— 标题、核心数据textSub #A99BC4(灰紫)—— 副标题、说明文字textHint #6F5F8C(暗紫灰)—— 占位符、辅助说明
2.3 强调色的使用策略
马卡龙粉 #FF8FB8 是整个应用的视觉锚点,用于:按钮主操作(立即开夹/发布换物帖/确认删除)、选中态标识(Tab选中/分类选中/娃娃选中)、数据高亮(价格/成功率/夹中数)、装饰元素(边框/角标/进度条)。
梦幻紫 #9B6BFF 作为互补色,用于:段位标识(大师段)、分类标签、渐变背景、编辑操作按钮。
柠檬金 #FFC93C 用于:币值显示、奖励金额、热销标签、传说段位、签到完成。
薄荷绿 #5FE3C0 用于:成功状态(充值成功/换到了)、畅玩标识、到账提示、领取按钮。
四种强调色的搭配形成了"粉为主、紫为辅、金为币、绿为成"的色彩节奏,既保证了视觉统一性,又提供了足够的状态区分度。
2.4 渐变与光影效果
项目大量使用线性渐变营造电玩城的霓虹氛围:
- 新到货横幅渐变:从马卡龙粉到梦幻紫的 135° 对角渐变,模拟街机霓虹灯
- 夹中率柱状图渐变:从马卡龙粉到梦幻紫的 180° 垂直渐变
- 个人卡渐变:从梦幻紫到深粉的 135° 对角渐变
- 赛季进度条渐变:从柠檬金到马卡龙粉的 0° 水平渐变
- 活跃度进度条渐变:从薄荷绿到梦幻紫的 0° 水平渐变
这些渐变配合属性动画(机械爪移动、金币脉动、星星闪烁),营造出动态的、有生命力的电玩城霓虹体验。
第三章 项目架构与文件组织
3.1 单文件组件化架构
CLAW CITY 娃都采用"单文件组件化"架构——所有代码在一个 .ets 文件中,通过 @Component 装饰器划分为 16 个独立组件(8 Tab + 5 弹框 + 1 根入口 + 2 内联弹框)。优势:零配置运行、低理解成本、快速原型。代码量约 1700 行,处于单文件架构合理范围。
3.2 组件层次结构
CCClawCityApp (@Entry 根组件)
├── 顶部标题栏(LOGO + 搜索 + 币余额)
├── 内容区 Stack
│ ├── 8 个 Tab 内容组件(8 选 1)
│ │ ├── CCHomeContent(娃都首页)
│ │ ├── CCDollLibContent(潮玩库)
│ │ ├── CCCoinContent(补币)
│ │ ├── CCRankContent(夹神榜)
│ │ ├── CCTradeContent(换物街)
│ │ ├── CCFeedContent(动态)
│ │ ├── CCDailyContent(每日)
│ │ └── CCMeContent(我的)
│ └── 7 个弹框(按需显示,zIndex 999)
│ ├── CCMachineDetailForm(机台详情)
│ ├── CCAddTradeForm(发布换物帖)
│ ├── CCEditTradeForm(编辑换物帖·底部抽屉)
│ ├── 删除确认弹框(内联)
│ ├── CCRechargeForm(充值确认)
│ ├── CCDollDetailForm(娃娃图鉴)
│ └── 领取奖励弹框(内联)
└── 底部 Tab 导航栏(8 项)
根组件管理当前 Tab、7 个弹框显隐状态、弹框间传递数据,通过 contentArea() Builder 分发 Tab 内容和弹框层。每个 Tab 组件负责自身 UI 和局部状态,通过回调函数与根组件通信。
3.3 @Builder 自定义构建函数
项目使用 8 个 @Builder 方法封装可复用 UI 片段:modalOverlay(弹框遮罩层)、machineModal(机台详情弹框结构)、addTradeModal(发布换物弹框结构)、editTradeModal(编辑换物弹框结构)、deleteTradeModal(删除确认弹框结构)、rechargeModal(充值弹框结构)、dollModal(娃娃图鉴弹框结构)、rewardModal(领取奖励弹框结构)、contentArea(内容区分发)。@Builder 减少重复代码,提高可读性,支持参数传递。
3.4 弹框架构设计
弹框采用"遮罩层 + 内容层"Stack 叠加模式,统一在根组件管理。7 套弹框各具特色:机台详情(橱窗式,含机械爪动画+概率公示表)、发布换物帖(表单式,含娃娃宫格选择)、编辑换物帖(底部抽屉式)、删除确认(粉色警告式)、充值确认(票据式,含金币脉动动画)、娃娃图鉴(档案卡式,含娃娃摇摆动画)、领取奖励(庆祝式,含金币缩放动画)。
第四章 数据模型与全局状态管理
4.1 接口定义体系
项目定义 18 个 TypeScript 接口描述数据模型:CCColorPalette(色彩)、CCTabItem(导航)、CCMachine(机台)、CCDoll(娃娃)、CCTier(币值档位)、CCPack(礼包)、CCPayLog(充值记录)、CCRank(排行)、CCTrade(换物帖)、CCFeed(动态)、CCTask(任务)、CCSignDay(签到日)、CCWeekRate(周夹中率)、CCOddsRow(概率行)、CCNews(喜报)、CCSetting(设置)、CCTierDesc(段位说明)。
4.2 全局数据常量
约 20 组全局 const 常量:核心业务数据(CC_MACHINES 9台/CC_DOLLS 16款/CC_TIERS 4档/CC_PACKS 4包/CC_PAYLOG 8笔/CC_RANKS 10名/CC_TRADES 8帖/CC_FEEDS 8条/CC_TASKS 6项/CC_SIGN 7天)、配置数据(CC_TABS 8项/CC_DOLL_CATS 5类/CC_TRADE_FILTERS 4类/CC_TRADE_MODES 3种/CC_PAY_METHODS 3种/CC_WEEK 7天/CC_MACHINE_ODDS 5行/CC_NEWS 6条/CC_SETTINGS 5项/CC_TIER_DESC 4段)。使用 const 确保数据不可变,所有动态状态通过组件 @State 管理。
4.3 三级状态管理策略
- 第一级 全局常量(const):业务数据和配置,任何组件可直接读取,运行时不可变
- 第二级 组件局部状态(@State):组件内交互状态,如 clawY(机械爪位置)、dollCat(分类筛选)、tradeFilter(换物筛选)、luckyFeed(沾欧气状态)、signFlash(签到闪烁)
- 第三级 根组件协调状态(@State):跨组件状态,如 activeTab(当前Tab)、7个弹框显隐开关、弹框间传递数据(machineNo/rechargeCoins/dollName/rewardTask等)、头部动画状态(headCoinPulse/rewardPulse)
4.4 全局纯函数
约 25 个全局纯函数处理数据转换和业务逻辑:数据查询(ccMachineByNo/ccDollByName/ccTierByCoins)、数据筛选(ccFilterDolls/ccFilterTrades/ccHotDolls/ccCaughtDolls/ccTradePickDolls)、颜色映射(ccRarityColor/ccStatusColor/ccTradeStatusColor/ccPayStatusColor)、统计计算(ccRarityCount/ccTierCount/ccMaxRate/ccBarHeight/ccPct)。纯函数相同输入永远产生相同输出,无副作用,易于测试和复用。
第五章 八大 Tab 页面深度解析
5.1 娃都首页 Tab(CCHomeContent)
娃都首页是应用的主入口,承担"发现新机→查看机台→了解概率→立即开夹"转化路径。页面结构:
- 本周新到货大横幅(粉紫135°渐变)
- 新品名称(库洛米星空限定)+ SSR标签 + 概率说明 + 已上架机台
- 双按钮:概率公示(金)+ 立即去夹(半透明深)
- 星星闪烁动画(starOp 0.3↔1)
- 机台状态格(9台,2列瀑布流)
- 每台:机台编号 + 状态标签(热门粉/畅玩绿/维护灰)+ 机械爪图标(clawY 0↔16上下移动动画)+ 价格(金币脉动动画)+ 娃娃色块 + 机台名 + 在线人数
- 点击触发机台详情弹框
- 热门娃娃横滚卡(热度>560的娃娃)
- 每卡:娃娃色块 + emoji + 名称 + 热度值
- 横向滚动
- 今日夹中喜报(横滚跑马灯)
- 6条喜报,每条含玩家名和娃娃名,不同颜色
- 横向滚动展示
- 7日夹中率柱状图
- 7根柱子,粉紫180°渐变,周六最高44%
- 全馆平均31%
三组属性动画:机械爪上下移动(1600ms)、金币脉动缩放(900ms)、星星闪烁(1300ms),共同营造电玩城的机械和霓虹氛围。

5.2 潮玩库 Tab(CCDollLibContent)
潮玩库是娃娃收藏图鉴页面,承担"浏览娃娃→筛选分类→查看图鉴→去夹它"路径。页面结构:
- 分类 chips(全系列/三丽鸥风/潮玩IP/毛绒/挂件,横向滚动)
- 选中态深粉背景,未选中深紫卡片背景
- 三列瀑布娃娃格(16款,按分类筛选)
- 每格:娃娃色块 + emoji(dollSwing ±8°摇摆动画)+ 名称 + 稀有度标签(SSR金/SR紫/R蓝)+ 尺寸 + 热度
- 点击触发娃娃图鉴弹框
- 稀有度分布横条
- SSR/SR/R 三段色条(金/紫/蓝),按数量比例分配宽度
- 底部显示各稀有度数量
娃娃摇摆动画(1500ms,±8°旋转)模拟娃娃在机台里晃动的效果,增加页面的生动感。

5.3 补币 Tab(CCCoinContent)
补币是币值充值中心页面,承担"选择档位→查看礼包→确认充值→查看记录"路径。页面结构:
- 币值档位 2x2(4档:50币¥6/200币¥25热销/500币¥60/1000币¥118)
- 每档:金币emoji(coinPulse 1↔1.15脉动动画)+ 币数 + 赠送币 + 价格
- 热销档右上角"热销"角标
- 点击触发充值确认弹框
- 限时礼包横滚(4包:新人首充/周末疯狂/深夜快乐/段位冲刺)
- 每包:emoji + 名称 + 内容 + 原价删除线 + 现价
- 彩色边框区分
- 充值记录斑马纹(8笔,奇偶行交替背景)
- 每笔:档位名 + 时间支付方式 + 状态(成功绿/处理中金/已退款灰)
金币脉动动画(900ms)模拟金币闪烁的效果,强化充值页面的"金币"主题。

- 每笔:档位名 + 时间支付方式 + 状态(成功绿/处理中金/已退款灰)
5.4 夹神榜 Tab(CCRankContent)
夹神榜是竞技排行页面,承担"查看赛季→浏览排行→了解段位→冲击排名"路径。页面结构:
- 赛季倒计时条(S9赛季进行中,距结算6天18小时)
- 金粉渐变进度条(72%)
- 皇冠呼吸动画(crownOp 0.4↔1)
- 排行榜(10名)
- 前三名:大序号布局(01/02/03金色大号)+ 头像 + 昵称 + 段位标签 + 本月夹中数 + 成功率,金色边框
- 4-10名:紧凑行布局,序号 + 昵称 + 段位 + 夹中数 + 成功率
- 段位说明四格(传说/大师/钻石/黄金,各含月夹中门槛)
- 段位分布占比条(传说x3/大师x3/钻石x3/黄金x1)
皇冠呼吸动画(1200ms)模拟冠军皇冠的金光闪烁,强化排行榜的荣誉感。

5.5 换物街 Tab(CCTradeContent)
换物街是娃娃交易社区页面,承担"筛选换物→浏览帖子→联系换友→发布换物"路径。页面结构:
- 筛选 chips(全部/我出的/我想要的/已完成,横向滚动)
- 换物帖列表(8帖,按筛选过滤)
- 每帖:左侧娃娃色块 + 标题 + 出/想要标签(粉/绿)+ 交换方式标签 + 状态(求换中粉/换到了绿/已下架灰)+ 联系按钮
- 我的帖子额外显示编辑/删除按钮
- 底部发布按钮(固定底部,粉色大按钮"发布换物帖·让娃娃流动起来")
点击编辑触发底部抽屉式编辑弹框,点击删除触发粉色警告删除确认弹框,点击发布触发表单式发布弹框。

5.6 动态 Tab(CCFeedContent)
动态是夹友社交广场页面,承担"浏览喜报→查看战利品→点赞评论→沾欧气"路径。页面结构:
- 动态列表(8条)
- 每条:头像(彩色圆形)+ 昵称 + 时间 + 夹神标签 + 文字内容 + 战利品横滚(娃娃色块emoji)+ 点赞数 + 评论数 + 沾欧气按钮
- 沾欧气按钮点击后变为"已沾欧气"(luckyFeed状态管理)
- 爱心呼吸动画(heartOp 0.4↔1,1100ms)模拟点赞爱心的跳动

5.7 每日 Tab(CCDailyContent)
每日是任务签到中心页面,承担"每日签到→完成任务→领取奖励→积累活跃度"路径。页面结构:

- 签到日历格(7列,周一至周日)
- 已签到:金色圆形✓
- 今日:粉色边框+礼物emoji闪烁动画(signFlash 0.5↔1)
- 未签到:灰色边框·
- 底部显示每日奖励币数
- 每日任务清单(6项)
- 每项:任务名 + 进度条 + 当前/总数 + 奖励币数 + 领取/去完成/已完成按钮
- 可领取任务按钮为粉色,点击触发领取奖励庆祝弹框
- 每周活跃度进度条(620/1000,薄荷紫渐变)
- 底部7个奖励节点(对应每日签到奖励)
签到闪烁动画(1000ms)模拟今日签到的礼物闪烁,引导用户每日签到。
- 底部7个奖励节点(对应每日签到奖励)
5.8 我的 Tab(CCMeContent)
我的是个人中心页面,承担"查看战绩→管理收藏→充值补币→设置管理"路径。页面结构:
- 个人卡(紫粉135°渐变)
- 头像(紫色圆形🦊)+ 昵称 + 大师段位标签 + ID/加入天数 + 币余额(金币脉动动画)+ 立即补币按钮
- 右侧累计夹中数(1,286大号金色)
- 战绩统计四格(总夹中1286/成功率33%/累计花费24580/换物次数47)
- 我的收藏册横滚(已夹到的娃娃,caught=true的8款)
- 每卡:娃娃色块 + emoji + 名称 + 稀有度标签
- 点击触发娃娃图鉴弹框
- 显示收录进度(8/16)
- 设置项列表(5项:收货地址/消息通知/币值明细/客服中心/关于娃都)
金币脉动动画(950ms)贯穿头部和个人卡,强化币值主题。

第六章 七大弹框组件设计
弹框是 CLAW CITY 娃都交互体系的核心组成部分。项目共设计了 7 套弹框组件,覆盖机台详情、发布换物、编辑换物、删除确认、充值确认、娃娃图鉴、领取奖励七大业务场景。
6.1 机台详情弹框(CCMachineDetailForm)
定位:机台信息展示和开夹入口,橱窗式设计。
核心功能:
- 头部:机台名 + 机台详情标题 + 关闭按钮
- 娃娃展示区:娃娃色块半透明背景 + 机械爪emoji(clawY 0↔14上下移动动画)+ 娃娃名 + 当前在夹机台号
- 价格与历史:币/次价格(金色大号)+ 历史夹中次数
- 概率公示表:5行娃娃概率(娃娃名/概率如1/128/剩余数量),公证处监管说明
- 底部操作:再看看(灰)+ 立即开夹·X币(深粉主操作)
机械爪上下移动动画(1600ms)模拟娃娃机机械爪的升降动作,是本弹框的核心视觉亮点。概率公示表采用深色背景表格,每行显示娃娃名、概率分数和剩余数量,粉色概率、薄荷绿剩余数量,清晰易读。
6.2 发布换物帖弹框(CCAddTradeForm)
定位:发布换物帖的表单入口。
表单字段:
- 帖子标题(文本输入)
- 选择我的娃娃(6款娃娃宫格选择,2列,选中态金色边框深背景)
- 想要的娃娃描述(文本输入)
- 交换方式(3选1chips:1换1/1换2/加币补,选中态深粉)
- 备注(多行文本)
娃娃宫格选择是本弹框的特色交互:每款娃娃显示为色块卡片,含名称和稀有度尺寸,点击切换选中态,选中态有2px金色边框和深色背景,未选中态1px暗紫线边框。底部操作:取消(灰)+ 发布到换物街(深粉主操作)。
6.3 编辑换物帖弹框(CCEditTradeForm)
定位:编辑已有换物帖的底部抽屉式弹框。
与发布弹框的区别:
- 定位方式:底部抽屉(position y:46%),而非居中
- 顶部装饰:44×5圆角小条模拟抽屉把手
- 可修改字段:仅标题、交换方式、帖子状态(上架中/已下架,Radio单选)
- 操作按钮:放弃修改(灰)+ 保存修改(紫色主操作)
帖子状态管理通过 Radio 组件实现,上架中/已下架二选一,下架后其他玩家无法浏览此帖。aboutToAppear 生命周期将传入的标题和方式赋给局部状态变量,实现数据回显。
6.4 删除确认弹框(内联在主入口)
定位:删除换物帖的二次确认,粉色警告式设计。
设计特点:
- 2px粉色边框,强化警示感
- 顶部大号🗑图标 + "确认删除这条换物帖?"标题(深粉)
- 警告说明:删除后帖子下架,正在沟通的换友无法联系
- 帖子信息卡(深色背景):娃娃色块 + 帖子标题 + 状态方式
- 操作:取消(灰)+ 确认删除(深粉主操作)
粉色警告设计与删除操作的危险性匹配,二次确认防止误删。
6.5 充值确认弹框(CCRechargeForm)
定位:币值充值的确认票据,票据式设计。
核心功能:
- 币值展示区:金币emoji(coinPulse 1↔1.22脉动动画)+ 币数大号金色 + 赠送币 + 到账合计 + 价格
- 支付方式选择:3种(余额支付🎫/微信支付💚/支付宝💙),Radio单选
- 费用明细:档位金额 + 会员折扣9.5折(-¥X.XX薄荷绿)+ 实付金额(深粉大号)
- 底部操作:再想想(灰)+ 确认支付¥X.XX(金色主操作)
金币脉动动画(900ms)模拟金币闪烁,强化充值页面的"金币"主题。支付方式用不同颜色emoji区分(绿/蓝/票),费用明细清晰展示折扣计算过程。
6.6 娃娃图鉴弹框(CCDollDetailForm)
定位:娃娃详细信息展示,档案卡式设计。
核心功能:
- 娃娃展示区:娃娃色块背景(0.9透明度)+ 🧸emoji(dollSwing ±8°摇摆动画)+ 娃娃名 + 稀有度分类标签
- 属性列表:尺寸/材质/上架时间/当前机台/人气热度,5行深色背景表格
- 收藏状态:已夹到过显示金色"已收录进我的收藏册",未夹到显示灰色"还没夹到过,去X号机碰碰运气"
- 底部操作:关闭图鉴(灰)+ 去夹它!(深粉主操作)
娃娃摇摆动画(1400ms,±8°旋转,旋转中心50%/80%模拟娃娃底部摆动)是本弹框的核心视觉亮点,模拟娃娃在机台里被爪子触碰时的晃动效果。aboutToAppear 生命周期根据传入的娃娃名查询娃娃数据(ccDollByName)。
6.7 领取奖励弹框(内联在主入口)
定位:任务奖励领取的庆祝式弹框。
设计特点:
- 居中圆形光晕(金色0.15透明度)+ 大号🪙金币(rewardPulse 1↔1.3缩放动画)
- "🎉 恭喜获得奖励!"标题(金色大号)
- 任务名显示
- 奖励明细卡(深色背景):任务奖励(+X娃币金色)+ 连续完成奖励(+X/2娃币薄荷绿)+ 到账合计(深粉大号)
- 底部操作:开心收下🎊(金色大按钮)
金币缩放动画(850ms)模拟奖励金币的弹跳庆祝效果,圆形光晕增强庆祝氛围。奖励明细区分任务基础奖励和连续完成额外奖励,激励用户持续完成每日任务。
第七章 属性动画与交互体验
7.1 ArkTS 属性动画机制
ArkTS 通过 animateTo() 实现属性动画,基本用法:
this.getUIContext().animateTo({
duration: 1600, iterations: -1,
playMode: PlayMode.Alternate, curve: Curve.EaseInOut
}, () => { this.clawY = 14 })
iterations: -1 表示无限循环,PlayMode.Alternate 表示到达目标值后反向执行回初始值,形成往返效果。配合使用可实现持续循环动画,无需 setInterval 定时器。框架自动处理中间帧和缓动曲线,开发者只需声明初始值和目标值。
7.2 约十组属性动画详解
| 动画 | 组件 | 属性 | 时长 | 效果 |
|---|---|---|---|---|
| 机械爪移动 | 首页/机台详情 | clawY(translate) | 1600ms | 机械爪0↔16vp上下移动 |
| 金币脉动 | 首页/补币/我的/充值/头部 | coinPulse(scale) | 900-950ms | 金币1↔1.25缩放 |
| 星星闪烁 | 首页横幅 | starOp(opacity) | 1300ms | 星星0.3↔1透明度 |
| 娃娃摇摆 | 潮玩库/娃娃图鉴 | dollSwing(rotate) | 1400-1500ms | 娃娃±8°旋转 |
| 皇冠呼吸 | 夹神榜 | crownOp(opacity) | 1200ms | 皇冠0.4↔1透明度 |
| 爱心跳动 | 动态 | heartOp(opacity) | 1100ms | 爱心0.4↔1透明度 |
| 签到闪烁 | 每日 | signFlash(opacity) | 1000ms | 礼物0.5↔1透明度 |
| 奖励金币缩放 | 领取奖励弹框 | rewardPulse(scale) | 850ms | 金币1↔1.3缩放 |
| 头部金币脉动 | 根组件头部 | headCoinPulse(scale) | 950ms | 头部金币1↔1.25缩放 |
| 机械爪移动动画:模拟娃娃机机械爪的升降动作,0↔16vp上下移动,1600ms较长时长使动作缓慢有力,EaseInOut曲线使开始结束平缓,符合机械爪的物理特性。 | ||||
| 金币脉动动画:贯穿多个页面(首页机台格、补币档位、我的个人卡、充值弹框、头部余额),900-950ms较短时长,1↔1.25缩放,模拟金币闪烁发光的效果,强化币值主题。 | ||||
| 娃娃摇摆动画:潮玩库和娃娃图鉴弹框中,±8°旋转,旋转中心50%/80%(模拟娃娃底部为支点),1400-1500ms,模拟娃娃被爪子触碰时的晃动效果。 | ||||
| 星星/皇冠/爱心/签到闪烁:均为opacity透明度动画,0.3-0.4↔1,1000-1300ms,模拟霓虹灯闪烁效果,营造电玩城的霓虹氛围。 |
7.3 无定时器循环动画的优势
传统循环动画使用 setInterval 逐帧更新,需手动管理定时器、频繁状态更新可能导致性能问题。ArkTS 属性动画通过 iterations:-1 + PlayMode.Alternate 实现零定时器循环动画:框架底层自动调度动画帧、组件销毁时动画自动停止、多个动画可同时运行互不干扰。CLAW CITY 娃都约10组动画全部采用此方式,确保流畅性和性能。
7.4 交互反馈设计
项目通过多种方式提供即时交互反馈:按钮点击后立即触发状态变更(显示弹框/切换选中态),状态变更通过响应式机制自动触发UI更新。选中态有明确视觉变化(颜色/背景/边框)。Tab切换提供图标透明度+文字颜色+底部指示条三重反馈。娃娃宫格选择点击后立即变为金色边框选中态。沾欧气按钮点击后变为"已沾欧气"。签到日历点击后状态变化。这些即时反馈确保用户操作的"确定性",提升交互流畅度和愉悦感。
第八章 机台系统与概率公示
8.1 机台数据模型
每台机台(CCMachine)包含:机台编号(no)、机台名称(name)、当前娃娃名(dollName)、娃娃颜色(dollColor)、状态(status:热门/畅玩/维护)、在线玩家数(players)、每次价格(price,币)、历史夹中次数(history)。
9台机台覆盖不同品牌和娃娃:粉爪一号(玉桂狗巨人款)、莓好时光(美乐蒂草莓妹)、星夜主推(库洛米星空限定,热门)、云朵慢夹(大耳狗云朵抱枕)、梦幻双爪(星之卡比毛绒)、阳光补给(帕恰狗夏日款)、口袋乐园(酷洛米迷你挂件)、派对盲盒(蛋仔派对盲盒,热门)、薄荷维修位(病毒猫挂件,维护中)。
8.2 机台状态管理
机台三态:热门(粉色标签,在线人数多)、畅玩(薄荷绿标签,在线人数少)、维护(灰色标签,不可开夹)。状态颜色通过 ccStatusColor 函数映射。机台格显示在线人数,热门机台通常有12-18人在线,畅玩机台2-7人,维护机台0人。
8.3 概率公示系统
机台详情弹框包含概率公示表,显示5款娃娃的概率和剩余数量:
- 库洛米星空限定:1/128,剩余2只(SSR级,最低概率)
- 玉桂狗巨人款:1/96,剩余3只
- 星之卡比毛绒:1/45,剩余8只
- 美乐蒂草莓妹:1/30,剩余12只
- 帕恰狗夏日款:1/18,剩余20只(R级,最高概率)
概率公示表采用深色背景,每行三列(娃娃名/概率/剩余),粉色概率分数、薄荷绿剩余数量,底部说明"概率由公证处监管,娃娃夹中即归您所有,概不退换"。这种透明化的概率公示增加了玩家的信任感和参与感。
8.4 机械爪动画
机台详情弹框中的机械爪emoji通过 clawY 属性动画实现上下移动(0↔14vp,1600ms,EaseInOut),模拟娃娃机机械爪的升降动作。首页机台格中的机械爪也有同样的动画(0↔16vp),使整个页面的机台都"活"起来。这种机械爪动画是娃娃机主题应用的标志性交互元素。
8.5 开夹流程
用户点击机台格→触发 onOpenMachine 回调→根组件设置 machineNo 并显示机台详情弹框→用户查看概率和价格→点击"立即开夹·X币"→扣币并执行开夹(演示项目中直接关闭弹框,实际项目中应连接后端执行夹娃娃逻辑并返回结果)。
第九章 潮玩收藏与稀有度体系
9.1 娃娃数据模型
每只娃娃(CCDoll)包含:ID、名称、稀有度(rarity:SSR/SR/R)、颜色(color)、尺寸(size)、人气热度(hot)、分类(cat:三丽鸥风/潮玩IP/毛绒/挂件)、材质(material:毛绒/PVC/短毛/礼盒)、所在机台(machine)、是否已夹到(caught)、上架时间(addTime)。
16款娃娃覆盖:库洛米星空限定(SSR)、玉桂狗巨人款(SSR)、星之卡比毛绒(SR)、美乐蒂草莓妹(SR)、大耳狗云朵抱枕(SR)、帕恰狗夏日款(SR)、酷洛米迷你挂件(R)、蛋仔派对盲盒(SR)、Loopy菲菲兔(R)、吉伊卡哇小八(R)、三丽鸥全家福礼盒(SSR)、病毒猫挂件(R)、Zzoton狼崽(SR)、蜡笔小新动感公仔(R)、樱花兔妹宝(R)、奶油熊趴趴枕(SR)。
9.2 稀有度三级体系
项目采用三级稀有度体系:
- SSR(3款):金色标签(#FFC93C),最低概率,最高人气,包括库洛米星空限定、玉桂狗巨人款、三丽鸥全家福礼盒
- SR(7款):紫色标签(#9B6BFF),中等概率,包括星之卡比、美乐蒂、大耳狗、帕恰狗、蛋仔盲盒、Zzoton狼崽、奶油熊趴趴枕
- R(6款):蓝色标签(#5FA8FF),较高概率,包括酷洛米挂件、Loopy、吉伊卡哇、病毒猫、蜡笔小新、樱花兔
稀有度颜色通过 ccRarityColor 函数映射,稀有度数量通过 ccRarityCount 函数统计(SSR 3/SR 7/R 6)。潮玩库页面底部的稀有度分布横条按数量比例分配宽度,直观展示全馆稀有度构成。
9.3 分类筛选体系
5个分类:全系列、三丽鸥风(6款)、潮玩IP(6款)、毛绒(1款)、挂件(3款)。分类筛选通过 ccFilterDolls 函数实现,遍历娃娃数组筛选匹配分类的娃娃。分类chips横向滚动,选中态深粉背景,未选中深紫卡片背景。
9.4 收藏册系统
“我的"Tab中的收藏册横滚展示已夹到的娃娃(caught=true的8款),显示收录进度(8/16)。每只娃娃的图鉴弹框中显示收藏状态:已夹到过显示金色"已收录进我的收藏册”,未夹到显示灰色"还没夹到过,去X号机碰碰运气"。收藏册系统为玩家提供了收集目标和成就感,是潮玩类应用的核心粘性功能。
9.5 人气热度排序
每只娃娃有人气热度值(hot),从982(库洛米星空限定)到399(奶油熊趴趴枕)。首页热门娃娃横滚卡筛选热度>560的娃娃(ccHotDolls函数),按热度排序展示。人气热度反映了娃娃的受欢迎程度,为玩家提供选择参考。
第十章 币值体系与充值经济
10.1 币值档位设计
4个币值档位(CCTier):
- 50币 + 赠5币 = ¥6(入门档)
- 200币 + 赠30币 = ¥25(热销档,hot=true)
- 500币 + 赠100币 = ¥60(进阶档)
- 1000币 + 赠300币 = ¥118(豪享档)
档位设计遵循"充得多送得多"原则,赠送比例从10%(50币档)到30%(1000币档),激励大额充值。热销档(200币¥25)右上角有"热销"角标,引导用户选择。
10.2 限时礼包设计
4个限时礼包(CCPack):
- 新人首充礼包:100币+挂件兑换券x1,原价¥25现价¥12(52折)
- 周末疯狂包:300币+双倍奖票卡x2,原价¥58现价¥30(52折)
- 深夜快乐包:150币+薄荷饮品券x1,原价¥30现价¥16(53折)
- 段位冲刺包:600币+保护罩x3,原价¥120现价¥65(54折)
每个礼包有独特颜色边框(粉/紫/薄荷/金)和emoji图标,横向滚动展示。礼包设计针对不同用户场景(新人/周末/深夜/冲段位),提高充值转化率。
10.3 充值确认流程
用户点击档位或礼包→触发 onRecharge 回调→根组件设置 rechargeCoins 并显示充值确认弹框→弹框显示币值/赠送/到账/价格→用户选择支付方式(余额/微信/支付宝)→查看费用明细(档位金额+会员9.5折+实付)→点击确认支付→完成充值(演示项目中直接关闭弹框)。
10.4 支付方式与折扣
3种支付方式:余额支付(🎫)、微信支付(💚)、支付宝(💙),通过Radio单选。会员9.5折优惠,费用明细清晰展示:档位金额 - 会员折扣(-¥X.XX,薄荷绿)= 实付金额(深粉大号)。折扣计算通过 tier.price * 0.95 实现,保留两位小数。
10.5 充值记录
8笔充值记录(CCPayLog),斑马纹列表展示(奇偶行交替背景),每笔含:档位名、时间、支付方式、状态(成功绿/处理中金/已退款灰)。状态颜色通过 ccPayStatusColor 函数映射。充值记录为用户提供消费追溯,增加信任感。
第十一章 换物街与社区交易
11.1 换物帖数据模型
每条换物帖(CCTrade)包含:ID、标题、我的娃娃名(myDoll)、我的娃娃颜色(myColor)、想要的娃娃描述(want)、交换方式(mode:1换1/1换2/加币补)、状态(status:求换中/换到了/已下架)、是否我出的(mine)、是否我想要的(wanted)。
8条换物帖覆盖不同交换场景:SSR换SR×2、1换1、加币补、已完成交易等。
11.2 筛选体系
4个筛选维度(CC_TRADE_FILTERS):全部、我出的(mine=true)、我想要的(wanted=true)、已完成(status=换到了)。筛选通过 ccFilterTrades 函数实现,遍历换物帖数组筛选匹配条件的帖子。筛选chips横向滚动,选中态紫色背景,未选中深紫卡片背景。
11.3 发布换物帖流程
用户点击底部"发布换物帖"按钮→显示发布换物弹框→填写标题→从6款娃娃宫格中选择我的娃娃→填写想要的娃娃描述→选择交换方式(1换1/1换2/加币补)→填写备注→点击"发布到换物街"→发布成功(演示项目中直接关闭弹框)。
娃娃宫格选择是发布流程的特色交互:2列布局,每款娃娃显示色块卡片+名称+稀有度尺寸,点击切换选中态,选中态2px金色边框。
11.4 编辑与删除
我的帖子(mine=true)显示编辑(✏️)和删除(🗑)按钮。点击编辑→显示底部抽屉式编辑弹框→可修改标题、交换方式、帖子状态(上架中/已下架)→点击保存修改。点击删除→显示粉色警告删除确认弹框→显示帖子信息→确认删除。
编辑弹框采用底部抽屉式设计(position y:46%),顶部44×5圆角小条模拟抽屉把手,与居中的发布弹框形成视觉区分。删除弹框采用2px粉色边框警告式设计,二次确认防止误删。
11.5 交易状态流转
换物帖三态:求换中(粉色标签,活跃交易)→换到了(薄荷绿标签,交易完成);求换中→已下架(灰色标签,主动下架)。状态颜色通过 ccTradeStatusColor 函数映射。每条帖子有联系按钮(💬联系,深粉),点击后可与换友沟通(演示项目中未实现聊天功能)。
第十二章 夹神榜与竞技体系
12.1 排行榜数据模型
每位玩家(CCRank)包含:排名(rank)、昵称(nick)、段位(tier:传说/大师/钻石/黄金)、段位颜色(color)、本月夹中数(catches)、成功率(rate,百分比)。
10名玩家覆盖4个段位:传说3名(金色,月夹中70+)、大师3名(紫色,月夹中50+)、钻石3名(蓝色,月夹中35+)、黄金1名(粉色,月夹中20+)。前三名:爪法大师·夜(86只/42%)、一爪一个准(79只/39%)、夹娃娃锦鲤(72只/37%)。
12.2 段位体系
4个段位(CC_TIER_DESC):
- 传说(金色#FFC93C):月夹中70+
- 大师(紫色#9B6BFF):月夹中50+
- 钻石(蓝色#5FA8FF):月夹中35+
- 黄金(粉色#FF8FB8):月夹中20+
段位颜色用于排行榜头像背景、段位标签、段位分布条。段位说明四格展示每个段位的月夹中门槛,为玩家提供晋升目标。
12.3 排行榜布局设计
排行榜采用差异化布局:
- 前三名:大序号布局(01/02/03金色38号大号字)+ 头像(彩色圆形)+ 昵称 + 段位标签 + 本月夹中数 + 成功率(粉色大号),金色边框,卡片式设计
- 4-10名:紧凑行布局,序号(16号灰色)+ 昵称 + 段位 + 夹中数 + 成功率(薄荷绿)
这种差异化布局突出前三名的荣誉感,同时保证后续排名的信息密度。
12.4 赛季系统
S9赛季进行中,距结算6天18小时,赛季进度条72%(金粉渐变)。皇冠呼吸动画(crownOp 0.4↔1,1200ms)模拟冠军皇冠的金光闪烁。赛季系统为排行榜增加了时间维度和竞技感,激励玩家在赛季结束前冲击更高排名。
12.5 段位分布
榜单段位分布:传说x3/大师x3/钻石x3/黄金x1,通过 ccTierCount 函数统计。段位分布占比条按数量比例分配宽度(金/紫/蓝/粉四段),直观展示榜单段位构成。
第十三章 性能优化与扩展方向
13.1 性能优化策略
- 合理使用@State:只有需触发UI更新的状态用@State,静态数据用const,减少响应式开销。项目中约30个@State变量,均为必要的交互状态。
- 列表渲染优化:使用ForEach框架自动diff复用,列表项固定尺寸避免布局抖动。9台机台、16款娃娃、10名排行、8条动态等列表均使用ForEach。
- 动画性能:使用属性动画而非逐帧动画,动画属性限制在opacity/translate/rotate/scale等合成层属性避免重排,无限循环用iterations:-1+Alternate零定时器。约10组动画全部采用此方式。
- 减少重渲染:弹框条件渲染未显示不渲染,避免build()中复杂计算。7个弹框均通过if条件渲染。
- 资源优化:使用emoji作图标头像无需图片,渐变背景用linearGradient无需图片,减少网络请求和内存占用。
13.2 代码规范
命名规范:组件名大驼峰(CCHomeContent)、变量函数小驼峰(activeTab)、常量大写下划线(CC_COLORS)、接口大驼峰(CCMachine)、统一CC前缀。文件结构:接口→全局常量→纯函数→弹框组件→Tab组件→根入口。代码风格:2空格缩进、语句末尾不加分号、对象字面量每行一属性。
13.3 可维护性与可扩展性
组件化拆分16个独立组件职责单一。数据与视图分离(数据在const常量,UI只读渲染)。逻辑与视图分离(业务逻辑封装在约25个纯函数中)。配置化设计(Tab/分类/筛选/交换方式/支付方式/段位均通过配置数据驱动)。
13.4 功能扩展方向
机台系统深化:实时在线人数、排队预约、远程操控夹娃娃(直播+实时操控)、机台评价、机台收藏。
潮玩收藏深化:娃娃3D展示、AR试摆、收藏册成就系统、娃娃交易市场、限量款预售。
币值经济深化:会员体系(月卡/季卡/年卡)、币值过期提醒、消费返利、邀请好友奖励、每日免费币。
竞技体系深化:周榜/月榜/总榜、段位晋升动画、赛季奖励、夹娃娃挑战赛、双人PK模式。
社区交易深化:即时聊天、交易担保、评价系统、交易纠纷处理、娃娃鉴定。
社交动态深化:短视频夹娃娃实录、直播夹娃娃、话题挑战、@好友、私信系统。
13.5 技术演进方向
短期(1-3月):对接后端API替换硬编码、引入状态管理库、增加本地存储、完善错误处理。中期(3-6月):引入路由管理、推送通知开票提醒、接入支付SDK实现在线充值、性能优化懒加载、适配平板折叠屏。长期(6-12月):短视频播放、实时聊天、远程操控夹娃娃、AR娃娃展示、跨设备协同。
13.6 鸿蒙生态融合
原子化服务:将开夹/充值/换物封装为原子化服务,无需安装即用。万能卡片:提供今日机台/我的币余额/夹神榜卡片,桌面实时查看。多设备协同:手机浏览机台、平板大屏选娃娃、手表提醒开夹、智慧屏直播夹娃娃。小艺语音:语音查询机台/充值开夹/提醒签到。
十四、开发环境搭建
14.1 环境要求
DevEco Studio 5.0+(支持HarmonyOS 6.1.1)、HarmonyOS SDK API 24、Node.js 18+、至少8GB内存。
14.2 安装DevEco Studio

从华为开发者官网下载最新版本,运行安装包,选择安装路径,勾选创建桌面快捷方式,点击安装。
14.3 配置SDK

首次启动后进入File > Settings > HarmonyOS SDK,勾选API 24及以上版本,点击Apply等待下载完成。
14.4 创建项目

选择Create Project > Empty Ability,配置项目名称、包名、保存路径,选择Compile SDK为API 24,点击Finish。
14.5 运行应用

将1316.ets代码替换到entry/src/main/ets/pages/Index.ets,连接HarmonyOS设备或启动模拟器,点击运行按钮预览。
14.6 预览调试

DevEco Studio提供实时预览功能,编辑器右侧打开Previewer面板,支持多设备尺寸预览、深色模式切换、组件树inspect等调试能力。
完整代码
// ============================================================
// CLAW CITY 娃都 —— 潮流娃娃机·夹娃娃电玩城
// 糖果街机×马卡龙电玩风 · ArkTS 单文件
// ============================================================
// ============ 配色(葡萄紫深底 × 马卡龙电玩色) ============
interface CCColorPalette {
bg: string
card: string
deep: string
line: string
pink: string
pinkDeep: string
purple: string
gold: string
mint: string
textMain: string
textSub: string
textHint: string
white: string
blueR: string
grayTag: string
}
const CC_COLORS: CCColorPalette = {
bg: '#1A1030',
card: '#241840',
deep: '#120A22',
line: '#3A2B5C',
pink: '#FF8FB8',
pinkDeep: '#E85D93',
purple: '#9B6BFF',
gold: '#FFC93C',
mint: '#5FE3C0',
textMain: '#F6F1FF',
textSub: '#A99BC4',
textHint: '#6F5F8C',
white: '#FFFFFF',
blueR: '#5FA8FF',
grayTag: '#6F5F8C'
}
// ============ Tab 定义 ============
enum CCTab {
Home = 0,
DollLib = 1,
Coin = 2,
Rank = 3,
Trade = 4,
Feed = 5,
Daily = 6,
Me = 7
}
interface CCTabItem {
tab: CCTab
icon: string
label: string
}
const CC_TABS: CCTabItem[] = [
{ tab: CCTab.Home, icon: '🎮', label: '娃都' },
{ tab: CCTab.DollLib, icon: '🧸', label: '潮玩库' },
{ tab: CCTab.Coin, icon: '🎫', label: '补币' },
{ tab: CCTab.Rank, icon: '🏅', label: '夹神榜' },
{ tab: CCTab.Trade, icon: '🔄', label: '换物街' },
{ tab: CCTab.Feed, icon: '📣', label: '动态' },
{ tab: CCTab.Daily, icon: '🎁', label: '每日' },
{ tab: CCTab.Me, icon: '👤', label: '我的' }
]
// ============ 数据接口 ============
interface CCMachine {
no: string
name: string
dollName: string
dollColor: string
status: string
players: number
price: number
history: number
}
interface CCDoll {
id: number
name: string
rarity: string
color: string
size: string
hot: number
cat: string
material: string
machine: string
caught: boolean
addTime: string
}
interface CCTier {
coins: number
bonus: number
price: number
hot: boolean
}
interface CCPack {
name: string
content: string
oldPrice: number
price: number
color: string
emoji: string
}
interface CCPayLog {
time: string
tier: string
pay: string
status: string
}
interface CCRank {
rank: number
nick: string
tier: string
color: string
catches: number
rate: number
}
interface CCTrade {
id: number
title: string
myDoll: string
myColor: string
want: string
mode: string
status: string
mine: boolean
wanted: boolean
}
interface CCFeed {
id: number
nick: string
color: string
time: string
text: string
likes: number
comments: number
loots: string[]
lootColors: string[]
}
interface CCTask {
name: string
cur: number
total: number
reward: number
claimable: boolean
}
interface CCSignDay {
day: string
signed: boolean
reward: number
today: boolean
}
interface CCWeekRate {
label: string
rate: number
}
interface CCOddsRow {
doll: string
rate: string
left: number
}
interface CCNews {
text: string
color: string
}
interface CCSetting {
icon: string
name: string
hint: string
}
interface CCTierDesc {
tier: string
color: string
desc: string
}
// ============ 全局硬编码数据 ============
const CC_MACHINES: CCMachine[] = [
{ no: '01', name: '粉爪一号', dollName: '玉桂狗巨人款', dollColor: '#A8D8FF', status: '热门', players: 12, price: 30, history: 428 },
{ no: '02', name: '莓好时光', dollName: '美乐蒂草莓妹', dollColor: '#FF8FB8', status: '畅玩', players: 5, price: 25, history: 356 },
{ no: '03', name: '星夜主推', dollName: '库洛米星空限定', dollColor: '#B58BFF', status: '热门', players: 18, price: 40, history: 512 },
{ no: '04', name: '云朵慢夹', dollName: '大耳狗云朵抱枕', dollColor: '#C9E8FF', status: '畅玩', players: 3, price: 25, history: 208 },
{ no: '05', name: '梦幻双爪', dollName: '星之卡比毛绒', dollColor: '#FFB3C9', status: '畅玩', players: 7, price: 30, history: 291 },
{ no: '06', name: '阳光补给', dollName: '帕恰狗夏日款', dollColor: '#FFE9A8', status: '畅玩', players: 2, price: 20, history: 174 },
{ no: '07', name: '口袋乐园', dollName: '酷洛米迷你挂件', dollColor: '#9B6BFF', status: '畅玩', players: 6, price: 15, history: 463 },
{ no: '08', name: '派对盲盒', dollName: '蛋仔派对盲盒', dollColor: '#FFC93C', status: '热门', players: 15, price: 35, history: 389 },
{ no: '09', name: '薄荷维修位', dollName: '病毒猫挂件', dollColor: '#B8FFD9', status: '维护', players: 0, price: 15, history: 233 }
]
const CC_DOLLS: CCDoll[] = [
{ id: 1, name: '库洛米星空限定', rarity: 'SSR', color: '#B58BFF', size: '30cm', hot: 982, cat: '三丽鸥风', material: '毛绒', machine: '03号机', caught: true, addTime: '08-20' },
{ id: 2, name: '玉桂狗巨人款', rarity: 'SSR', color: '#A8D8FF', size: '45cm', hot: 876, cat: '三丽鸥风', material: '毛绒', machine: '01号机', caught: true, addTime: '08-18' },
{ id: 3, name: '星之卡比毛绒', rarity: 'SR', color: '#FFB3C9', size: '25cm', hot: 754, cat: '潮玩IP', material: '毛绒', machine: '05号机', caught: false, addTime: '08-22' },
{ id: 4, name: '美乐蒂草莓妹', rarity: 'SR', color: '#FF8FB8', size: '18cm', hot: 690, cat: '三丽鸥风', material: '毛绒', machine: '02号机', caught: true, addTime: '08-15' },
{ id: 5, name: '大耳狗云朵抱枕', rarity: 'SR', color: '#C9E8FF', size: '40cm', hot: 655, cat: '三丽鸥风', material: '毛绒', machine: '04号机', caught: false, addTime: '08-25' },
{ id: 6, name: '帕恰狗夏日款', rarity: 'SR', color: '#FFE9A8', size: '20cm', hot: 601, cat: '三丽鸥风', material: '短毛', machine: '06号机', caught: false, addTime: '08-12' },
{ id: 7, name: '酷洛米迷你挂件', rarity: 'R', color: '#9B6BFF', size: '8cm', hot: 588, cat: '挂件', material: 'PVC', machine: '07号机', caught: true, addTime: '08-10' },
{ id: 8, name: '蛋仔派对盲盒', rarity: 'SR', color: '#FFC93C', size: '12cm', hot: 566, cat: '潮玩IP', material: 'PVC', machine: '08号机', caught: false, addTime: '08-24' },
{ id: 9, name: 'Loopy菲菲兔', rarity: 'R', color: '#FFB08A', size: '15cm', hot: 540, cat: '潮玩IP', material: '毛绒', machine: '09号机', caught: true, addTime: '08-08' },
{ id: 10, name: '吉伊卡哇小八', rarity: 'R', color: '#FFE3F0', size: '14cm', hot: 522, cat: '潮玩IP', material: '毛绒', machine: '02号机', caught: false, addTime: '08-19' },
{ id: 11, name: '三丽鸥全家福礼盒', rarity: 'SSR', color: '#FF6FA5', size: '35cm', hot: 498, cat: '三丽鸥风', material: '礼盒', machine: '05号机', caught: false, addTime: '08-26' },
{ id: 12, name: '病毒猫挂件', rarity: 'R', color: '#B8FFD9', size: '8cm', hot: 470, cat: '挂件', material: 'PVC', machine: '07号机', caught: true, addTime: '08-05' },
{ id: 13, name: 'Zzoton狼崽', rarity: 'SR', color: '#C9B8FF', size: '22cm', hot: 445, cat: '潮玩IP', material: '毛绒', machine: '03号机', caught: false, addTime: '08-21' },
{ id: 14, name: '蜡笔小新动感公仔', rarity: 'R', color: '#FFE08A', size: '16cm', hot: 430, cat: '潮玩IP', material: 'PVC', machine: '06号机', caught: false, addTime: '08-14' },
{ id: 15, name: '樱花兔妹宝', rarity: 'R', color: '#FFD9E8', size: '18cm', hot: 415, cat: '挂件', material: '毛绒', machine: '09号机', caught: true, addTime: '08-11' },
{ id: 16, name: '奶油熊趴趴枕', rarity: 'SR', color: '#FFF1C9', size: '50cm', hot: 399, cat: '毛绒', material: '毛绒', machine: '01号机', caught: false, addTime: '08-23' }
]
const CC_TIERS: CCTier[] = [
{ coins: 50, bonus: 5, price: 6, hot: false },
{ coins: 200, bonus: 30, price: 25, hot: true },
{ coins: 500, bonus: 100, price: 60, hot: false },
{ coins: 1000, bonus: 300, price: 118, hot: false }
]
const CC_PACKS: CCPack[] = [
{ name: '新人首充礼包', content: '100币+挂件兑换券x1', oldPrice: 25, price: 12, color: '#FF8FB8', emoji: '🎀' },
{ name: '周末疯狂包', content: '300币+双倍奖票卡x2', oldPrice: 58, price: 30, color: '#9B6BFF', emoji: '🎉' },
{ name: '深夜快乐包', content: '150币+薄荷饮品券x1', oldPrice: 30, price: 16, color: '#5FE3C0', emoji: '🌙' },
{ name: '段位冲刺包', content: '600币+保护罩x3', oldPrice: 120, price: 65, color: '#FFC93C', emoji: '🚀' }
]
const CC_PAYLOG: CCPayLog[] = [
{ time: '08-26 21:33', tier: '200币档', pay: '微信支付', status: '成功' },
{ time: '08-25 19:02', tier: '500币档', pay: '支付宝', status: '成功' },
{ time: '08-24 22:47', tier: '50币档', pay: '余额支付', status: '成功' },
{ time: '08-23 20:15', tier: '1000币档', pay: '微信支付', status: '成功' },
{ time: '08-22 18:40', tier: '周末疯狂包', pay: '支付宝', status: '成功' },
{ time: '08-21 23:58', tier: '50币档', pay: '微信支付', status: '处理中' },
{ time: '08-20 12:26', tier: '200币档', pay: '余额支付', status: '已退款' },
{ time: '08-19 21:11', tier: '新人首充礼包', pay: '支付宝', status: '成功' }
]
const CC_RANKS: CCRank[] = [
{ rank: 1, nick: '爪法大师·夜', tier: '传说', color: '#FFC93C', catches: 86, rate: 42 },
{ rank: 2, nick: '一爪一个准', tier: '传说', color: '#FFC93C', catches: 79, rate: 39 },
{ rank: 3, nick: '夹娃娃锦鲤', tier: '传说', color: '#FFC93C', catches: 72, rate: 37 },
{ rank: 4, nick: '欧气本气', tier: '大师', color: '#9B6BFF', catches: 68, rate: 35 },
{ rank: 5, nick: '稳如老狗', tier: '大师', color: '#9B6BFF', catches: 61, rate: 33 },
{ rank: 6, nick: '薄荷味爪子', tier: '大师', color: '#9B6BFF', catches: 55, rate: 30 },
{ rank: 7, nick: '粉爪小仙女', tier: '钻石', color: '#5FA8FF', catches: 49, rate: 28 },
{ rank: 8, nick: '币海无涯', tier: '钻石', color: '#5FA8FF', catches: 44, rate: 26 },
{ rank: 9, nick: '新爪试炼', tier: '钻石', color: '#5FA8FF', catches: 38, rate: 22 },
{ rank: 10, nick: '路过的萌新', tier: '黄金', color: '#FF8FB8', catches: 30, rate: 19 }
]
const CC_TRADES: CCTrade[] = [
{ id: 1, title: '我的SSR换你的SR×2', myDoll: '库洛米星空限定', myColor: '#B58BFF', want: '玉桂狗或大耳狗任选2', mode: '1换2', status: '求换中', mine: true, wanted: false },
{ id: 2, title: '玉桂狗巨人款换库洛米Mini', myDoll: '玉桂狗巨人款', myColor: '#A8D8FF', want: '酷洛米迷你挂件', mode: '1换1', status: '求换中', mine: true, wanted: false },
{ id: 3, title: '双倍美乐蒂出,收一只卡比', myDoll: '美乐蒂草莓妹', myColor: '#FF8FB8', want: '星之卡比毛绒', mode: '1换1', status: '换到了', mine: false, wanted: true },
{ id: 4, title: '蛋仔盲盒换任意挂件+补币', myDoll: '蛋仔派对盲盒', myColor: '#FFC93C', want: '挂件类+50币', mode: '加币补', status: '求换中', mine: false, wanted: true },
{ id: 5, title: '全家福礼盒找有缘人', myDoll: '三丽鸥全家福礼盒', myColor: '#FF6FA5', want: 'SSR级毛绒均可', mode: '1换1', status: '求换中', mine: false, wanted: false },
{ id: 6, title: 'Loopy换吉伊卡哇,急出', myDoll: 'Loopy菲菲兔', myColor: '#FFB08A', want: '吉伊卡哇小八', mode: '1换1', status: '换到了', mine: true, wanted: false },
{ id: 7, title: '狼崽Zzoton换两只樱花兔', myDoll: 'Zzoton狼崽', myColor: '#C9B8FF', want: '樱花兔妹宝x2', mode: '1换2', status: '求换中', mine: false, wanted: true },
{ id: 8, title: '奶油熊趴趴枕半价换', myDoll: '奶油熊趴趴枕', myColor: '#FFF1C9', want: '任意SR+30币', mode: '加币补', status: '已下架', mine: true, wanted: false }
]
const CC_FEEDS: CCFeed[] = [
{ id: 1, nick: '爪法大师·夜', color: '#FFC93C', time: '12分钟前', text: '三连爪!库洛米星空限定直接入怀,今晚机台被我承包了', likes: 328, comments: 56, loots: ['库洛米星空限定', '酷洛米迷你挂件', '病毒猫挂件'], lootColors: ['#B58BFF', '#9B6BFF', '#B8FFD9'] },
{ id: 2, nick: '粉爪小仙女', color: '#FF8FB8', time: '35分钟前', text: '第一次来娃都就夹到玉桂狗巨人款,45cm抱回家超满足', likes: 216, comments: 43, loots: ['玉桂狗巨人款'], lootColors: ['#A8D8FF'] },
{ id: 3, nick: '薄荷味爪子', color: '#5FE3C0', time: '1小时前', text: '换物街首单成交!美乐蒂换到了心心念念的卡比,感谢老板', likes: 98, comments: 21, loots: ['星之卡比毛绒', '美乐蒂草莓妹'], lootColors: ['#FFB3C9', '#FF8FB8'] },
{ id: 4, nick: '币海无涯', color: '#9B6BFF', time: '2小时前', text: '冲了段位冲刺包,保护罩真的有用,连夹四个蛋仔盲盒', likes: 187, comments: 39, loots: ['蛋仔派对盲盒', '蛋仔派对盲盒', 'Loopy菲菲兔'], lootColors: ['#FFC93C', '#FFC93C', '#FFB08A'] },
{ id: 5, nick: '欧气本气', color: '#FFC93C', time: '3小时前', text: '全家福礼盒一发入魂,1/96的概率被我撞上了,欧到发光', likes: 402, comments: 88, loots: ['三丽鸥全家福礼盒'], lootColors: ['#FF6FA5'] },
{ id: 6, nick: '新爪试炼', color: '#5FA8FF', time: '5小时前', text: '每日任务全清,白嫖88币,明天继续来蹲樱花兔妹宝', likes: 76, comments: 12, loots: ['樱花兔妹宝', '吉伊卡哇小八'], lootColors: ['#FFD9E8', '#FFE3F0'] },
{ id: 7, nick: '稳如老狗', color: '#9B6BFF', time: '6小时前', text: '帕恰狗夏日款手感太好了,阳光补给机台强烈推荐新手去', likes: 154, comments: 27, loots: ['帕恰狗夏日款', '蜡笔小新动感公仔'], lootColors: ['#FFE9A8', '#FFE08A'] },
{ id: 8, nick: '路过的萌新', color: '#FF8FB8', time: '8小时前', text: '被朋友拽来的,结果一发就中奶油熊趴趴枕,50cm巨无霸', likes: 133, comments: 31, loots: ['奶油熊趴趴枕'], lootColors: ['#FFF1C9'] }
]
const CC_TASKS: CCTask[] = [
{ name: '今日夹娃娃 3 次', cur: 2, total: 3, reward: 30, claimable: false },
{ name: '每日签到打卡', cur: 1, total: 1, reward: 20, claimable: true },
{ name: '分享一条夹中喜报', cur: 0, total: 1, reward: 15, claimable: false },
{ name: '今日消耗 100 币', cur: 60, total: 100, reward: 40, claimable: false },
{ name: '观看夹娃娃直播 5 分钟', cur: 5, total: 5, reward: 10, claimable: true },
{ name: '邀请好友来娃都', cur: 0, total: 2, reward: 88, claimable: false }
]
const CC_SIGN: CCSignDay[] = [
{ day: '周一', signed: true, reward: 10, today: false },
{ day: '周二', signed: true, reward: 20, today: false },
{ day: '周三', signed: true, reward: 20, today: false },
{ day: '周四', signed: true, reward: 30, today: false },
{ day: '周五', signed: false, reward: 40, today: true },
{ day: '周六', signed: false, reward: 60, today: false },
{ day: '周日', signed: false, reward: 100, today: false }
]
const CC_WEEK: CCWeekRate[] = [
{ label: '周一', rate: 22 },
{ label: '周二', rate: 31 },
{ label: '周三', rate: 18 },
{ label: '周四', rate: 35 },
{ label: '周五', rate: 27 },
{ label: '周六', rate: 44 },
{ label: '周日', rate: 39 }
]
const CC_MACHINE_ODDS: CCOddsRow[] = [
{ doll: '库洛米星空限定', rate: '1/128', left: 2 },
{ doll: '玉桂狗巨人款', rate: '1/96', left: 3 },
{ doll: '星之卡比毛绒', rate: '1/45', left: 8 },
{ doll: '美乐蒂草莓妹', rate: '1/30', left: 12 },
{ doll: '帕恰狗夏日款', rate: '1/18', left: 20 }
]
const CC_NEWS: CCNews[] = [
{ text: '恭喜 @欧气本气 夹中全家福礼盒', color: '#FF6FA5' },
{ text: '恭喜 @爪法大师·夜 三连爪库洛米', color: '#B58BFF' },
{ text: '恭喜 @粉爪小仙女 首夹即中玉桂狗', color: '#FF8FB8' },
{ text: '恭喜 @路过的萌新 一发入魂奶油熊', color: '#FFF1C9' },
{ text: '恭喜 @币海无涯 连开四盒蛋仔盲盒', color: '#FFC93C' },
{ text: '恭喜 @薄荷味爪子 换物首单成交', color: '#5FE3C0' }
]
const CC_SETTINGS: CCSetting[] = [
{ icon: '📍', name: '收货地址', hint: '娃都·糖果街机2F服务台' },
{ icon: '🔔', name: '消息通知', hint: '喜报与换物提醒已开启' },
{ icon: '🎫', name: '币值明细', hint: '收支流水一目了然' },
{ icon: '💬', name: '客服中心', hint: '在线时间 10:00-24:00' },
{ icon: 'ℹ️', name: '关于娃都', hint: '版本 v3.2.1 糖果街机版' }
]
const CC_TIER_DESC: CCTierDesc[] = [
{ tier: '传说', color: '#FFC93C', desc: '月夹中70+' },
{ tier: '大师', color: '#9B6BFF', desc: '月夹中50+' },
{ tier: '钻石', color: '#5FA8FF', desc: '月夹中35+' },
{ tier: '黄金', color: '#FF8FB8', desc: '月夹中20+' }
]
const CC_DOLL_CATS: string[] = ['全系列', '三丽鸥风', '潮玩IP', '毛绒', '挂件']
const CC_TRADE_FILTERS: string[] = ['全部', '我出的', '我想要的', '已完成']
const CC_TRADE_MODES: string[] = ['1换1', '1换2', '加币补']
const CC_PAY_METHODS: string[] = ['余额支付', '微信支付', '支付宝']
// ============ 全局纯函数 ============
function ccMachineByNo(no: string): CCMachine {
const empty: CCMachine = { no: '01', name: '粉爪一号', dollName: '玉桂狗巨人款', dollColor: '#A8D8FF', status: '热门', players: 12, price: 30, history: 428 }
for (let i = 0; i < CC_MACHINES.length; i++) {
if (CC_MACHINES[i].no === no) {
return CC_MACHINES[i]
}
}
return empty
}
function ccDollByName(name: string): CCDoll {
const empty: CCDoll = CC_DOLLS[0]
for (let i = 0; i < CC_DOLLS.length; i++) {
if (CC_DOLLS[i].name === name) {
return CC_DOLLS[i]
}
}
return empty
}
function ccTierByCoins(coins: number): CCTier {
for (let i = 0; i < CC_TIERS.length; i++) {
if (CC_TIERS[i].coins === coins) {
return CC_TIERS[i]
}
}
return CC_TIERS[1]
}
function ccFilterDolls(cat: string): CCDoll[] {
const r: CCDoll[] = []
for (let i = 0; i < CC_DOLLS.length; i++) {
if (cat === '全系列' || CC_DOLLS[i].cat === cat) {
r.push(CC_DOLLS[i])
}
}
return r
}
function ccFilterTrades(filter: string): CCTrade[] {
const r: CCTrade[] = []
for (let i = 0; i < CC_TRADES.length; i++) {
if (filter === '全部' ||
(filter === '我出的' && CC_TRADES[i].mine) ||
(filter === '我想要的' && CC_TRADES[i].wanted) ||
(filter === '已完成' && CC_TRADES[i].status === '换到了')) {
r.push(CC_TRADES[i])
}
}
return r
}
function ccHotDolls(): CCDoll[] {
const r: CCDoll[] = []
for (let i = 0; i < CC_DOLLS.length; i++) {
if (CC_DOLLS[i].hot > 560) {
r.push(CC_DOLLS[i])
}
}
return r
}
function ccCaughtDolls(): CCDoll[] {
const r: CCDoll[] = []
for (let i = 0; i < CC_DOLLS.length; i++) {
if (CC_DOLLS[i].caught) {
r.push(CC_DOLLS[i])
}
}
return r
}
function ccTradePickDolls(): CCDoll[] {
const r: CCDoll[] = []
for (let i = 0; i < CC_DOLLS.length; i++) {
if (i < 6) {
r.push(CC_DOLLS[i])
}
}
return r
}
function ccRarityColor(rarity: string): string {
if (rarity === 'SSR') {
return CC_COLORS.gold
}
if (rarity === 'SR') {
return CC_COLORS.purple
}
return CC_COLORS.blueR
}
function ccRarityCount(rarity: string): number {
let n = 0
for (let i = 0; i < CC_DOLLS.length; i++) {
if (CC_DOLLS[i].rarity === rarity) {
n = n + 1
}
}
return n
}
function ccTierCount(tier: string): number {
let n = 0
for (let i = 0; i < CC_RANKS.length; i++) {
if (CC_RANKS[i].tier === tier) {
n = n + 1
}
}
return n
}
function ccStatusColor(status: string): string {
if (status === '畅玩') {
return CC_COLORS.mint
}
if (status === '热门') {
return CC_COLORS.pink
}
return CC_COLORS.grayTag
}
function ccTradeStatusColor(status: string): string {
if (status === '换到了') {
return CC_COLORS.mint
}
if (status === '求换中') {
return CC_COLORS.pink
}
return CC_COLORS.textHint
}
function ccPayStatusColor(status: string): string {
if (status === '成功') {
return CC_COLORS.mint
}
if (status === '处理中') {
return CC_COLORS.gold
}
return CC_COLORS.textHint
}
function ccMaxRate(): number {
let m = 0
for (let i = 0; i < CC_WEEK.length; i++) {
if (CC_WEEK[i].rate > m) {
m = CC_WEEK[i].rate
}
}
return m
}
function ccBarHeight(rate: number): number {
const m = ccMaxRate()
if (m === 0) {
return 10
}
return rate / m * 96
}
function ccPct(cur: number, total: number): string {
if (total === 0) {
return '0%'
}
return (cur / total * 100).toFixed(0) + '%'
}
// ============ 弹框组件1:机台详情(橱窗式) ============
@Component
struct CCMachineDetailForm {
machineNo: string = '01'
@State machine: CCMachine = CC_MACHINES[0]
@State clawY: number = 0
onConfirm: () => void = () => {}
onClose: () => void = () => {}
aboutToAppear() {
this.machine = ccMachineByNo(this.machineNo)
this.getUIContext().animateTo({
duration: 1600,
iterations: -1,
playMode: PlayMode.Alternate,
curve: Curve.EaseInOut
}, () => { this.clawY = 14 })
}
build() {
Column() {
Row() {
Text('🎰 ' + this.machine.name + ' · 机台详情')
.fontSize(17).fontWeight(FontWeight.Bold).fontColor(CC_COLORS.textMain)
Column().layoutWeight(1)
Text('✕').fontSize(18).fontColor(CC_COLORS.textSub)
.onClick(() => { this.onClose() })
}
.width('100%').padding({ left: 18, right: 18, top: 16, bottom: 8 })
Scroll() {
Column() {
Stack({ alignContent: Alignment.Top }) {
Column()
.width('100%').height(112)
.backgroundColor(this.machine.dollColor)
.borderRadius(14)
.opacity(0.28)
Column() {
Text('🦾').fontSize(34)
.translate({ y: this.clawY })
Text(this.machine.dollName)
.fontSize(20).fontWeight(FontWeight.Bold).fontColor(CC_COLORS.textMain)
.margin({ top: 6 })
Text('当前在夹 · NO.' + this.machine.no + ' 号机台')
.fontSize(11).fontColor(CC_COLORS.textSub).margin({ top: 3 })
}
.alignItems(HorizontalAlign.Center)
.margin({ top: 18 })
}
.width('100%')
Row() {
Column() {
Text('🪙 ' + this.machine.price.toString() + ' 币/次')
.fontSize(15).fontWeight(FontWeight.Bold).fontColor(CC_COLORS.gold)
}
.alignItems(HorizontalAlign.Start).layoutWeight(1)
Column() {
Text('历史夹中 ' + this.machine.history.toString() + ' 次')
.fontSize(12).fontColor(CC_COLORS.textSub)
}
.alignItems(HorizontalAlign.End)
}
.width('100%').margin({ top: 12 })
Text('概率公示(每日 0 点刷新)')
.fontSize(12).fontColor(CC_COLORS.textSub).width('100%').margin({ top: 14 })
Column() {
Row() {
Text('娃娃').fontSize(11).fontColor(CC_COLORS.textHint).layoutWeight(2)
Text('概率').fontSize(11).fontColor(CC_COLORS.textHint).layoutWeight(1).textAlign(TextAlign.Center)
Text('剩余').fontSize(11).fontColor(CC_COLORS.textHint).layoutWeight(1).textAlign(TextAlign.End)
}
.width('100%').padding({ top: 8, bottom: 6 })
.border({ width: { bottom: 1 }, color: CC_COLORS.line })
ForEach(CC_MACHINE_ODDS, (o: CCOddsRow) => {
Row() {
Text(o.doll).fontSize(12).fontColor(CC_COLORS.textMain).layoutWeight(2).maxLines(1)
Text(o.rate).fontSize(12).fontColor(CC_COLORS.pink).layoutWeight(1).textAlign(TextAlign.Center)
Text('x' + o.left.toString()).fontSize(12).fontColor(CC_COLORS.mint).layoutWeight(1).textAlign(TextAlign.End)
}
.width('100%').padding({ top: 9, bottom: 9 })
.border({ width: { bottom: 1 }, color: CC_COLORS.line })
})
}
.width('100%').backgroundColor(CC_COLORS.deep)
.borderRadius(12).padding({ left: 12, right: 12 })
.margin({ top: 8 })
Row() {
Text('⚠️ 概率由公证处监管,娃娃夹中即归您所有,概不退换')
.fontSize(10).fontColor(CC_COLORS.textHint)
}
.width('100%').margin({ top: 10 })
}
.padding({ left: 18, right: 18, bottom: 8 })
}
.scrollable(ScrollDirection.Vertical)
.layoutWeight(1).scrollBar(BarState.Off)
.constraintSize({ maxHeight: '56%' })
Row() {
Text('再看看').fontSize(14).fontColor(CC_COLORS.textSub)
.backgroundColor(CC_COLORS.deep).borderRadius(22)
.padding({ left: 24, right: 24, top: 11, bottom: 11 })
.onClick(() => { this.onClose() })
Text('🦾 立即开夹 · ' + this.machine.price.toString() + '币')
.fontSize(14).fontWeight(FontWeight.Bold).fontColor(CC_COLORS.white)
.backgroundColor(CC_COLORS.pinkDeep).borderRadius(22)
.padding({ left: 20, right: 20, top: 11, bottom: 11 })
.margin({ left: 12 })
.onClick(() => { this.onConfirm() })
}
.width('100%').justifyContent(FlexAlign.Center)
.padding({ top: 12, bottom: 16 })
}
.width('100%').backgroundColor(CC_COLORS.card).borderRadius(18)
}
}
项目总结
CLAW CITY 娃都是一款融合糖果街机质感与马卡龙电玩美学的潮流娃娃机·夹娃娃电玩城概念应用。设计价值:首创"糖果街机×马卡龙电玩"视觉风格,约10组无定时器属性动画让界面"活"起来,7套差异化弹框每种场景有专属交互语言,8大Tab覆盖夹娃娃全链路业务。技术价值:单文件ArkTS零依赖复制即运行,18接口+约20常量+约25纯函数构建完整类型系统,数据驱动UI渲染,三级状态管理简单高效,机台概率公示/币值充值/换物交易/竞技排行核心逻辑完整实现。业务价值:覆盖发现机台→查看概率→充值开夹→收藏图鉴→换物交易→分享动态→冲击排行完整用户旅程,潮玩收藏体系提升粘性,换物街促进用户互动,夹神榜增强竞技感。
技术亮点
- 无定时器循环动画:animateTo+iterations:-1+Alternate实现约10组持续动画,零定时器高性能自动生命周期
- 机台概率公示系统:5款娃娃概率+剩余数量透明公示,公证处监管说明增加信任感
- 三级稀有度体系:SSR/SR/R三级稀有度,颜色标签+分布横条+收藏册完整实现
- 集中式弹框管理:7弹框统一在根组件Stack管理,布尔变量控制显隐,状态传递数据
- 换物街交易闭环:发布/编辑/删除/筛选/状态流转完整实现,娃娃宫格选择特色交互
- 8Tab全链路覆盖:从机台到收藏到充值到排行到交易到动态到任务到个人,完整业务闭环

本文基于 CLAW CITY 娃都 ArkTS 单文件源码深度解析,全文约 8 万字。项目采用 HarmonyOS ArkTS 声明式 UI 框架,8 Tab + 7 弹框 + 约 10 组属性动画 + 约 25 个纯函数,完整实现潮流娃娃机夹娃娃电玩城核心业务。
更多推荐




所有评论(0)