Mushroom - Icones animés

marche pas, mais c’est dans une mushroom-template-card, ça viens peut-être de la?

je confirme, ton code dans une button fonctionne.

Quand je veux une animation je passe par

Je voudrais reproduire cela:

type: custom:mushroom-template-card
icon: mdi:light-flood-up
icon_color: '{{ ''red'' if is_state(entity, ''on'') else ''disabled'' }}'
primary: Light
secondary: ''
entity: light.lumiere_cuisine
tap_action:
  action: toggle
fill_container: true
layout: vertical
card_mod:
  style:
    mushroom-shape-icon$: |
      ha-icon {
        {{ '--icon-animation: rotation 1s linear infinite;' if is_state(config.entity, 'on') }}
        transform-origin: 29% 88%;
      }
      @keyframes clip {
        0% {
          clip-path: inset(50% 0 0 0);
        }
        100% {
          clip-path: inset(0 0 0 0);
        }
      }
      .shape {
        --shape-animation: ping 2s infinite;
      }
      @keyframes ping {
        0% {
          box-shadow: 0 0 0 0 rgba(var(--rgb-red), 0.7);
        }
        
        70% {
          box-shadow: 0 0 0 10px transparent;
        }
        
        100% {
          box-shadow: 0 0 0 0 transparent;
        }
      }

Animation1

1 « J'aime »

Ok, cela fonctionne.
Possible de changer aussi l’icone en fonction du state?
par exemple, mdi:lightbulb lorsque éteins et mdi:lightbulb-on quand allumé?

Comment animé une partie de l’icone comme sur l’exemple du signal ici ?

Merci de tes réponses en tout cas.

je sais pas , mais il faut buché un peu :rofl: :wink: dans le lien que tu mets

Ben j’ai bien essayé mais cela fonctionne pas, ou alors pas comme prévu MDR
Par exemple moi le signal j’ai juste un effet sur la partie shape mais l’icon lui bouge pas d’un poil ^^

type: custom:mushroom-template-card
icon: mdi:wifi
icon_color: green
primary: Réseau
layout: vertical
fill_container: true
card_mod:
  style:
    mushroom-shape-icon$: |
      ha-icon {
        --icon-animation: clip 2s steps(1) infinite;
      }
      @keyframes clip {
        0% { clip-path: circle(0% at 50% 85%); }
        20% { clip-path: circle(30% at 50% 85%); }
        40% { clip-path: circle(55% at 50% 85%); }
        60% { clip-path: circle(80% at 50% 85%); }
      }
      .shape {
        --shape-animation: ping 2s infinite;
      }
      @keyframes ping {
        60% { box-shadow: 0 0 0 0 rgba(var(--rgb-green), 0.7); }
        100% { box-shadow: 0 0 5px 15px transparent; }
      }

J’ai réussi avec ce code:

card_mod:
  style: |
    ha-state-icon {
      animation: clip 2s steps(1) infinite;
    }
    @keyframes clip {
      0% { clip-path: circle(0% at 50% 85%); }
      20% { clip-path: circle(30% at 50% 85%); }
      40% { clip-path: circle(55% at 50% 85%); }
      60% { clip-path: circle(80% at 50% 85%); }
    }
    mushroom-shape-icon {
      --icon-symbol-size: 0.80em;
      --icon-size: 90px;
    }
    :host {
      --mush-card-primary-font-size: 16px;
    }

Par contre j’aimerai faire une carte « Météo » avec l’icone qui change en fonction de la météo.
Voici ma carte:

type: custom:mushroom-template-card
icon: mdi:weather-partly-cloudy
icon_color: orange
primary: Météo
layout: vertical
fill_container: true
tap_action:
  action: call-service
  service: browser_mod.popup
  data:
    title: Météo
    content:
      type: custom:meteofrance-weather-card
      entity: weather.nersac
      number_of_forecasts: '5'
      rainChanceEntity: sensor.nersac_rain_chance
      uvEntity: sensor.nersac_uv
      cloudCoverEntity: sensor.nersac_cloud_cover
      snowChanceEntity: sensor.nersac_snow_chance
      rainForecastEntity: sensor.nersac_next_rain
      alertEntity: sensor.16_weather_alert
      style: |
        ha-card {
          background: #333333;
        }
  target: {}
