Cuisine et Web

Recettes pour Cuisiniers ou Web Dev en herbes

Un diaporama en fondu. start/stop

Rédigé par G.Cyrille 2 commentaires 133 vue(s)
Classé dans : CSS, HTML, WebDev Mots clés : animation, slider, CSS var()

Un exemple de ce que l'on peut faire sans javascript en détournant l'usage habituel d'élément de formulaire pour que le visiteur puisse inter agir avec le diaporama en stoppant l'animation et afficher l'une des 3 images.

Voici un slider, relativement simple, de trois images qui passe de l'une à l'autre en fondu.

D'un côté une animation qui se déroule indéfiniment que l'on peut mettre en pause, et de l'autre, des inputs de type radio et leurs labels pour afficher telle ou telle image en stoppant l'animation.

MAJ en fin d'article: un exemple avec var() CSS pour faciliter l'ajout ou le retrait d'une image à ce diaporama.

Composé de 3 images nous auront une animation qui laissera visible l'image qu'un tiers du temps de l'animation. Il suffit alors de décaler le départ des animations aussi par un tiers de la durée la seconde et la deuxième de deux tiers, pour que les images s'affichent l'une après l'autre.

Pour stopper l'animation , on se sert d'un label et d'un pseudo pour afficher || ou > selon l'etat de l'input radio qui lui est lié.

Selon l'état de l'input, nous passerons la règle animation-play-state à running ou paused.

Pour afficher telle ou telle image, le principe est le même, en cliquant sur l'un des labels correspondant qui sont les points bleus sous l'image, l'animation est mise en paused et l'image correspondante affichée en avant plan.

Quelques ressources et les codes CSS et HTML sont visibles ci-dessous:

HTML

<div id="slidem">
    <input type="radio" id="img1" name="selection" >
    <input type="radio" id="img2" name="selection" >
    <input type="radio" id="img3" name="selection" >
    <input type="radio" id="go"   name="selection" >
    <input type="radio" id="stop" name="selection" >
    <div id="slider">
     <picture id="pic1">
      <img src="https://picsum.photos/id/1001/300/200">
     </picture>
     <picture id="pic2">
      <img src="https://picsum.photos/id/1004/300/200">
     </picture>
     <picture id="pic3">
      <img src="https://picsum.photos/id/1011/300/200">
     </picture>
    </div>
    <p>    
     <label for="img1"></label>
     <label for="img2"></label>    
     <label for="img3"></label> 
     <label for="go"  ></label>    
     <label for="stop"></label>    
    </p>
</div>

CSS

#slidem,#slider {
    width: 320px;
    margin: 1em auto;
    overflow: hidden;
    background: tomato;
    padding: 0.5em;
    box-shadow: 0 0 5px;
    }
input {
	position: absolute;
    left: -999px;
    }
#slider {
	position: relative;
    height: 200px;
    width:300px;
    white-space: nowrap;
    font-size: 0.01px;
    }
#slider img {
    position: absolute;
    z-index: 0;
    animation: slide 12s infinite;
    }
@keyframes slide {
    33%,
    66% {
        z-index: 0;
        opacity: 0;
    	}
    }
#pic1 img {
	animation-delay: 0s;
    }
#pic2 img {
    animation-delay: -4s;
    }
#pic3 img {
    animation-delay: -8s;
    }
#slidem p {
    text-align: center;
    position: relative;
    line-height: 0em;
    }
#slidem label[for^="img"] {
    border-radius: 50%;
    border: 1px solid;
    padding: 5px;
    font-size: 0.01px;
    margin: 0 5px;
    background: blue;
    box-shadow: inset 2px 2px 2px turquoise, 0 0 5px;
    }
#slidem label[for="go"],
#slidem label[for="stop"] {
	position: absolute;
    right: 1em;
    }
#slidem label[for="go"]:after {
	content: "\25B6";
    display: none;
	}
#slidem label[for="stop"]:after {
	content: "||";
    font-weight: bold;
    text-shadow: 1px 0 0, 2px 0 0, 0 0 5px;
    letter-spacing: 2px;
    }
#slidem :checked ~ #slider #pic1 img,
#slidem :checked ~ #slider #pic2 img,
#slidem :checked ~ #slider #pic3 img {
    animation-play-state: paused;
    }
#slidem :checked ~ p label[for="stop"]:after {
	display: none;
    }
