一、说明
- OH系统版本:OpenHarmony3.1Release
- IDE: 3.0.0.900
实现语言:ets。
- APP开屏视频挺常见,dayu200支持视频播放,3.5耳机口也正常输出音频。
- 表盘在现代车机中很常见,样式多,风格迥异,OHOS API8也支持丰富的2D绘图能力,像要绘制表盘还是相对容易的。捣鼓以上两个是为做智能座舱做准备。将二者结合展示如下:
二、首页视频播放
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提供的视频路径,也就是说分布式视频也可以实现的。
- 设置Video属性:muted(是否静音)、autoPlay(自动播放)、controls(控制栏)、objectFit(显示模式)、loop(是否循环播放)。其中,objectFit参数设置值为ImageFit.Cover则铺满整个容器。
- Video事件:
这里需要注意到,利用onFinish()事件,可以实现当播放完视频后我们可以直接跳跳转到APP内部。
2、开屏视频实现
新建一个基于ETS语言的项目,在index.ets中,先创建视频控制对象,以及视频路径。
@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('100%').height('100%')
.objectFit(ImageFit.Cover)
.autoPlay(true)
.controls(false)
.onStart(() => {
console.error('onStart');
})
.onPause(() => {
console.error('onPause');
})
.onFinish(() => {
console.error('onFinish');
router.push({url:'pages/gauge'})
})
}.backgroundColor('white').height("100%")
然后再页面创建时运行视频控制的start方法。
onPageShow() {
this.controller.requestFullscreen(true)
this.controller.start()
}
三、Canvas绘制仪表盘
1、接口分析
参考地址:画布组件绘制图像的方法很多,这里主要总结常用的以及仪表绘制用到的。
- 创建CanvasRenderingContext2D对象。
private settings: RenderingContextSettings = new RenderingContextSettings(true);
private fuel_gauge: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
- 事件:
onReady(callback: () => void) 画布组件的事件回调,可以在此时进行绘制。 - 属性:
//阴影
shadowBlur number 0.0 设置绘制阴影时的模糊级别,值越大越模糊,精度为float。
shadowColor <color> - 设置绘制阴影时的阴影颜色。
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})
效果如下:
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(() => {
//表环-车速
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 < 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()
})
表盘效果如下:
使用定时器改变指针旋转角度以及阴影颜色效果,再结合首页视频,得到帖子前面展示的样例。
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>120)
{
that.car_gauge_col = 'red'
}
if(that.car_velocity>240)
{
that.car_velocity=0;
that.fuel_value=60
clearInterval(that.intervalID)
}
},80)
}