card_mod:
  style: |
    ha-state-icon {
      animation: clip 5s steps(1) infinite;
    }
    @keyframes clip {
      0% { clip-path: circle(0% at 50% 85%); }
      20% { clip-path: circle(30% at 50% 85%); }
      40% { clip-path: circle(55% at 50% 85%); }
      60% { clip-path: circle(80% at 50% 85%); }
    }
    mushroom-shape-icon {
      --icon-symbol-size: 0.80em;
      --icon-size: 90px;
    }
    :host {
      --mush-card-primary-font-size: 16px;
    }

C’est possible?

Bonjour,
oui c’est possible, faut connaitre tout les états de la météo et adpater l’icone adéquat.

Exemple:

type: custom:mushroom-template-card
icon_color: blue
primary: Météo
layout: vertical
fill_container: true
icon: |
  {% if is_state('weather.xxxx', 'sunny') %}
    mdi:weather-sunny
  {% elif is_state('weather.xxxx', 'cloudy') %}
    mdi:weather-cloudy
  {% elif is_state('weather.xxxx', 'rainy') %}
    mdi:weather-rainy
  {% elif is_state('weather.xxxx', 'snowy') %}
    mdi:weather-snowy
  {% else %}
    mdi:weather-night
  {% endif %}

Merci, j’ai ajouté les différents états.

L’idée et d’ajouter en fonction de l’icone sa propre animation, c’est possible ça?
Dans le card-mod on peu définir une animation en fonction de l’icone ou sa sera toujours la même animation?

carte complète
type: custom:mushroom-template-card
icon: |
  {% if is_state('weather.nersac', 'clear-night') %}
    mdi:weather-night
  {% elif is_state('weather.nersac', 'cloudy') %}
    mdi:weather-sunny
  {% elif is_state('weather.nersac', 'exceptional') %}
    mdi:weather-
  {% elif is_state('weather.nersac', 'fog') %}
    mdi:weather-fog
  {% if is_state('weather.nersac', 'hail') %}
    mdi:weather-hail
  {% elif is_state('weather.nersac', 'lightning') %}
    mdi:weather-lightning
  {% elif is_state('weather.nersac', 'lightning-rainy') %}
    mdi:weather-lightning-rainy
  {% elif is_state('weather.nersac', 'partlycloudy') %}
    mdi:weather-partly-cloudy
  {% if is_state('weather.nersac', 'pouring') %}
    mdi:weather-pouring
  {% elif is_state('weather.nersac', 'rainy') %}
    mdi:weather-rainy
  {% elif is_state('weather.nersac', 'snowy') %}
    mdi:weather-snowy
  {% elif is_state('weather.nersac', 'snowy-rainy') %}
    mdi:weather-snowy-rainy
  {% if is_state('weather.nersac', 'sunny') %}
    mdi:weather-sunny
  {% elif is_state('weather.nersac', 'windy') %}
    mdi:weather-windy
  {% else %}
    mdi:weather-sunny-off
  {% endif %}
icon_color: deep-orange
primary: Météo
layout: vertical
fill_container: true
tap_action:
  action: call-service
  service: browser_mod.popup
  data:
    title: Météo
    content:
      type: custom:meteofrance-weather-card
      entity: weather.nersac
      number_of_forecasts: '5'
      rainChanceEntity: sensor.nersac_rain_chance
      uvEntity: sensor.nersac_uv
      cloudCoverEntity: sensor.nersac_cloud_cover
      snowChanceEntity: sensor.nersac_snow_chance
      rainForecastEntity: sensor.nersac_next_rain
      alertEntity: sensor.16_weather_alert
      style: |
        ha-card {
          background: #333333;
        }
  target: {}
card_mod:
  style: |
    mushroom-shape-icon {
      --icon-symbol-size: 0.80em;
      --icon-size: 90px;
    }
    :host {
      --mush-card-primary-font-size: 16px;
    }
    ha-state-icon {
      animation: cloudy 10s ease-in-out infinite, sun 2s infinite;
    }
    @keyframes cloudy {
      0%, 100% { transform: translateX(3px); }
      30% { transform: translateX(-1px); }
      45% { transform: translateX(1.5px); }
      75% { transform: translateX(-3.2px); }
    }
    @keyframes sun {
      50% { clip-path: polygon(0 67%, 18% 55%, 16% 31%, 41% 12%, 67% 24%, 77% 59%, 100% 64%, 100% 100%, 0 100%); }
    }

