CSS3优雅做动画系列之潜水艇动画

友情提醒,潜水艇动画的效果是真的屌,但知识点也真的多,建议直接CV大法把代码贴到你们的项目中,手写一遍,不要我看了,我收藏,我走了

此处,列一些我吸收的知识点,请尽情采撷。

CSS3优雅做动画系列之潜水艇动画

正文

省流,先上效果

CSS3优雅做动画系列之潜水艇动画

第一步、潜水艇的探照灯

1、先实现一个渐变的背景

.light {
  position: absolute;
  top: 0%;
  left: 0%;
  width: 500px;
  height: 100px;
  background: linear-gradient(to left, $lightColor, $bgColor);
}

CSS3优雅做动画系列之潜水艇动画

2、把背景定位到探照灯的位置

transform: translate(-18%, -45%);

CSS3优雅做动画系列之潜水艇动画

3、截取背景图,让它的样子变成探照灯射出去的光芒

-webkit-clip-path: polygon(0% 0%, 50% 45%, 50% 55%, 0% 100%);
clip-path: polygon(0% 0%, 50% 45%, 50% 55%, 0% 100%);

CSS3优雅做动画系列之潜水艇动画

clip-path是怎么实现这个神仙效果的呢,让我们分解其属性看下:

clip-path 是 CSS 属性,可以用来创造出各种各样的裁剪形状,其中 polygon() 函数是 clip-path 的其中一种用法。polygon() 函数可以创建一个由直线段连接各个点的多边形,每个点坐标通过 x 和 y 坐标的百分比指定。

语法如下:

clip-path: polygon(x1 y1, x2 y2, x3 y3, ..., xn yn);

代码中,clip-path 是通过一个四个顶点的多边形来裁剪元素的内容, 最后形成一个类似三角形的光束。该多边形的四个顶点的坐标如下:

  • 左上角:(0%, 0%)
  • 右上角:(50%, 45%)
  • 右下角:(50%, 55%)
  • 左下角:(0%, 100%)

这四个顶点通过 polygon() 函数的参数传递给 clip-path,最终将元素内容裁剪成这个多边形的形状,只显示多边形所包含的部分,而其他部分则被裁剪掉

第二步、探照灯的管子

定义一个长方形盒子,通过border,对其四个角设置宽度和颜色来实现

  width: 20px;
  height: 50px;
  border-right: 10px solid $lightShadowColor3;
  border-top: 10px solid $lightShadowColor2;
  border-left: 0px solid transparent;
  border-bottom: 0px solid transparent;
  border-top-right-radius: 10px;

CSS3优雅做动画系列之潜水艇动画

第三步、潜水艇的驾驶舱

核心也是通过clip-path进行裁剪, 把长方形盒子的右上裁剪掉

clip-path: polygon(0% 0%, 70% 0%, 100% 100%, 0% 100%);

CSS3优雅做动画系列之潜水艇动画

第四步、潜水艇的身体

此处没啥特殊属性,画一个长方形盒子,使用border-radius:50px; 就可以了

第五步、潜水艇上闪闪的玻璃窗

核心使用的background-image 配合animation 在不同帧画出不同的背景形状

