SVG之绘制路径动画

概览

本篇主要讲述如何展示绘制路径的动画以及相关的css的知识。

一. 应用示例

直接上代码看效果

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

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Circular Drawing Animation</title>
  <style>
    .circle-path {
      stroke-dasharray: 471.24;
      /* 圆的周长,对于半径为75的圆,周长约为 2 * 3.14 * 75 = 471.24 */
      stroke-dashoffset: 471.24;
      /* 初始时偏移整个周长,使路径不可见 */
      animation: draw-circle 2s linear infinite;
    }

    @keyframes draw-circle {
      from {
        stroke-dashoffset: 471.24;
      }

      to {
        stroke-dashoffset: 0;
      }
    }
  </style>
</head>

<body>
  <svg width="800" height="800">
    <circle cx="75" cy="75" r="75" fill="none" stroke="pink" stroke-width="2" class="circle-path" />
    <!-- 或者使用 <path> 元素绘制更复杂的路径,但这里为了简单起见使用了 <circle> -->
  </svg>
</body>

</html>

主要属性介绍
circle元素:
cx,cy: 指的是相对于svg画布,圆心的坐标位置;

stroke-dasharray: stroke-dasharray属性定义了一个用于绘制虚线效果的模式。这个模式由一系列的数字组成,表示实线部分和间隙部分的长度(以用户单位表示,如像素)。这些值会循环使用,直到路径的末尾。

在上面的例子中,stroke-dasharray取值为总的路径长度,说明就是所有的路径都是实线;

stroke-dashoffset : stroke-dashoffset 是 SVG(可缩放矢量图形)中的一个属性,用于控制虚线的起始偏移量。
通过设置 stroke-dashoffset 的值,可以改变虚线样式开始的位置。其值可以是长度值,例如 px 、 em 等单位。
如果 stroke-dashoffset 的值为正值,虚线会向右偏移;如果值为负值,虚线会向左偏移。
例如,如果设置 stroke-dasharray 为 5 5 (表示虚线段长 5 ,间隔长 5 ), stroke-dashoffset 为 10 ,则虚线的起始位置会向右偏移 10 个单位。
这个属性常用于创建动画效果,例如让虚线逐渐显示或移动。

stroke-dashoffset有点难理解,可以看下面的例子

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <svg width="300" height="200">
    <path d="M 50 50 H 200" fill="none" class="path">  
    </path>  
  </svg>
</body>
<script>
  const path = document.querySelector('.path');
// 获取总长度
const totalLength = path.getTotalLength();
// 设置 stroke-dasharray
path.style.strokeDasharray = totalLength;
// 设置 stroke-dashoffset
path.style.strokeDashoffset = totalLength;

let currentFrame = 0;
let totalFrames = 160;
const draw = function() {
    let progress = currentFrame / totalFrames;
    if (progress > 1) {
        window.cancelAnimationFrame(handle);
    } else {
        currentFrame++;
        // 更新 stroke-dashoffset
        path.style.strokeDashoffset = totalLength * (1 - progress);  
        // 100% -> 0
        handle = window.requestAnimationFrame(draw);
    }
};
draw();
</script>
<style>
  .path {
    stroke: pink;
    stroke-width: 4;
  }
</style>
</html>

strokeDashoffset的理解可以以绘制的终点为参考,位置 = 终点位置 - strokeDashoffset; 如果strokeDashoffset的值为总路径,说明此时的位置在绘制的起点,如果strokeDashoffset为0,则此时的位置在终点。

二. CSS自定义属性(CSS Variables)

<!DOCTYPE html>  
<html lang="en">  
<head>  
  <meta charset="UTF-8">  
  <meta name="viewport" content="width=device-width, initial-scale=1.0">  
  <title>SVG Path Animation</title>  
  <style>  
    .path {  
      stroke: pink;  
      stroke-width: 4;  
      fill: none;  
      stroke-dasharray: var(--dasharray);  
      stroke-dashoffset: var(--dashoffset);  
      animation: draw 4s linear infinite;  
    }  
    @keyframes draw {  
      to {  
        stroke-dashoffset: 0;  
      }  
    }  
  </style>  
</head>  
<body>  
  <svg width="300" height="200">  
    <path d="M 50 50 H 200" class="path" id="myPath">  
    </path>  
  </svg>  
  
  <script>  
    document.addEventListener('DOMContentLoaded', function() {  
      var path = document.getElementById('myPath');  
      var pathLength = path.getTotalLength();  
      path.style.setProperty('--dasharray', pathLength + 'px');  
      path.style.setProperty('--dashoffset', pathLength + 'px');  
    });  
  </script>  
</body>  
</html>

**CSS自定义属性(也称为CSS变量)**允许你在CSS文档中设置一次值,然后在整个文档中重用这些值。它们以–为前缀,其中是变量名。这些变量可以在CSS的任何地方使用,包括在var()函数中,该函数用于引用自定义属性的值。

:root {  
  --main-bg-color: coral;  
}  
  
body {  
  background-color: var(--main-bg-color);  
}

JavaScript与CSS自定义属性的交互
虽然CSS自定义属性是在CSS中定义的,但JavaScript可以读取和修改这些属性的值。这允许你根据用户的交互或应用的逻辑动态地改变样式。

// 读取CSS自定义属性的值  
let bgColor = getComputedStyle(document.documentElement).getPropertyValue('--main-bg-color');  
  
// 修改CSS自定义属性的值  
document.documentElement.style.setProperty('--main-bg-color', 'lightblue');

三. 拓展

线条光效动画

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

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <div class="g-svg">
    <svg height="100%" width="100%" xmlns="http://www.w3.org/2000/svg">
      <!-- 设置阴影 -->
      <defs>
        <filter id="shadow">
          <feDropShadow dx="0" dy="0" stdDeviation="3" flood-color="red"/>
        </filter>
      </defs>
      <polyline points="240 10 140 10 140 90 0 90" stroke="#ddd" fill="transparent" stroke-width="2" />
      <polyline class="g-dashed-line" points="240 10 140 10 140 90 0 90" fill="transparent" stroke-width="2" filter="url(#shadow)" />
    </svg>
  </div>
</body>
<style>
 .g-svg {
    width: 240px;
    height: 100px;
  }

 .g-dashed-line {
    stroke: #fc0;
    stroke-dasharray: 40, 320;
    stroke-dashoffset: 0;
    animation: move 2.4s infinite linear;
  }

  @keyframes move {
    0% {
      stroke-dashoffset: 0;
    }

    100% {
      stroke-dashoffset: -320;
    }
  }
</style>

</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值