HarmonyOS应用《玄象》开发实战:五行环绕太极:Stack 定位 + getFiveElementPosition 三角函数布局

发布时间:2026/7/26 22:02:26
HarmonyOS应用《玄象》开发实战:五行环绕太极:Stack 定位 + getFiveElementPosition 三角函数布局 阅读时长约 19 分钟 | 难度★★★★★ | 篇章第 3 篇 · 首页与功能导航对应源码entry/src/main/ets/pages/HomePage.ets中的getFiveElementPosition方法前言玄象项目首页今日天地卡片中5 个五行徽章围绕太极图呈五角星分布。这一视觉布局通过 ArkUI 的Stack层叠容器配合position精确定位实现其核心算法getFiveElementPosition运用三角函数计算每个徽章的圆周坐标。本篇将深入剖析玄象项目五行环绕太极的实现从Stack层叠容器、ForEach列表渲染、position精确定位到Math.cos/Math.sin三角函数布局算法。掌握这套圆周布局方法论您就能为任何 HarmonyOS 应用打造星宿环绕、轮盘布局等复杂视觉。提示圆周布局是玄象项目的核心视觉语言——五行环绕太极、二十八宿环绕紫微、二十四山环绕罗盘。一、五行环绕太极完整源码1.1 源码全貌Stack(){Canvas(this.taijiContext).width(180).height(180).onReady((){this.drawTaiji(this.taijiContext,this.taijiContext.width,this.taijiContext.height);})ForEach([火,木,山,水,金],(item:string,index:number){Text(item).fontSize(18).fontWeight(FontWeight.Bold).fontColor(#FFFFFF).width(44).height(44).textAlign(TextAlign.Center).backgroundColor(Colors.BG_CARD).border({width:1.5,color:Colors.PRIMARY_GOLD,radius:22}).borderRadius(22).position(this.getFiveElementPosition(index,180,44))},(item:string)item)}.width(220).height(220).align(Alignment.Center)1.2 三层视觉结构Stack (220×220) ├── Canvas (180×180 太极图) ← 底层 └── ForEach (5 个五行徽章) ← 上层 ├── Text 火 (index0) ├── Text 木 (index1) ├── Text 山 (index2) ├── Text 水 (index3) └── Text 金 (index4)二、Stack 层叠容器2.1 Stack 的对齐特性Stack默认让所有子元素居中对齐按声明顺序层叠。2.2 玄象项目 Stack 配置Stack(){Canvas(this.taijiContext).width(180).height(180)ForEach(...){Text(item)...}}.width(220).height(220).align(Alignment.Center)属性值含义width220Stack 宽度 220vpheight220Stack 高度 220vpalignAlignment.Center子元素居中对齐2.3 Stack 中 Canvas 与五行徽章的关系220×220 Stack 区域 ↓ ┌──────────────┐ │ │ │ 180×180 │ ← Canvas 居中 │ 太极图 │ │ │ └──────────────┘ 五个五行徽章 (44×44) 通过 position 精确放置在太极图周围三、ForEach 列表渲染3.1 ForEach 基本用法ForEach([火,木,山,水,金],(item:string,index:number){Text(item)// ....position(this.getFiveElementPosition(index,180,44))},(item:string)item)3.2 ForEach 三参数参数类型作用数据源string[]待渲染数组itemGenerator(item, index) void单项渲染函数keyGenerator(item) string唯一键生成函数3.3 keyGenerator 的作用(item:string)itemkeyGenerator返回数组元素本身‘火’、木’等作为唯一键帮助 ArkUI 高效更新列表。提示玄象项目五行数组顺序为[火, 木, 山, 水, 金]对应index0-4。四、position 精确定位4.1 position 属性.position(this.getFiveElementPosition(index,180,44))position(value: Position)设置组件相对于父容器的左上角坐标。4.2 Position 类型interfacePosition{x:number|string;y:number|string;}4.3 position 的特殊性使用position后组件脱离常规布局流按指定坐标放置。这正是五行徽章能精确环绕太极图的关键。五、getFiveElementPosition 三角函数算法5.1 完整源码privategetFiveElementPosition(index:number,containerSize:number,itemSize:number):Position{constangle(index*72-90)*Math.PI/180;constradiuscontainerSize/210;constcxcontainerSize/2;constcycontainerSize/2;return{x:cxradius*Math.cos(angle)-itemSize/2,y:cyradius*Math.sin(angle)-itemSize/2};}5.2 算法分解步骤 1计算角度 angle (index * 72 - 90) * π / 180 步骤 2计算半径 radius containerSize / 2 10 步骤 3确定圆心 cx containerSize / 2 cy containerSize / 2 步骤 4极坐标转直角坐标 x cx radius * cos(angle) - itemSize / 2 y cy radius * sin(angle) - itemSize / 25.3 角度计算详解constangle(index*72-90)*Math.PI/180;index计算角度弧度00*72 - 90 -90-90°-π/211*72 - 90 -18-18°-π/1022*72 - 90 5454°3π/1033*72 - 90 126126°7π/1044*72 - 90 198198°11π/105.4 72 度的由来5 个徽章均分圆周每个徽章占 360/5 72 度。5.5 -90 偏移的作用无偏移index0 在 0°右侧 有 -90 偏移index0 在 -90°上方玄象项目希望第一个徽章火位于太极图正上方因此引入 -90 偏移。5.6 弧度转换*Math.PI/180JavaScript 三角函数接受弧度而非角度。转换公式弧度 角度 × π / 180。5.7 半径计算constradiuscontainerSize/210;containerSize / 2 太极图半径 10 徽章向外延伸 10vp5.8 圆心与坐标constcxcontainerSize/2;// 90constcycontainerSize/2;// 90玄象项目太极图 Canvas 尺寸 180×180圆心位于 (90, 90)。5.9 最终坐标计算return{x:cxradius*Math.cos(angle)-itemSize/2,y:cyradius*Math.sin(angle)-itemSize/2};- itemSize / 2的意义position设置的是组件左上角坐标需减去半个徽章尺寸让徽章中心对齐圆周点。5.10 实际坐标计算示例以index0火为例angle -90° -π/2 radius 90 10 100 cx 90, cy 90 itemSize 44 cos(-π/2) 0 sin(-π/2) -1 x 90 100 * 0 - 44 / 2 90 - 22 68 y 90 100 * (-1) - 44 / 2 90 - 100 - 22 -32火徽章左上角位于 (68, -32)即太极图正上方略偏外。六、五行徽章的样式6.1 完整样式Text(item).fontSize(18).fontWeight(FontWeight.Bold).fontColor(#FFFFFF).width(44).height(44).textAlign(TextAlign.Center).backgroundColor(Colors.BG_CARD).border({width:1.5,color:Colors.PRIMARY_GOLD,radius:22}).borderRadius(22)6.2 圆形徽章的实现width 44, height 44 ← 正方形 borderRadius 22 ← 半径 边长 / 2 完整圆形6.3 金色边框.border({width:1.5,color:Colors.PRIMARY_GOLD,radius:22})1.5vp 宽度的金色边框与卡片金边呼应。七、五行徽章的视觉布局7.1 五行方位火 ┌────────┐ 金 │ 太极 │ 木 │ 图 │ 山 │ │ 水 └────────┘7.2 五行属性对照五行方位颜色火南上红木东右绿金西左白水北下蓝土中黄提示玄象项目五行数组用山代替土是设计变体。八、圆周布局的通用算法8.1 抽象通用算法functiongetCircularPosition(index:number,total:number,center:{x:number,y:number},radius:number,startAngle:number-90,itemSize:number0):Position{constangle(index*(360/total)startAngle)*Math.PI/180;return{x:center.xradius*Math.cos(angle)-itemSize/2,y:center.yradius*Math.sin(angle)-itemSize/2};}8.2 玄象项目应用场景场景totalstartAngle五行环绕太极5-90°二十八宿环绕28-90°二十四山罗盘240°八卦环绕中心8-90°8.3 算法封装建议// common/utils/CircularLayout.etsexportclassCircularLayout{staticgetPosition(index:number,total:number,centerX:number,centerY:number,radius:number,startAngle:number-90,itemSize:number0):Position{constangle(index*(360/total)startAngle)*Math.PI/180;return{x:centerXradius*Math.cos(angle)-itemSize/2,y:centerYradius*Math.sin(angle)-itemSize/2};}}九、五行徽章的交互扩展9.1 点击跳转Text(item).onClick((){router.pushUrl({url:pages/stems/HeavenlyStemsPage,params:{element:item}});})9.2 悬停高亮Text(item).scale({x:this.hoverIndexindex?1.1:1,y:this.hoverIndexindex?1.1:1}).animation({duration:200})9.3 旋转动画Staterotation:number0;Stack(){// ...}.rotate({angle:this.rotation}).animation({duration:60000,iterations:-1,curve:Curve.Linear})aboutToAppear(){this.rotation360;}提示玄象项目风水罗盘可结合圆周布局 旋转动画 陀螺仪传感器实现真实的罗盘体验。十、玄象项目圆周布局体系10.1 应用场景汇总模块圆周布局场景首页五行环绕太极星宿二十八宿列表周易八卦环绕、卦象大轮盘风水二十四山罗盘命理十二宫位排盘乐律十二律吕圆周10.2 圆周布局的视觉价值文化契合圆周布局契合东方天圆地方哲学。视觉聚焦中心元素被环绕元素强化。空间利用圆周布局比线性布局更紧凑。总结本篇以玄象项目五行环绕太极为蓝本深入剖析了 ArkUI 圆周布局算法从Stack层叠容器、ForEach列表渲染、position精确定位到getFiveElementPosition三角函数算法、极坐标转直角坐标、72 度均分原理。掌握这套圆周布局方法论您就能为任何 HarmonyOS 应用打造星宿环绕、轮盘布局等复杂视觉。下一篇《24 · 宜忌标签云ForEach padding borderRadius 的 chip 实现》将带您深入玄象项目首页宜忌标签的实现。如果这篇文章对你有帮助欢迎点赞、收藏⭐、关注你的支持是我持续创作的动力相关资源HarmonyOS 官方文档Stack 组件HarmonyOS 官方文档ForEach 组件HarmonyOS 官方文档position 属性MDN Math.cosdeveloper.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math/cos开源鸿蒙跨平台社区https://openharmonycrossplatform.csdn.net