旋转中的图片视觉差效果

Hello,亲爱的宝子们?最近我一个前端架构师却临时顶替产品经理的工作,导致最近一周实在太忙了,都没有来得及更新文章。在这里想大家道歉了!也想厚颜无耻的问问大家想我了吗?(●'◡'●)

今天给大家带来一个非常简单,但是效果却相当炸裂的旋转图片视觉差特效。先看效果:

 

今天咱们就一起来写一下这个特效吧!O(∩_∩)O 


一、网格布局

这样的案例,一眼就可以看出来是五个 div 元素包裹了五张不同的图片。直接写出来:

<div><img src="./img/1.jpg"></div>
<div><img src="./img/2.jpg"></div>
<div><img src="./img/3.jpg"></div>
<div><img src="./img/4.jpg"></div>
<div><img src="./img/5.jpg"></div>

这个时候,是没有任何样式效果的:

 

接下来,我们需要将这五个 div 元素控制成这样穿透性的排版:

 

简单分析一下,要实现这样的排版,首先需要做到三行三列

 

这样的排版,使用 css 中的 Grid 布局(又叫网格布局)是最方便快捷的,于是我们给五个 div 元素添加一个容器,用于划分网格

<section>
  <div><img src="./assets/img/1.jpg"></div>
  <div><img src="./assets/img/2.jpg"></div>
  <div><img src="./assets/img/3.jpg"></div>
  <div><img src="./assets/img/4.jpg"></div>
  <div><img src="./assets/img/5.jpg"></div>
</section>

然后,在 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 值,让其动画反向执行,以达到图片逆时针旋转的效果。

 

至此,我们所需要的效果就已经达到了。


完整源码

还是一样,毫不吝啬的将完整的源代码共享出来。( ̄▽ ̄)"

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>旋转中的视觉差效果 - CSS3</title>
<style type="text/css">
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;*/
}
div {
  display: flex;
  justify-content: center;
  align-items: center;
  border: 5px solid #696969;
  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 > img {
  width: 100%;
/*  animation: rotation 10s linear infinite reverse;*/
}
@keyframes rotation {
  to {
    transform: rotate(360deg);
  }
}
</style>
</head>
<body>
  <section>
    <div><img src="./assets/img/1.jpg"></div>
    <div><img src="./assets/img/2.jpg"></div>
    <div><img src="./assets/img/3.jpg"></div>
    <div><img src="./assets/img/4.jpg"></div>
    <div><img src="./assets/img/5.jpg"></div>
  </section>
</body>
</html>

另外,除了使用 reverse 控制动画反向执行,还可以使用 CSS4 中的变量实现。这里不做展开,附上完整的源代码供大家参考。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>旋转中的视觉差效果 - CSS4</title>
<style type="text/css">
section {
  --deg: 360deg;
  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;
}
div {
  display: flex;
  justify-content: center;
  align-items: center;
  border: 5px solid #696969;
  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 > img {
  --deg: -360deg;
  width: 300%;
  animation: rotation 10s linear infinite;
}
@keyframes rotation {
  to {
    transform: rotate(var(--deg));
  }
}
</style>
</head>
<body>
  <section>
  <div><img src="./assets/img/1.jpg"></div>
  <div><img src="./assets/img/2.jpg"></div>
  <div><img src="./assets/img/3.jpg"></div>
  <div><img src="./assets/img/4.jpg"></div>
  <div><img src="./assets/img/5.jpg"></div>
  </section>
</body>
</html>

尽管共享了我男朋友讲的有关 Grid 布局的课程,但是也是几年前的课程了,如今又有了新的思路,我将会梳理完整的知识点后做系列视频课程分享给大家!让我们尽情期待吧!

关注“临界程序员”微信公众号,为您送上更多精彩内容! 

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-20 04:06:02       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-20 04:06:02       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-20 04:06:02       45 阅读
  4. Python语言-面向对象

    2024-07-20 04:06:02       55 阅读

热门阅读

  1. 深入理解 Vue 3 组件通信

    2024-07-20 04:06:02       22 阅读
  2. 参考网站总结

    2024-07-20 04:06:02       21 阅读
  3. Spring注解开发

    2024-07-20 04:06:02       20 阅读
  4. C++ 数据结构

    2024-07-20 04:06:02       18 阅读
  5. PYQT按键长按机制

    2024-07-20 04:06:02       16 阅读
  6. godot使用ws

    2024-07-20 04:06:02       19 阅读
  7. mysql(四)

    2024-07-20 04:06:02       16 阅读
  8. Kubernetes Service 之 LoadBalancer

    2024-07-20 04:06:02       19 阅读
  9. 第五节 LLaVA模型lora推理模型解读(下篇)

    2024-07-20 04:06:02       17 阅读