#slidem :checked ~ p label[for="go"]:after,
#slidem #go:checked ~ p label[for="stop"]:after {
	display: block;
    }
#slidem #go:checked ~ p label[for="go"]:after {
	display: none;
    }
#slidem #img1:checked ~ #slider #pic1 img,
#slidem #img2:checked ~ #slider #pic2 img,
#slidem #img3:checked ~ #slider #pic3 img {
	z-index: 2 !important;
    opacity: 1 !important;
    transition: 0.5s;
    animation-play-state: paused;
    }
#slidem #go:checked ~ #slider img {
	animation-play-state: running;
    }
#slidem label {
	cursor: pointer;
    display: inline-block;
    }

Ajout 04/2021

Aller un peu plus loin avec les variables CSS

Ressource : var() CSS

Les variables CSS étaient proposées dés 2015 et sont aujourd'hui bien comprises par nos navigateurs, alors quels usages pourraient-elles avoir pour notre slider ?.

Ce slider vous intéresse, mais vous souhaitez plus de 3 images et la partie CSS gérant les animations n'est valable que pour 3 d'entre elles. Il vous semble probablement facile d'insérer une image de plus dans le code HTML, mais le côté animation vous inquiète.

Les variables CSS permettent de modifier ces valeurs automatiquement. En les regroupant dans la feuille de style pour ne pas avoir à rechercher un peu partout, une seule variable aura besoin d'être modifiée, celle contenant le nombre d'images. Si vous souhaitez changée la durée d'affichage des images, une seconde variable devra être modifiée.

Ces variables peuvent être utilisé avec calc() ce qui va permettre de mettre à jour plusieurs autres variables à partir d'une seule.

De la théorie...

html {
  --nbrImg :        4 ;
  --imgDuration :   3 ;
  --animDelay:      calc( var(--imgDuration) * 1s);
  --animDuration:   calc( var(--nbrImg) * var(--imgDuration) * 1s);
}
@keyframes slide {
  /* var(--animKeyframesa),
  var(--animeKeyframesb) */
  25%,
  50% {
    z-index: 0;
    opacity: 0;
  }
}
#pic1 img {
  animation-delay: 0s;
}
#pic2 img {
  animation-delay: calc(  var(--animDelay) * -1);
}
#pic3 img {
  animation-delay: calc(  var(--animDelay) * -2);
}
#pic4 img {
  animation-delay: calc(  var(--animDelay) * -3);
}

À la pratique.

  1. En reprenant la structure HTML, il faudra ajouter chaque nouvelle image dans son conteneur, l'input et le label qui lui sera destiné en incrémentant leur attribut id et for si l'on veut piloter l'animation manuellement
  2. Dans la feuille de style, il faudra mettre à jour la variable --nbrImg en indiquant le nombre d'image contenu dans le HTML de votre Slider revisité. La variable--imgDuration détermine la durée d'affichage de l'image, et les deux autres variables se calculeront toutes seules, n'y touchez plus. Il restera a mettre à jour les valeurs des 2 étapes entre lesquelles l'image est visible dans les @keyframes. Ici 100%/4images = 25%, les valeurs à reporter sont 25%, 50% {} et chaque image utilisera une part de 25% de temps d'affichage
  3. Il faudra aussi ajouter le selecteur pour cette nouvelle image et le delai, décalage d'affichage , ou X est le numéro de l'image et Y (X-1) le délais calculé:#picX img { animation-delay: calc( var(--animDelay) * -Y); }.

Pourquoi cette multiplication négative sur le délai de l'animation ?

Ce délais négatif permet d'avoir l'ensemble des animations déjà en cours, autrement, il faut attendre que le premier cycle se termine pour être fluide et sans défaut visuel.

Schéma du déroulé de l'animation

L'animation se comporte comme si elle avait débuté il y a déjà six secondes, l'effet de fondu entre les images est alors déjà présent et stabilisé.

Mise à jour en ligne

See the Pen basic CSS slider, select & click start/pause by gc-nomade (@gc-nomade) on CodePen.

C'est tout pour cette reprise.

Laisser un message.

Quelle est le deuxième caractère du mot ilw0m ?

2 commentaires

#1  - Daniel a dit :

Sympa l article!

Répondre
#2  - Chris a dit :

Merci, mais c'est compliqué. Est ce qu'il y a un moyen plus simple?

Répondre