I am trying to achieve an animation effect as follows:
When a banner is shown, the bottom right corner of the next banner should be visible. When you click on this c
This should work for any browser with transition support: https://jsfiddle.net/freer4/cqqxjjgu/1/
Essentially, make a really big cover slide, with the same background color as your next slide, and pull it over your current slide. Then fade out to reveal the next slide.
So a little adjustment on the 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>
Change the jQuery to select either the next slide or the first if there are no more:
$(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");
}
});
});
And set up some intricate transitions you can adjust the timing of:
.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;
}
Aside: This example is completely flexible (doesn't care about size):
.banners {
width: 100%;
height: 100%;
}
Or with images: https://jsfiddle.net/freer4/ens7caaL/
This will work everywhere, even in IE/Edge. It's based on CSS transition
s and replacing CSS classes via JavaScript.
I'm using rotated rectangle to crop images. Demo of main principle (contains a lot of hardcoded, previously calculated values):
*,
*: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>
Main demo (there are a lot of hardcoded values). For better understanding how it works you can add border
to .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>
To understand how it works I moved all calculations to CSS variables AKA CSS custom properties. They work in many browsers but not in combination with CSS calc
function. This example works perfectly only in Chrome but will help to understand and modify this example (just replace CSS variables with calculated hardcoded values). Also you can move this calculations to CSS preprocessor or JavaScript code.
$(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>
To change this to fullscreen you need to set --width: 100vw
and --height: 100vh
. (Of course, then you'll have to replace CSS variables with hardcoded values to work in all browsers). Demo:
$(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>
Also demo with CSS variables that work in Firefox (Firefox is not friendly with combination of CSS variables and transform: rotate
, so I just replaced transform: rotate
with hardcoded values):
$(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>
A simple example accomplishing this effect with no 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>
Basically, just use keyframes to animate the clip path. Get fancy with the z-indexes and some sibling selectors.
This sample working on Firefox, Chrome, IE.
For change sliding rule change 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>
Also you can use SildeShow Maker softwares like Amazing Slider.
easy download, easy use: download link
it's very powerful software. see Screenshot
This is an answer without the use of clip-path, because browser compatibility on DOM elements other than svg
is low.
I see now that Vadim had the same idea as me with the rotated container (hadn't checked back here until I had finished), but from what I can tell there are still enough differences between our answers to justify posting my 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>
clip-path
I just change the height
of the slide containers, using transition
for the animation effects.Unfortunately, as usual, IE processes transform:rotate() differently from other browsers. Visually the rotations happen, but the browser still seems to reserve the original space of the elements, so therefor the exposed corner of the next slide is not clickable because the current slide is 'covering' it. Using the -ms-
or -webkit-
prefix doesn't make a difference.
The following code snippet DOES work in 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>
<div class="corner">
that covers all the slides..corner
, and at the start of the handler a reference to the next slide is stored into a variable, which is used in the rest of the code..corner
.Have a look at the code snippet below, for a list of slides in JS (if someone needs it):
$(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>
Can't really think of anything else, as I said, I prefer the first one. But none the less, it may come in handy for someone.