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函数在滑动过程中不断重新绘制,来实现惯性滑动效果

相关推荐
fengxinzi_zack4 小时前
HarmonyOS应用开发实战:萌宠日记 - 健康分类数据隔离
harmonyos·鸿蒙
不言鹅喻8 小时前
HarmonyOS ArkTS 实战:实现一个校园考试安排与考场查询应用
华为·harmonyos
JaneConan8 小时前
鸿蒙 韶非 UI 系列:能力调用 startAbilityForResult,跳能力拿回参,鸿蒙能力路由入门
后端·harmonyos
FrameNotWork9 小时前
HarmonyOS 6.0 文件加密与安全存储:从哈希到硬件级密钥管理全链路实战
安全·哈希算法·harmonyos
Georgewu10 小时前
【HarmonyOS AI】鸿蒙开发者需要搞懂的 AI Coding 概念
harmonyos
FF2501_9402285810 小时前
HarmonyOS开发实战:小分享-App项目架构全景解析
后端·华为·harmonyos·鸿蒙
解局易否结局11 小时前
鸿蒙原生开发实战:Native 图片处理与二维码全链路解析
华为·harmonyos
<小智>12 小时前
鸿蒙多功能工具箱开发实战(十二)-二十四节气与黄历数据展示
ui·华为·harmonyos
Georgewu12 小时前
【HarmonyOS AI】DevEco CLI、Skills、知识库运用AI Coding提效详解
harmonyos