找回密码
 立即注册

微信扫码登录

搜索
查看: 291|回复: 7

[UI界面] 自制第三方卡片分享,grid-button-card,一个带动画的按钮切换卡片

[复制链接]

36

主题

252

回帖

2222

积分

论坛UI达人

积分
2222
金钱
1929
HASS币
60
发表于 3 天前 | 显示全部楼层 |阅读模式
本帖最后由 gasment 于 2025-10-29 14:23 编辑

自制卡片计划第四弹,往期链接:
【更新V2】自制第三方卡片分享,popup-button-card,一个自带弹窗的按钮卡片 - 『HomeAssistant』综合讨论区 - 『瀚思彼岸』» 智能家居技术论坛 - Powered by Discuz!

自制第三方卡片分享,slider-mod-card,一个简洁的滑动条卡片 - 『HomeAssistant』综合讨论区 - 『瀚思彼岸』» 智能家居技术论坛 - Powered by Discuz!
自制第三方卡片分享,countdown-mod-card,一个紧凑型定时卡片 - 『HomeAssistant』综合讨论区 - 『瀚思彼岸』» 智能家居技术论坛 - Powered by Discuz!


最近写卡片上瘾了,又来造轮子了。

创建网格布局的按钮,很多卡片都可以做到,但是动画效果基本没有或者需要自己搓css,于是有了下面这个。。。


卡片预览:
preview1.webp
preview2.webp
switch实体用例:
preview3.webp
select实体用例:
preview4.webp

2025.10.29更新 v1.1.0
  • 新增:子按钮的二次确认弹窗,可用于防误触(触发弹窗附带震动效果,仅支持官方APP)
  • 相关配置项:confirm_dialog/confirm_dialog_content,使用方法已更新至下文
  • preview5.webp

介绍:
Grid Button Card 是一个高度可定制的 Lovelace 卡片,它允许您在一个卡片内创建灵活的按钮网格布局。
其核心特色是 “飞行高亮” (Flying Highlight) 效果:当卡片的某个状态激活时,一个独立的高亮层会以平滑的动画效果,从上一个激活的按钮“飞”到当前激活的按钮上。适用于switch、select等选项互斥的实体
主要特性:
  • 动态网格布局:通过 CSS Grid 自由定义按钮的排列、大小和间距。
  • 飞行高亮效果:根据实体状态自动、平滑地移动高亮层。
  • 乐观更新:点击按钮后,高亮层会立即移动到目标位置,提供即时反馈,使用可自定义的延迟来同步实体。
  • 丰富的样式定制:卡片、按钮、图标、文本等几乎所有元素的样式都可以通过 YAML 进行深度定制。
  • 模板支持:所有内容和大部分样式都支持js模板语法 ([[[...]]]),实现动态卡片。
  • 标准动作:支持 call-service, navigate, toggle 等标准的 Home Assistant 点击动作


此项目全部功能实现代码由AI生成 Power By ChatGPT

安装说明:

  • 复制本项目github仓库地址:
    游客,如果您要查看本帖隐藏内容请回复
  • 在HACS添加Custom repositories,Repositories填写仓库地址,Type选择Dashboard; 搜索:grid-button-card,下载安装,按提示刷新页面


配置说明:
顶层配置
yaml配置项 效果说明 使用说明 配置示例
type 声明卡片类型 必需,固定为 custom:grid-button-card type: custom:grid-button-card
variables 变量功能,可在卡片js模板中读取与复用可选,变量支持js模板动态取值 见下文variables部分
sync_state驱动高亮层移动的状态源,
它的计算结果将与各按钮的 sync_state 值进行比较
必需,通常设置为一个能代表当前实体状态的模板,
如 [[[ return states['select.my_entity'].state; ]]]
见下文sync_state部分
sync_state_delay乐观更新的回滚延迟时间(毫秒)。
点击后,高亮层会立即移动,
如果在这段时间内 sync_state 未能更新到目标值,高亮层将返回原位
可选,默认值1000ms,可根据实体响应速度调整 sync_state_delay: 500
button_grid 定义所有按钮的布局名称和具体配置必需,键名(如 button1)必须与 styles.grid 中 grid-template-areas 定义的区域名对应 见下文button_grid部分
styles 定义卡片顶层容器的样式 可选,一个 CSS 样式对象数组 见下文styles部分

JS表达式写法
  • 基本与button-card一致
  • 分行符使用“|”、“>-”,另起一行使用[[[···]]]包裹js代码
  • 读取实体主属性使用:states[`your_entity_id`].state
  • 读取实体附加属性使用:states[`your_entity_id`].attributes.xxxxx
  • 可以使用变量代替实体id: states[`${variables.your_entity_id}`].state
  • 支持赋值变量var/cont/let,支持if else 多行嵌套
  • 使用return返回数值
