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

相关推荐
威哥爱编程5 分钟前
HarmonyOS 7 Agent 开发实战 02:Agent 工程脚手架与对话 UI 骨架
agent·harmonyos
Georgewu8 小时前
【HarmonyOS 7】 HarmonyOS 应用 Skill创建和编排详解
harmonyos
Georgewu10 小时前
【HarmonyOS 7】 应用 Agent 接入云 A2A 与端 A2A 的实践详解
harmonyos
马剑威(威哥爱编程)16 小时前
【共创稿事节】HarmonyOS 7 Agent 开发实战 05:流式输出做打字机对话
华为·harmonyos
OH_TPC19 小时前
【鸿蒙优选三方库】@ohos/coap:让鸿蒙设备说上 IoT 的母语
物联网·华为·harmonyos·鸿蒙
程序猿追20 小时前
渐变中间那一格怎么算?用 colormath 做个鸿蒙调色器
华为·harmonyos
程序猿追21 小时前
在 HarmonyOS 6 上做了张 3D 翻转卡片,正面背面来回翻
3d·华为·harmonyos
小π军21 小时前
安卓、iOS、鸿蒙三端的理解
android·ios·harmonyos
m0_738185821 天前
Flutter 鸿蒙化实战:volume_controller 适配 OpenHarmony,系统音量控制
flutter·华为·harmonyos·鸿蒙
用户117910488331 天前
每个会话一个子进程:多会话真并行的架构取舍
开源·harmonyos