鸿蒙6新特性:光源视效

手机召唤小艺的时候会出现底部和全屏边框的光影效果,鸿蒙6.0为我们提供了API可以自定义光源视效,这篇文章来了解一下如何使用。

演示效果

演示.gif

从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'})
    }
  }
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容