HarmonyOS 点光源效果开发指南

一、概述

点光源效果是 HarmonyOS 6.0.0(20) Beta1 版本新增的视觉效果能力,通过 @kit.UIDesignKit 中的 hdsEffect 模块实现。

该效果可以让组件:

  • 发光:作为光源照亮周围组件
  • 受光:被其他光源照亮,在边缘或内容区域产生光效

适用于提升用户交互体验,营造沉浸式 UI 效果。


二、基本概念

2.1 光源组件(发光)

设置 sourceTypeoptions 参数,使组件成为点光源,向周围发出光线。

2.2 受光组件(被照亮)

设置 illuminatedType 参数,使组件可以被附近的光源照亮。

2.3 约束限制

  • 单个组件最多同时受 12 个光源 照亮
  • 支持的组件:ButtonToggleRowColumnImageFlexStackSelectMenuMenuItem
  • 光源位置初始化为组件正中心,不会跟着组件位移变化,因此不建议在滚动组件中使用

三、导入模块

import { hdsEffect } from '@kit.UIDesignKit';

四、API 详解

4.1 核心类:HdsEffectBuilder

构建视觉效果的建造者类。

// 创建构建器
const builder = new hdsEffect.HdsEffectBuilder();

// 添加点光源效果
builder.pointLight({ /* 配置参数 */ });

// 构建最终效果
const effect = builder.buildEffect();

// 应用到组件
Component.visualEffect(effect)

4.2 pointLight 方法

pointLight(value: PointLightEffect): HdsEffectBuilder

参数 PointLightEffect:

属性 类型 必填 说明
sourceType PointLightSourceType 发光效果类型(预设值)
illuminatedType PointLightIlluminatedType 受光效果类型
options PointLightOptions 自定义发光参数

⚠️ 注意:sourceType 优先级高于 options,两者同时设置时 options 不生效。


五、枚举类型

5.1 PointLightSourceType(发光类型)

枚举值 说明
NONE 0 不发光(默认)
SOFT 1 柔和光源,发光强度较弱,照亮范围较小
BRIGHT 2 明亮光源,发光强度较高,照亮范围较大

5.2 PointLightIlluminatedType(受光类型)

枚举值 说明
NONE 0 不被照亮(默认)
BORDER 1 边缘被照亮
CONTENT 2 内容被照亮
BORDER_CONTENT 3 边缘和内容都被照亮
DEFAULT_FEATHERING_BORDER 20 边缘被照亮,带羽化效果

5.3 PointLightOptions(自定义发光参数)

属性 类型 说明
color ResourceColor 光源颜色,默认 Color.White
intensity number 光源强度,建议 0~1,越大越强
height Dimension 光源高度,越高照射范围越大
bloom number 泛光效果强度,建议 0~1

六、使用示例

6.1 基础示例:按下发光

import { hdsEffect } from '@kit.UIDesignKit';

@Entry
@Component
struct PointLightDemo {
  // 控制发光状态
  @State lightSource: hdsEffect.PointLightSourceType = hdsEffect.PointLightSourceType.NONE;

  build() {
    Column({ space: 20 }) {
      // 光源按钮
      Button('点击发光')
        .width(120)
        .height(50)
        .visualEffect(new hdsEffect.HdsEffectBuilder()
          .pointLight({
            sourceType: this.lightSource,
            illuminatedType: hdsEffect.PointLightIlluminatedType.BORDER
          })
          .buildEffect())
        .onTouch((event: TouchEvent) => {
          if (event.type === TouchType.Down) {
            // 按下时发光
            this.lightSource = hdsEffect.PointLightSourceType.BRIGHT;
          } else if (event.type === TouchType.Up || event.type === TouchType.Cancel) {
            // 松开时熄灭
            this.lightSource = hdsEffect.PointLightSourceType.NONE;
          }
        })

      // 受光组件
      Row()
        .width(80)
        .height(80)
        .backgroundColor('#808080')
        .borderRadius(40)
        .visualEffect(new hdsEffect.HdsEffectBuilder()
          .pointLight({
            illuminatedType: hdsEffect.PointLightIlluminatedType.BORDER
          })
          .buildEffect())
    }
    .width('100%')
    .height('100%')
    .backgroundColor(Color.Black)
    .justifyContent(FlexAlign.Center)
  }
}

6.2 自定义颜色发光

@Entry
@Component
struct ColoredLightDemo {
  @State isPressed: boolean = false;

