CSS révéler de coin animation
J'essaie d'obtenir un effet d'animation comme suit:
Lorsqu'une bannière est affichée, le coin inférieur droit de la bannière suivante doit être visible. Lorsque vous cliquez sur ce coin, il doit masquer la bannière actuelle et révéler la suivante.
Mon balisage actuel est le suivant:
<div class="banners">
<div class="image active" style="background-color: red;">
<div class="corner"></div>
</div>
<div class="image" style="background-color: blue;">
<div class="corner"></div>
</div>
</div>
CSS comme suit: Notez que j'ai utilisé clip-path
pour créer le coin:
.banners {
width: 800px;
height: 600px;
}
.image {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
}
.image.active {
z-index: 1;
clip-path: polygon(100% 0, 100% 65%, 60% 100%, 0 100%, 0 0);
}
.corner {
width: 50%;
height: 50%;
position: absolute;
right: 0;
bottom: 0;
}
JS:
$(document).ready(function () {
$('.corner').click(function() {
$('.image.active').removeClass('active');
$(this).parent().addClass('active');
});
});
Voici un JSFiddle de tout le code ci-dessus: https://jsfiddle.net/cqqxjjgu/
Un problème immédiat avec ceci est que parce que j'utilise z-index
pour spécifier que la bannière 'active' actuelle devrait avoir la priorité, quand supprimer la classe active
Il affiche juste la bannière suivante immédiatement, donc idéalement le z-index
ne devrait être changé qu'une fois l'animation terminée.
Quelqu'un a-t-il une idée de comment je peux réaliser cela? Idéalement, j'ai besoin d'une solution de navigateur croisé (pas trop agité à propos D'IE
5 réponses
Un exemple simple accomplissant cet effet sans javascript:
https://jsfiddle.net/freer4/j2159b1e/2/
html, body{
height:100%;
width:100%;
margin:0;
padding:0;
}
.banners {
position:relative;
background:#000;
width: 100%;
height: 100%;
overflow:hidden;
}
.banners input{
display:none;
}
.slide1{
background-image: url(https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT5T6nwVYWsbzLcLF-JNxnGXFFFwkZMBcCMbaqeTevuldkxHg0N);
}
.slide2{
background-image:url(http://www.rd.com/wp-content/uploads/sites/2/2016/02/06-train-cat-shake-hands.jpg);
}
.slide3{
background-image:url(https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTKr6YlGNsqgJzvgBBkq1648_HsuDizVn_ZXC6iQp9kjXFzLvs1BA);
}
.image {
display:block;
height:100%;
width:100%;
position: absolute;
overflow:hidden;
z-index:1;
text-align:center;
background-position:0 0;
background-size:cover;
transition:z-index 1s step-end;
clip-path: polygon(100% 0, 100% 100%, 100% 100%, 0 100%, 0 0);
animation-duration: 2s;
animation-name: clipout;
}
input:checked + .image{
z-index:3;
transition:z-index 1s step-end;
clip-path: polygon(100% 0, 100% 50%, 50% 100%, 0 100%, 0 0);
animation-duration: 2.2s;
animation-name: clipin;
cursor:default;
}
.image:nth-child(2),
input:checked + * + * + .image{
z-index:2;
cursor:pointer;
}
.content{
color:#FFF;
display:inline-block;
vertical-align:middle;
font-family:arial;
text-transform:uppercase;
font-size:24px;
opacity:0;
transition:0s opacity 1s;
}
input:checked + .image .content{
opacity:1;
transition:0.8s opacity 0.8s;
}
.spanner{
vertical-align:middle;
width:0;
height:100%;
display:inline-block;
}
@keyframes clipout {
from { clip-path: polygon(100% 0, 100% 50%, 50% 100%, 0 100%, 0 0); }
50% { clip-path: polygon(100% 0, 100% -100%, -100% 100%, 0 100%, 0 0); }
51% { clip-path: polygon(100% 0, 100% 100%, 100% 100%, 0 100%, 0 0); }
to { clip-path: polygon(100% 0, 100% 100%, 100% 100%, 0 100%, 0 0); }
}
@keyframes clipin{
from { clip-path: polygon(100% 0, 100% 100%, 100% 100%, 0 100%, 0 0); }
50% { clip-path: polygon(100% 0, 100% 100%, 100% 100%, 0 100%, 0 0); }
to { clip-path: polygon(100% 0, 100% 50%, 50% 100%, 0 100%, 0 0); }
}
<div class="banners">
<input type="radio" id="slide1" name="slides" checked="checked" />
<label class="image slide1" for="slide1">
<div class="content">
Slide 1
</div>
<div class="spanner"></div>
</label>
<input type="radio" id="slide2" name="slides" />
<label class="image slide2" for="slide2">
<div class="content">
Slide 2
</div>
<div class="spanner"></div>
</label>
<input type="radio" id="slide3" name="slides" />
<label class="image slide3" for="slide3">
<div class="content">
Slide 3
</div>
<div class="spanner"></div>
</label>
</div>
Fondamentalement, il suffit d'utiliser des images clés pour animer le chemin du clip. Obtenez fantaisie avec les z-index et quelques sélecteurs frères et sœurs.
Cela devrait fonctionner pour n'importe quel navigateur avec le support de transition: https://jsfiddle.net/freer4/cqqxjjgu/1/
Essentiellement, faites une diapositive de couverture vraiment grande, avec la même couleur d'arrière-plan que votre diapositive suivante, et tirez-la sur votre diapositive actuelle. Puis fondu pour révéler la diapositive suivante.
Donc un petit ajustement sur le html:
<div class="banners">
<div class="image active" style="background-color: black;">
<div class="content">
Slide 1
</div>
<div class="spanner"></div>
<div class="corner" style="background-color: cyan;"></div>
</div>
<div class="image" style="background-color: cyan;">
<div class="content">
Slide 2
</div>
<div class="spanner"></div>
<div class="corner" style="background-color: magenta;"></div>
</div>
<div class="image" style="background-color: magenta;">
<div class="content">
Slide 3
</div>
<div class="spanner"></div>
<div class="corner" style="background-color: black;"></div>
</div>
</div>
Modifiez le jQuery pour sélectionner la diapositive suivante ou la première s'il n'y en a plus:
$(document).ready(function () {
$('.corner').click(function() {
var $parent = $(this).parent();
$parent.removeClass("active");
if ($parent.next().length){
$parent.next().addClass("active");
} else {
$parent.prevAll().last().addClass("active");
}
});
});
Et mettre en place un peu complexe transitions vous pouvez ajuster la synchronisation de:
.image {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
overflow:hidden;
z-index:1;
transition:z-index 2s step-end, 1s opacity 1s ease-in-out;
text-align:center;
opacity:0;
}
.image.active{
opacity:1;
z-index:2;
transition:z-index 2s step-end, 0s opacity 0s;
}
.corner {
width: 200%;
height: 200%;
position: absolute;
top: -100%;
left: -100%;
clip-path: polygon(100% 0, 0 70%, 0 100%, 100% 100%, 100% 0, 100% 0);
z-index:3;
margin-left:150%;
margin-top:150%;
transition:2s top ease-in-out, 2s left ease-in-out, 0s margin 2s;
}
.image.active .corner{
top:0;
left:0;
margin-top:0;
margin-left:0;
transition:0s top ease-in-out 1s, 0s left ease-in-out 1s, 2s margin ease-in-out 1s;
}
Mis à part: cet exemple est complètement flexible (ne se soucie pas de la taille):
.banners {
width: 100%;
height: 100%;
}
Ou avec des images: https://jsfiddle.net/freer4/ens7caaL/
C'est une réponse sans l'utilisation de clip-path
, parce que compatibilité du navigateur sur les éléments DOM autres que svg
est faible.
Je vois maintenant que Vadim avait la même idée que moi avec le conteneur tourné (je n'avais pas vérifié ici avant d'avoir terminé), mais d'après ce que je peux dire, il y a encore assez de différences entre nos réponses pour justifier l'affichage de ma solution:
$(document).ready(function() {
$(".slider").on("click",".next",function() {
if ($(this).prev().length) {$(this).prev().removeClass("curr");} else {$(this).siblings().last().removeClass("curr");} //deactivate current slide
if ($(this).next().length) {$(this).next().addClass("next");} else {$(this).siblings().first().addClass("next");} //prepare slide that follows next slide
$(this).removeClass("next").addClass("curr"); //activate next slide
});
});
.slider, .slider .img {
width: 55vw;
height: calc(55vw / 16*9);
background: #000 center/contain no-repeat;
}
.slider {position:relative; margin:0 auto; overflow:hidden;}
.slider .slide {
position: absolute;
z-index: 0;
width: 250%;
height: 0;
transform: translateX(-50%) rotate(-20deg);
transform-origin: 50% 0;
transition:z-index 0s 0.7s, height 0.7s;
overflow: hidden;
}
.slider .slide.next {z-index:1; height:155%; opacity:0.5; transition:z-index 0s 1.1s, height 0s 0.7s; cursor:pointer;}
.slider .slide.curr {z-index:2; height:135%; opacity:1.0; transition:z-index 0s 1.1s, height 0.4s 0.7s, opacity 0.7s;}
.slider .slide .img {margin-left:50%; transform:rotate(20deg); transform-origin:0 0;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="slider">
<div class="slide curr"><div class="img" style="background-image:url(https://placeimg.com/640/480/animals);"></div></div>
<div class="slide next"><div class="img" style="background-image:url(https://placeimg.com/640/480/people);"></div></div>
<div class="slide"><div class="img" style="background-image:url(https://placeimg.com/640/480/nature);"></div></div>
<div class="slide"><div class="img" style="background-image:url(https://placeimg.com/640/480/tech);"></div></div>
<div class="slide"><div class="img" style="background-image:url(https://placeimg.com/640/480/arch);"></div></div>
</div>
codepen: https://codepen.io/anon/pen/JJQRvMjsfiddle: https://jsfiddle.net/tq2hw7b9/5/
- au lieu de
clip-path
je change simplement leheight
des conteneurs de diapositives, en utilisanttransition
pour les effets d'animation.
IE TROUBLES
Malheureusement, comme d'habitude, c'est à dire des processus transform:rotate()
différemment des autres navigateurs. Visuellement, les rotations se produisent, mais le navigateur semble toujours réserver l'espace d'origine des éléments, donc par conséquent, le coin exposé de la diapositive suivante est non cliquable parce que la diapositive actuelle la "recouvre". L'utilisation du préfixe -ms-
ou -webkit-
ne fait pas de différence.
L'extrait de code suivant Fonctionne dans IE:
$(document).ready(function() {
$(".slider .corner").on("click",function() {
var $next = $(this).siblings(".next");
if ($next.prev().length) {$next.prev().removeClass("curr");} else {$next.siblings(".slide").last().removeClass("curr");} //deactivate current slide
if ($next.next(".slide").length) {$next.next().addClass("next");} else {$next.siblings().first().addClass("next");} //prepare slide that follows next slide
$next.removeClass("next").addClass("curr"); //activate next slide
});
});
.slider, .slider .img {
width: 55vw;
height: calc(55vw / 16*9);
background: #000 center/contain no-repeat;
}
.slider {position:relative; margin:0 auto; overflow:hidden;}
.slider .corner {
position: absolute;
z-index: 3;
bottom: 0;
right: 0;
width: 100%;
height: 21%;
transform: rotate(-20deg);
transform-origin: 100% 0;
cursor: pointer;
}
.slider .slide {
position: absolute;
z-index: 0;
width: 250%;
height: 0;
transform: translateX(-50%) rotate(-20deg);
transform-origin: 50% 0;
transition:z-index 0s 0.7s, height 0.7s;
overflow: hidden;
}
.slider .slide.next {z-index:1; height:155%; opacity:0.5; transition:z-index 0s 1.1s, height 0s 0.7s;}
.slider .slide.curr {z-index:2; height:135%; opacity:1.0; transition:z-index 0s 1.1s, height 0.4s 0.7s, opacity 0.7s;}
.slider .slide .img {margin-left:50%; transform:rotate(20deg); transform-origin:0 0;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="slider">
<div class="slide curr"><div class="img" style="background-image:url(https://placeimg.com/640/480/animals);"></div></div>
<div class="slide next"><div class="img" style="background-image:url(https://placeimg.com/640/480/people);"></div></div>
<div class="slide"><div class="img" style="background-image:url(https://placeimg.com/640/480/nature);"></div></div>
<div class="slide"><div class="img" style="background-image:url(https://placeimg.com/640/480/tech);"></div></div>
<div class="slide"><div class="img" style="background-image:url(https://placeimg.com/640/480/arch);"></div></div>
<div class="corner"></div>
</div>
codepen: https://codepen.io/anon/pen/GEbrzQjsfiddle: https://jsfiddle.net/8ggqndj1/
- j'ai ajouté un
<div class="corner">
supplémentaire qui couvre tous les diapositive. - le gestionnaire de clics dans JS est maintenant lié à ce
.corner
, et au début du Gestionnaire une référence à la diapositive suivante est stockée dans une variable, qui est utilisée dans le reste du code. - en CSS, Il y a aussi une nouvelle règle pour le
.corner
.
TABLEAU DE DIAPOSITIVES DANS JS
Jetez un oeil à l'extrait de code ci-dessous, pour une liste de diapositives dans JS (si quelqu'un en a besoin):
$(document).ready(function() {
var slides = [
2, //index for next slide
"https://placeimg.com/640/480/animals",
"https://placeimg.com/640/480/people",
"https://placeimg.com/640/480/nature",
"https://placeimg.com/640/480/tech",
"https://placeimg.com/640/480/arch"
];
//INITIALIZE SLIDESHOW--------------------
$(".slider").css("background-image","url("+slides[2]+")"); //set next slide
$(".slider .current .img").css("background-image","url("+slides[1]+")"); //set current slide, and set slide-height to slideshow-height
//SLIDESHOW CLICK-HANDLER--------------------
$(".slider .current").on("click",function(e){e.stopPropagation();});
$(".slider").on("click",function() {
$(this).children(".current").animate({height:0},700,function(){
$(this).children(".img").css("background-image","url("+slides[slides[0]]+")"); //set the current slide to the next slide
$(this).css("height","155%"); //cover entire slide
if (slides[0]==slides.length-1) {slides[0]=1;} else {++slides[0];} //increase/loop index for next slide
$(this).parent().css("background-image","url("+slides[slides[0]]+")"); //set the next slide to the next slide after that
$(this).animate({height:"135%"},400); //reveal corner for next slide
});
});
});
.slider, .slider .img {
width: 55vw;
height: calc(55vw / 16*9);
background: #000 center/contain no-repeat;
}
.slider {margin:0 auto; cursor:pointer; overflow:hidden;}
.slider .current {
width: 250%;
height: 135%;
transform: translateX(-50%) rotate(-20deg);
transform-origin: 50% 0;
overflow: hidden;
cursor: default;
}
.slider .current .img {margin-left:50%; transform:rotate(20deg); transform-origin:0 0;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="slider"><div class="current"><div class="img"></div></div></div>
codepen: https://codepen.io/anon/pen/EXBgewjsfiddle: https://jsfiddle.net/qghv9bnh/13/
- Il peut contenir des préférences pour certains, bien que je pense que ma première solution est beaucoup plus propre, plus rapide et flexible pour ajouter des diapositives supplémentaires (certainement lorsque vous utilisez un CMS comme WordPress ou Joomla):
- les images ne sont chargées que lorsque vous utilisez réellement le curseur, de sorte que les utilisateurs économisent de la bande passante pour chaque diapositive sur laquelle ils ne cliquent pas.
- le HTML est très concise et ne grandira jamais, peu importe le nombre de diapositives que vous avez, donc votre HTML aura l'air plus propre (mais si vous utilisez PHP pour les inclure, il aura l'air tout aussi propre, même plus propre).
Je ne peux pas vraiment penser à autre chose, comme je l'ai dit, je préfère le premier. Mais néanmoins, il peut être utile pour quelqu'un.
Cela fonctionnera partout, même dans IE / Edge. Il est basé sur CSS transition
s et remplace les classes CSS via JavaScript.
J'utilise un rectangle pivoté pour recadrer des images. Démo du principe principal (contient beaucoup de valeurs codées en dur, précédemment calculées):
*,
*:before,
*:after {
box-sizing: border-box;
}
body {
margin: 0;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
div {
width: 300px;
height: 200px;
border: 1px solid red;
position: relative;
}
div:after {
content: "";
position: absolute;
left: -86.6px;
top: 50px;
width: 359.8px;
height: 240px;
transform-origin: 0 0;
transform: rotate(-30deg);
border: 1px solid blue;
}
<div></div>
Démo principale (il y a beaucoup de valeurs codées en dur). Pour mieux comprendre comment il fonctionne, vous pouvez ajouter border
à .slide-cropper
:
$(document).ready(function() {
$(".banners").on("click", ".slide-cropper.next .slide-content", function() {
var $container = $(this).closest(".slide");
$(".slide-cropper").removeClass("prev")
.removeClass("current")
.removeClass("next");
$(this).closest(".slide-cropper").addClass("current");
var $prevContainer;
if ($container.prev().length) {
$prevContainer = $container.prev();
} else {
$prevContainer = $container.siblings(":last");
}
$prevContainer.find(".slide-cropper").addClass("prev");
var $nextContainer;
if ($container.next().length) {
$nextContainer = $container.next();
} else {
$nextContainer = $container.siblings(":first");
}
$nextContainer.find(".slide-cropper").addClass("next");
});
});
*,
*:before,
*:after {
box-sizing: border-box;
}
/* all body styles are just for demo */
/* just centering the slider */
body {
margin: 0;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.banners {
width: 300px;
height: 200px;
position: relative;
}
.slide {
width: 100%;
height: 100%;
}
.slide .slide-cropper {
position: absolute;
left: -86.6px;
top: 50px;
width: 359.8px;
height: 323.2px;
transform-origin: 0 0;
transform: rotate(-30deg);
overflow: hidden;
transition: height 2s linear;
}
.slide-content {
position: absolute;
background-size: 100% 100%;
left: 100px;
top: 0;
width: 300px;
height: 200px;
transform: rotate(30deg);
transform-origin: 0 0;
z-index: 0;
/* just styles for text */
/* using flexbox to center text */
display: flex;
justify-content: center;
align-items: center;
color: #fff;
font-size: 3em;
}
.slide1 .slide-content {
background-image: url("https://i.stack.imgur.com/tt875.jpg");
}
.slide2 .slide-content {
background-image: url("https://i.stack.imgur.com/hzbmw.jpg");
}
.slide3 .slide-content {
background-image: url("https://i.stack.imgur.com/4UxLW.jpg");
}
.slide-cropper.prev {
height: 0;
z-index: 3;
}
.slide-cropper.current {
height: 240px;
transition-delay: 2s;
z-index: 2;
}
.slide-cropper.next {
z-index: 1;
}
/* Fix for IE */
.slide-cropper.current {
pointer-events: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="banners">
<div class="slide slide1">
<div class="slide-cropper current">
<div class="slide-content">
Slide 1
</div>
</div>
</div>
<div class="slide slide2">
<div class="slide-cropper next">
<div class="slide-content">
Slide 2
</div>
</div>
</div>
<div class="slide slide3">
<div class="slide-cropper">
<div class="slide-content">
Slide 3
</div>
</div>
</div>
</div>
Pour comprendre comment ça marche j'ai déplacé tous les calculs vers variables CSS AKA css custom properties . Ils fonctionnent dans de nombreux navigateurs mais pas en combinaison avec la fonction CSS calc
. Cet exemple ne fonctionne parfaitement que dans Chrome mais aidera à comprendre et à modifier cet exemple (il suffit de remplacer les variables CSS par des valeurs codées en dur calculées). Vous pouvez également déplacer ces calculs vers le préprocesseur CSS ou le code JavaScript.
$(document).ready(function() {
$(".banners").on("click", ".slide-cropper.next .slide-content", function() {
var $container = $(this).closest(".slide");
$(".slide-cropper").removeClass("prev")
.removeClass("current")
.removeClass("next");
$(this).closest(".slide-cropper").addClass("current");
var $prevContainer;
if ($container.prev().length) {
$prevContainer = $container.prev();
} else {
$prevContainer = $container.siblings(":last");
}
$prevContainer.find(".slide-cropper").addClass("prev");
var $nextContainer;
if ($container.next().length) {
$nextContainer = $container.next();
} else {
$nextContainer = $container.siblings(":first");
}
$nextContainer.find(".slide-cropper").addClass("next");
});
});
*,
*:before,
*:after {
box-sizing: border-box;
}
html {
--width: 300px;
--height: 200px;
/* rotate for image cropping */
--rotate-angle: 30deg;
/* sin 30 degrees for image cropping */
--sin-rotate-angle: 0.5;
/* cos 30 degrees for image cropping */
--cos-rotate-angle: 0.8660254037844386;
/* clipper ratio for width, can be from 0 to 1 */
--clipper-ratio: 0.45;
--animation-timeout: 2s;
}
/* all body styles are just for demo */
/* just centering the slider */
body {
margin: 0;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.banners {
width: var(--width);
height: var(--height);
position: relative;
}
.slide {
width: 100%;
height: 100%;
}
.slide .slide-cropper {
position: absolute;
left: calc(-1 * var(--height) * var(--sin-rotate-angle) * var(--cos-rotate-angle));
top: calc(var(--height) * var(--sin-rotate-angle) * var(--sin-rotate-angle));
width: calc(var(--height) * var(--sin-rotate-angle) + var(--width) * var(--cos-rotate-angle));
height: calc(var(--height) * var(--cos-rotate-angle) + var(--width) * var(--sin-rotate-angle));
transform-origin: 0 0;
transform: rotate(calc(-1 * var(--rotate-angle)));
overflow: hidden;
transition: height var(--animation-timeout) linear;
}
.slide-content {
position: absolute;
background-size: 100% 100%;
left: calc(var(--height) / 2);
width: var(--width);
height: var(--height);
transform: rotate(var(--rotate-angle));
transform-origin: 0 0;
z-index: 0;
/* just styles for text */
display: flex;
justify-content: center;
align-items: center;
color: #fff;
font-size: 3em;
}
.slide1 .slide-content {
background-image: url("https://i.stack.imgur.com/tt875.jpg");
}
.slide2 .slide-content {
background-image: url("https://i.stack.imgur.com/hzbmw.jpg");
}
.slide3 .slide-content {
background-image: url("https://i.stack.imgur.com/4UxLW.jpg");
}
.slide-cropper.prev {
height: 0;
z-index: 3;
}
.slide-cropper.current {
height: calc(var(--height) * var(--cos-rotate-angle) + var(--clipper-ratio) * var(--width) * var(--sin-rotate-angle));
transition-delay: var(--animation-timeout);
z-index: 2;
}
.slide-cropper.next {
z-index: 1;
}
/* Fix for IE */
.slide-cropper.current {
pointer-events: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="banners">
<div class="slide slide1">
<div class="slide-cropper current">
<div class="slide-content">
Slide 1
</div>
</div>
</div>
<div class="slide slide2">
<div class="slide-cropper next">
<div class="slide-content">
Slide 2
</div>
</div>
</div>
<div class="slide slide3">
<div class="slide-cropper">
<div class="slide-content">
Slide 3
</div>
</div>
</div>
</div>
Pour changer cela en plein écran vous devez définir --width: 100vw
et --height: 100vh
. (Bien sûr, vous devrez remplacer les variables css par des valeurs codées en dur pour fonctionner dans tous les navigateurs). Démo:
$(document).ready(function() {
$(".banners").on("click", ".slide-cropper.next .slide-content", function() {
var $container = $(this).closest(".slide");
$(".slide-cropper").removeClass("prev")
.removeClass("current")
.removeClass("next");
$(this).closest(".slide-cropper").addClass("current");
var $prevContainer;
if ($container.prev().length) {
$prevContainer = $container.prev();
} else {
$prevContainer = $container.siblings(":last");
}
$prevContainer.find(".slide-cropper").addClass("prev");
var $nextContainer;
if ($container.next().length) {
$nextContainer = $container.next();
} else {
$nextContainer = $container.siblings(":first");
}
$nextContainer.find(".slide-cropper").addClass("next");
});
});
*,
*:before,
*:after {
box-sizing: border-box;
}
html {
--width: 100vw;
--height: 100vh;
/* rotate for image cropping */
--rotate-angle: 30deg;
/* sin 30 degrees for image cropping */
--sin-rotate-angle: 0.5;
/* cos 30 degrees for image cropping */
--cos-rotate-angle: 0.8660254037844386;
/* clipper ratio for width, can be from 0 to 1 */
--clipper-ratio: 0.45;
--animation-timeout: 2s;
}
/* all body styles are just for demo */
/* just centering the slider */
body {
margin: 0;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.banners {
width: var(--width);
height: var(--height);
position: relative;
}
.slide {
width: 100%;
height: 100%;
}
.slide .slide-cropper {
position: absolute;
left: calc(-1 * var(--height) * var(--sin-rotate-angle) * var(--cos-rotate-angle));
top: calc(var(--height) * var(--sin-rotate-angle) * var(--sin-rotate-angle));
width: calc(var(--height) * var(--sin-rotate-angle) + var(--width) * var(--cos-rotate-angle));
height: calc(var(--height) * var(--cos-rotate-angle) + var(--width) * var(--sin-rotate-angle));
transform-origin: 0 0;
transform: rotate(calc(-1 * var(--rotate-angle)));
overflow: hidden;
transition: height var(--animation-timeout) linear;
}
.slide-content {
position: absolute;
background-size: 100% 100%;
left: calc(var(--height) / 2);
width: var(--width);
height: var(--height);
transform: rotate(var(--rotate-angle));
transform-origin: 0 0;
z-index: 0;
/* just styles for text */
display: flex;
justify-content: center;
align-items: center;
color: #fff;
font-size: 3em;
}
.slide1 .slide-content {
background-image: url("https://i.stack.imgur.com/tt875.jpg");
}
.slide2 .slide-content {
background-image: url("https://i.stack.imgur.com/hzbmw.jpg");
}
.slide3 .slide-content {
background-image: url("https://i.stack.imgur.com/4UxLW.jpg");
}
.slide-cropper.prev {
height: 0;
z-index: 3;
}
.slide-cropper.current {
height: calc(var(--height) * var(--cos-rotate-angle) + var(--clipper-ratio) * var(--width) * var(--sin-rotate-angle));
transition-delay: var(--animation-timeout);
z-index: 2;
}
.slide-cropper.next {
z-index: 1;
}
/* Fix for IE */
.slide-cropper.current {
pointer-events: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="banners">
<div class="slide slide1">
<div class="slide-cropper current">
<div class="slide-content">
Slide 1
</div>
</div>
</div>
<div class="slide slide2">
<div class="slide-cropper next">
<div class="slide-content">
Slide 2
</div>
</div>
</div>
<div class="slide slide3">
<div class="slide-cropper">
<div class="slide-content">
Slide 3
</div>
</div>
</div>
</div>
Aussi démo avec des variables CSS qui fonctionnent dans Firefox (Firefox n'est pas convivial avec la combinaison de variables CSS et transform: rotate
, donc je viens de remplacer transform: rotate
par des valeurs codées en dur):
$(document).ready(function() {
$(".banners").on("click", ".slide-cropper.next .slide-content", function() {
var $container = $(this).closest(".slide");
$(".slide-cropper").removeClass("prev")
.removeClass("current")
.removeClass("next");
$(this).closest(".slide-cropper").addClass("current");
var $prevContainer;
if ($container.prev().length) {
$prevContainer = $container.prev();
} else {
$prevContainer = $container.siblings(":last");
}
$prevContainer.find(".slide-cropper").addClass("prev");
var $nextContainer;
if ($container.next().length) {
$nextContainer = $container.next();
} else {
$nextContainer = $container.siblings(":first");
}
$nextContainer.find(".slide-cropper").addClass("next");
});
});
*,
*:before,
*:after {
box-sizing: border-box;
}
html {
--width: 100vw;
--height: 100vh;
/* sin 30 degrees for image cropping */
--sin-rotate-angle: 0.5;
/* cos 30 degrees for image cropping */
--cos-rotate-angle: 0.8660254037844386;
/* clipper ratio for width, can be from 0 to 1 */
--clipper-ratio: 0.45;
--animation-timeout: 2s;
}
/* all body styles are just for demo */
/* just centering the slider */
body {
margin: 0;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.banners {
width: var(--width);
height: var(--height);
position: relative;
}
.slide {
width: 100%;
height: 100%;
}
.slide .slide-cropper {
position: absolute;
left: calc(-1 * var(--height) * var(--sin-rotate-angle) * var(--cos-rotate-angle));
top: calc(var(--height) * var(--sin-rotate-angle) * var(--sin-rotate-angle));
width: calc(var(--height) * var(--sin-rotate-angle) + var(--width) * var(--cos-rotate-angle));
height: calc(var(--height) * var(--cos-rotate-angle) + var(--width) * var(--sin-rotate-angle));
transform-origin: 0 0;
transform: rotate(-30deg);
overflow: hidden;
transition: height var(--animation-timeout) linear;
}
.slide-content {
position: absolute;
background-size: 100% 100%;
left: calc(var(--height) / 2);
width: var(--width);
height: var(--height);
transform: rotate(30deg);
transform-origin: 0 0;
z-index: 0;
/* just styles for text */
display: flex;
justify-content: center;
align-items: center;
color: #fff;
font-size: 3em;
}
.slide1 .slide-content {
background-image: url("https://i.stack.imgur.com/tt875.jpg");
}
.slide2 .slide-content {
background-image: url("https://i.stack.imgur.com/hzbmw.jpg");
}
.slide3 .slide-content {
background-image: url("https://i.stack.imgur.com/4UxLW.jpg");
}
.slide-cropper.prev {
height: 0;
z-index: 3;
}
.slide-cropper.current {
height: calc(var(--height) * var(--cos-rotate-angle) + var(--clipper-ratio) * var(--width) * var(--sin-rotate-angle));
transition-delay: var(--animation-timeout);
z-index: 2;
}
.slide-cropper.next {
z-index: 1;
}
/* Fix for IE */
.slide-cropper.current {
pointer-events: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="banners">
<div class="slide slide1">
<div class="slide-cropper current">
<div class="slide-content">
Slide 1
</div>
</div>
</div>
<div class="slide slide2">
<div class="slide-cropper next">
<div class="slide-content">
Slide 2
</div>
</div>
</div>
<div class="slide slide3">
<div class="slide-cropper">
<div class="slide-content">
Slide 3
</div>
</div>
</div>
</div>
Cet exemple de travail sur Firefox, Chrome, IE.
Pour le changement changement de règle coulissante transition
$(document).ready(function () {
$('.angle').click(function() {
var $parent = $(this).parent();
$parent.removeClass("current");
if ($parent.next().length){
$parent.next().addClass("current");
} else {
$parent.prevAll().last().addClass("current");
}
});
});
body{
height:100%;
width:100%;
}
.slideShow {
width: 100%;
height: 100%;
}
.image {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
overflow:hidden;
z-index:1;
transition:z-index 2s step-end, 1s opacity 1s ease-in-out;
text-align:center;
opacity:0;
background-size:100% 100%;
background-attachment:fixed;
}
.image.current{
opacity:1;
z-index:2;
transition:z-index 2s step-end, 0s opacity 0s;
}
.angle {
width: 200%;
height: 200%;
position: absolute;
top: -100%;
left: -100%;
clip-path: polygon(100% 0, 0 70%, 0 100%, 100% 100%, 100% 0, 100% 0);
z-index:3;
margin-left:150%;
margin-top:150%;
transition:2s top ease-in-out, 2s left ease-in-out, 0s margin 2s;
background-size:100% 100%;
background-attachment:fixed;
}
.image.current .angle{
top:0;
left:0;
margin-top:0;
margin-left:0;
transition:0s top ease-in-out 1s, 0s left ease-in-out 1s, 2s margin ease-in-out 1s;
}
.main{
color:#FFF;
display:inline-block;
vertical-align:middle;
font-family:arial;
text-transform:uppercase;
font-size:24px;
}
.middle{
vertical-align:middle;
width:0;
height:100%;
display:inline-block;
}
.image1, .image3 .angle{
background-image: url(http://i3.imgbus.com/doimg/4c5o0m8m6o5n4e0.png);
}
.image1 .angle, .image2{
background-image:url(http://i4.imgbus.com/doimg/1c7obm6m1o3nbb0.png);
}
.image2 .angle, .image3{
background-image:url(http://i3.imgbus.com/doimg/ccbo5m2m8o8n759.jpg);
}
<div class="slideShow">
<div class="image image1 current">
<div class="main">
</div>
<div class="middle"></div>
<div class="angle" style="background-color: cyan;"></div>
</div>
<div class="image image2" style="background-color: cyan;">
<div class="main">
</div>
<div class="middle"></div>
<div class="angle" style="background-color: magenta;"></div>
</div>
<div class="image image3" style="background-color: magenta;">
<div class="main">
</div>
<div class="middle"></div>
<div class="angle"></div>
</div>
</div>
Vous pouvez également utiliser des logiciels SildeShow Maker comme Amazing Slider .
Téléchargement Simple, facile à utiliser: lien de téléchargement