Pareille tu peu avoir une animation d’ifferent suivant l’état avec card_mod.

exemple, change l’animation que tu veut.:

    ha-state-icon {
      {% if is_state('weather.nersac', 'clear-night') %}
        animation: cloudy 10s ease-in-out infinite, sun 2s infinite;
      {% elif is_state('weather.nersac', 'cloudy') %}
        animation: cloudy 10s ease-in-out infinite, sun 2s infinite;
      {% else %}
        animation: cloudy 10s ease-in-out infinite, sun 2s infinite;
      {% endif %}     
    }

J’ai fait ça, je pense que c’est les indentation qui son pas bonnes, l’icone ne s’anime pas…

card_mod:
  style: |
    mushroom-shape-icon {
      --icon-symbol-size: 0.80em;
      --icon-size: 90px;
    }
    :host {
      --mush-card-primary-font-size: 16px;
    }
    ha-state-icon {
      {% if is_state('weather.nersac', 'clear-night') %}
        animation: moon 10s linear infinite, stars 5s linear infinite;
        }
        @keyframes moon {
          0%, 100% { transform: rotate(12deg); }
          30% { transform: rotate(-6deg); }
          45% { transform: rotate(8deg); }
          75% { transform: rotate(-10deg); }
        }
        @keyframes stars {
          0%, 3.1%, 14.1% { clip-path: inset(0 0 0 0); }
          3% { clip-path: polygon(1% 1%, 0% 99%, 99% 100%, 99% 62%, 68% 62%, 62% 44%, 76% 34%, 100% 34%, 99% 0%); }
          14% { clip-path: polygon(1% 1%, 0% 99%, 99% 100%, 100% 25%, 51% 45%, 38% 34%, 36% 0); }
        } 
      {% elif is_state('weather.nersac', 'cloudy') %}
        animation: cloudy 10s ease-in-out infinite;
        }
        @keyframes cloudy {
          0%, 100% { transform: translateX(3px); }
          30% { transform: translateX(-1px); }
          45% { transform: translateX(1.5px); }
          75% { transform: translateX(-3.2px); }
        }
      {% if is_state('weather.nersac', 'exceptional') %}
        animation: sunny 8s ease-in-out infinite alternate;
        }
        @keyframes sunny {
          70% { transform: rotate(360deg) scale(1); }
          80% { transform: scale(1); }
          90% { transform: scale(1.15); }
          100% { transform: scale(1); }
        }
      {% elif is_state('weather.nersac', 'fog') %}
        animation: cloudy 10s ease-in-out infinite, fog 4s infinite; 
        }
        @keyframes cloudy {
          0%, 100% { transform: translateX(3px); }
          30% { transform: translateX(-1px); }
          45% { transform: translateX(1.5px); }
          75% { transform: translateX(-3.2px); }
        }
        @keyframes fog {
          0%, 26%, 76%, 100% { clip-path: inset(0 0 0 0); }
          25% { clip-path: polygon(0 0, 100% 0, 100% 59%, 60% 59%, 60% 74%, 100% 74%, 100% 100%, 0 100%); }
          75%  { clip-path: polygon(0 0, 100% 0, 100% 100%, 26% 100%, 26% 76%, 0 76%); }
        }
      {% if is_state('weather.nersac', 'hail') %}
        animation: cloudy 10s ease-in-out infinite, hail 2s infinite; 
        }
        @keyframes cloudy {
          0%, 100% { transform: translateX(3px); }
          30% { transform: translateX(-1px); }
          45% { transform: translateX(1.5px); }
          75% { transform: translateX(-3.2px); }
        }
        @keyframes hail {
          0%, 26%, 51%, 76%, 100% { clip-path: inset(0 0 0 0); }
          25% { clip-path: polygon(0 0, 100% 0, 100% 100%, 62% 100%, 47% 69%, 56% 55%, 43% 43%, 31% 58%, 48% 68%, 63% 100%, 0 100%); }
          50%  { clip-path: polygon(0 0, 100% 0, 100% 100%, 62% 100%, 61% 86%, 74% 74%, 61% 60%, 46% 69%, 60% 87%, 63% 100%, 0 100%); }
          75%  { clip-path: polygon(0 0, 100% 0, 100% 100%, 47% 100%, 56% 83%, 42% 68%, 27% 81%, 37% 100%, 0 100%); }
        }
      {% elif is_state('weather.nersac', 'lightning') %}
        animation: cloudy 10s ease-in-out infinite, lightning 4s infinite; 
        }
        @keyframes cloudy {
          0%, 100% { transform: translateX(3px); }
          30% { transform: translateX(-1px); }
          45% { transform: translateX(1.5px); }
          75% { transform: translateX(-3.2px); }
        }
        @keyframes lightning {
          10%, 15% { clip-path: polygon(0 0, 100% 0, 100% 100%, 47% 100%, 69% 55%, 66% 40%, 48% 39%, 24% 100%, 0 100%); transform: scale(1.1); }
          10.1%, 15.1% { clip-path: inset(0 0 0 0); transform: scale(1); }
        }
      {% elif is_state('weather.nersac', 'partlycloudy') %}
        animation: cloudy 10s ease-in-out infinite, sun 2s infinite;
        }
        @keyframes cloudy {
          0%, 100% { transform: translateX(3px); }
          30% { transform: translateX(-1px); }
          45% { transform: translateX(1.5px); }
          75% { transform: translateX(-3.2px); }
        }
        @keyframes sun {
          50% { clip-path: polygon(0 67%, 18% 55%, 16% 31%, 41% 12%, 67% 24%, 77% 59%, 100% 64%, 100% 100%, 0 100%); }
        }
      {% if is_state('weather.nersac', 'pouring') %}
        animation: cloudy 10s ease-in-out infinite, rain 1s infinite; 
        }
        @keyframes cloudy {
          0%, 100% { transform: translateX(3px); }
          30% { transform: translateX(-1px); }
          45% { transform: translateX(1.5px); }
          75% { transform: translateX(-3.2px); }
        }
        @keyframes rain {
          0%, 50%, 100% { clip-path: inset(0 0 0 0); }
          25% { clip-path: polygon(0 0, 100% 0, 100% 83%, 54% 83%, 62% 47%, 47% 46%, 38% 83%, 0 83%); }
          75%  { clip-path: polygon(0 0, 100% 0, 100% 70%, 75% 70%, 80% 48%, 63% 48%, 54% 94%, 32% 94%, 46% 46%, 30% 46%, 23% 72%, 0 72%); }
        }
      {% elif is_state('weather.nersac', 'rainy') %}
        animation: cloudy 10s ease-in-out infinite, rain 1.5s infinite; 
        }
        @keyframes cloudy {
          0%, 100% { transform: translateX(3px); }
          30% { transform: translateX(-1px); }
          45% { transform: translateX(1.5px); }
          75% { transform: translateX(-3.2px); }
        }
        @keyframes rain {
          50% { clip-path: polygon(0 0, 100% 0, 100% 73%, 71% 73%, 50% 39%, 29% 73%, 0 73%); }
        }
      {% if is_state('weather.nersac', 'snowy') %}
        animation: cloudy 10s ease-in-out infinite, snow 4s infinite; 
        }
        @keyframes cloudy {
          0%, 100% { transform: translateX(3px); }
          30% { transform: translateX(-1px); }
          45% { transform: translateX(1.5px); }
          75% { transform: translateX(-3.2px); }
        }
        @keyframes snow {
          50% { clip-path: polygon(0 0, 100% 0, 100% 100%, 65% 100%, 76% 73%, 57% 49%, 34% 56%, 26% 79%, 37% 100%, 0 100%); }
          51% { clip-path: inset(0 0 0 0); }
        }
      {% if is_state('weather.nersac', 'sunny') %}
        animation: sunny 8s ease-in-out infinite alternate;
        }
        @keyframes sunny {
          70% { transform: rotate(360deg) scale(1); }
          80% { transform: scale(1); }
          90% { transform: scale(1.15); }
          100% { transform: scale(1); }
        }
      {% elif is_state('weather.nersac', 'windy') %}
        animation: cloudy 10s ease-in-out infinite; 
        transform-origin: 15% 50%
        }
        @keyframes cloudy {
          0%, 100% { transform: scaleX(1.2); }
          30% { transform: scaleX(0.9); }
          45% { transform: scaleX(1.1); }
          75% { transform: scaleX(0.8); }
        }
      {% else %}
        animation: cloudy 10s ease-in-out infinite, sun 2s infinite;
      {% endif %}     
    }

