共计 4795 个字符,预计需要花费 12 分钟才能阅读完成。
Hello,亲爱的宝子们?最近我一个前端架构师却临时顶替产品经理的工作,导致最近一周实在太忙了,都没有来得及更新文章。在这里想大家道歉了!也想厚颜无耻的问问大家想我了吗?(●’◡’●)
今天给大家带来一个非常简单,但是效果却相当炸裂的旋转图片视觉差特效。先看效果:
今天咱们就一起来写一下这个特效吧!O(∩_∩)O
一、网格布局
这样的案例,一眼就可以看出来是 五个 div 元素 包裹了 五张 不同的 图片。直接写出来:
这个时候,是没有任何样式效果的:
接下来,我们需要将这 五个 div 元素 控制成这样 穿透性 的排版:
简单分析一下,要实现这样的排版,首先需要做到 三行三列:
这样的排版,使用 css 中的 Grid 布局 (又叫 网格布局 )是最方便快捷的,于是我们给 五个 div 元素 添加一个 容器 ,用于 划分网格。
然后,在 css 中给容器设置 三行三列 的网格布局。
section {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
}
想了解更多关于 Grid 布局 的知识,可以关注我们之后的文章。或者可以访问我男朋友多年前在慕课网录制的《Grid 布局基础》。
为了更好的展示效果,我们使用 固定定位 把容器固定在 屏幕中央 ,并设置 相同 的宽 和高。
section {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
width: 500px;
height: 500px;
margin: auto;
}
通过 Chrome 浏览器 的开发者工具 ,我们把 五个 div 元素 注释了之后,可以看到渲染之后的 网格布局。
这样,我们已经实现了对容器的 三行三列 的网格布局,但是和我们需要的布局方式还有点点不同。
没错,我们需要类似于 合并单元格 一样的,存在行和列之间的 穿透效果 。这里就需要用到 Grid 布局 中的 网格区域。
grid-template-areas:
"topLeft topLeft topRight"
"bottomLeft center topRight"
"bottomLeft bottomRight bottomRight"
;
我们可以这样定义每一个 网格区域 , 相同的值 将会视为 同一个区域 。但是这样给 网格区域 命名,有点长了,于是简化一下:
grid-template-areas:
"TL TL TR"
"BL CE TR"
"BL BR BR"
;
这样,就可以在代码的视觉上也可以看出来 网格区域 的划分:
网格区域 已经定义好了,接下来就应该让 五个 div 元素 来认领 这五个网格区域 了。
section {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
grid-template-areas:
"TL TL TR"
"BL CE TR"
"BL BR BR"
;
width: 500px;
height: 500px;
margin: auto;
}
div {overflow: hidden;}
div:nth-child(1) {grid-area: TL;}
div:nth-child(2) {grid-area: TR;}
div:nth-child(3) {grid-area: BL;}
div:nth-child(4) {grid-area: CE;}
div:nth-child(5) {grid-area: BR;}
这里,我们设置了 div 的 溢出 为隐藏 ,这样里面的 图片 都会局限在对应的 div 范围里面。
基本上布局已经出来了。接下来,我们需要给每一个 网格区域 之间有一个 空隙。
section {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
grid-template-areas:
"TL TL TR"
"BL CE TR"
"BL BR BR"
;
gap: 10px;
width: 500px;
height: 500px;
margin: auto;
}
div {
border: 5px solid #696969;
overflow: hidden;
}
通过 gap 属性控制 弹性盒模型 的空隙 ,同时也给 div 一个 5px 的 灰色边框,于是我们得到了想要的布局效果:
这里,我们再优化一下,让每一个 div 的图片都居中显示:
div {
display: flex;
justify-content: center;
align-items: center;
border: 5px solid #696969;
overflow: hidden;
}
看一下效果:
感觉,图片大小再控制一下就完美了:
div > img {width: 100%;}
由于我们的 网格区域 有长大于宽 的矩形 ,也有 长小于宽 的矩形 。如果设置 图片 的宽度 为 100%,将会有部分 网格区域 中的 图片 不能 填充满 整个 网格区域。
我这里就直接写成 300% 了。
div > img {width: 300%;}
这就得到了我们需要的效果:
于是,我们巧妙的使用 Grid 布局 把五张图片 做成了 个性化 的布局。
二、动画效果
布局已经完成,接下来我们就需要实现 旋转 的动画效果。
很明显,我们是需要让 整个容器 顺时针 匀速 旋转,于是我们先定义一个 动画 为旋转 360deg 的状态:
@keyframes rotation {
to {transform: rotate(360deg);
}
}
然后,我们对 整个容器 调用该动画:
section {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
grid-template-areas:
"TL TL TR"
"BL CE TR"
"BL BR BR"
;
gap: 10px;
width: 500px;
height: 500px;
margin: auto;
animation: rotation 10s linear infinite;
}
这里,我们还是一样设置了 infinite,让其 动画 可以 不断重复。
录制一圈的 GIF 图片大小已经超过 5MB 了,所以我就只录制这一段了,望大家体谅。大家可以代码实现了之后看 完整效果。
我们会发现,图片 也跟着 容器 在旋转 了。有什么办法让 图片 不跟着 容器 一起 旋转 呢?最简单的办法莫过于“相对运动”。
灵感来源于生活,编程的灵感亦如此。设想一下,当我们和朋友以 相同的速度 朝着 同一个方向 迈步向前走的时候,相对 于朋友来说,我们就是 静止 的。同样的道理,如果我们和朋友同样以 相同的速度 朝着 相反的方向 迈步走的时候,相对于朋友来说,我们就是以 两倍的速度 在远离。
物理知识科普完成,回到案例中。现在 容器 是以 顺时针 在旋转 , 图片 也跟着 容器 在顺时针旋转 ,所以 图片相对于容器 来说是 静止 的。但是 相对 于我们的 浏览器窗口 , 图片 和容器 都是在 顺时针旋转 。这个时候,如果我们让 图片 以相同的角速度逆时针旋转 ,那么, 图片相对于容器 来说就是以 两倍的角速度逆时针旋转 ,但是 相对 于我们的 浏览器窗口 来说,却刚好与 容器 的角速度相抵 ,所以是 静止 的。
div > img {
width: 300%;
animation: rotation 10s linear infinite reverse;
}
我们在 图片 中也调用 旋转 的动画 ,然后设置 reverse 值,让其动画 反向执行 ,以达到图片 逆时针旋转 的效果。
至此,我们所需要的效果就已经达到了。
完整源码
还是一样,毫不吝啬的将完整的源代码共享出来。(~▽~)”
旋转中的视觉差效果 - CSS3
另外,除了使用 reverse 控制动画 反向执行 ,还可以使用 CSS4 中的 变量 实现。这里不做展开,附上完整的源代码供大家参考。
旋转中的视觉差效果 - CSS4
↓
↓
↓
尽管共享了我男朋友讲的有关 Grid 布局 的课程,但是也是几年前的课程了,如今又有了新的思路,我将会梳理完整的知识点后做系列视频课程分享给大家!让我们尽情期待吧!
关注“临界程序员”微信公众号,为您送上更多精彩内容!
原文地址: 旋转中的图片视觉差效果