如何用css 展开清明上河图
站长
· 阅读数 12
前言
上周末杭州微地震的时候,人在图书馆,听大家说"地震了,头又点晕"的时候,我丝毫没意识到,还以为是中午没睡觉的困意🥱🥱,然而我看到旁边挂着一幅画动了。这时候我就想,如果这画平时是轻卷着的,地震的时候自动展开,上面写着几个大字“地震了,大家快跑”,那不就可以挽救很多生命了么。 问题的关键是这画怎么自动展开?作为一个前端coder,我想到了css。
一、先睹为快
选一张清明上河图(局部)
二、思路分析
就和把大象装进冰箱一样简单,左右各有两个一模一样的卷轴,中间来放画,注意几点细节:
- 卷轴合上的时候,中间是有画布连着的
- 卷轴展开的时候画是逐渐出来的,不是一次出来的,超出部分肯定要
overflow: hidden
的 - 右轴的移动和画布展开所用时间是一致的
三、代码实现
3.1 先看骨架
<body>
<div class="container">
<div class="leftReelWrapper">
<div class="leftTopHandleBorder"></div>
<div class="leftTopHandle"></div>
<div class="leftTopReel"></div>
<div class="leftBottomHandle"></div>
<div class="leftBottomHandleBorder"></div>
</div>
<div class="content">
<img class="pic" src='./qingming_content.png' width="469px" height="261px" />
</div>
<div class="rightReelWrapper">
<div class="rightTopHandleBorder"></div>
<div class="rightTopHandle"></div>
<div class="rightReel"></div>
<div class="rightBottomHandle"></div>
<div class="rightBottomHandleBorder"></div>
</div>
</div>
</body>
3.2 画轴
我们以左轴为例,为避免视觉影响,先把骨架中的content
部分注释掉
然后添加如下css代码
<style type="text/css">
body {
background: #888;
}
.container {
margin: 0 auto;
width: 800px;
height: 500px;
background: #fff;
position: relative;
margin-top: 100px;
}
.leftReelWrapper {
position: absolute;
left: 50px;
top: 50%;
margin-top: -180px;
}
.leftTopReel{
width: 20px;
height: 300px;
margin-left: 3px;
background: linear-gradient(90deg, #884433, #FBBC62, #CC5F3D);
}
.leftTopHandle, .leftBottomHandle{
width: 20px;
height: 24px;
margin-left: 3px;
background: linear-gradient(90deg, #411C1D, #832C29, #411C1D);
}
/*轴上柄的末端小边*/
.leftTopHandleBorder, .leftBottomHandleBorder {
width: 26px;
height: 6px;
border-radius: 6px;
background: linear-gradient(90deg, #411C1D, #832C29, #411C1D);
}
</style>
现在效果是这样的(有点像金箍棒):
一根画好之后,另外一根是一模一样的实现,只要调整下定位就可以,两根代码如下:
<style type="text/css">
body {
background: #888;
}
.container {
margin: 0 auto;
width: 800px;
height: 500px;
background: #fff;
position: relative;
margin-top: 100px;
}
.leftReelWrapper {
position: absolute;
left: 50px;
top: 50%;
margin-top: -180px;
}
/*右轴定位*/
.rightReelWrapper {
position: absolute;
left: 76px;
top: 50%;
margin-top: -180px;
}
/*添加类名 .rightReel*/
.leftTopReel, .rightReel {
width: 20px;
height: 300px;
margin-left: 3px;
background: linear-gradient(90deg, #884433, #FBBC62, #CC5F3D);
}
/*添加类名 .rightTopHandle .rightBottomHandle*/
.leftTopHandle, .leftBottomHandle, .rightTopHandle, .rightBottomHandle {
width: 20px;
height: 24px;
margin-left: 3px;
background: linear-gradient(90deg, #411C1D, #832C29, #411C1D);
}
/*轴上柄的末端小边*/
/*添加类名 .rightTopHandleBorder, .rightBottomHandleBorder*/
.leftTopHandleBorder, .leftBottomHandleBorder, .rightTopHandleBorder, .rightBottomHandleBorder {
width: 26px;
height: 6px;
border-radius: 6px;
background: linear-gradient(90deg, #411C1D, #832C29, #411C1D);
}
</style>
两根轴画好之后是这样子:
3.3 展开
展开分两部分,一个是右轴的水平移动,一个是画布内容展开。
- 先看右轴的移动
@keyframes moveReel {
to {
transform: translateX(500px);
}
}
/*右轴定位*/
.rightReelWrapper {
...
// 加上这行
animation: moveReel 5s linear 3s forwards;
}
- 画布展开
先把骨架结构里的
content
放上去,不放图片
添加如下css代码:
@keyframes expandPainting {
to {
width: 468px;
border: 20px solid #E05717;
}
}
.content {
position: absolute;
/*这里使用border作为内容画布的边框,两轴静止的时候填充到中间细缝,没有设 background, 也方便直接在content里放图片,达到一种透视效果*/
border-left: 20px solid #E05717;
border-top: 20px solid #E05717;
border-bottom: 20px solid #E05717;
width: 6px;
height: 261px;
left: 72px;
top: 56%;
margin-top: -180px;
/*这里添加动画*/
animation: expandPainting 5s linear 3s forwards;
}
此时效果是这样的:
3.4 放图收工
最后一步就是把图片放上去,记得加overflow:hidden
.content {
...,
overflow: hidden;
}
最终效果图如下:
结语
这种方式自动展开画的方式对于地震预测是不可接受的🤔。 奉上完整代码