background-image: linear-gradient(45deg, $windowLightColor, #fff);
animation: shadow-change 1s linear infinite;

// 动画
@keyframes shadow-change {
  0%,
  100% {
    background-image: linear-gradient(
      45deg,
      $windowLightColor 0%,
      $windowLightColor 20%,
      #fff 21%,
      #fff 39%,
      $windowLightColor 40%,
      #fff 41%,
      #fff 59%,
      $windowLightColor 60%
    );
  }
  // ... 具体见下面的全文
}

此处的background-image 并不仅仅用来存放背景图片,也可以被用来自定义的背景效果。

linear-gradient表示线性渐变,指定了渐变的方向角度(45度)。$windowLightColor#fff表示渐变的颜色。数字%表示渐变过程中的位置。

整个代码的意思是:将页面的背景颜色设置成由$windowLightColor这个颜色开始,在45度方向上从左上角向右下角变成#fff的渐变过程,并在#fff以后从右下角向左上角渐变回$windowLightColor

第六步、潜水艇的尾翼

父盒子通过transitiontransitionanimation实现尾翼整体的转动效果

CSS3优雅做动画系列之潜水艇动画

transition: transform 1s;
transform-style: preserve-3d;
animation: rotateInfinite 1s linear infinite;

// 动画
@keyframes rotateInfinite {
  0% {
    transform: rotateX(0deg);
  }
  50% {
    transform: rotateX(180deg);
  }
  100% {
    transform: rotateX(360deg);
  }
}

两个子盒子通过transform变形生成尾翼的样子

尾翼一

transform: rotateY(180deg) rotateX(225deg);

尾翼二

transform: rotateX(45deg);

核心点罗列

1、 perspective:600px;意味着该元素的后代元素(使用 3D 变换)将视觉上位于 3D 空间内,并在转换时受到视距值的影响。此处观察者和 3D 元素之间的距离为 600 像素。(实际并没啥效果,删了也不影响,懂行的小伙伴可以评论区留言)

2、transition: transform 1s 表示变换过渡,将应用于在 transform 属性。并且,这个过渡动画会持续一秒钟。

3、transform-style: preserve-3d ,父元素设置为 preserve-3d 属性时,它的子元素将能够在 3D 空间内变换。这里的 preserve-3d 主要表示父元素保留 3D 空间,而非只有单纯的 2D 平面效果。

大功告成,下面贴上全部代码

<template>
<div class="seaContainer">
<div class="submarine__container">
<div class="light"></div>
<div class="submarine__periscope"></div>
<div class="submarine__periscope-glass"></div>
<div class="submarine__sail">
<div class="submarine__sail-shadow dark1">
</div>
<div class="submarine__sail-shadow light1"></div>
<div class="submarine__sail-shadow dark2"></div>
</div>
<div class="submarine__body">
<div class="submarine__window one">
</div>
<div class="submarine__window two">
</div>
<div class="submarine__shadow-dark"></div>
<div class="submarine__shadow-light"></div>
<div class="submarine__shadow-arcLight"></div>
</div>
<div class="submarine__propeller">
<div class="propeller__perspective">
<div class="submarine__propeller-parts darkOne"></div>
<div class="submarine__propeller-parts lightOne"></div>
</div>        
</div>
</div>
<div class="bubbles__container">
<span class="bubbles bubble-1"></span>
<span class="bubbles bubble-2"></span>
<span class="bubbles bubble-3"></span>
<span class="bubbles bubble-4"></span>
</div>
<div class="ground__container">
<div class="ground ground1">
<span class="up-1"></span>
<span class="up-2"></span>
<span class="up-3"></span>
<span class="up-4"></span>
<span class="up-5"></span>
<span class="up-6"></span>
<span class="up-7"></span>
<span class="up-8"></span>
<span class="up-9"></span>
<span class="up-10"></span>
</div>
<div class="ground ground2">
<span class="up-1"></span>
<span class="up-2"></span>
<span class="up-3"></span>
<span class="up-4"></span>
<span class="up-5"></span>
<span class="up-6"></span>
<span class="up-7"></span>
<span class="up-8"></span>
<span class="up-9"></span>
<span class="up-10"></span>
<span class="up-11"></span>
<span class="up-12"></span>
<span class="up-13"></span>
<span class="up-14"></span>
<span class="up-15"></span>
<span class="up-16"></span>
<span class="up-17"></span>
<span class="up-18"></span>
<span class="up-19"></span>
<span class="up-20"></span>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
//colors
$bgColor: #130560;
$subMarineColor: #e30449;
$lightShadowColor: #ef689e;
$lightShadowColor2: #c6003d;
$lightShadowColor3: #e92d77;
$darkShadowColor: #a10532;
$periscopeColor: #F0F78B;
$propellerColor: #f7e349;
$propellerColor2: #f7ac08;
$windowLightColor: #c9e5d9;
$lightColor: #817E97;
$seaGroundColor1:#0c0051;
$seaGroundColor2:#08003b;
//sizes
html,body {
background:#130560;
overflow:hidden;
}
.seaContainer {
position: absolute;
top: 0%;
left: 0%;
width: 100%;
height: 100%;
background: #130560;
overflow:hidden;
}
.submarine__container {
position: absolute;
top: 50%;
left: 50%;
width: 400px;
height: 200px;
transform: translate(-50%, -50%);
}
.submarine__body {
position: absolute;
top: 50%;
left: 50%;
width: 250px;
height: 80px;
background: $subMarineColor;
border-radius: 50px;
transform: translate(-50%, -50%);
}
.submarine__propeller {
position: absolute;
left: 80%;
top: 50%;
width: 30px;
height: 50px;
transform: translate(0%, -50%);
perspective: 600px;
}
.propeller__perspective
{
width: 100%;
height: 100%;
transition: transform 1s;
transform-style: preserve-3d;
animation:rotateInfinite 1s linear infinite;
cursor: pointer;
}
.submarine__propeller-parts
{
position: absolute;
left: 0%;
width: 100%;
height: 100%;
top: 0%;
perspective: 1000px;
transform-style: preserve-3d;
}
.darkOne {
top:0%;
background: $propellerColor2;
transform: rotateY(180deg)rotateX(225deg)
}
.lightOne
{
top:0%;
background: $propellerColor;
transform:rotateX(45deg);
}
.submarine__sail {
position: absolute;
top: 40%;
left: 50%;
width: 90px;
height: 50px;
transform: translate(-50%, -100%);
background: $lightShadowColor2;
clip-path: polygon(0% 0%, 70% 0%, 100% 100%, 0% 100%);
}
.submarine__sail-shadow {
position: absolute;
width: 160%;
height: 10%;
background: $darkShadowColor;
border-radius: 5px;
}
.dark1 {
left: 0%;
top: 0%;
transform: translate(0%, -33%);
}
.dark2
{
left:0%;
top:50%;
}
.light1{
left:20%;
top:20%;
width:50%;
background:$lightShadowColor;
}
.submarine__window {
width: 25px;
height: 25px;
border-radius: 100%;
background-image: linear-gradient(45deg,$windowLightColor,#fff);
border: 8px solid $darkShadowColor;
z-index:10;
animation:shadow-change 1s linear infinite;
}
.one,
.two {
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
}
.one {
left: 40%;
}
.two {
left: 20%;
}
.submarine__shadow-dark {
position: absolute;
left: 70%;
top: 50%;
width: 70px;
height: 10px;
border-radius: 5px;
transform: translate(-50%, -50%);
background: $darkShadowColor;
}
.submarine__shadow-light {
position: absolute;
left: 35%;
top: 13%;
width: 100px;
height: 6px;
border-radius: 5px;
transform: translate(-50%, -50%);
background: $lightShadowColor;
}
.submarine__shadow-arcLight {
position: absolute;
top: 65%;
left: 80%;
width: 20px;
height: 20px;
border-radius: 50%;
background: $lightShadowColor;
}
.submarine__periscope {
position: absolute;
top: 0%;
left: 40%;
width: 20px;
height: 50px;
border-right: 10px solid $lightShadowColor3;
border-top: 10px solid $lightShadowColor2;
border-left: 0px solid transparent;
border-bottom: 0px solid transparent;
border-top-right-radius: 10px;
}
.submarine__periscope-glass {
position: absolute;
left: 40%;
top: 0%;
width: 5px;
height: 15px;
background: $propellerColor2;
transform: translate(-50%, -15%);
}
.light {
position: absolute;
top: 0%;
left: 0%;
width: 500px;
height: 100px;
background: linear-gradient(to left, $lightColor, $bgColor);
/* The points are: centered top, left bottom, right bottom */
clip-path: polygon(0% 0%, 50% 45%, 50% 55%, 0% 100%);
transform: translate(-18%, -45%);
}
.bubbles__container
{
position:absolute;
top:50%;
left:55%;
width:100px;
height:50px;
transform:translate(100%,-50%);
}
.bubbles
{
position:absolute;
width:10px;
height:10px;
border-radius:100%;
left:5%;
top:5%;
background:#fff;
opacity:0.8;
}
$bubble-class: bubble;
@for $i from 1 through 4{
.#{$bubble-class}-#{$i}{
top:15%*($i+1-1);
left:1%;
opacity: 0;
animation:move-right 1s infinite linear;
animation-delay: 0.25s*$i;
}
}
.ground__container
{
position:absolute;
top:75%;
left:0%;
width:100%;
height:25%;
background:$seaGroundColor2;
margin-top:20px;
}
.ground1
{
top:75%;
height:100%;
background:$seaGroundColor1;
}
.ground2
{
position:absolute;
top:35%;
width:100%;
height:100%;
background:$seaGroundColor2;
}
.ground span
{
position:absolute;
width:60px;
height:60px;
border-radius:100%;
}
.ground1 span
{
background:$seaGroundColor1;
}
.ground2 span
{
background:$seaGroundColor2;
width:80px;
height:80px;
border-radius:100%;
transform:translateY(30%);
}
$ground-class: up;
@for $i from 1 through 20 
{
.#{$ground-class}-#{$i}{
left:-10%*($i+-1);
top:-20px*($i*0.10);
animation:moveThegroundRight $i+2s infinite linear;
}
}
//animation
@keyframes shadow-change
{
0%,100%
{
background-image: linear-gradient(45deg,$windowLightColor 0%,$windowLightColor 20% ,#fff 21%, #fff 39%, $windowLightColor 40%,#fff 41%,#fff 59%,$windowLightColor 60%);
}
20%
{
background-image: linear-gradient(45deg,$windowLightColor 20%,$windowLightColor 40% ,#fff 41%, #fff 59%, $windowLightColor 60%,#fff 61%,#fff 79%,$windowLightColor 80%);
}
40%
{
background-image: linear-gradient(45deg,$windowLightColor 40%,$windowLightColor 60% ,#fff 61%, #fff 79%, $windowLightColor 80%,#fff 81%,#fff 99%,$windowLightColor 0%);
}
60%
{
background-image: linear-gradient(45deg,$windowLightColor 60%,$windowLightColor 80% ,#fff 81%, #fff 99%, $windowLightColor 0%,#fff 1%,#fff 19%,$windowLightColor 20%);
}
80%
{
background-image: linear-gradient(45deg,$windowLightColor 80%,$windowLightColor 0% ,#fff 1%, #fff 19%, $windowLightColor 20%,#fff 21%,#fff 39%,$windowLightColor 40%);
}
}
@keyframes move-right {
0%
{
opacity:0;
}
10%
{
opacity:0.4;
transform:translate(10%,10%);
}
50%
{
opacity:0.2;
transform:translate(450%,25%);
}
80%
{
opacity:0;
transform:translateX(555%);
}
100%
{
opacity:0;
left:0%;
top:0%;
}
}
@keyframes rotateInfinite{
0%
{
transform: rotateX(0deg);
}
50%
{
transform: rotateX(180deg);
}
100%
{
transform: rotateX(360deg);
}
}
@keyframes moveThegroundRight
{
90%
{
opacity:1;
left:100%;
}
95%,100%
{
left:1050%;
opacity:0;
}
}
</style>

完结

这篇文章是我在网上冲浪的时候发现的效果,其实我一直蛮感兴趣走路动画,只是一直没时间搞,都用来刷某音和某站了。这里把动画效果和实现方式整理了一下,希望对小伙伴有帮助。

后续,我可能还会更新其他CSS3动画方面的,因为的确很感兴趣。

欢迎转载,但请注明来源。

最后,希望小伙伴们给我个免费的点赞,祝大家心想事成,平安喜乐。

CSS3优雅做动画系列之潜水艇动画

原文链接:https://juejin.cn/post/7221094608054419516 作者:尘落笔记

(0)
上一篇 2023年4月13日 上午10:10
下一篇 2023年4月13日 上午10:21

相关推荐

发表评论

登录后才能评论