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

相关推荐
SummerKaze1 天前
为鸿蒙开发者写一个 nvm:hmvm 的设计与实现
harmonyos
在人间耕耘3 天前
HarmonyOS Vision Kit 视觉AI实战:把官方 Demo 改造成一套能长期复用的组件库
人工智能·深度学习·harmonyos
王码码20353 天前
Flutter for OpenHarmony:socket_io_client 实时通信的事实标准(Node.js 后端的最佳拍档) 深度解析与鸿蒙适配指南
android·flutter·ui·华为·node.js·harmonyos
HarmonyOS_SDK3 天前
【FAQ】HarmonyOS SDK 闭源开放能力 — Ads Kit
harmonyos
Swift社区3 天前
如何利用 ArkUI 框架优化鸿蒙应用的渲染性能
华为·harmonyos
特立独行的猫a3 天前
uni-app x跨平台开发实战:开发鸿蒙HarmonyOS影视票房榜组件完整实现过程
华为·uni-app·harmonyos·轮播图·uniapp-x
盐焗西兰花3 天前
鸿蒙学习实战之路-STG系列(5/11)-守护策略管理-添加与修改策略
服务器·学习·harmonyos
盐焗西兰花3 天前
鸿蒙学习实战之路-STG系列(4/11)-应用选择页功能详解
服务器·学习·harmonyos
lbb 小魔仙4 天前
鸿蒙跨平台项目实战篇03:React Native Bundle增量更新详解
react native·react.js·harmonyos
特立独行的猫a4 天前
uni-app x跨平台开发实战:开发鸿蒙HarmonyOS滚动卡片组件,scroll-view无法滚动踩坑全记录
华为·uni-app·harmonyos·uniapp-x