废话不多说, 直接上最终效果图和代码吧
1. flex-box.
什么是flex-box捏, 它是为了适应当前设备屏幕大小不一而提出的一种 display 方法. 当一个父元素的显示被设定为 display:flex 时, 它内部的子元素们会被平均分配占满父元素的空间, 并且当父元素的尺寸变化时, 子元素的尺寸也会相应变化! 是不是很神奇呢? 不仅如此, 你还可以任意分配子元素们的排列顺序, 如果觉得某个子元素需要突出显示, 就可以给这个子元素以特殊身份, 让它相比其他子元素大一些, 或者小一些! 由于其的自适应特性, flex 是移动开发的一把利器, 我们先来看看一个小应用:
设计一个对话框函数, 当传入一个回调函数时, 只显示一个'确定'按钮, 占100%宽度; 当传入两个回调函数(确定和取消)时, 分别显示'确定'和'取消'按钮, 各占50%宽度, 样式分别如下:
怎么实现呢? 我们当然可以用JS来做, 但是(凡事就怕一个但是哈哈)! 我们作为有追求的前端, 战斗在CSS探索的第一线, 现在有了如此好用的 flex 属性, 为毛不立马用起来呢? 说走咱就走, 按钮容器和按钮本身的CSS如下:
关键是按钮的 width:100% 属性. 有了它, 当容器里只有一个按钮时, 它的宽度会拓展为容器的100%宽度; 而当容器里有两个按钮时, 按钮的宽度都为100%, 怎么办呢? 由于两个按钮势均力敌, 它们只好平分秋色, 各占50%的空间了!
有的同学要问了: 要是我不想按钮把空间占满怎么办呢? 这时候, 可以设定按钮的宽度各为45%, 然后在父元素上设置 justify-content:center , 意思是两个子元素只占了90%的横向空间, 那怎么分配剩下的10%空间呢? 那就两边各分配5%吧! 除此之外, 该属性的其它值, 可以让子元素左右对齐, 更多 flexbox 的神奇应用, 请参考这篇文章~
A Complete Guide to Flexbox
回到我们的例子. 在卡片们没有被应用 transform 属性之前, 它们看起来是这个样子的:
七个元素平均分布, 占据了父元素的全部横向空间. 其中中间的元素应用了 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
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
}else if(i == middleIndex){
elem.style.zIndex = i+1;
elem.style.flexGrow = 2;
}else{
elem.style.zIndex = coverCount - i;
}
}
初始化完成后效果图如下:
此时每个卡片的 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, 效果图如下:
然而静态的展示是不够的, 我们的目标是! 要让它动起来! 来回左右动! 到这里CSS已经无能为力, 改JS闪亮登场的时候了!~
4.JS控制
控制左右移动的函数如下, 接受一个参数 left 或者 right 表示要移动的方向~
// 定义提取旋转角度和translateX值的正则, 例如 -> $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){
// 当前值为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来补刀, 让我们的卡片们动起来!
太极熊猫2百度版 安卓版v1.7.1
下载黎明觉醒应用宝版 安卓版v1.111.1
下载暗影格斗3国际版 (Shadow Fight 3)最新版v1.40.3
下载王者战魂华为版 安卓版v3.6.1
下载放置魔法学院免广告版 v2.9.5
放置魔法学院内置Mod菜单是游戏的破解版本,在该版本中为玩家
万乘之国qq版本 安卓版v1.0.5
万乘之国qq版本是一款极具魅力的策略游戏,玩家们可以通过不同
动物餐厅国际服无限内购版 v12.9
动物餐厅国际服免广告版是游戏的破解版本,在该版本中为玩家去除
欧洲卡车司机 安卓版v3.2
欧洲卡车司机是款模拟经营游戏,这款游戏的画面还是蛮逼真的,给
疯狂大酒店 (Grand Hotel Mania)最新中文版v4.10.0.20
疯狂大酒店(Grand Hotel Mania)是一款好玩的