【HTML】SVG实现炫酷的描边动画

前沿

今天闲来无事,看到Antfu大佬的个性签名,觉得还是非常炫酷的,于是也想要搞一个自己的个性签名用来装饰自己的门面,不过由于手写的签名太丑了,遂放弃。于是尝试理解原理,深入研究此等密法,终于小有所成,发现原来是描边动画,于是记载如下,方便以后借鉴。
image.png

正文

首先,这里涉及的技术是SVG,当然很多前端小伙伴们会觉得SVG有点陌生。是的,SVG是一种图像格式,一般都是由设计师给我们前端画好了,我们只需要下载来用就可以啦。不过,如果能了解SVG对于自己的技术发展还是很有帮助的,首先我们来看一个简单的SVG动画例子。

线的动画

效果图:

代码如下:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>SVG描边动画</title><style>.p {/* 设置描边颜色为红色。 */stroke: red;/* 设置描边的宽度为10像素 */stroke-width: 10;/* 设置虚线的长度和间隔,这里表示长度为200像素,间隔也为200像素 */stroke-dasharray: 200;/* 设置虚线的起始偏移量为200像素,即虚线从起点开始的位置。 */stroke-dashoffset: 200;/** 应用名为"stroke"的动画,持续时间为2秒.并且动画结束后保持最终状态(forwards)*/animation: stroke 2s forwards;}@keyframes stroke {to {/* 表示在动画结束时将虚线的偏移量设置为0,即完全显示描边。 */stroke-dashoffset:  0;}}</style></head><body><svg class="icon" width="200" height="200"><line class="p" x1="0" y1="50%" x2="100%" y2="50%" /></svg></body>
</html>

分析:
我们从两方面入手分析,分别是html标签和css代码。

  • 对于html代码,我们不难发现这是一个svg,里面包含了标签为p的一条线。这条线的Y轴占一半,也就是竖直剧中,这条线的X轴从0100%表示这条线是从开始画到线的结束,长度为200px.
  • 对于css代码,这边有两个属性需要大家深刻理解,分别是stroke-dasharraystroke-dashoffset,以及还有一个keyframes动画的含义。
    • stroke-dasharray: 这个属性定义了虚线的图案,即虚线的长度和间隔。它是一个数组值,交替表示虚线的绘制部分和空白部分的长度。例如,如果设置为"20,10",则表示虚线的每一段长20像素,每一段之间的间隔长10像素。如果只设置一个值,如"400",则表示虚线的长度为400像素,间隔也为400像素,实际上这样的设置会形成实线效果,因为虚线长度和间隔相等。
    • stroke-dashoffset: 这个属性控制虚线的起始偏移量。它可以是正值或负值,正值表示虚线从路径的起点往路径的终点方向偏移,负值则相反。这个属性通常与动画结合使用,通过改变stroke-dashoffset的值来实现描边动画效果。例如,如果一条路径的虚线长度加间隔总和为200像素,将stroke-dashoffset设置为200像素,则虚线会被完全偏移出去,路径看起来就像是没有描边的。随着stroke-dashoffset逐渐减小到0,虚线会逐渐显示出来,形成动画效果。
    • keyframes: @keyframes用于定义动画的关键帧。to是@keyframes中的一个关键字,表示动画结束时的状态。在这里例子中,定义了名为stroke的关键帧动画,通过to { stroke-dashoffset: 0; }表示在动画结束时将虚线的偏移量设置为0,即完全显示描边。

不知道大家理解了没有,我举两个例子考考大家。

  1. 不带动画时,当stroke-dasharray为50,stroke-dashoffset为0是什么样的。
  2. 不带动画时,当stroke-dasharray为50,stroke-dashoffset为50是什么样的。

结论如下:

圆的动画

