An example of Css+js to realize Apple cover flow effect

Source: Internet
Author: User
Tags foreach event listener reflection

Don't say much nonsense, directly on the final effect diagram and code bar


<! DOCTYPE html>
<meta charset= "UTF-8" >
<title>coverflow-demo</title>
<style>
div.innerwrapper{
perspective:300px;
width:600px;
height:300px;
margin:100px Auto;
Display:flex;
Align-items:flex-start;
Background-color: #000;
Overflow:hidden;
padding-top:5%;
}
div.cover{
height:50%;
Flex-grow:1;
Transition:all 5s ease;
background-size:100% 100%;
Background-repeat:no-repeat;
margin:0;
-webkit-box-reflect:below 5% linear-gradient (transparent, white);
border:1px solid #fff;

}
Div.cover:nth-child (1) {
Background-image:url (' covers/computergraphics-album-covers-2014-15.jpg ');
}
Div.cover:nth-child (2) {
Background-image:url (' covers/funkadelic-maggot-brain-album-covers-billboard-1000x1000.jpg ');
}
Div.cover:nth-child (3) {
Background-image:url (' covers/green-day-american-idiot-album-covers-billboard-1000x1000.jpg ');
}
Div.cover:nth-child (4) {
Background-image:url (' covers/insurgency-digital-album-cover-design.jpg ');
}
Div.cover:nth-child (5) {
Background-image:url (' covers/pink-floyd-dark-side-of-the-moon-album-covers-billboard-1000x1000.jpg ');
}
Div.cover:nth-child (6) {
Background-image:url (' covers/sonic-quiver-time-and-space1-1000x1000.jpg ');
}
Div.cover:nth-child (7) {
Background-image:url (' covers/tumblr_inline_nydppi1mp91t7tdyh_500.jpg ');
}
Button[required= ' Required ']{
Background-color: #000;
}
</style>
<body>
<div class= ' container ' >
<div class= "Innerwrapper" >
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
<button required= ' Required ' >222</button>
<script>
;(function (parent) {
var cards = parent.queryselectorall (' div '), Covercount = cards.length, Middleindex = (coverCount-1)/2, Middlecover = cards [Middleindex], parentwidth = middleCover.parentNode.clientWidth, currentindex = Middleindex;
var maxrotate = Stepper = Maxrotate/middleindex, Maxzindex = Middleindex + 1;
var Rotatereg =/rotatey\ (\-?\d{1,3}\.? \d*) deg\)/, Translatereg =/translatex\ (\-?\d{1,3}\.? \d*) px\)/;
Debugger
for (var i = 0; i<covercount; i++) {
var elem = cards[i];
Elem.classList.add (' cover ');
Elem.style.transform = ' Translatex (0px) Rotatey (' + (maxrotate-(i*stepper). toFixed (0)) + ' deg ';
Elem.style.flexGrow = 1;
if (I<middleindex) {
Elem.style.zIndex = i+1;
}else if (i = = Middleindex) {
Elem.style.zIndex = i+1;
Elem.style.flexGrow = 2;
}else{
Elem.style.zIndex = Covercount-i;
}
}
function move (direction) {
if (currentindex== (direction== ' right ' 0:covercount-1)) return;
direction== ' right '? currentindex--:currentindex++;
maxzindex++;
[].foreach.call (Cards, function (element, index) {
var previousrotate = parseint (Element.style.transform.match (Rotatereg) [1]);
var previoustranslate = parseint (Element.style.transform.match (Translatereg) [1]);
Translatex + px One right button is clicked
var currentrotate, Currenttranslate;
if (direction== ' right ') {
Currentrotate = Previousrotate-stepper;
Currenttranslate = previoustranslate+ (parentwidth/(covercount+1));
}else{
Currentrotate = Previousrotate+stepper;
Currenttranslate = previoustranslate-(parentwidth/(covercount+1));
}
Element.style.transform = ' Translatex (' + currenttranslate + ' px ') rotatey (' + currentrotate + ' deg ')
Element.style.zIndex =
if (index = = currentindex) {
Element.style.flexGrow = 2;
Element.style.zIndex = Maxzindex;
}else{
Element.style.flexGrow = 1;
}
});
}
Document.addeventlistener (' KeyUp ', function (e) {
if (E.which = = 37) {
Move (' right ');
}else if (E.which = = 39) {
Move (' left ');
}
})
}) (Document.queryselector ('. Innerwrapper '));
</script>
</body>
Explain a little bit about the following points of knowledge here:

1. Flex-box.

What is Flex-box pinch, it is to adapt to the current device screen size of a display method proposed. When a parent element's display is set to Display:flex, the child elements within it are evenly allocated to occupy the parent element's space, and the dimensions of the child elements change as the parent element changes in size! Isn't it amazing? Not only that, you can also arbitrarily assign the order of the child elements, if you feel that a child element needs to be highlighted, you can give the child element to a special identity, so that it compared to other child elements larger, or smaller! Because of its adaptive characteristics, Flex is mobile development of a sharp weapon, we first look at a small application:

Design a dialog function that, when passed in a callback function, displays only a ' OK ' button, which takes up 100% of the width; When the two callback functions (OK and cancel) are passed in, the ' OK ' and ' Cancel ' buttons are displayed, each representing 50% widths, each with the following styles:

How to achieve it? We can certainly use JS to do, but (everything is afraid of a but haha)! We as have the pursuit of the front-end, the battle in the front line of the CSS exploration, now has so easy to use the Flex attribute, for Mao not immediately used it? Let's go. The CSS for the button container and button itself is as follows:

The key is the width:100% property of the button. With it, when there is only one button in the container, its width expands to the 100% width of the container; And when there are two buttons in the container, the width of the button is 100%, how to do? As the two buttons are evenly matched, they have to share 50% of the space!

