缩放图片展示特效
首先看一下这个特效的最终效果:
首先来分析一下这个效果都有哪些功能
- 首先初始化效果为6列,分别展示了图片的一部分
- 进入页面或者刷新页面时,每一列出现有一定时间间隔,有错落感
- 鼠标移入每一列时,每一列会有变化
- 鼠标点击每一列时,会展开当前图片,其余图片隐藏掉,同时图片出现一个title 和一个 close按钮
- 关闭每一列时会收紧当前图片,并还原到初始化状态
首先乍一看好像很复杂的样子,但是这个特效真的用了 99%的css3属性,仅仅是在打开关闭和类名切换的时候用到了一点点js。
那么怎么来实现呢?
第一步:做一个初始化页面
主要思路就是一个ul 里面有6个li
当然了,这里我还在外面包裹了一个大盒子,现在附上每一个li的代码
<li class="item ">
<div class="pic_area">
<div class="pic"></div>
<div class="title"><h2>Mellifluous</h2></div>
<div class="txt">
<div class="header">cloud1</div>
<div class="close"></div>
</div>
</div>
</li>
说一下每一个类名的含义:
- pic-area是我们最终放图片的地方,因为看最终成型效果的时候可以发现,在刷新的时候,会有一个灰色的背景,所以要新开辟一个图片区,来实现这个效果。
接下来我们给容器设定宽高,并使他们横排排列,
.wrapper .container{
width: 800px;
height: 600px;
display: flex;
justify-content: space-between;
align-items: center;
}
.item{
width: 16%;
height: 100%;
border-radius: 25px;
overflow: hidden;
background-color: #424242;
}
差不多就是这样一个效果然后给每一个加入背景图片,(在pic里设置)背景图片position 为center size 为cover,然后中间的title依靠绝对定位,同时给他的父级pic-area 设置相对定位,通过平移实现居中,还有一些位置大小上的小细节,大家慢慢调整就好
注意在设置圆角时,一定要设置overflow:hidden,因为我们用的是背景图,虽然边框变成了圆角,但是盒子本身还是方的
.item .pic_area{
height: 100%;
width: 100%;
transition: transform 0.5s;
position: relative;
}
.item .pic{
background-size: cover;
background-position: center;
opacity: 0.6;
}
.item:nth-of-type(1) .pic{
width: 100%;
height: 100%;
background-image: url(../img/tq1.jpg);
}
.item:nth-of-type(2) .pic{
width: 100%;
height: 100%;
background-image: url(../img/tq2.jpg);
}
.item:nth-of-type(3) .pic{
width: 100%;
height: 100%;
background-image: url(../img/tq3.jpg);
}
.item:nth-of-type(4) .pic{
width: 100%;
height: 100%;
background-image: url(../img/tq4.jpg);
}
.item:nth-of-type(5) .pic{
width: 100%;
height: 100%;
background-image: url(../img/tq5.jpg);
}
.item:nth-of-type(6) .pic{
width: 100%;
height: 100%;
background-image: url(../img/tq6.jpg);
}
.item .title{
position: absolute;
top: 50%;
left: 50%;
text-align: center;
transform: translateY(-50%);
transform: translateX(-50%);
font-size: 12px;
transition: 0.5s opacity linear 1s;
}
在上述代码中,同时也设置了每一列的初始透明度:opacity:0.7
接下来增加鼠标移入的效果:
通过过渡属性使得动画看起来更加的自然,通过 linear 让变化是匀速的
.title h2{
transition: font-size 0.3s linear;
}
.item:hover h2{
font-size: 22px;
}
.item:hover .pic{
opacity: 1;
transition: opacity 0.3s linear;
}
至此整个效果已经初具规模
第二步:页面进入特效,与错落感的实现
这里我们会用到一点点js来控制它的类名
.init .item .pic_area{
transform: translate3d(0 ,100%,0);
}
这里 init是我一开始就加入到ul上的类名,也就是说当我的ul有init时,要沿着y轴平移他自己的100% 这里虽然只是在一个坐标轴上平移,但是我还是启动了3d,因为有了3d之后会使用GPU加速,这样动画会更加的丝滑~
接下来我们通过js来控制这个类名:
var timer = setTimeout(function(){
$('.container').removeClass('init');
},300)
因为这个效果只需要执行一次,所以使用了timeout延时器来做,进入页面300毫秒后移除init类名
这里用了jQuery语法,用原生js做一样的道理
然后我们得到的效果应该是六列同时移动
那么接下来:
.item:nth-of-type(2) .pic_area{
transition-delay: 0.1s;
}
.item:nth-of-type(3) .pic_area{
transition-delay: 0.2s;
}
.item:nth-of-type(4) .pic_area{
transition-delay: 0.3s;
}
.item:nth-of-type(5) .pic_area{
transition-delay: 0.4s;
}
.item:nth-of-type(6) .pic_area{
transition-delay: 0.5s;
}
通过css3增加延时,就可以实现错落感
第三步:打开效果
仔细观察完成图,我们发现点击之后,选中的列先不动,其余的高度先缩小,然后宽度后缩小,然后我们选中的列宽度变大
同样也是通过类名来控制样式
.active{
width: 100%;
}
.container-active .item:not(.active){
height: 0%;
width: 0%;
}
not是没有某个类名的样式,也就是说 ,当item有了active类名时,宽度变为100%,没有active的类名宽高都变为0%,但是这样做有个缺点,就是一开始我们就是什么都看不到了,因为一开始所有的item都没有active,active是靠js加上的,所有给他的父级加了一个 container-active类名,他的父级有这个类名时,子元素item才会启动这个效果,相当于一个开关的作用,这样在正常情况下,所有的item不会都消失不见
以下为jq代码,原生js道理相同:
$('.item').click(function () { // 给每一个item注册一个点击事件,实现打开列的效果
$(this).addClass('active');
$('.container').addClass('container-active');
});
紧接着继续观察完成图,宽高变化是由顺序的
.container-active .item{
transition: height 0.5s linear,width 0.5s linear 0.5s;
}
打开之后,中间的title要消失,因为打开之后,父级有类名,所以这是有类名时的情况就好,有类名是透明度opacity为 0
.container-active .title{
opacity: 0;
transition: 0.2s opacity linear;
}
第四步:关闭效果
首先关闭按钮不是一个X字母,或者其他图片或者icon,是用css画出来的
这里选中close区域,通过::after ::before 生成两个小盒子,长长的细细的,定位在它身上,一个顺时针旋转45度,另一个逆时针旋转45度
.item .txt .close::after{
content: "";
height: 2px;
width: 25px;
background-color: #fff;
position: absolute;
top:15px;
right: 25px;
transform: rotateZ(45deg);
}
.item .txt .close::before{
content: "";
height: 2px;
width: 25px;
background-color: #fff;
position: absolute;
top:15px;
right: 25px;
transform: rotateZ(-45deg);
}
然后我们的txt部分,也就是打开之后,最上面的部分,在打开之前是隐藏起来的,然后还有位置,等一些样式需要设置
.item .txt{
position: absolute;
width: 100%;
height: 30px;
left: 0px;
top: 30px;
transition: opacity 0.5s linear;
opacity: 0;
}
.item .txt .header{
float: left;
margin-left: 30px;
line-height: 30px;
}
.item .txt .close{
float: right;
margin-right: 30px;
cursor: pointer;
}
.active .txt{
opacity: 1;
transition: opacity 0.5s linear 1s;
}
.item .txt .close{
width: 25px;
height: 25px;
}
.item .txt .close::after{
content: "";
height: 2px;
width: 25px;
background-color: #fff;
position: absolute;
top:15px;
right: 25px;
transform: rotateZ(45deg);
}
.item .txt .close::before{
content: "";
height: 2px;
width: 25px;
background-color: #fff;
position: absolute;
top:15px;
right: 25px;
transform: rotateZ(-45deg);
}
然后给close注册一个点击事件
$('.close').click(function (e) {
e.stopPropagation();
$('.container').removeClass('container-active');
$('.item').removeClass('active');
});
点击close的同时,移除container-active 类名 和active 类名
注意,这里因为会发生冒泡的缘故,所以会导致类名重复添加,刚刚删除之后会立马有重新加上,会导致,关闭不了的效果
一定要记得 使用: **e.stopPropagation();**阻止冒泡
//封装兼容冒泡的函数
function stopBobble(event){
if( event.stopPropagation()){
return event.stopPropagation();
}else{
return event.cancelBobble = true ;
}
}
其实这里如果使用原生js来阻止冒泡的话,大可不必在使用兼容语法了,因为前面都用的都是css3的新属性,ie是兼容不了的,更别说冒泡了,写一下就当回忆一下。
然后还有一个小细节要注意的是,关闭的时候,是和打开的动画是相反的
所以要给item加上这样一行代码
.item{
width: 16%;
height: 100%;
border-radius: 25px;
overflow: hidden;
background-color: #424242;
transition: width 0.5s linear ,height 0.5s linear 0.5s;
}
最后这个项目就结束啦!
可以通过此链接免费获取项目源代码