我们知道了线的动画,那么我们举一反三举个类似的例子,如何画一个圆呢?其实本质跟上面一样,不过有些许不同。稍后我们细致分析下。
效果图:
2.gif
代码如下:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>SVG描边动画</title><style>.p {stroke: red;stroke-width: 10;stroke-dasharray: var(--length);stroke-dashoffset: var(--length);animation: stroke 2s forwards;/** 不给填充色 **/fill: none;}@keyframes stroke {to {stroke-dashoffset: 0;}}</style></head><body><svg class="icon" width="200" height="200"><circle class="p" cx="50%" cy="50%" r="30%"></circle></svg><script>const paths = document.querySelectorAll(".icon .p");paths.forEach((path) => {// +1是为了去除圆起点和末尾的空隙。const len = path.getTotalLength() + 1;path.style.setProperty("--length", len);});</script></body>
</html>

分析:
我们将代码跟线的代码稍作对比,发现最大有一处不同,也就是多了JS的代码,我们分析下为什么需要JS代码呢。
你看下面这段代码,定义了一个圆形,圆形中心点的x和y坐标,都设置为 “50%” 表示圆形中心点位于SVG画布居中,r="30%" 这是圆形的半径,设置为 “30%” 表示半径是SVG画布宽度和高度的30%。
这就有一个问题了,半径为30%,这个圆的长度到底多长呢?手算的话是不是太累了,于是我们就想到了用Js通过调用getTotalLengthAPI直接取到长度,岂不一劳永逸?

<circle class="p" cx="50%" cy="50%" r="30%"></circle>

SVG的动画

有读者问,我理解了一条线的动画,也理解了圆的动画,我现在想要其他SVG的动画该如何实现呢? 很好的问题,其实几乎所有的SVG动画原理于一条线的动画几乎类似,都是触类旁通滴。
我们去网上随便下一个SVG图。楼主下了一个爱心,将原先的代码对应的path改成爱心的即可。

注意,记得去掉path标签里的stroke-dasharraystroke-dashoffset

效果图:
Feb-19-2024 09-19-13.gif
代码如下:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>SVG描边动画</title><style>.p {stroke: red;stroke-width: 2;stroke-dasharray: var(--length);stroke-dashoffset: var(--length);animation: stroke 4s forwards;fill: none;}@keyframes stroke {to {stroke-dashoffset: 0;}}</style></head><body><svg class="icon" width="200" height="200"><pathclass="p"d="M150.383,18.301c-7.13-3.928-15.308-6.187-24.033-6.187c-15.394,0-29.18,7.015-38.283,18.015    c-9.146-11-22.919-18.015-38.334-18.015c-8.704,0-16.867,2.259-24.013,6.187C10.388,26.792,0,43.117,0,61.878    C0,67.249,0.874,72.4,2.457,77.219c8.537,38.374,85.61,86.771,85.61,86.771s77.022-48.396,85.571-86.771    c1.583-4.819,2.466-9.977,2.466-15.341C176.104,43.124,165.716,26.804,150.383,18.301z"></path></svg><script>const paths = document.querySelectorAll(".icon .p");paths.forEach((path) => {const len = path.getTotalLength() + 1;path.style.setProperty("--length", len);});</script></body>
</html>

尾注

本人参考了若干篇文章以及视频,在此对他们表示感谢🙏。

  • 渡一教育 的 《SVG的描边动画》视频
  • 掘金 singsong作者的 《SVG 描边动画就这么简单》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/259801.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Springboot的新能源充电系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的新能源充电系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&a…

【开源】基于JAVA+Vue+SpringBoot的就医保险管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 科室档案模块2.2 医生档案模块2.3 预约挂号模块2.4 我的挂号模块 三、系统展示四、核心代码4.1 用户查询全部医生4.2 新增医生4.3 查询科室4.4 新增号源4.5 预约号源 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVue…

ZigBee学习——基于AF的数据通信

文章目录 一、简单描述符1.1 简单介绍1.2 简单描述结构体介绍1.3 结构体中的簇1.4 应用场景 二、AF通信原理2.1 通信过程2.2 端点号分类2.3 通信方式2.4 注册简单描述符 三、数据发送API简介3.1 AF层数据发送API3.2 基于AF层封装的通信API3.2.1 点对点通信API3.2.2 广播通信API…

Linux------环境变量

目录 前言 一、环境变量 二、添加PATH环境变量 三、HOME环境变量 四、查看所有环境变量 1.指令获取 2.代码获取 2.1 getenv 2.2main函数的第三个参数 2.3 全局变量environ 五、环境变量存放地点 六、添加自命名环境变量 七、系统环境变量具有全局属性 八、环境变…

Shiro-05-5 分钟入门 shiro 安全框架实战笔记

序言 大家好&#xff0c;我是老马。 前面我们学习了 web 安全之 Spring Security 入门教程 这次我们来一起学习下另一款 java 安全框架 shiro。 什么是Apache Shiro&#xff1f; Apache Shiro是一个功能强大且易于使用的Java安全框架&#xff0c;它为开发人员提供了一种直…

区块链技术和Hyperledger Fabric介绍

1 区块链介绍 1.1 区块链技术形成 1.1.1 起源 在比特币诞生之时&#xff0c;技术专家们开始研究比特币的底层技术&#xff0c;并抽象提取出来&#xff0c;形成区块链技术&#xff0c;或者称分布式账本技术。 1.1.2 定义 简称BT&#xff08;Blockchain technology&#xff…

8 款顶级开源漏洞扫描工具推荐

1.OpenVAS OpenVAS漏洞扫描器是一种漏洞分析工具&#xff0c;由于其全面的特性&#xff0c;可以使用它来扫描服务器和网络设备。这些扫描器将通过扫描现有设施中的开放端口、错误配置和漏洞来查找IP地址并检查任何开放服务。扫描完成后&#xff0c;将自动生成报告并以电子邮件形…

基于springboot的鞋类商品购物商城系统

文章目录 目录 文章目录 前言 一、功能设计 二、功能实现 2.1 后台功能 2.1.1 管理员登录界面 2.1.2 系统首页 2.1.3 会员管理 2.1.4 栏目管理 2.1.5 商品管理 2.1.6 评价管理 2.1.7 订单管理 2.2 前台功能 2.2.1 新用户注册登录 2.2.2 首页 2.2.3 商品分类 2.2.4 地址管理 2.2…

(AtCoder Beginner Contest 341)(A - D)

比赛地址 : Tasks - Toyota Programming Contest 2024#2&#xff08;AtCoder Beginner Contest 341&#xff09; A . Print 341 模拟就好了 &#xff0c; 先放一个 1 , 然后放 n 个 01 ; #include<bits/stdc.h> #define IOS ios::sync_with_stdio(0);cin.tie(0);cout…

Nature Chemical Engineering 威斯康星大学让机器人科学家做实验,自主设计全新蛋白质

【导读】这个自动化蛋白质设计系统可以自己设计和测试新的蛋白质&#xff0c;不需要人类的帮助。就像一个能自己做实验的机器人科学家。它能通过自主学习自行进行蛋白质设计&#xff0c;同时在实验室里自动进行测试。 AI Agent&#xff0c;已经可以不需要人类帮助&#xff0c;…

数据结构-邻接矩阵

介绍 邻接矩阵&#xff0c;是表示图的一种常见方式&#xff0c;具体表现为一个记录了各顶点连接情况的呈正方形的矩阵。 假设一共有以下顶点&#xff0c;其连接关系如图所示 那么&#xff0c;怎么表示它们之间的连接关系呢&#xff1f; 我们发现&#xff0c;各条边所连接的都…

7.1 Qt 中输入行与按钮

目录 前言&#xff1a; 技能&#xff1a; 内容&#xff1a; 参考&#xff1a; 前言&#xff1a; line edit 与pushbotton的一点联动 当输入行有内容时&#xff0c;按钮才能使用&#xff0c;并能读出输入行的内容 技能&#xff1a; pushButton->setEnabled(false) 按钮不…

django中的中间件

在Django中&#xff0c;中间件&#xff08;Middleware&#xff09;是一个轻量级的、底层的“插件”系统&#xff0c;用于全局地修改Django的输入或输出。每个中间件组件都负责执行一些特定的任务&#xff0c;比如检查用户是否登录、处理日志、GZIP压缩等。Django的中间件提供了…

Python安装GDAL库

目录 一、GDAL介绍 二、GDAL应用 三、python安装GDAL库 一、GDAL介绍 GDAL&#xff08;Geospatial Data Abstraction Library&#xff09;是一个在X/MIT许可协议下的开源栅格空间数据转换库。它利用抽象数据模型来表达所支持的各种文件格式&#xff0c;并且提供了一系列命令…

10分钟带你了解分布式系统的补偿机制

我们知道&#xff0c;应用系统在分布式的情况下&#xff0c;在通信时会有着一个显著的问题&#xff0c;即一个业务流程往往需要组合一组服务&#xff0c;且单单一次通信可能会经过 DNS 服务&#xff0c;网卡、交换机、路由器、负载均衡等设备&#xff0c;而这些服务于设备都不一…

(10)Hive的相关概念——文件格式和数据压缩

目录 一、文件格式 1.1 列式存储和行式存储 1.1.1 行存储的特点 1.1.2 列存储的特点 1.2 TextFile 1.3 SequenceFile 1.4 Parquet 1.5 ORC 二、数据压缩 2.1 数据压缩-概述 2.1.1 压缩的优点 2.1.2 压缩的缺点 2.2 Hive中压缩配置 2.2.1 开启Map输出阶段压缩&…

elementui 中 el-date-picker 控制选择当前年之前或者之后的年份

文章目录 需求分析 需求 对 el-date-picker控件做出判断控制 分析 给 el-date-picker 组件添加 picker-options 属性&#xff0c;并绑定对应数据 pickerOptions html <el-form-item label"雨量年份&#xff1a;" prop"date"><el-date-picker …

洛谷 P6546 [COCI2010-2011#2] PUŽ

讲解&#xff1a; 首先还是正常输入&#xff1a; int a,b,v; cin>>a>>b>>v; 然后经入一个函数num&#xff1a; cout<<num(1.0*(v-a),(a-b))1<<endl; 之所以要乘以1.0是因为要向上取整&#xff01;而这个num函数的两个参数则是“蜗牛白天爬了多…

【智能家居入门2】(MQTT协议、微信小程序、STM32、ONENET云平台)

此篇智能家居入门与前两篇类似&#xff0c;但是是使用MQTT协议接入ONENET云平台&#xff0c;实现微信小程序与下位机的通信&#xff0c;这里相较于使用http协议的那两篇博客&#xff0c;在主程序中添加了独立看门狗防止程序卡死和服务器掉线问题。后续还有使用MQTT协议连接MQTT…

LabVIEW焊缝缺陷超声检测与识别

LabVIEW焊缝缺陷超声检测与识别 介绍基于LabVIEW的焊缝缺陷超声检测与识别系统。该系统利用LabVIEW软件和数据采集卡的强大功能&#xff0c;实现了焊缝缺陷的在线自动检测&#xff0c;具有通用性、模块化、功能化和网络化的特点&#xff0c;显著提高了检测的效率和准确性。 随…