Animation design

Bonjour

Je partage Mon p’tit délire avec un code pour certaines occasions (décembre, janvier, printemps, été) qui s’affiche sur ma tablette (automatiquement) pour animer et agrémenter un peu cette dernière.
Vous pouvez adapter les tailles, les postions, les couleurs, modifier les dates
d’activation etc…
Pour plus de simplicité, j’ai mis le code dans un fichier plugin html display et à intégrer
au design comme un équipement.

Là, évidement les flocons et noël
VID_20251228_084042

<style>
  /* Animations pour les éléments qui tombent */
  .falling {
    position: fixed;
    top: -60px;
    pointer-events: none;
    z-index: 9999;
    animation-name: fall, wind;
    animation-timing-function: linear, ease-in-out;
    animation-iteration-count: infinite;
  }

  /* Tailles et couleurs */
  .snowflake { color: #fff; font-size: 12px; }
  .santa { font-size: 40px; }
  .gift { font-size: 30px; }
  .champagne { font-size: 32px; }
  .galette { font-size: 34px; }
  .skieur { font-size: 36px; }
  .flower { font-size: 20px; }
  .egg { font-size: 30px; }
  .chicken { font-size: 36px; }
  .sun { font-size: 30px; }
  .sunflower { font-size: 36px; }

  @keyframes fall { from { transform: translateY(0); } to { transform: translateY(110vh); } }
  @keyframes wind { 0% { margin-left:0 } 50% { margin-left:50px } 100% { margin-left:0 } }

  /* Guirlande Noël réaliste avec fil mouvant */
  .garland-realistic {
    position: fixed;
    top: 25px;
    left: -35px;
    width: 100%;
    height: 60px;
    pointer-events: none;
    z-index: 9999;
  }

  @keyframes blink {
    0% { opacity:0.2 }
    50% { opacity:1 }
    100% { opacity:0.2 }
  }

  @keyframes sway {
    0% { transform: translateY(0px) }
    25% { transform: translateY(2px) }
    50% { transform: translateY(0px) }
    75% { transform: translateY(-2px) }
    100% { transform: translateY(0px) }
  }

  .garland-wire {
    animation: sway 3s ease-in-out infinite;
    transform-origin: top center;
  }
</style>

<script>
  const now = new Date();
  const month = now.getMonth();
  const day = now.getDate();

  function randomLeft() { return Math.random() * 95 + 'vw'; }
  function randomDuration(min, max) { return Math.random() * (max - min) + min; }

  function createElement(className, emoji, minDur, maxDur, count=1){
    for(let i=0;i<count;i++){
      const el = document.createElement('div');
      el.className = 'falling ' + className;
      el.innerHTML = emoji;
      el.style.left = randomLeft();
      el.style.fontSize = (Math.random()*20+8) + 'px';
      const duration = randomDuration(minDur,maxDur);
      el.style.animationDuration = duration+'s, '+randomDuration(5,9)+'s';
      document.body.appendChild(el);
      setTimeout(()=>el.remove(), duration*1000);
    }
  }

  // ❄️ Neige Décembre et Janvier
  if(month===11 || month===0){
    for(let i=0;i<50;i++){ createElement('snowflake','❄',30,50); }
    setInterval(()=>createElement('snowflake','❄',30,50), 500);

    // 🎄 Noël (Décembre)
    if(month===11){
      setInterval(()=>createElement('santa','🎅',35,55), 15000);
      setInterval(()=>createElement('santa','🎅',35,55,3), 70000);
      setInterval(()=>createElement('gift','🎁',25,40), 20000);

      // Guirlande réaliste avec fil ondulé et léger mouvement
      const container = document.createElement('div');
      container.className = 'garland-realistic';
      container.innerHTML = `
        <svg viewBox="0 0 1000 60" width="100%" height="60">
          <path class="garland-wire"
                d="M0,30 C150,0 300,60 450,30 C600,0 750,60 900,30 C1050,0 1200,60 1350,30"
                stroke="#222" stroke-width="3" fill="transparent"/>
          
          <circle cx="50" cy="30" r="6" fill="red" style="animation: blink 1.5s infinite alternate"/>
          <circle cx="150" cy="20" r="6" fill="yellow" style="animation: blink 1.5s infinite alternate 0.3s"/>
          <circle cx="250" cy="40" r="6" fill="green" style="animation: blink 1.5s infinite alternate 0.6s"/>
          <circle cx="350" cy="30" r="6" fill="blue" style="animation: blink 1.5s infinite alternate 0.9s"/>
          <circle cx="450" cy="35" r="6" fill="orange" style="animation: blink 1.5s infinite alternate 1.2s"/>
          <circle cx="550" cy="30" r="6" fill="red" style="animation: blink 1.5s infinite alternate 0.5s"/>
          <circle cx="650" cy="20" r="6" fill="yellow" style="animation: blink 1.5s infinite alternate 0.8s"/>
          <circle cx="750" cy="40" r="6" fill="green" style="animation: blink 1.5s infinite alternate 1.1s"/>
          <circle cx="850" cy="25" r="6" fill="blue" style="animation: blink 1.5s infinite alternate 1.4s"/>
          <circle cx="950" cy="35" r="6" fill="orange" style="animation: blink 1.5s infinite alternate 1.7s"/>
        </svg>
      `;
      document.body.appendChild(container);
    }

    // Janvier
    if(month===0){
      setInterval(()=>createElement('champagne','🍾',30,45), 15000);
      setInterval(()=>createElement('galette','👑🥧',35,55), 60000);
      setInterval(()=>createElement('skieur','⛷️',25,40), 15000);
    }
  }

  // 🐣 Pâques 3-10 avril
  if(month===3 && day>=3 && day<=10){
    for(let i=0;i<60;i++){ createElement('flower','🌸',25,40); }
    setInterval(()=>createElement('egg','🥚',25,40), 15000);
    setInterval(()=>createElement('chicken','🐔',25,40), 15000);
  }

  // 🌞 Été 21 juin → 6 juillet
  if((month===5 && day>=21) || (month===6 && day<=6)){
    for(let i=0;i<60;i++){ createElement('sun','🌞',25,40); }
    setInterval(()=>createElement('sunflower','🌻',25,40,3), 15000);
  }
</script>

Passez une bonne fin d’année

12 « J'aime »

merci pour ton partage

pour info, j’ai un message dans le centre de notification quand je vais sur le design sur lequel j’ai rajouter ton équipement

avec cette modif, c’est ok

<style>
  /* Animations pour les éléments qui tombent */
  .falling {
    position: fixed;
    top: -60px;
    pointer-events: none;
    z-index: 9999;
    animation-name: fall, wind;
    animation-timing-function: linear, ease-in-out;
    animation-iteration-count: infinite;
  }

  /* Tailles et couleurs */
  .snowflake { color: #fff; font-size: 12px; }
  .santa { font-size: 40px; }
  .gift { font-size: 30px; }
  .champagne { font-size: 32px; }
  .galette { font-size: 34px; }
  .skieur { font-size: 36px; }
  .flower { font-size: 20px; }
  .egg { font-size: 30px; }
  .chicken { font-size: 36px; }
  .sun { font-size: 30px; }
  .sunflower { font-size: 36px; }

  @keyframes fall { from { transform: translateY(0); } to { transform: translateY(110vh); } }
  @keyframes wind { 0% { margin-left:0 } 50% { margin-left:50px } 100% { margin-left:0 } }

  /* Guirlande Noël réaliste avec fil mouvant */
  .garland-realistic {
    position: fixed;
    top: 50px;
    left: -150px;
    width: 100%;
    height: 60px;
    pointer-events: none;
    z-index: 9999;
  }

  @keyframes blink {
    0% { opacity:0.2 }
    50% { opacity:1 }
    100% { opacity:0.2 }
  }

  @keyframes sway {
    0% { transform: translateY(0px) }
    25% { transform: translateY(2px) }
    50% { transform: translateY(0px) }
    75% { transform: translateY(-2px) }
    100% { transform: translateY(0px) }
  }

  .garland-wire {
    animation: sway 3s ease-in-out infinite;
    transform-origin: top center;
  }
</style>

<script>
{ // Début du bloc d'isolation
  const now = new Date();
  const month = now.getMonth();
  const day = now.getDate();

  function randomLeft() { return Math.random() * 95 + 'vw'; }
  function randomDuration(min, max) { return Math.random() * (max - min) + min; }

  function createElement(className, emoji, minDur, maxDur, count=1){
    for(let i=0;i<count;i++){
      const el = document.createElement('div');
      el.className = 'falling ' + className;
      el.innerHTML = emoji;
      el.style.left = randomLeft();
      el.style.fontSize = (Math.random()*20+8) + 'px';
      const duration = randomDuration(minDur,maxDur);
      el.style.animationDuration = duration+'s, '+randomDuration(5,9)+'s';
      document.body.appendChild(el);
      setTimeout(()=>el.remove(), duration*1000);
    }
  }

  // ❄️ Neige Décembre et Janvier
  if(month===11 || month===0){
    for(let i=0;i<50;i++){ createElement('snowflake','❄',30,50); }
    setInterval(()=>createElement('snowflake','❄',30,50), 500);

    // 🎄 Noël (Décembre)
    if(month===11){
      setInterval(()=>createElement('santa','🎅',35,55), 15000);
      setInterval(()=>createElement('santa','🎅',35,55,3), 70000);
      setInterval(()=>createElement('gift','🎁',25,40), 20000);

      const container = document.createElement('div');
      container.className = 'garland-realistic';
      container.innerHTML = `
        <svg viewBox="0 0 1000 60" width="100%" height="60">
          <path class="garland-wire"
                d="M0,30 C150,0 300,60 450,30 C600,0 750,60 900,30 C1050,0 1200,60 1350,30"
                stroke="#222" stroke-width="3" fill="transparent"/>
          
          <circle cx="50" cy="30" r="6" fill="red" style="animation: blink 1.5s infinite alternate"/>
          <circle cx="150" cy="20" r="6" fill="yellow" style="animation: blink 1.5s infinite alternate 0.3s"/>
          <circle cx="250" cy="40" r="6" fill="green" style="animation: blink 1.5s infinite alternate 0.6s"/>
          <circle cx="350" cy="30" r="6" fill="blue" style="animation: blink 1.5s infinite alternate 0.9s"/>
          <circle cx="450" cy="35" r="6" fill="orange" style="animation: blink 1.5s infinite alternate 1.2s"/>
          <circle cx="550" cy="30" r="6" fill="red" style="animation: blink 1.5s infinite alternate 0.5s"/>
          <circle cx="650" cy="20" r="6" fill="yellow" style="animation: blink 1.5s infinite alternate 0.8s"/>
          <circle cx="750" cy="40" r="6" fill="green" style="animation: blink 1.5s infinite alternate 1.1s"/>
          <circle cx="850" cy="25" r="6" fill="blue" style="animation: blink 1.5s infinite alternate 1.4s"/>
          <circle cx="950" cy="35" r="6" fill="orange" style="animation: blink 1.5s infinite alternate 1.7s"/>
        </svg>
      `;
      document.body.appendChild(container);
    }

    // Janvier
    if(month===0){
      setInterval(()=>createElement('champagne','🍾',30,45), 15000);
      setInterval(()=>createElement('galette','👑🥧',35,55), 60000);
      setInterval(()=>createElement('skieur','⛷️',25,40), 15000);
    }
  }

  // 🐣 Pâques
  if(month===3 && day>=3 && day<=10){
    for(let i=0;i<60;i++){ createElement('flower','🌸',25,40); }
    setInterval(()=>createElement('egg','🥚',25,40), 15000);
    setInterval(()=>createElement('chicken','🐔',25,40), 15000);
  }

  // 🌞 Été
  if((month===5 && day>=21) || (month===6 && day<=6)){
    for(let i=0;i<60;i++){ createElement('sun','🌞',25,40); }
    setInterval(()=>createElement('sunflower','🌻',25,40,3), 15000);
  }
} // Fin du bloc d'isolation
</script>

Bonjour

Normalement ce n’est qu’une info car si j’ai bon, je me suis aperçu que lors de la mis en place d’un code html, j’ai l’impression qu’il est pris en compte avant même qu’il ne soit validé ou sauvegardé, serai-ce lucky luke caché dans jeedom :smile:

Est-ce que c’est seulement au moment oú tu inserts l’équipement? Et après est-ce que tu as bien les objets en plus des flocons qui apparaissent? Je crois que oui car les vois sur ta capture d’écran.

Si oui pour moi c’est normal, cela me le fait à chaque équipement lié à un code html, mais une fois mis en place dans mon design l’erreur n’apparaît plus et il a même tendance à disparaitre
après rafraîchissement de la page.

Perso je suis en débian 12 v4.5.1, mais cela n’a pas d’impact.

Tiens moi au jus…

J’ai bien tous les objets qui apparaissent mais j’avais aussi le message dans le centre de notification jeedom a chaque fois que je retournerais sur le design
Je suis avec jeedom 11 et version 4.4.20

La notification est Dans quel log?

aucune idée
le message apparait dans le centre des messages jeedom avec un triangle
centre

Bonjour

J’ai revu un peu le code, de mon coté aucun défaut, juste au moment de sa mise en place dans le design.
Pour info via le PC avec firefox, sur la tablette avec fullykiosk et sur mon tél android avec brave.

<style>
  /* Animations pour les éléments qui tombent */
  .falling {
    position: absolute; /* Placer les éléments partout sur la page */
    top: -20px; /* Démarrer juste au-dessus de la page */
    pointer-events: none;
    z-index: 9999;
    animation-name: fall, wind;
    animation-timing-function: linear, ease-in-out;
    animation-iteration-count: infinite;
  }

  /* Tailles et couleurs */
  .snowflake { color: #ffff; font-size: 12px; }
  .santa { font-size: 40px; }
  .gift { font-size: 30px; }
  .champagne { font-size: 32px; }
  .galette { font-size: 34px; }
  .skieur { font-size: 36px; }
  .flower { font-size: 20px; }
  .egg { font-size: 30px; }
  .chicken { font-size: 36px; }
  .sun { font-size: 30px; }
  .sunflower { font-size: 36px; }

  @keyframes fall { from { transform: translateY(0); } to { transform: translateY(700px); } } /* Limite la largeur et hauteur de la chute à 700px (hauteur de la fenêtre) */
  @keyframes wind { 0% { margin-left: 0 } 50% { margin-left: 50px } 100% { margin-left: 0 } }

  /* Guirlande Noël réaliste avec fil mouvant */
  .garland-realistic {
    position: fixed;
    top: 25px;
    left: -35px;
    width: 100%;
    height: 60px;
    pointer-events: none;
    z-index: 9999;
  }

  @keyframes blink {
    0% { opacity: 0.2 }
    50% { opacity: 1 }
    100% { opacity: 0.2 }
  }

  @keyframes sway {
    0% { transform: translateY(0px) }
    25% { transform: translateY(2px) }
    50% { transform: translateY(0px) }
    75% { transform: translateY(-2px) }
    100% { transform: translateY(0px) }
  }

  .garland-wire {
    animation: sway 3s ease-in-out infinite;
    transform-origin: top center;
  }

  /* Animation pour le feu d'artifice */
  .firework {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background-color: rgba(255, 255, 0, 0.7);
    animation: fireworkAnimation 1s ease-out infinite;
    z-index: 9998;
  }

  @keyframes fireworkAnimation {
    0% {
      transform: scale(1) translate(0, 0);
      opacity: 1;
    }
    50% {
      transform: scale(3) translate(var(--randX), var(--randY));
      opacity: 0.7;
    }
    100% {
      transform: scale(5) translate(var(--randX), var(--randY));
      opacity: 0;
    }
  }
</style>

<script>
  const now = new Date();
  const month = now.getMonth();
  const day = now.getDate();

  // Fonction pour générer des positions aléatoires mais limitées à la zone de 1275x795px
  function randomLeft() { return Math.random() * 1200 + 'px'; }
  function randomTop() { return Math.random() * 460 + 'px'; } // Placer les éléments aléatoirement sur la hauteur
  function randomDuration(min, max) { return Math.random() * (max - min) + min; }

  function createElement(className, emoji, minDur, maxDur, count=1){
    for (let i = 0; i < count; i++) {
      const el = document.createElement('div');
      el.className = 'falling ' + className;
      el.innerHTML = emoji;
      
      // Positionner l'élément aléatoirement sur la page
      el.style.left = randomLeft();
      el.style.top = randomTop();  // Répartition aléatoire sur la hauteur
      el.style.fontSize = (Math.random() * 20 + 8) + 'px'; // Taille aléatoire des éléments
      
      const duration = randomDuration(minDur, maxDur);
      el.style.animationDuration = duration + 's, ' + randomDuration(5, 9) + 's'; // Durée de la chute

      document.body.appendChild(el);
      setTimeout(() => el.remove(), duration * 450); // Supprimer après que l'élément ait fini de tomber
    }
  }

  // Fonction pour afficher immédiatement tous les éléments de la saison
  function displaySeasonalElements() {
    // Neige pour décembre et janvier
    if (month === 11 || month === 0) {
      // Créer des flocons de neige immédiatement, mais en continu
      setInterval(() => createElement('snowflake', '❄', 30, 50, 2), 500);  // Fréquence accrue pour les flocons mais 2 flocons toutes les 500ms

      // 🎄 Noël (Décembre)
      if (month === 11) {
        // Créer plusieurs Père Noël à intervalles réguliers
        setInterval(() => createElement('santa', '🎅', 35, 55, 1), 6000);  // 2 Père Noël toutes les 500ms
        setInterval(() => createElement('gift', '🎁', 25, 40, 1), 7000);  // 2 cadeaux toutes les 600ms
        
        // Guirlande réaliste
        const container = document.createElement('div');
        container.className = 'garland-realistic';
        container.innerHTML = `
          <svg viewBox="0 0 1000 60" width="100%" height="60">
            <path class="garland-wire"
                  d="M0,30 C150,0 300,60 450,30 C600,0 750,60 900,30 C1050,0 1200,60 1350,30"
                  stroke="#222" stroke-width="3" fill="transparent"/>
            <circle cx="50" cy="30" r="6" fill="red" style="animation: blink 1.5s infinite alternate"/>
            <circle cx="150" cy="20" r="6" fill="yellow" style="animation: blink 1.5s infinite alternate 0.3s"/>
            <circle cx="250" cy="40" r="6" fill="green" style="animation: blink 1.5s infinite alternate 0.6s"/>
            <circle cx="350" cy="30" r="6" fill="blue" style="animation: blink 1.5s infinite alternate 0.9s"/>
            <circle cx="450" cy="35" r="6" fill="orange" style="animation: blink 1.5s infinite alternate 1.2s"/>
            <circle cx="550" cy="30" r="6" fill="red" style="animation: blink 1.5s infinite alternate 0.5s"/>
            <circle cx="650" cy="20" r="6" fill="yellow" style="animation: blink 1.5s infinite alternate 0.8s"/>
            <circle cx="750" cy="40" r="6" fill="green" style="animation: blink 1.5s infinite alternate 1.1s"/>
            <circle cx="850" cy="25" r="6" fill="blue" style="animation: blink 1.5s infinite alternate 1.4s"/>
            <circle cx="950" cy="35" r="6" fill="orange" style="animation: blink 1.5s infinite alternate 1.7s"/>
          </svg>
        `;
        document.body.appendChild(container);
      }

      // Janvier
      if (month === 0) {
        setInterval(() => createElement('champagne', '🍾', 30, 45, 1), 6000);  // 2 bouteilles de champagne toutes les 500ms
        setInterval(() => createElement('galette', '👑🥧', 35, 55, 1), 7000);  // 2 galettes toutes les 500ms
        setInterval(() => createElement('skieur', '⛷️', 25, 40, 1), 8000);  // 2 skieurs toutes les 500ms
      }

      // Feu d'artifice du 1er janvier
      if (month === 0 && day === 1) {
        setInterval(createFirework, 500); // Crée un feu d'artifice toutes les 500ms
      }
    }

    // Pâques (3-10 avril)
    if (month === 3 && day >= 3 && day <= 10) {
      // Créer des fleurs de printemps immédiatement, mais en continu
      setInterval(() => createElement('flower', '🌸', 25, 40, 2), 500);  // 2 fleurs toutes les 500ms
      setInterval(() => createElement('egg', '🥚', 25, 40, 1), 4000);  // 2 œufs toutes les 600ms
      setInterval(() => createElement('chicken', '🐔', 25, 40, 1), 5000);  // 1 poule toutes les 600ms
    }

    // Été (21 juin → 6 juillet)
    if ((month === 5 && day >= 21) || (month === 6 && day <= 6)) {
      // Créer des soleils et tournesols immédiatement et de manière continue
      setInterval(() => createElement('sun', '🌞', 25, 40, 2), 500);  // 2 soleils toutes les 500ms
      setInterval(() => createElement('sunflower', '🌻', 25, 40, 2), 4000);  // 2 tournesols toutes les 600ms
    }
  }

  // Fonction pour créer des feux d'artifice
  function createFirework() {
    const firework = document.createElement('div');
    firework.classList.add('firework');
    
    // Position aléatoire
    firework.style.left = `${Math.random() * window.innerWidth}px`;
    firework.style.top = `${Math.random() * window.innerHeight}px`;

    // Variations aléatoires dans la direction du feu d'artifice
    firework.style.setProperty('--randX', `${(Math.random() - 0.5) * 100}px`);
    firework.style.setProperty('--randY', `${(Math.random() - 0.5) * 100}px`);

    // Ajouter l'élément au body
    document.body.appendChild(firework);

    // Supprimer le feu d'artifice après l'animation
    setTimeout(() => firework.remove(), 1000);
  }

  // Affichage immédiat des éléments de la saison
  displaySeasonalElements();
</script>

Bonne journée et bonne année