公司动态

鸿蒙 ArkTS 实战|波点变动动画实现:setInterval 帧驱动 + 坐标映射 + 象限判定

📅 2026/8/25 23:54:38
鸿蒙 ArkTS 实战|波点变动动画实现:setInterval 帧驱动 + 坐标映射 + 象限判定
一、设计思路波点变动是本章技术核心一个波点沿直线 y kx b 匀速往返让抽象的线性关系动起来。实现要点有四帧驱动setInterval 定时步进、状态机movingRight 控制往返、坐标映射数学系 ↔ 像素系、象限判定坐标符号 → 象限文本。本篇拆解这四块代码。二、帧驱动setInterval 每 30ms 步进一步EntryComponentstruct LinearEquation{privatetimer:number0;// 定时器句柄销毁时清理aboutToAppear():void{this.solve();this.draw();// 波点变动每 30ms 前进 0.2≈33 帧/秒视觉平滑this.timersetInterval((){this.tick();},30);}aboutToDisappear():void{clearInterval(this.timer);// 离开页面必须清理否则后台空转}// 每一帧x 步进 → y 重算 → 象限刷新 → 重绘privatetick():void{letnxthis.dotX(this.movingRight?0.2:-0.2);if(nxthis.xRange){// 到达右边界nxthis.xRange;this.movingRightfalse;// 掉头向左}if(nx-this.xRange){// 到达左边界nx-this.xRange;this.movingRighttrue;// 掉头向右}this.dotXnx;this.dotYthis.yOf(nx);// 波点永远贴在直线上this.dotQuadrantthis.quadrantOf(nx,this.dotY);this.draw();}}要点setInterval返回number型句柄必须保存aboutToDisappear中clearInterval这是 HarmonyOS 页面生命周期的最佳实践。步长 0.2、间隔 30ms → 速度约 6.7 单位/秒x 全范围 20 单位约 3 秒一趟往返节奏适中。tick()是纯步进只修改 State不做计算外的事情职责单一。三、坐标映射数学系 ↔ 像素系// 世界坐标 → 画布像素画布中心 原点y 轴向上为正privatetoPixel(x:number,y:number,w:number,h:number):Pixel{return{px:w/2(x/this.xRange)*(w/2),py:h/2-(y/this.yRange)*(h/2)};}坐标系原点y 方向x 范围y 范围数学系画布中心向上为正±10±6像素系左上角向下为正0~w0~h映射公式拆解px w/2 (x/10) * (w/2)x 0 时在中心x 10 时到右边缘x −10 到左边缘。py h/2 − (y/6) * (h/2)唯一差别是 y 前是负号——把数学的向上翻转为像素的向下。所有绘制网格、轴线、直线、波点都经过这一个函数保证全图坐标一致。四、象限判定坐标符号 → 象限文本privatequadrantOf(x:number,y:number):string{if(x0y0)return第一象限;if(x0y0)return第二象限;if(x0y0)return第三象限;return第四象限;}象限判定就是符号表的代码化象限x 符号y 符号口诀Ⅰ同正Ⅱ−左正上Ⅲ−−同负Ⅳ−右下边界坐标轴上归入非负区x 0 且 y 0 判为Ⅱ象限保证任何时刻都有确定结果。五、波点绘制光晕 实心 描边constdpthis.toPixel(this.dotX,this.dotY,w,h);// 外圈光晕半径 10 的半透明绿ctx.beginPath();ctx.arc(dp.px,dp.py,10,0,Math.PI*2);ctx.fillStylergba(16,185,129,0.25);ctx.fill();// 实心核心半径 5 的亮绿ctx.beginPath();ctx.arc(dp.px,dp.py,5,0,Math.PI*2);ctx.fillStyle#10B981;ctx.fill();// 白色描边增强对比深色背景也清晰ctx.strokeStyleColor.White;ctx.lineWidth2;ctx.stroke();三层绘制的意义光晕制造发光感让运动中的点更醒目白描边保证任何背景色下都可见。Color.White是 ArkUI 内置枚举Canvas 可直接用作 strokeStyle。六、动画与 UI 双刷新的配合// 数据面板State 自动刷新 —— 不需要任何手动操作Text(this.dotX.toFixed(1))// 每次 tick 改 dotX 后自动重渲染// Canvas 图手动重绘 —— 需要每帧调用 draw()// 因此 tick() 末尾固定调 this.draw()// 波点数据面板UI 层State 驱动自动刷新Row({space:10}){Column({space:4}){Text(横坐标 x).fontSize(12).fontColor(#9CA3AF)Text(this.dotX.toFixed(1)).fontSize(18).fontWeight(FontWeight.Bold).fontColor(#10B981)}.layoutWeight(1)Column({space:4}){Text(纵坐标 y).fontSize(12).fontColor(#9CA3AF)Text(this.dotY.toFixed(1)).fontSize(18).fontWeight(FontWeight.Bold).fontColor(#10B981)}.layoutWeight(1)Column({space:4}){Text(所在象限).fontSize(12).fontColor(#9CA3AF)Text(this.dotQuadrant).fontSize(14).fontWeight(FontWeight.Bold).fontColor(#4C7DFF)}.layoutWeight(1.4)}.width(100%).margin({top:4})性能注意30ms 一帧、一帧只改 3 个 State 一次 Canvas 重绘开销极小不要在 tick 里做字符串拼接、数组操作等重活。七、调试与扩展建议需求改哪里加快/减慢波点调setInterval间隔或步长 0.2换运动轨迹改tick()中 x 的更新规则如正弦x sin(t)显示轨迹残影不clearRect改用半透明底色填充即可显示坐标网格刻度在网格线上加fillText标注数字暂停/继续用 State 布尔值包住tick()主体八、波点变动与数学本质波点变动不只是动画——它演示了函数的本质给定 x函数唯一确定 y。波点每走一步y kx b都被验证一次当它扫过交点方程 ax b 0 的解在 x 轴上对应的点时可以引导观察y 0 时 x 的值正是方程的解。代码与数学在这个页面上互为注解。