波浪动画效果的实现

 实现思路:

        设计波浪形状、实现波浪的动画效果、设置多层波浪的交错动画。

1. 设计波浪形状

         波浪的形状是通过SVG(可缩放矢量图形)来实现的。SVG是一种基于XML的矢量图形格式,适合绘制分辨率独立的图形。使用<path>元素来定义波浪的路径。

        定义路径数据:路径数据使用d属性,它包含了一系列的命令和参数,这些命令描述了如何绘制图形。常用的命令包括:M x,y: 移动到指定坐标,设定路径的起点。c dx1,dy1 dx2,dy2 dx,dy: 画贝塞尔曲线,起点是上一个坐标,终点是由dx,dy确定,相对前一个坐标。dx1,dy1dx2,dy2定义控制点的相对位置。

        本篇使用的数据路径如下:

<path id="gentle-wave" d="M-160 30c30 0 58-3 88-3s 58 3 88 3 58-3 88-3 58 3 88 3 v44h-352z" />

        注:

                1.M-160 30: 从起点(-160, 30)开始。

      2.c30 0 58-3 88-3: 画出一段平缓的波浪。

      3.s 58 3 88 3: 继续绘制波浪,s命令指定与前一个控制点镜像的控制点。

      4.v44: 垂直向下移动44个单位。

      5.h-352: 水平向左绘制352个单位,闭合路径。

2. 实现波浪的动画效果

        为了使波浪动起来,使用CSS动画。通过在多个<use>元素中引用相同的<path>,并给这些元素设置不同的动画属性,可以模拟波浪的运动。

        动画属性设置: animation: move 4s cubic-bezier(.55, .5, .45, .5) infinite: 为波浪设置动画。move是动画的名称,4s表示动画周期为4秒,cubic-bezier函数用于定义动画的速度曲线,infinite表示动画将无限循环。

@keyframes move {
    0% {
        transform: translateX(-90px);
    }
    100% {
        transform: translateX(85px);
    }
}

        动画实现transform: translateX(...)用于在水平方向上移动波浪,制造出波动的效果。

3. 多层波浪的交错动画

        通过设置不同的动画延迟和持续时间,可以使各层波浪看起来交错波动,从而增加画面的层次感。

        设置不同的透明度和动画时间:fill-opacity: 控制波浪的透明度。animation-delay: 设置动画的开始延迟时间,使各层波浪的运动出现层次。animation-duration: 控制动画的周期长度,让波浪看起来更自然。

.waves use {
    fill-opacity: 1; /* 默认透明度 */
}

/* 第一层波浪 */
.waves use:nth-child(1) {
    animation-delay: -2s; /* 动画延迟时间 */
    animation-duration: 7s; /* 动画周期 */
    fill: rgba(100, 255, 155, 0.7); /* 颜色及透明度设置 */
}

/* 第二层波浪 */
.waves use:nth-child(2) {
    animation-delay: -3s;
    animation-duration: 10s;
    fill: rgba(100, 255, 155, 0.5);
}

/* 第三层波浪 */
.waves use:nth-child(3) {
    animation-delay: -4s;
    animation-duration: 13s;
    fill: rgba(100, 255, 155, 0.3);
}

/* 第四层波浪 */
.waves use:nth-child(4) {
    animation-delay: -5s;
    animation-duration: 20s;
    fill: rgba(100, 255, 155, 0.9);
}

成品展示

转gif有瑕疵,真实效果请自行运行查看


完整代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background-color: #f0f0f0;
        }

        .container {
            position: relative;
            width: 200px;
            height: 200px;
            overflow: hidden;
            border-radius: 100px;
            background: radial-gradient(at center, skyblue, lightblue, white);
            display: flex;
            align-items: flex-end;
            border: 1px solid #8f8f8f;
            box-shadow: 1px 1px 3px #66666679;
        }

        .waves {
            position: relative;
            width: 100%;
            height: 20vh;
            margin-bottom: -7px;
            min-height: 100px;
            max-height: 150px;
        }

        .parallax>use {
            animation: move 4s cubic-bezier(.55, .5, .45, .5) infinite;
        }

        @keyframes move {
            0% {
                transform: translateX(-90px);
            }

            100% {
                transform: translateX(85px);
            }
        }

        .waves use {
            fill-opacity: 1;
        }

        .waves use:nth-child(1) {
            animation-delay: -2s;
            animation-duration: 7s;
        }

        .waves use:nth-child(2) {
            animation-delay: -3s;
            animation-duration: 10s;
        }

        .waves use:nth-child(3) {
            animation-delay: -4s;
            animation-duration: 13s;
        }

        .waves use:nth-child(4) {
            animation-delay: -5s;
            animation-duration: 20s;
        }
    </style>
</head>

<body>
    <div class="container">
        <div>
            <svg class="waves" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
                viewBox="0 24 150 28" preserveAspectRatio="none" shape-rendering="auto">
                <defs>
                    <path id="gentle-wave" d="M-160 30c30 0 58-3 88-3s 58 3 88 3 58-3 88-3 58 3 88 3 v44h-352z" />
                </defs>
                <g class="parallax">
                    <use xlink:href="#gentle-wave" x="48" y="1" fill="rgba(100,255,155,0.7)" />
                    <use xlink:href="#gentle-wave" x="48" y="1" fill="rgba(100,255,155,0.5)" />
                    <use xlink:href="#gentle-wave" x="48" y="2" fill="rgba(100,255,155,0.3)" />
                    <use xlink:href="#gentle-wave" x="48" y="3" fill="rgba(100,255,155,0.9)" />
                </g>
            </svg>
        </div>
    </div>
</body>

</html>

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值