Ca serait plutot comme ca:

card_mod:
  style: |
    mushroom-shape-icon {
      --icon-symbol-size: 0.80em;
      --icon-size: 90px;
    }
    :host {
      --mush-card-primary-font-size: 16px;
    }
    ha-state-icon {
      {% if is_state('weather.nersac', 'clear-night') %}
        animation: moon 10s linear infinite;
      {% elif is_state('weather.nersac', 'cloudy') %}
        animation: cloudy 10s ease-in-out infinite;
      {% else %}
        animation: sun 2s infinite;
      {% endif %}		
    }
    @keyframes moon {
      0%, 100% { transform: rotate(12deg); }
      30% { transform: rotate(-6deg); }
      45% { transform: rotate(8deg); }
      75% { transform: rotate(-10deg); }
    }
    @keyframes cloudy {
      0%, 100% { transform: translateX(3px); }
      30% { transform: translateX(-1px); }
      45% { transform: translateX(1.5px); }
      75% { transform: translateX(-3.2px); }
    }
    @keyframes sun {
      50% { clip-path: polygon(0 67%, 18% 55%, 16% 31%, 41% 12%, 67% 24%, 77% 59%, 100% 64%, 100% 100%, 0 100%); }
    }

C’est ça merci.
Par contre ça pose pas de soucis que plusieurs keyframes est le même nom?

    @keyframes moon {
      0%, 100% { transform: rotate(12deg); }
      30% { transform: rotate(-6deg); }
      45% { transform: rotate(8deg); }
      75% { transform: rotate(-10deg); }
    }
    @keyframes cloudy {
      0%, 100% { transform: translateX(3px); }
      30% { transform: translateX(-1px); }
      45% { transform: translateX(1.5px); }
      75% { transform: translateX(-3.2px); }
    }
    @keyframes sun {
      50% { clip-path: polygon(0 67%, 18% 55%, 16% 31%, 41% 12%, 67% 24%, 77% 59%, 100% 64%, 100% 100%, 0 100%); }
    }
    @keyframes stars {
      0%, 3.1%, 14.1% { clip-path: inset(0 0 0 0); }
      3% { clip-path: polygon(1% 1%, 0% 99%, 99% 100%, 99% 62%, 68% 62%, 62% 44%, 76% 34%, 100% 34%, 99% 0%); }
      14% { clip-path: polygon(1% 1%, 0% 99%, 99% 100%, 100% 25%, 51% 45%, 38% 34%, 36% 0); }
    } 
    @keyframes sunny {
      70% { transform: rotate(360deg) scale(1); }
      80% { transform: scale(1); }
      90% { transform: scale(1.15); }
      100% { transform: scale(1); }
    }
    @keyframes fog {
      0%, 26%, 76%, 100% { clip-path: inset(0 0 0 0); }
      25% { clip-path: polygon(0 0, 100% 0, 100% 59%, 60% 59%, 60% 74%, 100% 74%, 100% 100%, 0 100%); }
      75%  { clip-path: polygon(0 0, 100% 0, 100% 100%, 26% 100%, 26% 76%, 0 76%); }
    }
    @keyframes hail {
      0%, 26%, 51%, 76%, 100% { clip-path: inset(0 0 0 0); }
      25% { clip-path: polygon(0 0, 100% 0, 100% 100%, 62% 100%, 47% 69%, 56% 55%, 43% 43%, 31% 58%, 48% 68%, 63% 100%, 0 100%); }
      50%  { clip-path: polygon(0 0, 100% 0, 100% 100%, 62% 100%, 61% 86%, 74% 74%, 61% 60%, 46% 69%, 60% 87%, 63% 100%, 0 100%); }
      75%  { clip-path: polygon(0 0, 100% 0, 100% 100%, 47% 100%, 56% 83%, 42% 68%, 27% 81%, 37% 100%, 0 100%); }
    }
    @keyframes lightning {
      10%, 15% { clip-path: polygon(0 0, 100% 0, 100% 100%, 47% 100%, 69% 55%, 66% 40%, 48% 39%, 24% 100%, 0 100%); transform: scale(1.1); }
      10.1%, 15.1% { clip-path: inset(0 0 0 0); transform: scale(1); }
    }
    @keyframes rain {
      0%, 50%, 100% { clip-path: inset(0 0 0 0); }
      25% { clip-path: polygon(0 0, 100% 0, 100% 83%, 54% 83%, 62% 47%, 47% 46%, 38% 83%, 0 83%); }
      75%  { clip-path: polygon(0 0, 100% 0, 100% 70%, 75% 70%, 80% 48%, 63% 48%, 54% 94%, 32% 94%, 46% 46%, 30% 46%, 23% 72%, 0 72%); }
    }
    @keyframes rain {
      50% { clip-path: polygon(0 0, 100% 0, 100% 73%, 71% 73%, 50% 39%, 29% 73%, 0 73%); }
    }
    @keyframes snow {
      50% { clip-path: polygon(0 0, 100% 0, 100% 100%, 65% 100%, 76% 73%, 57% 49%, 34% 56%, 26% 79%, 37% 100%, 0 100%); }
      51% { clip-path: inset(0 0 0 0); }
    }
    @keyframes cloudy {
      0%, 100% { transform: scaleX(1.2); }
      30% { transform: scaleX(0.9); }
      45% { transform: scaleX(1.1); }
      75% { transform: scaleX(0.8); }
    }

