当前位置: 首页 > news >正文

HarmonyOS7 旋转手势:RotationGesture 实现双指旋转组件

文章目录

    • 前言
    • 效果展示
    • 实现原理
      • RotationGesture 的工作方式
      • 旋转的渲染
    • 代码详解
      • 状态变量
      • 可旋转的组件
      • 角度显示与重置
      • 完整代码
    • 进阶技巧
      • 角度吸附
      • 限制旋转范围
      • 旋转 + 缩放组合
    • 写在最后

前言

旋转手势在各种创意类 App 中很常见——照片编辑器里旋转图片、地图里旋转视角、游戏中旋转道具。ArkUI 提供了RotationGesture来检测双指旋转,返回旋转角度。

今天来实现一个可旋转的组件,实时显示旋转角度,并支持重置。

效果展示

一个橙色的正方形,里面有十字线和旋转图标。用户用两根手指旋转,方块跟着旋转。上方实时显示当前旋转角度。底部有"重置角度"按钮。

实现原理

RotationGesture 的工作方式

RotationGesture检测两根手指连线的角度变化。当两根手指的连线从水平变成倾斜时,event.angle就是旋转的角度值(正值顺时针,负值逆时针)。

跟 PanGesture 和 PinchGesture 一样,event.angle是相对于本次手势起点的相对值,需要累加。

当前角度 = 上次角度 + 本次手势的 angle

旋转的渲染

ArkUI 的.rotate()属性用来旋转组件:

.rotate({angle:this.angle})

angle正值表示顺时针旋转,单位是度(degree)。

代码详解

状态变量

@Stateangle:number=0@StatelastAngle:number=0

两个变量:当前显示角度和上次手势结束时的角度。

可旋转的组件

Column(){Stack(){Column(){}.width(4).height(60).backgroundColor('#FFFFFF')Column(){}.width(60).height(4).backgroundColor('#FFFFFF')Column(){Text('⟳').fontSize(30).fontColor('#FFFFFF')}.offset({x:0,y:-40})}}.width(140).height(140).backgroundColor('#FFA500').borderRadius(20).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center).rotate({angle:this.angle}).gesture(RotationGesture({fingers:2}).onActionUpdate((event:GestureEvent)=>{this.angle=this.lastAngle+event.angle}).onActionEnd(()=>{this.lastAngle=this.angle}))

方块内部用两个细长的白色矩形交叉形成十字线,加上一个旋转符号,视觉上暗示"可以旋转"。

.rotate({ angle: this.angle })让整个方块按当前角度旋转。旋转是围绕组件中心点进行的。

角度显示与重置

Text(`旋转角度:${Math.floor(this.angle)}°`).fontSize(18).fontWeight(FontWeight.Bold).fontColor('#4D96FF').margin({bottom:24})Button('重置角度').width('100%').height(42).backgroundColor('#E0E0E0').borderRadius(10).fontColor('#333333').fontSize(15).margin({top:20}).onClick(()=>{this.angle=0this.lastAngle=0})

Math.floor取整显示角度,避免小数位看着乱。重置按钮把两个状态变量都清零。

完整代码

@Entry@Componentstruct RotationGesturePage{@Stateangle:number=0@StatelastAngle:number=0build(){Column(){Column(){Text('旋转手势').fontSize(16).fontWeight(FontWeight.Bold).margin({bottom:16})Text(`旋转角度:${Math.floor(this.angle)}°`).fontSize(18).fontWeight(FontWeight.Bold).fontColor('#4D96FF').margin({bottom:24})Column(){Stack(){Column(){}.width(4).height(60).backgroundColor('#FFFFFF')Column(){}.width(60).height(4).backgroundColor('#FFFFFF')Column(){Text('⟳').fontSize(30).fontColor('#FFFFFF')}.offset({x:0,y:-40})}}.width(140).height(140).backgroundColor('#FFA500').borderRadius(20).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center).rotate({angle:this.angle}).gesture(RotationGesture({fingers:2}).onActionUpdate((event:GestureEvent)=>{this.angle=this.lastAngle+event.angle}).onActionEnd(()=>{this.lastAngle=this.angle}))Button('重置角度').width('100%').height(42).backgroundColor('#E0E0E0').borderRadius(10).fontColor('#333333').fontSize(15).margin({top:20}).onClick(()=>{this.angle=0;this.lastAngle=0})}.width('100%').padding(24).backgroundColor('#FFFFFF').borderRadius(12).alignItems(HorizontalAlign.Center)}.width('100%').height('100%').backgroundColor('#F5F6FA').padding(16)}}

