手机召唤小艺的时候会出现底部和全屏边框的光影效果,鸿蒙6.0为我们提供了API可以自定义光源视效,这篇文章来了解一下如何使用。
演示效果
从API 6.0.0(20)系统提供了hdsEffect模块提供组件的拓展视效能力。不支持模拟器测试。
点光源视效
pointLight(value: PointLightEffect): HdsEffectBuilder
通过点光源接口可以设置组件的发光效果以及被照亮的受光效果,使得组件交互体验更显沉浸。
创建一个组件点光源效果,单个组件最多同时受12个光源照亮。支持点光源效果的组件范围如下:Button、Toggle、Row、Column、Image、Flex、Stack、Select、Menu、MenuItem。
点光源效果属性 PointLightEffect
| 名称 |
类型 |
说明 |
| illuminatedType |
PointLightIlluminatedType |
组件受光效果类型 |
| sourceType |
PointLightSourceType |
组件发光效果类型 |
| options |
PointLightOptions |
组件自定义发光参数选项 |
发光组件属性配置
sourceType的优先级高于options。当同时设置sourceType和options时,options自定义发光参数不会生效。
组件发光效果类型 PointLightSourceType
| 名称 |
说明 |
| NONE |
点光源不生效,组件无发光效果。 |
| SOFT |
柔和点光源,发光强度较弱,周围照亮范围较小 |
| BRIGHT |
明亮点光源,发光强度较高,周围照亮范围较大 |
自定义发光参数 PointLightOptions
| 名称 |
说明 |
| color |
光源颜色 |
| intensity |
光源强度,范围0~1 |
| height |
光源高度 |
| bloom |
泛光效果强度,范围0~1 |
组件受光效果类型 PointLightIlluminatedType
| 名称 |
说明 |
| NONE |
不被照亮 |
| BORDER |
边缘被照亮 |
| CONTENT |
内容被照亮 |
| BORDER_CONTENT |
边缘和内容被照亮 |
| DEFAULT_FEATHERING_BORDER |
边缘被照亮,并且有羽化效果 |
shader视效
提供了双边边缘流光和UV背景流光两种视效
shaderEffect(params: ShaderEffectParams): HdsEffectBuilder
创建一个shader视效。
视效配置 ShaderEffectParams
| 名称 |
类型 |
说明 |
| effectType |
EffectType |
视效类型 |
| animation |
AnimationParams |
视效动画参数配置 |
| params |
EffectParams |
shader参数配置 |
| controller |
ShaderEffectController |
视效控制器 |
双边边缘流光视效
通过双边边缘流光接口可以设置组件的边缘发光效果,并且可以设置两条边的起始、终止位置和边缘颜色效果,常用于胶囊组件、屏幕边缘发光等。
effectType: hdsEffect.EffectType.DUAL_EDGE_FLOW_LIGHT
双边边缘流光视效参数DualEdgeFlowLightParam
| 名称 |
类型 |
说明 |
| firstEdgeFlowLight |
EdgeFlowLightParam |
第一条流光参数配置 |
| secondEdgeFlowLight |
EdgeFlowLightParam |
第二条流光参数配置 |
边缘流光视效参数 EdgeFlowLightParam
| 名称 |
说明 |
| startPos |
开始位置,以视效容器的上边缘的中点为起始点,起始点沿边缘至目标位置的距离与容器周长的比值。 |
| endPos |
结束位置,以视效容器的上边缘的中点为起始点,起始点沿边缘至目标位置的距离与容器周长的比值。 |
| color |
流光颜色 |
UV流光视效参数
| 名称 |
类型 |
说明 |
| colorSource |
Array<ResourceColor> |
背景流光颜色 |
| colorTarget |
Array<ResourceColor> |
目标渐变颜色 |
视效动画参数 AnimationParams
| 名称 |
说明 |
| duration |
视效动画播放一次时间 |
| iterations |
播放次数,-1为重复执行 |
| curve |
动画曲线 |
| delay |
视觉动画延迟播放时间 |
| autoPlay |
是否自动执行 |
| onFinish |
结束时回调函数 |
| expectedFrameRateRange |
帧率设置 |
自带背景的双边流光组件 HdsVisualComponent
通过通用视效组件HdsVisualComponent提供的自带背景的双边流光效果场景接口,支持设置两条边缘流光的起始、终止位置、边缘颜色效果以及与流光相叠加的背景板颜色,用于胶囊组件、屏幕边缘发光等。
scene(sceneType: HdsSceneType, controller: HdsSceneController, callback?: HdsSceneFinishCallback, frameRateRange?: hdsEffect.ExpectedFrameRateRange)
场景视效参数 SceneParams
| 名称 |
说明 |
| backgroundMaskColors |
背景蒙层颜色数组 |
| firstEdgeFlowLight |
第一条流光参数配置 |
| secondEdgeFlowLight |
第二条流光参数配置 |
演示代码
import { hdsEffect, HdsSceneController, HdsSceneType, HdsVisualComponent,HdsVisualComponentAttribute } from '@kit.UIDesignKit'
import { MyRadioModifier } from '../utils/MyAttributeModifier'
import { WindowUtils } from '../utils/WindowUtils';
@Entry
@ComponentV2
struct HdsEffectTest{
@Local illuminatedType: hdsEffect.PointLightIlluminatedType = hdsEffect.PointLightIlluminatedType.NONE;
@Local lightColor:ResourceColor = Color.Red
@Local light_intensity:number=0 //光源强度
@Local light_height:number=0 //光源高度
@Local light_bloom:number=0 //泛光效果强度
@Local dua_controller: hdsEffect.ShaderEffectController = new hdsEffect.ShaderEffectController();
@Local uv_controller: hdsEffect.ShaderEffectController = new hdsEffect.ShaderEffectController();
@Local switchIsOn: boolean = true
@Local sceneController: HdsSceneController = new HdsSceneController()
.setSceneParams({
backgroundMaskColors: [Color.Red,Color.Green],
firstEdgeFlowLight: {
startPos: 0,
endPos: 0.5,
color: Color.Green
},
secondEdgeFlowLight: {
startPos: 0,
endPos: -0.5,
color: Color.Red
}
})
aboutToAppear(): void {
WindowUtils.setWindowFullScreen(true)
}
aboutToDisappear(): void {
WindowUtils.setWindowFullScreen(false)
}
build() {
Stack(){
HdsVisualComponent()
.scene(HdsSceneType.DUAL_EDGE_FLOW_LIGHT_WITH_BACKGROUND_MASK, this.sceneController)
.width('100%')
.height('100%')
Column({space:20}){
Column({space:10}){
Text('组件受光效果类型').fontSize(20)
Row(){
Radio({ value: 'r0', group: 'radioGroup' })
.attributeModifier(new MyRadioModifier(true))
.onChange((isChecked: boolean) => {
this.illuminatedType = hdsEffect.PointLightIlluminatedType.NONE
})
Text('不被照亮 ')
Radio({ value: 'r1', group: 'radioGroup' })
.attributeModifier(new MyRadioModifier())
.onChange((isChecked: boolean) => {
this.illuminatedType = hdsEffect.PointLightIlluminatedType.BORDER
})
Text('边缘被照亮 ')
Radio({ value: 'r2', group: 'radioGroup' })
.attributeModifier(new MyRadioModifier())
.onChange((isChecked: boolean) => {
this.illuminatedType = hdsEffect.PointLightIlluminatedType.CONTENT
})
Text('内容被照亮 ')
}
Row(){
Radio({ value: 'r3', group: 'radioGroup' })
.attributeModifier(new MyRadioModifier())
.onChange((isChecked: boolean) => {
this.illuminatedType = hdsEffect.PointLightIlluminatedType.BORDER_CONTENT
})
Text('边缘和内容被照亮 ')
Radio({ value: 'r20', group: 'radioGroup' })
.attributeModifier(new MyRadioModifier())
.onChange((isChecked: boolean) => {
this.illuminatedType = hdsEffect.PointLightIlluminatedType.DEFAULT_FEATHERING_BORDER
})
Text('羽化效果 ')
}
}.alignItems(HorizontalAlign.Start)
.borderRadius(5)
.visualEffect(new hdsEffect.HdsEffectBuilder()
.pointLight({
illuminatedType:this.illuminatedType,
}).buildEffect())
Column({space:20}){
Row(){
Radio({ value: 'r0', group: 'rgColor' })
.attributeModifier(new MyRadioModifier(true))
.onChange((isChecked: boolean) => {
this.lightColor = Color.Red
})
Text('光源-红 ')
Radio({ value: 'r1', group: 'rgColor' })
.attributeModifier(new MyRadioModifier())
.onChange((isChecked: boolean) => {
this.lightColor = Color.Yellow
})
Text('光源-黄 ')
Radio({ value: 'r2', group: 'rgColor' })
.attributeModifier(new MyRadioModifier())
.onChange((isChecked: boolean) => {
this.lightColor = Color.Blue
})
Text('光源-蓝 ')
}
Row({ space: 10 }) {
Text('光源强度:' + this.light_intensity/100)
Slider({
value: this.light_intensity,
min: 0,
max: 100,
style: SliderStyle.OutSet
}).width('50%')
.onChange((value: number) => {
this.light_intensity = value;
})
}
Row({ space: 10 }) {
Text('光源高度:' + this.light_height)
Slider({
value: this.light_height,
min: 0,
max: 320,
style: SliderStyle.OutSet
}).width('50%')
.onChange((value: number) => {
this.light_height = value;
})
}
Row({ space: 10 }) {
Text('泛光效果:' + this.light_bloom/100)
Slider({
value: this.light_bloom,
min: 0,
max: 100,
style: SliderStyle.OutSet
}).width('50%')
.onChange((value: number) => {
this.light_bloom = value;
})
}
}.visualEffect(new hdsEffect.HdsEffectBuilder()
.pointLight({
illuminatedType:hdsEffect.PointLightIlluminatedType.BORDER,
}).buildEffect())
Button('光源')
.width(60)
.height(60)
.borderRadius(30)
.backgroundColor(this.lightColor)
.visualEffect(new hdsEffect.HdsEffectBuilder()
.pointLight({ //创建一个组件点光源效果
options: {
color: this.lightColor,
intensity: this.light_intensity,
height: this.light_height,
bloom:this.light_bloom
}
}).buildEffect())
Row({space:10}){
Text('双边边缘流光').fontSize(20)
Toggle({ type: ToggleType.Switch, isOn: this.switchIsOn })
.selectedColor('#007DFF') //打开状态下的背景颜色
.switchPointColor('#FFFFFF') //圆形滑块颜色
.onChange((isOn: boolean) => {
this.switchIsOn = isOn
if (this.switchIsOn) {
this.dua_controller.resume()
}else {
this.dua_controller.pause()
}
})
Text(this.switchIsOn ? '开始' : '暂停').fontColor(this.switchIsOn ? Color.Red : Color.Black).fontSize(20)
}.visualEffect(new hdsEffect.HdsEffectBuilder()
.shaderEffect({
effectType: hdsEffect.EffectType.DUAL_EDGE_FLOW_LIGHT,
animation: {
duration: 5000,
iterations: -1,
autoPlay: true,
},
controller: this.dua_controller,
params: {
firstEdgeFlowLight: {
startPos: 0,
endPos: 1.0,
color: '#1AD0F1',
},
secondEdgeFlowLight: {
startPos: 0.5,
endPos: 1.5,
color: '#FFA4E5',
}
}
})
.buildEffect())
.width('80%')
.height(80)
Stack(){
Text('UV流光视效').fontSize(20)
}.visualEffect(new hdsEffect.HdsEffectBuilder()
.shaderEffect({
effectType: hdsEffect.EffectType.UV_BACKGROUND_FLOW_LIGHT,
animation: {
duration: 4000,
iterations: -1,
autoPlay: true,
curve:Curve.Smooth
},
controller: this.uv_controller,
params: {
colorSource:[Color.Red,Color.Blue,Color.Yellow]
}
})
.buildEffect())
.width('80%')
.height(80)
}.width('100%').height('100%').padding({top:WindowUtils.getStatusHeight()+'px'})
}
}
}