示例:
button_effect_color: |
    [[[
        var state = states[`sensor.entity`].state
        if (state === "off"){
        return "#D7DFED"
        } else if (state === "cool"){
        return "#2483FF"
        } else if (state === "heat"){
        return "#FF6B6B"
        } else if (state === "dry"){
        return "#54CEAE"
        } else if (state === "fan_only"){
        return "#4CCBA9"
        } else if (state === "auto"){
        return "#464BD8"
        } else {
        return "#D7DFED"
        }
    ]]]
variables用法
  • 支持多个变量定义,每个变量支持静态或动态js模板
variables:
  example_1: 114514
  example_2: |
      [[[
        var value = states[`light.entity`].state;
        if (value === "on"){
          return "打开"
        } else {
            return "关闭"
        }
      ]]]
  example_3: switch.my_switch
  • 在卡片内使用变量
name: |
  [[[return variables.example_1]]]
state: |
  [[[
    var value = states[`${variables.example_3}`].state;
    if (value === "on"){
      return "打开"
    } else {
        return "关闭"
    }
  ]]]


sync_state配置
  • sync_state存在于两个地方,第一个是顶层的sync_state,另一个是button_grid.<button-grid-name>.sync_state,当button_grid.<button-grid-name>.sync_state = 顶层sync_state时,该button_grid就会被应用高亮动画
  • 顶层sync_state配置:
sync_state: |
        [[[return states[`your_entity_id`].state]]]
    #或使用条件判断
sync_state: |
        [[[
            var value = states[`your_entity_id`].state
            if (value < 100){
                return "on"
            } else {
                return "off"
            }
        ]]]
  • button_grid内的sync_state配置,此处通常配置为静态内容,当此值与顶层的sync_state相同时,按钮就会被点亮
button_grid:
  button1:
    sync_state: on

顶层styles配置
  • 顶层的styles配置用于卡片顶层容器和按钮布局样式,支持card和grid入口
  • card,用于卡片顶层容器css样式:
styles:
  card:
    - padding: 5px
    - border-radius: 20px
    - background: rgba(0,0,0,0)
  • grid,用于配置按钮布局样式
子配置 效果说明 使用说明 配置示例
grid-template-areas 配置按钮的网格布局 必需 ,area名称必须与button_grid下的一致 见下文styles -> grid详情
grid-template-columns 配置网格的列宽 可选,支持px/%/fr等常见数值 见下文styles -> grid详情
grid-template-rows 配置网格的行高 可选,支持px/%/fr等常见数值 见下文styles -> grid详情
column-gap 配置网格列间距 可选,支持px/%/fr等常见数值 column-gap: 10px
row-gap 配置网格行间距 可选,支持px/%/fr等常见数值 row-gap: 10px
justify-items/justify-content 配置网格、网格内容的水平对齐方式 可选,支持start/center/end justify-items: center
align-items/align-content 配置网格、网格内容的垂直对齐方式 可选,支持start/center/end align-items: center


顶层styles -> grid配置
  • grid-template-areas配置,示例一个3 x 2的布局(button1/2/3/4/5/6只是示例名称,可自定义,但是必需与button_grid的子对象一致)
styles:
  grid:
    - grid-template-areas: |
        "button1 button2 button3"
        "button4 button5 button6"
  • grid-template-columns,网格的列宽配置,按上面3x2示例,从左到右分别定义每列的宽度
styles:
  grid:
    - grid-template-columns: 50px auto 100px
  • grid-template-rows,网格的行高配置,按上面3x2示例,从上到下分别定义每行的高度
styles:
  grid:
    - grid-template-rows: 50% 50%

button_grid配置
配置项 效果说明 使用说明 配置示例
name按钮的名称文本可选,支持模板和字符串name: example
label按钮的标签文本可选,支持模板和字符串label: example
state按钮的状态文本可选,支持模板和字符串state: example
icon按钮的图标可选。可以是 mdi:xxxx 或一个图片URL。支持模板icon: mdi:lightbulb
sync_state此按钮对应的状态值。
当顶层的 sync_state 计算结果与此值相等时,
此按钮将被高亮
必需。通常为字符串、数值 参考上文sync_state配置
confirm_dialog二次确认对话框,防误触可选,接受true/false,支持模板和变量读取confirm_dialog: false
confirm_dialog_content二次确认对话框内的文本提示可选,接受字符串,支持模板和变量读取confirm_dialog_content: 你确定要操作吗?
sync_button_highlight定义当此按钮被高亮时,高亮层的背景颜色可选,接受任何 CSS 颜色值,
如 '#FF5722' 或 'rgba(255, 87, 34, 0.3)'。
如果省略,会使用一个默认的蓝色
sync_button_highlight: blue
tap_action此按钮的点击动作可选,写法与ha开发者选项中的动作yaml配置一致见下文tap_action配置
styles定义此按钮及其内部元素的样式可选。一个 CSS 样式对象数组。见下文button_grid -> styles配置

tap_action配置
  • 更多可配置项,可前往ha开发者选项的动作页面,摘抄yaml配置
  • 开关切换:
tap_action:
  action: toggle
  target:
    entity_id: <your_switch_entity_id>
  • 灯开关、切换