Some students have to ask: what if I don't want the button to fill up the space? At this time, you can set the width of the button is 45%, and then set the Justify-content:center on the parent element, meaning that two of the child elements accounted for only 90% of the horizontal space, then how to allocate the remaining 10% space? Then allocate 5% on both sides! In addition, the other values of the attribute, you can make the child element to align, more flexbox magical application, please refer to this article ~

A Complete Guide to Flexbox
Back to our example. They look like this before the cards are applied to the transform properties:


The average distribution of seven elements occupies the entire horizontal space of the parent element. The middle element uses the Flex-grow:2 attribute, making it superior to other elements, twice times the size of other elements ~ ~

2. Transform

In fact, with the previous picture, the initial form of the page has been almost ~ now just to set the parent element perspective (on the perspective, 3D transformation, etc., see my article). To get a more obvious 3D effect, the perspective of the parent element is set to a smaller value of 300px, which is equivalent to the distance from the 3D transformation plane 300px. The greater the value of the perspective, which is equivalent to the distance from the farther, 3D effect is less obvious, the more intense the effect of the plane ~

Set the perspective, and then the elements to set the 3D effect. The first step is simple: assuming that there are 7 elements, along the y-axis maximum rotation angle of 42 degrees, then the 0,1,2 number of elements are rotated 42, 28, 14 degrees, 3rd elements rotate 0 degrees at the same time to become large twice times, 4,5,6 elements are rotated-14,-28,-42 degrees respectively. You can do this with a simple for loop, with the following code:

for (var i = 0; i<covercount; i++) {
var elem = cards[i];
Elem.classList.add (' cover ');
Sets the element's Translatex to 0px, the rotation angle to the maximum rotation angle-Directory value * Stepping value
Elem.style.transform = ' Translatex (0px) Rotatey (' + (maxrotate-(i*stepper). toFixed (0)) + ' deg ';
Elem.style.flexGrow = 1;
Set the z-index of the elements to differentiate between the order and the middle element and set the intermediate elements larger
if (I<middleindex) {
Elem.style.zIndex = i+1;
}else if (i = = Middleindex) {
Elem.style.zIndex = i+1;
Elem.style.flexGrow = 2;
}else{
Elem.style.zIndex = Covercount-i;
}
}
After the initialization is completed, the effect diagram is as follows:


At this time each card's Translatex is 0, this value must write beforehand, can change this value to realize the card the left and right movement effect; The values of Rotatey are 42, 28, 14, 0,-14, 28, 42 degrees respectively; Flex-grow (relative to the size of other child elements) are 1, 1, 1, 2, 1, 1, 1, respectively.

3.-webkit-box-reflect

How does a beautiful reflection come true? Haha in fact a line of CSS can be done, that is the powerful-webkit-box-reflect, the value of below 5% linear-gradient (transparent, white). Believe that smart friends see here has been understood, in order to avoid misunderstanding, a little more explanation ~ below is the reflection in the box below, 5% means offset, and the box is the distance of the box width of the 5%, linear-gradient (Transparent, white) Refers to the color of the reflection, from transparent to completely opaque. The color of the gradient syntax is only transparent, the color of the white is not obvious ~ to here, we use most of the CSS, the effect of the chart is as follows:


However, the static display is not enough, our goal is! Make it Move! Move around, back and forth! Here CSS has nothing to do, change JS debut when the!~

4.JS Control

The function that controls the left and right moves is as follows, accepting an argument to the right or right indicates the direction to move.

Defines a regular for extracting rotation angles and Translatex values, such as-> $0.style.transform.match (/rotatey\ (\-?\d{1,3}\.?). \d*) (deg\)/) <-["Rotatey (14deg)", "14"]
var Rotatereg =/rotatey\ (\-?\d{1,3}\.? \d*) deg\)/, Translatereg =/translatex\ (\-?\d{1,3}\.? \d*) px\)/;
function move (direction) {
When the current value is 0 or the current value is the number of cards, return
if (currentindex== (direction== ' right ' 0:covercount-1)) return;
The current value is either self increasing or self reducing
direction== ' right '? currentindex--:currentindex++;
Maximum Z-index self-increase
maxzindex++;
[].foreach.call (Cards, function (element, index) {
The angle of rotation before the transformation is extracted
var previousrotate = parseint (Element.style.transform.match (Rotatereg) [1]);
Translatex before extracting the transform
var previoustranslate = parseint (Element.style.transform.match (Translatereg) [1]);
var currentrotate, Currenttranslate;
if (direction== ' right ') {
Calculate the value of a Rotatey
Currentrotate = Previousrotate-stepper;
Calculate the distance of the translation
Currenttranslate = previoustranslate+ (parentwidth/(covercount+1));
}else{
Currentrotate = Previousrotate+stepper;
Currenttranslate = previoustranslate-(parentwidth/(covercount+1));
}
Write element properties
Element.style.transform = ' Translatex (' + currenttranslate + ' px ') rotatey (' + currentrotate + ' deg ')
Element.style.zIndex =
if (index = = currentindex) {
Element.style.flexGrow = 2;
Keep writing to Maxzindex to ensure that the elements that are flipped are always at the front
Element.style.zIndex = Maxzindex;
}else{
Element.style.flexGrow = 1;
}
});
}
Add the event listener to the button or keyboard, so it's done!

To sum up:

Flex-box can make your elements flex and easily implemented based on the number of elements overloaded! Various attributes allow you to manipulate flex elements arbitrarily!

Transform to achieve a beautiful 3D transformation effect!

-webkit-box-reflect to achieve a more cool reflection effect!

Finally JS to fill the knife, let our cards move up!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.