html5 coverflow,CSS+JS实现苹果cover flow效果

news/2024/11/7 9:28:40/

废话不多说, 直接上最终效果图和代码吧

github地址:

bVCs1I

coverflow-demo

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;

}

222

;(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 = 42, 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

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

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 + 80 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'));

稍微解释下这里用到的几个知识点:

1. flex-box.

什么是flex-box捏, 它是为了适应当前设备屏幕大小不一而提出的一种display方法. 当一个父元素的显示被设定为display:flex时, 它内部的子元素们会被平均分配占满父元素的空间, 并且当父元素的尺寸变化时, 子元素的尺寸也会相应变化! 是不是很神奇呢? 不仅如此, 你还可以任意分配子元素们的排列顺序, 如果觉得某个子元素需要突出显示, 就可以给这个子元素以特殊身份, 让它相比其他子元素大一些, 或者小一些! 由于其的自适应特性, flex是移动开发的一把利器, 我们先来看看一个小应用:

设计一个对话框函数, 当传入一个回调函数时, 只显示一个'确定'按钮, 占100%宽度; 当传入两个回调函数(确定和取消)时, 分别显示'确定'和'取消'按钮, 各占50%宽度, 样式分别如下:

bVCs5b

bVCs5c

怎么实现呢? 我们当然可以用JS来做, 但是(凡事就怕一个但是哈哈)! 我们作为有追求的前端, 战斗在CSS探索的第一线, 现在有了如此好用的flex属性, 为毛不立马用起来呢? 说走咱就走, 按钮容器和按钮本身的CSS如下:

bVCs6s

bVCs6D

关键是按钮的width:100%属性. 有了它, 当容器里只有一个按钮时, 它的宽度会拓展为容器的100%宽度; 而当容器里有两个按钮时, 按钮的宽度都为100%, 怎么办呢? 由于两个按钮势均力敌, 它们只好平分秋色, 各占50%的空间了!

有的同学要问了: 要是我不想按钮把空间占满怎么办呢? 这时候, 可以设定按钮的宽度各为45%, 然后在父元素上设置justify-content:center, 意思是两个子元素只占了90%的横向空间, 那怎么分配剩下的10%空间呢? 那就两边各分配5%吧! 除此之外, 该属性的其它值, 可以让子元素左右对齐, 更多flexbox的神奇应用, 请参考这篇文章~

A Complete Guide to Flexbox

回到我们的例子. 在卡片们没有被应用transform属性之前, 它们看起来是这个样子的:

bVCs9A

七个元素平均分布, 占据了父元素的全部横向空间. 其中中间的元素应用了flex-grow:2的属性, 使得它比其他元素高人一等, 面积是其他元素的两倍~~

2. transform

其实有了上一幅图, 初始页面的雏形就已经差不多了~现在只需要给父元素设置视角(关于视角, 3D变换等内容, 请见我的这一篇文章). 为了得到比较明显3D效果, 设置了父元素的perspective为较小的值300px, 就相当于从距离3D变换平面300px的距离看. perspective的值越大, 相当于从越远的距离看, 3D效果越不明显, 平面化效果越强烈~

设置好了视角, 接下来该给元素们设置3D效果了. 第一步很简单: 假设有7个元素, 沿Y轴最大旋转角度为42度, 则0,1,2号元素分别旋转42, 28, 14度, 3号元素旋转0度同时变大2倍,4,5,6号元素分别旋转-14, -28, -42度. 用一个简单的for循环就可以完成这项任务, 代码如下:

for(var i = 0; i

var elem = cards[i];

elem.classList.add('cover');

// 设置元素的translateX为0px, 旋转角度为最大旋转角度-目录值*步进值

elem.style.transform = 'translateX(0px) rotateY(' + (maxRotate-(i*stepper).toFixed(0)) + 'deg)';

elem.style.flexGrow = 1;

// 设置元素的z-index以区分前后顺序, 并将中间元素设置大一些

if(i

elem.style.zIndex = i+1;

}else if(i == middleIndex){

elem.style.zIndex = i+1;

elem.style.flexGrow = 2;

}else{

elem.style.zIndex = coverCount - i;

}

}

初始化完成后效果图如下:

bVCthf

此时每个卡片的translateX为0, 这个值要预先写好, 才能通过改变该值来实现卡片的左右移动效果; rotateY的值分别为42, 28, 14, 0, -14, -28, 42度; flex-grow(相对于其它子元素的大小)分别为1, 1, 1, 2, 1, 1, 1

3.-webkit-box-reflect

那么漂亮的倒影是怎么实现的呢? 哈哈其实一行CSS就能搞定, 那就是强大的-webkit-box-reflect, 值为below 5% linear-gradient(transparent, white). 相信聪明的小伙伴看到这里已经明白了大概了, 为了避免误解, 稍稍再解释一下~below是倒影在盒子下方, 5%表示offset, 和盒子的距离是盒子宽度的5%, linear-gradient(transparent, white)指的是倒影的颜色, 从透明到完全不透明. 渐变语法的颜色在这里起作用的只有透明度, 白色的颜色是不会显出来的~到这里, 我们用的大部分都是CSS, 效果图如下:

bVCtir

然而静态的展示是不够的, 我们的目标是! 要让它动起来! 来回左右动! 到这里CSS已经无能为力, 改JS闪亮登场的时候了!~

4.JS控制

控制左右移动的函数如下, 接受一个参数left或者right表示要移动的方向~

// 定义提取旋转角度和translateX值的正则, 例如 -> $0.style.transform.match(/rotateY\((\-?\d{1,3}\.?\d*)deg\)/)

var rotateReg = /rotateY\((\-?\d{1,3}\.?\d*)deg\)/, translateReg = /translateX\((\-?\d{1,3}\.?\d*)px\)/;

function move(direction){

// 当前值为0或者当前值为卡片数目时, 返回

if(currentIndex==(direction=='right'?0:coverCount-1))return;

// 当前值自增或者自减

direction=='right'?currentIndex--:currentIndex++;

// 最大Z-index自增

maxZIndex++;

[].forEach.call(cards, function(element, index) {

// 提取变换之前的旋转角度

var previousRotate = parseInt(element.style.transform.match(rotateReg)[1]);

// 提取变换之前的translateX

var previousTranslate = parseInt(element.style.transform.match(translateReg)[1]);

var currentRotate, currentTranslate;

if(direction=='right'){

// 计算rotatey的值

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;

// 不断写入maxZIndex, 确保翻过的元素始终在最前面

element.style.zIndex = maxZIndex;

}else{

element.style.flexGrow = 1;

}

});

}

再给按钮或者键盘增加事件监听, 这样就完成啦!

总结一下:

flex-box可以让你的元素变得flex, 轻松实现根据元素数目重载! 各种属性让你任意操作flex元素!

transform实现漂亮的3D变换效果!

-webkit-box-reflect实现更加酷炫的倒影效果!

最后JS来补刀, 让我们的卡片们动起来!

参考资料


http://www.ppmy.cn/news/232184.html

相关文章

苹果计算机做视频教程,Mac版Final Cut Pro x使用技巧及视频教程

Final Cut Pro X是Mac系统最常用的一款视频剪辑,下面小编就为大家讲解Mac版Final Cut Pro x使用技巧及视频教程。 推荐下载: 软件名称:Final Cut Pro X for Mac(视频剪辑软件) V10.4.10 苹果电脑特别版软件大小:3.02GB更新时间&am…

苹果六电池_2340mAh!让iPhone 7重获新生,华严苛大容量手机电池评测

-----充电头网深度评测 第1151期----- 智能机时代,目前市场是以安卓和苹果为两大阵营的。暂且抛开安卓不谈,众所周知苹果的iPhone手机电池容量一直都非常小,往往都比同时期的安卓机至少要少1000mAh左右,纵使苹果的系统再封闭&…

Mac 键盘快捷键,苹果Macbook电脑快捷键

估计有很多人跟我一样,一开始使用苹果电脑的时候有很多的不习惯,因为这里的很多界面和快捷键都与我们之前使用的windows系统有很多区别, 但只要我们使用半天以上就很快上手基础操作,但如果你比较喜欢使用快捷键的话可以看看我给大…

苹果营销页的交互动画,见证CSS的魔力

前言 前两天在浏览 苹果 16寸 营销页面 的时候,发现了几个比较有意思的交互,心里想着自己虽然是一个穷逼,但是知识是无界限的呀,于是便研究了一波。 ❝ 文章主要讲交互效果,所以文中会有很多 gif 图,大家最…

苹果风格ui设计_重新设计苹果音乐应用程序ui ux案例研究

苹果风格ui设计 重点 (Top highlight) TLDR? UI重新设计 (TLDR? UI Redesign) I didn’t realise how much I’d written for this piece (this is my first ever completed case study) so if you want to see just the UI redesign solely then please go to my Behance po…

为何苹果为何苹果甘愿冒险自主研发芯片?

来源:内容来自「腾讯科技」 7月4日,据外媒报道,苹果不久前宣布将把Mac上使用的处理器从英特尔芯片迁移到自己的Apple Silicon上,尽管这是意料之中的事,但苹果为何甘愿冒险甚至似乎相当渴望进行这种转型的,仍…

揭秘苹果应用审核团队(史上最全版)

????????关注后回复 “进群” ,拉你进程序员交流群???????? 一、前言 大家好!又到了我们的吃瓜时刻啦, 准备好小板凳哈~ 最近,Epic Games vs Apple 的诉讼大战非常的精彩,在上一篇文章《论证&#xff…

苹果硅:Wintel的过去

重点 (Top highlight) by Jean-Louis Gasse 通过让路易斯加塞(Jean-LouisGasse) 我们将进入一个令人兴奋的,混乱的过渡。 Apple Silicon不仅会制造出更好的Mac,还将迫使微软在ARM行为(包括硬件和软件)上完善Windows。 反过来,这将导致PC OEM…