进阶技巧

角度吸附

让角度在接近 0°、90°、180°、270° 时自动吸附:

.onActionEnd(()=>{this.lastAngle=this.angleconstsnapped=Math.round(this.angle/90)*90if(Math.abs(this.angle-snapped)<10){animateTo({duration:200},()=>{this.angle=snappedthis.lastAngle=snapped})}})

当角度距离 90 的整数倍不超过 10 度时,自动吸附到整数值。

限制旋转范围

如果只需要 0-360 度的范围:

.onActionUpdate((event:GestureEvent)=>{letnewAngle=this.lastAngle+event.anglethis.angle=((newAngle%360)+360)%360})

用取模运算把角度限制在 0-360 范围内。

旋转 + 缩放组合

GestureGroup同时支持旋转和缩放:

.gesture(GestureGroup(GestureMode.Parallel,RotationGesture({fingers:2}).onActionUpdate((event)=>{this.angle=this.lastAngle+event.angle}).onActionEnd(()=>{this.lastAngle=this.angle}),PinchGesture({fingers:2}).onActionUpdate((event)=>{this.scale=Math.max(0.5,Math.min(3,this.lastScale*event.scale))}).onActionEnd(()=>{this.lastScale=this.scale})))

GestureMode.Parallel允许两个手势同时识别——用户一边旋转一边缩放,两个效果叠加。

写在最后

RotationGesture是 ArkUI 手势家族中最"酷"的一个。双指旋转的操作方式直觉且有趣。.rotate()属性配合手势回调,几行代码就能实现流畅的旋转效果。

旋转手势最常见的应用是图片编辑和地图,配合缩放和拖拽,就能实现一个功能完整的画布操作。

http://www.jsqmd.com/news/1233300/

相关文章:

  • 塑身衣不会卷边哪家好? - 中媒介
  • 找冷链锁鲜靠谱的烤小肠批发商 - 中媒介
  • 推荐洗衣液贴牌全流程定制服务商 - 中媒介
  • 操作系统不支持压缩包内文件搜索怎么办?
  • LangChain框架实战:大语言模型应用开发指南
  • SolidWorks建模到3D打印:解决外壳装配误差的DFM实战指南
  • HarmonyOS7 滑动手势:SwipeGesture 检测快速滑动方向
  • 沈阳哪里能买到安全的有机全脂羊乳粉? - 中媒介
  • 白酒老酒库存足哪家效果好? - 中媒介
  • 瓜子哪家干净卫生? - 中媒介
  • 湖南工地专用内墙涂料抗裂效果好不好 - 中媒介
  • 2026宠物小程序开发十大公司测评:洗护预约、用品商城与会员怎么选?含零代码SAAS、AI编程、源码定制
  • LangChain:大语言模型集成框架的核心技术与应用
  • PyTorch 2框架核心优化与实战指南
  • Windows右键菜单混乱不堪?3个步骤让它重获新生
  • AI工具如何革新企业级应用设计流程
  • 婴儿游泳洗澡服务哪家专业安全 - 中媒介
  • 从入门到高阶:2026电商美工精英班,PS、C4D、AI、PR全掌握
  • 2026年7月行业内专业的V型混合机实力厂家推荐,真空耙式干燥机/振动流化床干燥机/双锥混合机,V型混合机直销工厂选哪家 - 品牌推荐师
  • MyBatis-Plus高阶用法与Spring Boot3实战技巧
  • Java 17性能优化:ZGC、JIT与向量API实战解析
  • 深圳特色速冻食品批发 - 中媒介
  • Shiny for Python:构建交互式数据可视化应用指南
  • 运城市闻喜县2026最新黄金回收门店及联系方式指南 黄金回收白银回收铂金回收店铺TOP5排行榜 - 大熊猫898989
  • Structured Pruning of Large Language Models 解读
  • ML工程师的组织影响力:从模型交付到业务闭环
  • 周口市淮阳县2026最新黄金回收门店及联系方式指南 黄金回收白银回收铂金回收店铺TOP5排行榜 - 盛世金银回收
  • Sqribble:面向结构化文档的云原生操作系统
  • MiniMax M3预留吞吐量服务:生产环境部署与优化指南
  • ECS框架性能深度评测:Arch、Flecs、EnTT与Unity Entities横向对比