  build() {
    Column({ space: 20 }) {
      // 红色光源按钮
      Button('红色光')
        .width(100)
        .height(50)
        .backgroundColor('#F44336')
        .visualEffect(new hdsEffect.HdsEffectBuilder()
          .pointLight({
            illuminatedType: hdsEffect.PointLightIlluminatedType.BORDER,
            options: {
              color: '#F44336',           // 红色光
              intensity: this.isPressed ? 0.8 : 0,  // 按下时强度0.8
              height: 100                 // 光源高度
            }
          })
          .buildEffect())
        .onTouch((event: TouchEvent) => {
          this.isPressed = event.type === TouchType.Down;
        })

      // 周围的受光组件
      Row({ space: 10 }) {
        ForEach([1, 2, 3], () => {
          Column()
            .width(60)
            .height(60)
            .backgroundColor('#808080')
            .borderRadius(30)
            .visualEffect(new hdsEffect.HdsEffectBuilder()
              .pointLight({
                illuminatedType: hdsEffect.PointLightIlluminatedType.BORDER
              })
              .buildEffect())
        })
      }
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#1a1a1a')
    .justifyContent(FlexAlign.Center)
  }
}

6.3 多光源照亮效果

@Entry
@Component
struct MultiLightDemo {
  @State light1: hdsEffect.PointLightSourceType = hdsEffect.PointLightSourceType.NONE;
  @State light2: hdsEffect.PointLightSourceType = hdsEffect.PointLightSourceType.NONE;

  build() {
    Column({ space: 30 }) {
      Row({ space: 20 }) {
        // 光源1 - 蓝色
        Button('蓝光')
          .backgroundColor('#2196F3')
          .visualEffect(new hdsEffect.HdsEffectBuilder()
            .pointLight({
              sourceType: this.light1,
              illuminatedType: hdsEffect.PointLightIlluminatedType.BORDER
            })
            .buildEffect())
          .onTouch((event: TouchEvent) => {
            this.light1 = event.type === TouchType.Down 
              ? hdsEffect.PointLightSourceType.BRIGHT 
              : hdsEffect.PointLightSourceType.NONE;
          })

        // 光源2 - 绿色  
        Button('绿光')
          .backgroundColor('#4CAF50')
          .visualEffect(new hdsEffect.HdsEffectBuilder()
            .pointLight({
              sourceType: this.light2,
              illuminatedType: hdsEffect.PointLightIlluminatedType.BORDER
            })
            .buildEffect())
          .onTouch((event: TouchEvent) => {
            this.light2 = event.type === TouchType.Down 
              ? hdsEffect.PointLightSourceType.BRIGHT 
              : hdsEffect.PointLightSourceType.NONE;
          })
      }

      // 中央受光组件 - 可同时被两个光源照亮
      Stack()
        .width(100)
        .height(100)
        .backgroundColor('#404040')
        .borderRadius(50)
        .visualEffect(new hdsEffect.HdsEffectBuilder()
          .pointLight({
            illuminatedType: hdsEffect.PointLightIlluminatedType.BORDER_CONTENT
          })
          .buildEffect())
    }
    .backgroundColor(Color.Black)
  }
}

七、最佳实践

7.1 交互反馈

使用 onTouch 事件控制发光状态,实现按下发光、松开熄灭的效果:

.onTouch((event: TouchEvent) => {
  if (event.type === TouchType.Down) {
    this.lightSource = hdsEffect.PointLightSourceType.BRIGHT;
  } else if (event.type === TouchType.Up || event.type === TouchType.Cancel) {
    this.lightSource = hdsEffect.PointLightSourceType.NONE;
  }
})

7.2 颜色一致性

让发光颜色与按钮底色一致,提升视觉统一性:

.backgroundColor('#2196F3')
.visualEffect(new hdsEffect.HdsEffectBuilder()
  .pointLight({
    options: {
      color: '#2196F3',  // 与底色一致
      intensity: isPressed ? 0.8 : 0,
      height: 100
    }
  })
  .buildEffect())

7.3 受光边框注意事项

如果受光组件设置了 border 的颜色和宽度,会覆盖掉点光源效果。建议受光组件不设置 border 或使用透明边框。

7.4 性能建议

  • 避免在滚动列表中使用点光源
  • 控制同一区域的光源数量(不超过12个)
  • 使用 SOFT 类型可以获得更柔和但性能更好的效果

八、常见问题

Q1: 为什么光源效果不显示?

  • 确认 SDK 版本 ≥ 6.0.0(20)
  • 确认使用了支持的组件类型
  • 确认背景色较暗(光效在深色背景更明显)

Q2: sourceType 和 options 的区别?

  • sourceType:使用预设的发光效果(SOFT/BRIGHT)
  • options:自定义光源颜色、强度、高度等参数
  • 两者不能同时使用sourceType 优先级更高

Q3: 如何实现动态发光效果?

通过 @State 状态变量控制 intensitysourceType,配合 onTouch 事件实现交互式发光。


九、参考文档

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