鸿蒙怎么实现组件移到点击处,看这一篇就够了

在鸿蒙中,我们想实现组件移动位置,出现在点击处,我们怎么实现呢?

基础概念

首先,我们需要知道一个基础概念

组件的位置移动本质来说是:相对于初始位置,组件在 x、y 轴上移动一定距离

如下图所示:以组件的左上角为标准,可以看到组件的移动距离

而鸿蒙为我们提供了一个方法 translate,可以让组件在 x、y 轴上进行移动

kotlin 复制代码
Text("111")
  .width(30)
  .height(30)
  .translate({ 
    x: this.positionX, 
    y: this.positionY, 
    })

怎么计算移动位置

我们现在知道了,可以 translate 来让组件进行移动,那么现在只需要解决一个问题就行了:让组件在 x、y 轴上移动的后位置和手指点击的位置一样

而这一点就是最难的一点,下面我们就来一点点分析

在进行计算距离时,有以下注意点:

  • 鸿蒙的点击事件是相对于整个屏幕的
  • 组件初始位置在父容器中,而父容器不一定完全和屏幕相等,这时需要减去父容器相对于屏幕位置
  • 组件初始位置不一定父容器左上角,这时需要减去组件相对于父容器位置

所以可以得到下面的公式:

组件移动位置 = 点击位置 - 父容器相对于屏幕位置- 组件相对于父容器位置 - 组件半径(居中显示)

如果组件原始的位置在父组件的左上角,那么公式就可以进行简化:

组件移动位置 = 点击位置 - 父容器相对于屏幕位置 - 组件半径

代码

typescript 复制代码
import { LIKE_ICON_SIZE, TAP_GESTURE_COUNT } from './Constant'

@Component
export default struct LikeComponent {
  @State positionX: number = 0
  @State positionY: number = 0
  ICON_SIZE = 50

  onClick(event: GestureEvent) {
    if (event && event.fingerList && event.fingerList.length > 0) {

      // 因为父组件不是铺满整个屏幕的,而点击事件的的位置是全局的,所以需要减去容器左上角的位置
      const position = event.target.area.globalPosition
      const areaX: number = position.x as number ? position.x as number : 0
      const areaY: number = position.y as number ? position.y as number : 0

      // 因为图片是左上角对齐的,要让图片显示在手指位置,需要减去图片的半径
      const ImageRadius = this.ICON_SIZE / 2

      // 手指位置 - 容器左上角位置 - 图片半径
      // 注意:因为这里图片的初始位置是左上角,如果放在中间,还需要减去图片相对于容器的位置
      this.positionX = event.fingerList[0].globalX - areaX - ImageRadius
      this.positionY = event.fingerList[0].globalY - areaY - ImageRadius
    }
  }

  build() {
    // 初始位置在左上角
    Stack({ alignContent: Alignment.TopStart }) {
      Text("111")
        .width(this.ICON_SIZE)
        .height(this.ICON_SIZE)
        // 数据改变时,改变组件位置
        .translate({ x: this.positionX, y: this.positionY, z: 0 })
    }
    .height('80%')
    .width('100%')
    .parallelGesture(
      TapGesture({ count: 1 })
        .onAction((event) => {
          this.onClick(event)
        })
    )
  }
}

使用上面的代码,就可以实现如下图所示的功能了

"本文正在参加华为鸿蒙有奖征文征文活动"

相关推荐
蒜蓉大猩猩21 分钟前
Vue.js - 组件化编程
开发语言·前端·javascript·vue.js·前端框架·ecmascript
王解1 小时前
一篇文章读懂 Prettier CLI 命令:从基础到进阶 (3)
前端·perttier
乐闻x1 小时前
最佳实践:如何在 Vue.js 项目中使用 Jest 进行单元测试
前端·vue.js·单元测试
檀越剑指大厂1 小时前
【Python系列】异步 Web 服务器
服务器·前端·python
我是Superman丶1 小时前
【前端】js vue 屏蔽BackSpace键删除键导致页面后退的方法
开发语言·前端·javascript
Hello Dam1 小时前
基于 Spring Boot 实现图片的服务器本地存储及前端回显
服务器·前端·spring boot
小仓桑1 小时前
利用 Vue 组合式 API 与 requestAnimationFrame 优化大量元素渲染
前端·javascript·vue.js
Hacker_xingchen1 小时前
Web 学习笔记 - 网络安全
前端·笔记·学习
天海奈奈1 小时前
前端应用界面的展示与优化(记录)
前端
多多*2 小时前
后端并发编程操作简述 Java高并发程序设计 六类并发容器 七种线程池 四种阻塞队列
java·开发语言·前端·数据结构·算法·状态模式