目录

HarmonyNext实现Canvas绘制图形的滑动和缩放效果

文章目录

概要

使用Canvas可以绘制图形,但是如果要实现图形的缩放和滑动效果,则需要我们自己通过拦截手势事件来实现了。

整体架构流程

实现思路:

1、通过给Canvas组件添加捏合手势来计算图形显示比例、通过添加拖拽手势来计算图形移动的距离。

2、触发Canvas重新绘制,绘制时通过上一步计算出来的显示比例和移动距离,来控制图形的绘制区域。

技术名词解释

  • Canvas 画图,用来显示绘制的图形

技术细节

添加捏合手势和拖拽手势

kotlin 复制代码
.gesture(
  // 组合手势模式
  GestureGroup(GestureMode.Parallel,
    // 捏合手势
    PinchGesture({ fingers: 2 })
      .onActionStart((event: GestureEvent) => {
      })
      .onActionUpdate((event: GestureEvent) => {
	    // 计算缩放比例
        if (Math.round(event.scale * 10) % 2 == 0) {
          this.dataCursor.setScale(this.pinchValue * event.scale)
          this.redrawTimes++
        }
      })
      .onActionEnd(() => {
        this.pinchValue = this.dataCursor.scale
      }),
    // 拖拽手势
    PanGesture(new PanGestureOptions({ direction: this.chartGestureEvent.isLongPress ? PanDirection.All : PanDirection.Horizontal }))
      .onActionStart((event: GestureEvent) => {
        if (!event.fingerList[0] || event.fingerList.length > 1) return
		// 记录按下时的坐标点
        this.chartGestureEvent.downX = event.fingerList[0].globalX
        this.chartGestureEvent.downTime = new Date().getTime()
        this.redrawTimes++
      })
      .onActionUpdate((event: GestureEvent) => {
        if (!event.fingerList[0] || event.fingerList.length > 1) return
		// 计算移动距离
        let moveX = event.fingerList[0].globalX
        this.chartGestureEvent.moveY = event.fingerList[0].globalY
        this.chartGestureEvent.moveX = moveX
        // 手指往右滑
        if (event.offsetX > 0) {
          this.panDirection = PanDirection.Right
        }
        // 手指往左滑
        else if (event.offsetX < 0) {
          this.panDirection = PanDirection.Left
        }
        else {
          this.panDirection = PanDirection.None
        }
  
        if (Math.abs(event.offsetX) > 20) {
          let startIndex = Math.round(this.panValue - event.offsetX / 20)
          this.dataCursor.setStartIndex(startIndex)
          this.redrawTimes++
        }
      })
      .onActionEnd(() => {
        if (!this.chartGestureEvent || this.chartGestureEvent.isLongPress) return
  
        this.panValue = this.dataCursor.startIndex
  
		// 判断是否为快速滑动
        let exeDuration = new Date().getTime() - this.chartGestureEvent.downTime
        let speed = Math.abs((this.chartGestureEvent.moveX - this.chartGestureEvent.downX) / exeDuration)
        if (speed < 0.5) return
  
        this.chartGestureEvent.downX = this.chartGestureEvent.moveX
        this.chartGestureEvent.downY = this.chartGestureEvent.moveY
        this.chartGestureEvent.downTime = new Date().getTime()
  
        // 实现惯性滑动效果
        this.animationUtil.interceptor(Math.round(160 * speed), (count) => {
          let offsetCount = Math.round(1 / this.dataCursor.scale * count)
          if (offsetCount > 20) {
            offsetCount = 20
          }
          if (this.panDirection == PanDirection.Right) {
            let startIndex = this.dataCursor.startIndex - offsetCount
            if (startIndex < 0) startIndex = 0
            this.dataCursor.setStartIndex(startIndex)
          } else if (this.panDirection == PanDirection.Left) {
            let startIndex = this.dataCursor.startIndex + offsetCount
            if (startIndex >= this.dataCursor.totalCount) startIndex = this.dataCursor.totalCount - offsetCount
            this.dataCursor.setStartIndex(startIndex)
          }
          this.panValue = this.dataCursor.startIndex
          this.redrawTimes++
        })
      })
  ))

为了实现惯性滑动效果,我们将滑动距离拆分成多段,并通过setTimeout函数在滑动过程中不断重新绘制,来实现惯性滑动效果

本文是转载文章,点击查看原文
如有侵权,请联系 xyy@jishuzhan.net 删除
相关推荐
别说我什么都不会12 小时前
OpenHarmony源码分析之分布式软总线:trans_service模块(2)/会话管理之新会话
分布式·嵌入式·harmonyos
蓝枫Amy13 小时前
鸿蒙应用程序包HAP的开发与使用
harmonyos
别说我什么都不会15 小时前
OpenHarmony源码分析之分布式软总线:trans_service模块(1)/认证通道管理
分布式·嵌入式·harmonyos
全栈若城16 小时前
84.HarmonyOS NEXT 路由导航与页面管理:构建清晰的应用架构
华为·架构·harmonyos·harmonyos next
全栈若城17 小时前
87.HarmonyOS NEXT 单元测试与自动化测试指南:构建可靠的测试体系
华为·单元测试·harmonyos·harmonyos next
没有了遇见18 小时前
HarmonyOS学习ArkUI之线性布局 (Row/Column)
harmonyos·arkts
别说我什么都不会18 小时前
OpenHarmony轻量系统服务管理|鸿蒙业务模型重要概念详解
物联网·嵌入式·harmonyos
枫叶丹419 小时前
【HarmonyOS Next之旅】DevEco Studio使用指南(三)
华为·harmonyos·harmonyos next
个案命题21 小时前
打造流畅的下拉刷新与轮播交互:HarmonyOS手势识别与组件协同实战
华为·harmonyos·鸿蒙
我爱鸿蒙开发21 小时前
一文带你深入了解Stage模型
前端·架构·harmonyos