0. 说明

OH系统版本:OpenHarmony3.1Release
IDE: 3.0.0.900
实现语言:ets

  • APP开屏视频挺常见,dayu200支持视频播放,3.5耳机口也正常输出音频。
  • 表盘在现代车机中很常见,样式多,风格迥异,OHOS API8也支持丰富的2D绘图能力,像要绘制表盘还是相对容易的。捣鼓以上两个是为做智能座舱做准备。将二者结合展示如下:
    #DAYU200体验官# 首页aito视频&Canvas绘制仪表盘(ets)-鸿蒙开发者社区

1. 首页视频播放

1.1 Video组件总结

参考地址:基于TS的Video组件说明
Video开发流程如下:

  • 创建视频控制对象:
//一个VideoController对象可以控制一个或多个video。
controller: VideoController = new VideoController();
controller.start()、 pause()、 stop() 、
setCurrentTime(number,SeekMode)指定进度位置,并指定挑转模式(前后、最近关键帧以及精准跳转)、
requesFullscreen(boolean)、exitFullscreen()
  • 获取视频路径:@State srcs: Resource = \(rawfile(‘video1’); 网络视频也可以,需要配置INTERNET权限。值得注意的是,还可访问通过Data Ability提供的视频路径,也就是说分布式视频也可以实现的。</li> <li>设置Video属性:muted(是否静音)、autoPlay(自动播放)、controls(控制栏)、objectFit(显示模式)、loop(是否循环播放)。其中,objectFit参数设置值为ImageFit.Cover则铺满整个容器。</li> <li>Video事件:<br/> <img title="#DAYU200体验官# 首页aito视频&amp;Canvas绘制仪表盘(ets)-鸿蒙开发者社区" src="https://www.thewebua.com/uploads/202405/01/18c882e524576eec.webp" alt="#DAYU200体验官# 首页aito视频&amp;Canvas绘制仪表盘(ets)-鸿蒙开发者社区"/><br/> 这里需要注意到,利用onFinish()事件,可以实现当播放完视频后我们可以直接跳跳转到APP内部。</li> </ul> <h3>1.2 开屏视频实现</h3> <p>新建一个基于ETS语言的项目,在index.ets中,先创建视频控制对象,以及视频路径。</p> <pre><code> @State srcs: Resource = \)r(‘app.media.aito’); @State previewUris: Resource = $r(‘app.media.car_cover’); //预览封面 controller: VideoController = new VideoController();

    在Component中的build下创建Video组件,使用Column容器容纳,

            Column() {

        Video({
          src: this.srcs,
          previewUri: this.previewUris,
          controller: this.controller
        }).width(&#39;100%&#39;).height(&#39;100%&#39;)
          .objectFit(ImageFit.Cover)
          .autoPlay(true)
          .controls(false)
          .onStart(() =&gt; {
            console.error(&#39;onStart&#39;);
          })
          .onPause(() =&gt; {
            console.error(&#39;onPause&#39;);
          })
          .onFinish(() =&gt; {
            console.error(&#39;onFinish&#39;);
            router.push({url:&#39;pages/gauge&#39;})
          })
      }.backgroundColor(&#39;white&#39;).height(&#34;100%&#34;)
    

    然后再页面创建时运行视频控制的start方法

      onPageShow() {

    this.controller.requestFullscreen(true)
    this.controller.start()
    

    }

    2. Canvas绘制仪表盘

    2.1 接口分析

    参考地址:画布组件绘制图像的方法很多,这里主要总结常用的以及仪表绘制用到的。

    • 创建CanvasRenderingContext2D对象
     private settings: RenderingContextSettings = new RenderingContextSettings(true);
      private fuel_gauge: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
    
    • 事件:
      onReady(callback: () =&gt; void) 画布组件的事件回调,可以在此时进行绘制。
    • 属性:
    //阴影
    shadowBlur	number	0.0	设置绘制阴影时的模糊级别,值越大越模糊,精度为float。
    shadowColor	&lt;color&gt;	-	设置绘制阴影时的阴影颜色。
    shadowOffsetX	number	-	设置绘制阴影时和原有对象的水平偏移值。
    shadowOffsetY	number	-	设置绘制阴影时和原有对象的垂直偏移值。
    //颜色
    fillStyle、strokeStyle
    //线宽、文字样式、线条端点样式
    lineWidth
    front
    lineCap	string	‘butt’	指定线端点的样式,可选值为:

    - ‘butt’:线端点以方形结束。
    - ‘round’:线端点以圆形结束。
    - ‘square’:线端点以方形结束,该样式下会增加一个长度和线段厚度相同,宽度是线段厚度一半的矩形。
    

    • 提供绘制方法
    //方形
       this.fuel_gauge.fillStyle = ‘#0000ff’
       this.fuel_gauge.fillRect(20, 160, 150, 100)//起点,宽高
    //边框 不填充

    1. this.context.strokeRect(30, 30, 200, 150)//矩形轮廓
    2. stroke(path?: Path2D): void //绘制轮廓 this.context.moveTo(25, 25) this.context.lineTo(25, 105) this.context.strokeStyle = ‘rgb(0,0,255)’ this.context.stroke() //删除不要区域- 刷新图形时常用 clearRect(x: number, y: number, w: number, h: number): void //圆形 arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean): void this.context.beginPath() this.context.arc(100, 75, 50, 0, 6.28) this.context.stroke() //文字 fillText(text: string, x: number, y: number): void //图片 drawImage(image: ImageBitmap, dx: number, dy: number): void drawImage(image: ImageBitmap, dx: number, dy: number, dWidth: number, dHeight: number): void
    • 如何让图动起来
      可以获取系统时间,或者使用setTime来实现动态刷新图像。看起来图形在动其实只是某些结构在转动、移动或者缩放
    //转动
    rotate(rotate: number): void //针对当前坐标轴进行顺时针旋转。
    //缩放
    scale(x: number, y: number): void //设置canvas画布的缩放变换属性,后续的绘制操作将按照缩放比例进行缩放。
    
    • gauge组件
      说起绘制仪器表盘,gauge组件其实也常用到。和Text组件一样,gauge已经高度定义,我们只能做简单的定义参数。gauge的使用方法如下:
    //图像可以随参数变化
          //电量表
          Gauge({ value: this.fuel_value, min: 0, max: 120 })
            .startAngle(210)
            .endAngle((this.fuel_value))
            .colors([[0xF01020, 1],[0xCFB53B, 1], [0x5BA854, 1]])
            .strokeWidth(20)
            .width(120)
            .height(120)
            .margin({top:30})
    

    效果如下:
    #DAYU200体验官# 首页aito视频&Canvas绘制仪表盘(ets)-鸿蒙开发者社区

    2.2 绘制表盘

    首先创建2D绘制对象,以及用到的变量

    private settings: RenderingContextSettings = new RenderingContextSettings(true);
    private car_gauge: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
    

    然后绘制圆盘与数字:

     //车速表
          Canvas(this.car_gauge)
            .width(‘45%’)
            .height(‘20%’)
            .backgroundColor(‘#000000’)
            .onReady(() =&gt; {
              //表环-车速
              this.car_gauge.clearRect(-100, -100, 600, 600);
              this.car_gauge.beginPath()
              this.car_gauge.translate(0, 0)
              this.car_gauge.shadowBlur=30
              this.car_gauge.shadowColor=this.car_gauge_col
              this.car_gauge.arc(this.gauge_speed_x, this.gauge_speed_y, 100, 0, 6.28)
              this.car_gauge.fillStyle = ‘black’
              this.car_gauge.fill()
              this.car_gauge.closePath()
              //数字环
              this.car_gauge.beginPath()
              this.car_gauge.translate(this.gauge_speed_x, this.gauge_speed_y)
              this.car_gauge.font = ‘20px bold’
              this.car_gauge.textAlign = ‘center’
              this.car_gauge.textBaseline = “middle”
              this.car_gauge.fillStyle = “#cfb35b”
              for (var i = 0;i &lt; this.car_speed.length; i++) {
                this.car_gauge.fillText(
                  this.car_speed[i],
                  80 * Math.cos(((i * 30 - 60) * Math.PI) / 180),
                  80 * Math.sin(((i * 30 - 60) * Math.PI) / 180)
                );
              }
              this.car_gauge.closePath()
              //速度
              this.car_gauge.beginPath()
              this.car_gauge.translate(-this.gauge_speed_x, -this.gauge_speed_y)
              this.car_gauge.fillStyle = ‘#0000000’
              //this.car_gauge.fillText(“Km/H”, 0, 25, 20)
              this.car_gauge.closePath()
    

    绘制指针,指针需要旋转一定角度,所以坐标一定要固定好在圆盘中心

                  //速度指针
              this.car_gauge.beginPath()
              this.car_gauge.arc(this.gauge_speed_x, this.gauge_speed_y, 10, 0, 6.28)
              this.car_gauge.fillStyle = ‘red’
              this.car_gauge.fill()
              this.car_gauge.closePath()
              var radius = Math.PI / 120 * this.car_velocity
              this.car_gauge.save()
              this.car_gauge.beginPath()
              this.car_gauge.translate(this.gauge_speed_x, this.gauge_speed_y)
              this.car_gauge.lineWidth = 8
              this.car_gauge.strokeStyle = ‘red’
              this.car_gauge.lineCap = ‘round’
              this.car_gauge.rotate(radius)
              this.car_gauge.moveTo(0, 0)
              this.car_gauge.lineTo(0, 60)
              this.car_gauge.stroke()
              this.car_gauge.closePath()
              this.car_gauge.restore()
            })
    

    表盘效果如下:
    #DAYU200体验官# 首页aito视频&Canvas绘制仪表盘(ets)-鸿蒙开发者社区#DAYU200体验官# 首页aito视频&Canvas绘制仪表盘(ets)-鸿蒙开发者社区
    使用定时器改变指针旋转角度以及阴影颜色效果,再结合首页视频,得到帖子前面展示的样例。

      update_canvas()
    {
    var that = this;
    that.car_velocity =0
    that.intervalID  = setInterval(function(){
      //      prompt.showToast({
      //        message:“car_velocity”+that.car_velocity,
      //      })
      that.car_velocity +=10;
      that.fuel_value +=20
      if(that.car_velocity&gt;120)
      {
        that.car_gauge_col = ‘red’
      }
      if(that.car_velocity&gt;240)
      {
        that.car_velocity=0;
        that.fuel_value=60
        clearInterval(that.intervalID)
      }
    },80)
    }