1

SVG实现海浪效果


前言
今天无意间看到了某网站的海浪效果,F12看了下是用竟然是用SVG实现的,瞬间勾起了我的好奇心。话不多说,先看效果图。

image.png

SVG介绍
SVG是一种开放标准的矢量图形语言,**可让你设计激动人心的、高分辨率的Web图形页面**。
今天的主角 -- path
path元素是SVG基本形状中最强大的一个,它不仅能创建其他基本形状,还能创建更多其他形状。

你可以用path元素绘制矩形(直角矩形或者圆角矩形)、圆形、椭圆、折线形、多边形,以及一些其他的形状,例如贝塞尔曲线、2次曲线等曲线。 

path元素的形状是通过属性d来定义的,属性d的值是一个“命令+参数”的序列
path常用属性
stroke // 定义线条颜色
fill // 定义填充颜色(支持rgba)
d // 定义图形 (必须)
path的d属性
M = moveto  // 定义起点
L = lineto  // 画线, 需要定义起点和终点
H = horizontal lineto  // 水平线,只需定义长度
V = vertical lineto  // 垂直线,只需定义长度
C = curveto  // 三次贝塞尔曲线 
S = smooth curveto  // 光滑曲线
Q = quadratic Bézier curve  // 二次贝塞尔曲线
T = smooth quadratic Bézier curveto  // 光滑二次贝塞尔曲线
A = elliptical Arc  // 椭圆弧
Z = closepath // 闭合图形(从当前点连接起点)

注意:以上所有命令均允许小写字母。大写表示绝对定位,**小写表示相对定位**。
坐标规则

image.png

画一条线
起点: (50,50)  // M50,50
终点: (100, 100) // L100,100
<svg width="100%" height="500px">
    <path stroke="blue" d="M50,50 L 100 100 Z" />
</svg>

image.png

画一个三角形
定点A: (100,100)  // M50,50
左下角B点: (50, 150) // L 50,150
右下角C点:(150, 150) // L 150,150
<svg width="100%" height="500px" style="background: rgba(33, 150, 243, 0.3)">
    <!-- 使用绝对定位 -->
    <path fill="none" stroke="blue" d="M100,100 L50 150 L150,150 Z" />

    <!-- 使用相对定位(当前画笔的位置为原点) -->
    <path fill="rgba(33, 150, 243, 0.7)" d="M300,100 l-50 50 l100,0 Z" />
</svg>

image.png

画一条曲线
比较复杂,下次单独讲解
<svg width="100%" height="200px" style="background: rgba(33, 150, 243, 0.3)">
    <!-- 二次贝塞尔曲线 c x1 y1 x y -->
    <path fill="rgba(33, 150, 243, 0.7)" d="M100,100 q150 -50 300 0 Z" />

    <!-- 三次贝塞尔曲线 c x1 y1 x2 y2 x y -->
    <path fill="rgba(33, 150, 243, 0.7)" d="M500,100 c100 -50 200 -50 300 0 Z" />
</svg>

image.png

分析海浪由什么组成

image.png
image.png

1、我们可以看到,波浪是由三组图像组成的,所以需要3个path来实现
2、每一组波浪由 曲线、直线 填充背景色组成
画海浪
<svg width="100%" height="300px" style="background: rgba(33, 150, 243, 0.3)">
   <!-- 使用了两次c,画了两次曲线 -->
   <path fill="rgba(33, 150, 243, 0.5)" d="M0,100 c200 -50 300 -50 500 0 c200 50 300 50 500 0 l0,100 l-1600, 0 Z" />
</svg>

image.png

画三条海浪
1、背景色形成远近错觉
2、三条波浪的位置前后错开
<svg width="100%" height="300px" style="background: rgba(33, 150, 243, 0.3)">
    <path fill="rgba(33, 150, 243, 0.3)" d="M100,100 c200 -50 300 -50 500 0 c200 50 300 50 500 0 l0,100 l-1600, 0 Z" />
    <path fill="rgba(33, 150, 243, 0.5)" d="M400,100 c200 -50 300 -50 500 0 c200 50 300 50 500 0 l0,100 l-1600, 0 Z" />
    <path fill="rgba(33, 150, 243, 0.7)" d="M200,100 c200 -50 300 -50 500 0 c200 50 300 50 500 0 l0,100 l-1600, 0 Z" />
</svg>

image.png

如何让海浪动起来
1、只需要改变每组海浪的起点位置即可
2、使用js动态改变path的d属性
3、为了效果更好,分别定义每组波浪的移动速度
<svg id="svg-area" width="100%" height="200px">
    <path fill="rgba(33, 150, 243, 0.3)" d="M-605.75,100c300 -50 500 -50 800 0c300 50 500 50 800 0c300 -50 500 -50 800 0c300 50 500 50 800 0c300 -50 500 -50 800 0c300 50 500 50 800 0c300 -50 500 -50 800 0c300 50 500 50 800 0l0,200 l-6400,0Z"></path>
    <path fill="rgba(33, 150, 243, 0.5)" d="M-605.75,100c300 -50 500 -50 800 0c300 50 500 50 800 0c300 -50 500 -50 800 0c300 50 500 50 800 0c300 -50 500 -50 800 0c300 50 500 50 800 0c300 -50 500 -50 800 0c300 50 500 50 800 0l0,200 l-6400,0Z"></path>
    <path fill="rgba(33, 150, 243, 0.7)" d="M-108.75,100c300 -50 500 -50 800 0c300 50 500 50 800 0c300 -50 500 -50 800 0c300 50 500 50 800 0c300 -50 500 -50 800 0c300 50 500 50 800 0c300 -50 500 -50 800 0c300 50 500 50 800 0l0,200 l-6400,0Z"></path>
</svg>

<script>
    let waterSvg = document.querySelector('#svg-area');
    let svgCommonPath = '100 c300 -50 500 -50 800 0c300 50 500 50 800 0c300 -50 500 -50 800 0c300 50 500 50 800 0c300 -50 500 -50 800 0c300 50 500 50 800 0c300 -50 500 -50 800 0c300 50 500 50 800 0l0,200 l-6400,0Z';

    let pathMConfig = [
        {startX: -605.75, step: 1, min: -1600},
        {startX: -605.75, step: 1.75, min: -4800},
        {startX: -108.75, step: 2.5, min: -1600}
    ]

    setInterval(function(){
        pathMConfig.forEach((item, index) => {
            item.startX = item.startX < item.min ? 0 : item.startX - item.step;
            waterSvg.children[index].setAttribute('d', `M${item.startX},${svgCommonPath}`);
        })
    }, 50)
</script>

欢迎留言评论!


Eric
540 声望10 粉丝

热爱学习的骚年,一起成长吧!