A mon avis si , ça va poser problème. Pourquoi le même nom, mets un nom différent.

comment je le fait correspondre a l’icone a animer?

moon est le nom du keyframe, change juste le nom du keyframe dans la ligne animation pour avoir l’effet souhaiter

Yes, compris, j’ai corrigé ça devrait le faire, merci beaucoup!

Tant que je t’es tu saurais surement comment animé l’icone du thermomètre, j’ai bricolé ça:

card_mod:
  style: |
    ha-card:active {
      transform: scale(0.975);
      transition: 0s;
    }
    :host {
      --mush-card-primary-font-size: 16px;
    }
    mushroom-shape-icon {
      --icon-symbol-size: 0.80em;
      --icon-size: 90px;
    }
    ha-state-icon {
      animation: charge 3s linear infinite;
    }
    @keyframes charge {
      0%, 80% { clip-path: inset(0 0 0 0); }
      10% { clip-path: polygon(0% 0%, 0% 100%, 34% 100%, 34% 24%, 67% 24%, 67% 84%, 34% 84%, 34% 100%, 100% 100%, 100% 0%); }
      20% { clip-path: polygon(0% 0%, 0% 100%, 34% 100%, 34% 24%, 67% 24%, 67% 74%, 34% 74%, 34% 100%, 100% 100%, 100% 0%); }
      30% { clip-path: polygon(0% 0%, 0% 100%, 34% 100%, 34% 24%, 67% 24%, 67% 64%, 34% 64%, 34% 100%, 100% 100%, 100% 0%); }
      40% { clip-path: polygon(0% 0%, 0% 100%, 34% 100%, 34% 24%, 67% 24%, 67% 54%, 34% 54%, 34% 100%, 100% 100%, 100% 0%); }
      50% { clip-path: polygon(0% 0%, 0% 100%, 34% 100%, 34% 24%, 67% 24%, 67% 44%, 34% 44%, 34% 100%, 100% 100%, 100% 0%); }
      60% { clip-path: polygon(0% 0%, 0% 100%, 34% 100%, 34% 24%, 67% 24%, 67% 34%, 34% 34%, 34% 100%, 100% 100%, 100% 0%); }
      70% { clip-path: polygon(0% 0%, 0% 100%, 34% 100%, 34% 24%, 67% 24%, 67% 24%, 34% 24%, 34% 100%, 100% 100%, 100% 0%); }
    }

Mais du coup, la partie qui monte est beaucoup trop grosse, je trouve pas ou réduire dans le keyframes…
image

Désoler, mais mets connaissance on des limites :wink:
Je suis pas un pro de l’animation, je n’utilise que pulse et blink.
Un autre utilisateur pourra t’aider.

1 « J'aime »