本文原创发布在华为开发者社区

介绍

本示例构建了一个视频播放进度条案例,主要实现的功能是为正在播放的视频添加一个刻度条组件用以表示进度。

添加视频播放进度条源码链接

效果预览

请添加链接描述

使用说明

  • 打开应用,展示待播放的视频以及播放、暂停两个按钮。
  • 点击播放按钮,视频播放,刻度条会随视频的进度条而移动。
  • 拖动刻度条也可以视频进度进行拖动。

实现思路

  1. 利用videoController简单的设置video的播放、暂停按钮控制。
Button("播放")
.onClick(() => {
    this.videoController.start()
})
Button("暂停")
.onClick(() => {
    this.videoController.pause()
})
  1. 定义一个名为 setScale 的函数,用于处理与缩放(scale)相关的操作,并根据缩放情况来调整一系列相关的变量值;
    基于 barMultiple 调整其他关键变量,根据 this.barMultiple 的值进一步调整 this.stepVp 和 this.stepDuration 这两个变量;
    计算与绘制准备相关逻辑;最后触发绘制操作,调用 this.drawBar() 函数
  setScale(scale: number): void {
    let scaleChange = scale - this.zoomSize
    ···
    this.zoomSize = scale
    ···
    let minUnit = this.stepVp / this.stepDuration
    let halfStep = this.canvasWidth / 2
    let currentStep = this.currentDuration * minUnit
    ···
    this.drawBar()
  }
  1. 构造videoPlaying()函数,进行触摸移动状态判断操作及早期返回,基于时间和画布宽度的计算与赋值调整,再次触摸移动状态判断及绘制触发。

  videoPlaying(time: number) {
    ···
    let minUnit = this.stepVp / this.stepDuration
    this.currentDuration = time
    this.currentTime = this.getTimeFromSeconds(this.currentDuration)
    let currentStep = this.currentDuration * minUnit
    ···
    let halfStep = this.canvasWidth / 2
    this.drawBar()
  }
  
  1. 构造penGestureUpdate()函数,进行基础变量计算与初始化,根据移动方向及相关条件处理movedX,更新当前时长及对应时间表示,基于当前时长的空间位置计算,触发绘制操作。
  penGestureUpdate(event: GestureEvent): void {
    let minUnit = this.stepVp / this.stepDuration
    let movedX = event.offsetX - this.lastTouchX
    this.lastTouchX = event.offsetX
    ···
    let maxMovedX = 0 - this.totalDuration * minUnit
    ···
      maxMovedX =  (this.currentDuration - this.totalDuration) * minUnit
      movedX = Math.floor(movedX / minUnit) * minUnit

    this.currentDuration = this.currentDuration - movedX / minUnit
    ···
    this.currentTime = this.getTimeFromSeconds(this.currentDuration)
    let currentStep = this.currentDuration * minUnit
    let halfStep = this.canvasWidth / 2
    ···
    this.drawBar()
  }
  1. 构造drawBar()函数,首先计算最小单位和相关尺度数量,绘制主水平线条,然后循环绘制刻度和时间描述。
  drawBar(): void {
    let minUnit = this.stepVp / this.stepDuration
    this.scalePaint!.clearRect(0, 0, this.canvasWidth, 80)

    let totalScale = Math.ceil(this.totalDuration / this.stepDuration)
    let maxWindowScale = Math.floor(this.canvasWidth / this.stepVp)

    this.scalePaint!.beginPath()
    this.scalePaint!.moveTo(0, 60)
    this.scalePaint!.lineTo(this.canvasWidth, 60)
    this.scalePaint!.stroke()

    let firstStepDuration = Math.ceil(this.beginDuration / this.stepDuration) * this.stepDuration
    let beginStep = Math.floor(firstStepDuration / this.stepDuration)
    ···
    ···
  }
  1. 构造getTimeFromSeconds()函数,将秒数转换为小时、分钟和秒,return的时候使用字符串模板和padStart来确保小时、分钟和秒都是两位数。
  getTimeFromSeconds(seconds: number): string {
    
    const hours = Math.floor(seconds / 3600); // 每小时3600秒
    const minutes = Math.floor((seconds % 3600) / 60); // 剩余秒数转换为分钟
    const remainingSeconds = Math.round(seconds % 60); // 剩余的秒数

    // 使用字符串模板和padStart来确保小时、分钟和秒都是两位数
    return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;
  }

鸿蒙场景化代码
1 声望0 粉丝