tap_action:
  action: light.turn_on / light.turn_off / toggle
  target:
    entity_id: <your_light_entity_id>
  • 选项选择
tap_action:
  action: select.option
  target:
    entity_id: <your_select_entity_id>
  data:
    option: <option_name>

button_grid -> styles 配置示例
配置项效果说明使用说明
card作用于该按钮的背景层可以设置 background、border-radius 等
grid作用于按钮内部承载 icon/name 等元素的网格容器仅支持设置areas为name/state/icon/label,不支持自定义
name/state/label分别作用于按钮的名称、状态和标签文本元素可以设置 font-size、color、justify-self、align-self 等
icon作用于按钮的图标元素可以设置 height、width 等
配置示例:
button_grid:
  button1:
    styles:
      card:
        - background-color: 'rgba(120, 120, 120, 0.15)'
      grid: 
        - grid-template-areas: |
                "icon name"
                "icon state"
        - grid-template-rows: auto auto
        - grid-template-columns: 50% 50%
        - align-content: center
      icon:
        - color: green
        - height: 20px
        - width: 20px
      name:
        - font-size: 16px
        - letter-spacing: 5px
      state:
        - font-size: 12px
        - color: white

完整配置示例:
type: custom:grid-button-card
sync_state: |
  [[[
        var value = states[`your_entity_id`].state
        if (value < 100){
            return "on"
        } else {
            return "off"
        }
   ]]]
sync_state_delay: 800
styles:
  card:
    - background-color: 'rgba(50, 50, 50, 0.1)'
    - border-radius: '16px'
    - padding: '8px'
  grid:
    - grid-template-areas: |
        "button1 button2"
    - grid-template-columns: auto auto
    - grid-template-rows: 50% 50%
    - gap: 8px

button_grid:
  button1:
    name: 按钮1
    sync_state: on
    confirm_dialog: true
    confirm_dialog_content: 你确定要操作吗?
    state: |
      [[[ return states[`your_entity_id`].state ]]]
    icon: /local/icon/your_on_icon.svg
    tap_action:
      action: switch.turn_off
      target:
        entity_id: <your_entity_id>
    styles:
      card:
        - background-color: 'rgba(120, 120, 120, 0.15)'
      grid: 
        - grid-template-areas: 
                "icon name"
                "icon state"
        - grid-template-rows: 50% 50%
        - grid-template-columns: 50px auto
      icon:
        - color: rgb(36,62,186)
        - height: 30px
        - width: 30px
      name:
        - font-size: 16px
        - color: black
      state:
        - font-size: 12px
        - color: white
        - align-self: start

  button2:
    name: 按钮2
    sync_state: off
    state: |
      [[[ return states[`your_entity_id`].state ]]]
    icon: /local/icon/your_off_icon.svg
    tap_action:
      action: switch.turn_off
      target:
        entity_id: <your_entity_id>
    styles:
      card:
        - background-color: 'rgba(120, 120, 120, 0.15)'
      grid: 
        - grid-template-areas: 
                "icon name"
                "icon state"
        - grid-template-rows: 50% 50%
        - grid-template-columns: 50px auto
      icon:
        - color: rgb(36,62,186)
        - height: 30px
        - width: 30px
      name:
        - font-size: 16px
        - color: black
      state:
        - font-size: 12px
        - color: white
        - align-self: start








评分

参与人数 1金钱 +12 收起 理由
隔壁的王叔叔 + 12 感谢楼主分享!

查看全部评分

回复

使用道具 举报

3

主题

37

回帖

537

积分

高级会员

积分
537
金钱
497
HASS币
0
发表于 3 天前 | 显示全部楼层
学习下,不错的思路
回复

使用道具 举报

9

主题

218

回帖

1340

积分

金牌会员

积分
1340
金钱
1113
HASS币
0
发表于 3 天前 | 显示全部楼层
感谢分享
回复

使用道具 举报

14

主题

1671

回帖

5566

积分

论坛元老

积分
5566
金钱
3881
HASS币
0
发表于 3 天前 | 显示全部楼层
这过度动画好看
回复

使用道具 举报

1

主题

133

回帖

760

积分

高级会员

积分
760
金钱
626
HASS币
0
发表于 前天 17:29 | 显示全部楼层
谢谢分享
回复

使用道具 举报

2

主题

49

回帖

212

积分

中级会员

积分
212
金钱
161
HASS币
0
发表于 昨天 07:41 | 显示全部楼层
大佬厉害~~
回复

使用道具 举报

11

主题

110

回帖

1660

积分

金牌会员

积分
1660
金钱
1539
HASS币
0
发表于 昨天 10:41 | 显示全部楼层
试一试,多谢分享
回复

使用道具 举报

0

主题

25

回帖

196

积分

注册会员

积分
196
金钱
171
HASS币
0
发表于 昨天 11:18 | 显示全部楼层
dddddddddddd
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian ( 晋ICP备17001384号-1 )

GMT+8, 2025-10-30 21:56 , Processed in 0.065462 second(s), 14 queries , MemCached On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表