找回密碼
 立即註冊
惟家LINE群QRCODE
    查看: 3|回覆: 0

    用 card-mod 幫平面圖加動畫(不用換成 SVG)

    [複製鏈接]

    !lvup!   100%

    363

    主題

    27

    回帖

    2200萬

    積分

    管理員

    積分
    22005752
    發表於 3 天前 | 顯示全部樓層 |閱讀模式
    很多人以為要做動畫一定要用 SVG。

    其實Picture Elements 配 card-mod,就能做出不錯的動畫



    先裝 card-mod


    • HACS → 前端 → 搜尋 card-mod → 下載
    • 重新整理瀏覽器(Ctrl+F5)


    強烈建議:裝成「前端模組」而不是資源

    card-mod 有些功能裝成前端模組才會正常運作
    而且效能好很多。
    1. # configuration.yaml
    2. frontend:
    3.   extra_module_url:
    4.     - /hacsfiles/lovelace-card-mod/card-mod.js
    複製代碼

    改完重啟 HA,然後清瀏覽器快取。

    card-mod 是什麼

    一句話:讓你對任何卡片套用自己的 CSS。

    最基本的用法:
    1. type: picture-elements
    2. image: /local/floorplan/home.png
    3. card_mod:
    4.   style: |
    5.     ha-card {
    6.       border-radius: 16px;
    7.       box-shadow: 0 4px 16px rgba(0,0,0,0.12);
    8.     }
    9. elements:
    10.   - ...
    複製代碼

    重要限制:card-mod 只對有 `ha-card` 元素的卡片有效


    • 能用:picture-elements、tile、entities、button 等幾乎所有可見的卡片
    • 不能用:conditional、entity_filter、vertical-stack、horizontal-stack、grid


    那些「容器型」的卡片沒有自己的 ha-card
    但它們裡面包的卡片可以各自用 card-mod。



    動畫一:脈動(最常用)

    讓警報圖示一閃一閃的:
    1.   - type: conditional
    2.     conditions:
    3.       - entity: binary_sensor.kitchen_leak
    4.         state: "on"
    5.     elements:
    6.       - type: icon
    7.         icon: mdi:water-alert
    8.         style:
    9.           top: 44%
    10.           left: 72%
    11.           color: "#e53935"
    12.           "--mdc-icon-size": 36px
    13.           animation: pulse 1.2s infinite
    複製代碼

    然後在卡片層定義那個動畫:
    1. card_mod:
    2.   style: |
    3.     @keyframes pulse {
    4.       0%   { opacity: 1;   transform: translate(-50%, -50%) scale(1); }
    5.       50%  { opacity: 0.4; transform: translate(-50%, -50%) scale(1.25); }
    6.       100% { opacity: 1;   transform: translate(-50%, -50%) scale(1); }
    7.     }
    複製代碼

    這裡有一個非常重要的細節

    keyframes 裡的 transform 一定要包含 `translate(-50%, -50%)`。

    為什麼:Picture Elements 預設用 transform: translate(-50%, -50%)
    把元素置中在座標上。

    如果你的動畫只寫 transform: scale(1.25)
    它會覆蓋掉原本的置中,元素就會往右下角跳掉

    這是最多人踩的坑。

    動畫二:呼吸燈(柔和的明暗變化)
    1.         style:
    2.           animation: breathe 3s ease-in-out infinite
    複製代碼
    1. card_mod:
    2.   style: |
    3.     @keyframes breathe {
    4.       0%, 100% { opacity: 0.55; }
    5.       50%      { opacity: 1; }
    6.     }
    複製代碼

    適合:表示「正在運作中」,例如除濕機、洗衣機。

    比閃爍溫和很多,不會讓人煩躁。

    動畫三:旋轉(風扇、掃地機)
    1.   - type: state-icon
    2.     entity: fan.living_room
    3.     style:
    4.       top: 16%
    5.       left: 12%
    6.       animation: spin 2s linear infinite
    複製代碼
    1.     @keyframes spin {
    2.       from { transform: translate(-50%, -50%) rotate(0deg); }
    3.       to   { transform: translate(-50%, -50%) rotate(360deg); }
    4.     }
    複製代碼

    讓轉速對應實際風速
    1.       animation: >
    2.         spin {{ 4 - (state_attr('fan.living_room','percentage') | int(0) / 33) }}s
    3.         linear infinite
    複製代碼

    風速越快轉越快。這個小細節做出來很有趣。

    只在開著時才轉
    1.       animation: >
    2.         {% if is_state('fan.living_room','on') %}
    3.         spin 2s linear infinite
    4.         {% else %}
    5.         none
    6.         {% endif %}
    複製代碼



    動畫四:漸變(最實用,也最自然)

    這個不是 keyframes 動畫,而是 transition。

    差別


    • animation —— 一直重複播放(脈動、旋轉)
    • transition —— 狀態改變時,平滑地過渡


    transition 是做平面圖最該用的,因為它不吵
    1.   - type: image
    2.     entity: light.living_room
    3.     image: /local/floorplan/rooms/living_on.png
    4.     style:
    5.       top: 50%
    6.       left: 50%
    7.       width: 100%
    8.       transition: opacity 0.8s ease-in-out
    9.       opacity: >
    10.         {{ 1 if is_state('light.living_room','on') else 0 }}
    複製代碼

    燈開的時候房間會在 0.8 秒內慢慢亮起來,關的時候慢慢暗下去。

    這個效果做出來之後,整張平面圖的質感完全不一樣。

    再進一步:亮度也跟著漸變
    1.       opacity: >
    2.         {{ ((state_attr('light.living_room','brightness') | int(0)) / 255)
    3.            | round(2) }}
    複製代碼

    把燈調到 30%,平面圖上的房間也只有 30% 亮。

    完整範例

    把上面的東西組合起來:
    1. type: picture-elements
    2. image: /local/floorplan/home.png
    3. card_mod:
    4.   style: |
    5.     ha-card {
    6.       border-radius: 16px;
    7.       overflow: hidden;
    8.     }
    9.     @keyframes pulse {
    10.       0%   { opacity: 1;   transform: translate(-50%, -50%) scale(1); }
    11.       50%  { opacity: 0.4; transform: translate(-50%, -50%) scale(1.25); }
    12.       100% { opacity: 1;   transform: translate(-50%, -50%) scale(1); }
    13.     }
    14.     @keyframes spin {
    15.       from { transform: translate(-50%, -50%) rotate(0deg); }
    16.       to   { transform: translate(-50%, -50%) rotate(360deg); }
    17.     }
    18.     @keyframes breathe {
    19.       0%, 100% { opacity: 0.55; }
    20.       50%      { opacity: 1; }
    21.     }
    22. elements:
    23.   # --- 亮燈圖層(漸變)---
    24.   - type: image
    25.     entity: light.living_room
    26.     image: /local/floorplan/rooms/living_on.png
    27.     style:
    28.       top: 50%
    29.       left: 50%
    30.       width: 100%
    31.       transition: opacity 0.8s ease-in-out
    32.       opacity: >
    33.         {{ ((state_attr('light.living_room','brightness') | int(0)) / 255)
    34.            | round(2) }}
    35.     tap_action:
    36.       action: toggle
    37.   # --- 燈的圖示 ---
    38.   - type: state-icon
    39.     entity: light.living_room
    40.     style:
    41.       top: 24%
    42.       left: 22%
    43.       transition: color 0.5s
    44.     tap_action:
    45.       action: toggle
    46.     hold_action:
    47.       action: more-info
    48.   # --- 漏水警報(脈動)---
    49.   - type: conditional
    50.     conditions:
    51.       - entity: binary_sensor.kitchen_leak
    52.         state: "on"
    53.     elements:
    54.       - type: icon
    55.         icon: mdi:water-alert
    56.         style:
    57.           top: 44%
    58.           left: 72%
    59.           color: "#e53935"
    60.           "--mdc-icon-size": 36px
    61.           animation: pulse 1.2s infinite
    62.   # --- 風扇(旋轉)---
    63.   - type: state-icon
    64.     entity: fan.living_room
    65.     style:
    66.       top: 16%
    67.       left: 12%
    68.       animation: >
    69.         {% if is_state('fan.living_room','on') %}
    70.         spin 2s linear infinite
    71.         {% else %}
    72.         none
    73.         {% endif %}
    複製代碼



    動畫的五個原則(很重要)

    一、預設不要動

    一張一直在動的平面圖會讓人很煩。

    我的原則:


    • 常態 → transition(只在狀態改變時動一下)
    • 異常 → animation(持續動,吸引注意)


    二、transition 時間 0.3-0.8 秒


    • 太快(0.1s)→ 感覺不到
    • 太慢(2s)→ 覺得系統很鈍


    0.5 秒左右是最舒服的。

    三、同時動的東西不要超過兩個

    三個圖示同時在閃,眼睛不知道要看哪裡。

    四、動畫一定要有意義


    • 旋轉 → 表示「正在轉」(風扇、洗衣機)
    • 脈動 → 表示「需要注意」(警報)
    • 漸變 → 表示「狀態改變了」


    純粹為了好看的動畫,兩天後你就會想關掉。

    五、在手機上測試效能

    太多動畫會讓手機發燙、耗電。

    特別注意


    • animation 是持續消耗的(即使你沒在看那個頁面)
    • transition 只在改變時消耗,幾乎沒成本


    所以能用 transition 就不要用 animation。

    除錯:動畫沒作用怎麼辦


    • 圖示跳到右下角 → keyframes 少了 translate(-50%, -50%)
    • 完全沒動靜 → card-mod 沒裝好,或沒清瀏覽器快取
    • 範本沒生效 → style 裡的範本要用 > 區塊,不要用引號
    • 在電腦上正常、手機上不動 → 手機的省電模式可能會停用動畫


    ---

    下一篇:要不要升級到 SVG

    我會誠實講 SVG 好在哪、以及什麼情況下你根本不需要。
    您需要登入後纔可以回帖 登入 | 立即註冊

    本版積分規則

    Archiver|手機版|惟家的智能論壇

    GMT+8, 2026-9-24 12:21 , Processed in 0.078062 second(s), 24 queries .

    快速回覆 返回頂部 返回列表