首页/新闻资讯/正文详情

wired-elements 的 wired-spinner 手绘风加载指示器:API 详解与源码级动画原理

发布时间:2026/9/23 16:45:05 来源:云帆数科 栏目:资讯中心
wired-elements 的 wired-spinner 手绘风加载指示器:API 详解与源码级动画原理
wired-elements 的 wired-spinner 手绘风加载指示器API 详解与源码级动画原理【免费下载链接】wired-elementsCollection of custom elements that appear hand drawn. Great for wireframes or a fun look.项目地址: https://gitcode.com/gh_mirrors/wi/wired-elementswired-spinner 是 wired-elements 组件库中一个手绘素描风的加载指示器loading spinner用于展示进度或任务进行中的状态。本文以 docs/wired-spinner.md 为主线结合 src/wired-spinner.ts 源码与 examples/spinner.html 示例完整讲解其安装、HTML 用法、两个核心属性spinning、duration以及 CSS 着色方式并深入剖析其基于 SVG 与requestAnimationFrame的动画实现原理帮助你既能快速上手也能理解其内部机制。组件简介wired-spinner是一个继承自WiredBase的 Web Component自定义元素渲染为一个 76×76 的 SVG 画布外圈是一个粗糙手绘风格的椭圆描边内部是一个通过斜线填充hachure绘制的小旋钮knob旋钮沿椭圆轨道匀速旋转形成加载动画。它的定位是给线框图wireframe或趣味界面提供一个符合整体手绘风格的加载反馈。完整的 wired-elements 组件集合与在线演示可在 wiredjs.com 查看本组件与库内其他元素如 wired-button、wired-progress配合使用效果最佳。安装与引入方式一npm 安装推荐在你的 JavaScript 项目中安装 wired-elements 包npm i wired-elements然后在代码中按需导入模块两种写法等价均从包名导出import { WiredSpinner } from wired-elements; // 或 import { WiredSpinner } from wired-elements/lib/wired-spinner.js;第一种写法利用 src/wired-elements.ts 中的统一出口export * from ./wired-spinner批量导入第二种写法直接指向单文件模块适合只想引入单个组件、减小打包体积的场景。当前仓库package.json声明版本为3.0.0-rc.7采用 ESMtype: module依赖litv2 系列与roughjsv4.3.1请确保你的构建工具支持 ES Modules 与自定义元素。方式二CDN 直接加载不经过构建工具时可以在 HTML 中通过script typemodule直接加载script typemodule srchttps://unpkg.com/wired-elements/lib/wired-spinner.js?module/script方式三本地构建后引用仓库根目录执行npm run build即rm -rf lib tsc见 package.json后会生成lib/目录示例页面 examples/spinner.html 便是这样引用本地产物的script typemodule src../lib/wired-spinner.js/script基本用法在 HTML 中直接书写wired-spinner标签即可wired-spinner idsp/wired-spinner wired-spinner spinning duration1000/wired-spinner第一个 spinner 未设置任何属性默认静止spinning默认为false只显示一个手绘椭圆环与静态旋钮。第二个 spinner 设置了spinning布尔属性HTML 中布尔属性只要出现即为true与duration1000因此会以每圈 1000ms 的速度旋转。交互示例点击按钮切换旋转状态参考 examples/spinner.html可以用一个按钮动态切换spinning属性wired-spinner idsp/wired-spinner wired-buttonToggle/wired-button script document.querySelector(wired-button).addEventListener(click, () { const sp document.getElementById(sp); sp.spinning !sp.spinning; }); /script由于spinning是响应式属性见下文属性表直接通过 JavaScript 修改sp.spinning即可驱动动画启停无需手动操作 DOM。属性Propertieswired-spinner 只有两个对外属性均定义在 src/wired-spinner.ts属性类型默认值说明spinningBooleanfalse是否处于旋转状态。为true时启动动画为false时停止。durationNumber1500完成一整圈旋转所需的时间毫秒。spinning 的响应式行为源码中通过property({ type: Boolean }) spinning false;声明并在生命周期钩子updated()中监听updated() { super.updated(); if (this.spinning) { this.startSpinner(); } else { this.stopSpinner(); } }也就是说只要spinning变为true组件立即调用startSpinner()重置计时并从第 0 帧开始旋转变为false时调用stopSpinner()取消动画帧。因此同一时刻只会有一个动画循环在运行反复切换也不会叠加多个定时器startSpinner()内部先调用stopSpinner()做防重入处理。duration 的作用边界duration表示旋钮走完一整圈旋转 360°的毫秒数数值越小转速越快。需要说明的是它只影响旋转速度不改变旋钮的轨道半径、组件尺寸或椭圆形状即使duration设置为 0单圈耗时也会被钳制在至少一帧value通过Math.min(1, ...)截断内完成。从源码看duration未设置上下限校验请按实际需要传入合理的正整数。样式定制wired-spinner 的配色非常简单修改元素自身的color样式即可改变其颜色。wired-spinner { color: red; /* 手绘描边与旋钮将变为红色 */ } wired-spinner.custom { color: #2c7be5; /* 也可以按类名单独指定 */ }这一机制依赖于 src/wired-base.ts 中的BaseCSSpath { stroke: currentColor; ... }以及 src/wired-spinner.ts 内的组件样式。组件内所有path的描边颜色均取currentColor因此只需覆盖color即可整体换色外圈椭圆描边stroke-opacity: 0.65、stroke-width: 1.5营造淡而细腻的手绘笔触旋钮.knob类stroke-width: 2.8、stroke-opacity: 1比外圈更粗更实突出旋转主体组件宿主display: inline-block; position: relative便于在文档流中内联布局。color支持任何合法的 CSS 颜色值例如#ff6600、rgb(...)、var(--primary)等。除此之外组件不暴露尺寸属性画布固定为 76×76见 src/wired-spinner.ts 的canvasSize()返回值如需缩放可对宿主元素使用 CSStransform: scale(...)。源码级原理解析1. 绘制阶段椭圆环 斜线填充旋钮组件渲染逻辑为render()返回一个空svg真正的内容在draw()中绘制src/wired-spinner.tsprotected draw(svg: SVGSVGElement, size: Point) { ellipse(svg, size[0] / 2, size[1] / 2, Math.floor(size[0] * 0.8), Math.floor(0.8 * size[1]), this.seed); this.knob hachureEllipseFill(0, 0, 20, 20, this.seed); this.knob.classList.add(knob); svg.appendChild(this.knob); this.updateCursor(); }外圈调用 src/wired-lib.ts 的ellipse()圆心在 (38, 38)宽高约为画布的 80%约 60.8px通过 roughjs 生成带随机抖动的手绘感椭圆路径内部options()使用roughness: 1、bowing: 0.85、maxRandomnessOffset: 2等参数见 src/wired-lib.ts。旋钮调用hachureEllipseFill(0, 0, 20, 20, this.seed)src/wired-lib.ts生成一个 20×20、以斜线hachure填充的小椭圆挂上.knob类并追加到 SVG。seed每个实例在构造时都会生成一个随机seedMath.floor(Math.random() * 2 ** 31)见 src/wired-base.ts保证每个 spinner 的笔触抖动、填充疏密都是独一无二的手绘痕迹这也是所有 wired 元素每次都不一样的原因。draw()由WiredBase.wiredRender()统一驱动src/wired-base.ts当尺寸未变化时不会重复重绘首次渲染后会给宿主添加wired-rendered类把透明度从0过渡到1BaseCSS中:host { opacity: 0 }→:host(.wired-rendered) { opacity: 1 }实现柔和的淡入效果。2. 动画阶段requestAnimationFrame 驱动动画的核心在startSpinner()/stopSpinner()/nextTick()/tick()这组私有方法src/wired-spinner.tsprivate nextTick() { this.frame window.requestAnimationFrame((t) this.tick(t)); } private tick(t: number) { if (this.spinning) { if (!this.timerstart) this.timerstart t; this.value Math.min(1, (t - this.timerstart) / this.duration); this.updateCursor(); if (this.value 1) { this.value 0; this.timerstart 0; } this.nextTick(); } else { this.frame 0; } }运行逻辑nextTick()通过window.requestAnimationFrame注册下一帧回调并把句柄存入this.frametick(t)收到浏览器提供的时间戳t以首次回调时间作为timerstart用(t - timerstart) / duration计算本圈进度value范围 01updateCursor()根据value计算旋钮的新位置当value达到 1 时归零并重置计时起点开启下一圈从而实现无缝循环只要spinning仍为true就继续注册下一帧一旦为false循环自然终止this.frame 0。stopSpinner()则会立即调用window.cancelAnimationFrame(this.frame)取消尚未执行的帧保证停止响应即时生效。3. 旋钮定位极坐标圆周运动updateCursor()src/wired-spinner.ts用极坐标把旋钮放到椭圆轨道上const position: Point [ Math.round(38 25 * Math.cos(this.value * Math.PI * 2)), Math.round(38 25 * Math.sin(this.value * Math.PI * 2)) ]; this.knob.style.transform translate3d(${position[0]}px, ${position[1]}px, 0) rotateZ(${Math.round(this.value * 360 * 2)}deg);圆心 (38, 38)轨道半径 25pxvalue从 0 到 1 对应角度 0 到 2πMath.cos/Math.sin给出圆周上的坐标translate3d使用 GPU 合成层旋转过程顺滑同时叠加rotateZ(value * 720)让旋钮自身每圈额外自转 720°两圈强化滚动的视觉动感动画是纯 CSStransform更新不触发回流/重排性能友好。4. 与 wired-elements 体系的协作wired-spinner通过customElement(wired-spinner)注册src/wired-spinner.ts并与其他组件一同从 src/wired-elements.ts 统一导出。它复用了WiredBase的canvasSize/draw抽象与seed机制是理解整个 wired 手绘体系roughjs 绘制 lit 响应式 随机 seed的最佳入门组件之一同类的进度类组件还有 wired-progress 与 wired-progress-ring可对比阅读。常见问题与提示为什么我的 spinner 不动默认spinning为false请确认已设置spinning属性或通过 JS 将sp.spinning置为true同时确认脚本为typemodule且组件已正确加载未加载成功时自定义元素不会被注册。如何调整速度修改duration属性即可单位为毫秒默认 1500ms/圈duration1000比默认快约 1/3。如何换颜色设置colorCSS 属性例如wired-spinner { color: tomato; }。如何停止动画将spinning置为false组件会通过cancelAnimationFrame立即停止不会在后台空转消耗资源。结语wired-spinner以极简的 API两个属性 一个颜色样式提供了与 wired-elements 手绘风格完全统一的加载指示能力外圈手绘椭圆 斜线填充旋钮 圆周旋转动画。通过阅读 src/wired-spinner.ts 源码你还能复用其极坐标定位 requestAnimationFrame 循环 CSS transform 更新的动画范式为自己的组件实现类似的轻量动效。无论是快速搭建线框图原型还是为趣味界面补充加载反馈它都是一个开箱即用、风格统一的选择。【免费下载链接】wired-elementsCollection of custom elements that appear hand drawn. Great for wireframes or a fun look.项目地址: https://gitcode.com/gh_mirrors/wi/wired-elements创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

3天搞定美丽中国高清下载:从报错到实战的保姆级教程
3天搞定美丽中国高清下载:从报错到实战的保姆级教程

3天搞定美丽中国高清下载:从报错到实战的保姆级教程 刚接手水利移动终端项目,一运行老代码,满屏的 404 Not Found 和 SyntaxError 。 版本升级后 API 全变了,原本能跑的下载逻辑瞬间崩盘,连个高清视频都拉不下来。… · 2026/9/23 16:44:59

从查价格到管价格,采购价格智能体能做什么?
从查价格到管价格,采购价格智能体能做什么?

导语:价格是采购决策中最敏感、也最难判断的因素之一。面对历史价格、成本、市场行情和供应商报价等多维信息,如何更快判断价格是否合理,并提升日常价格管理效率,正在成为企业采购数智化的重要课题。 供应商报价比上次高了&#x… · 2026/9/23 16:44:59

Hive Agent 用量与状态追踪:本地遥测能力盘点与云上可见架构方案
Hive Agent 用量与状态追踪:本地遥测能力盘点与云上可见架构方案

Hive Agent 用量与状态追踪:本地遥测能力盘点与云上可见架构方案 【免费下载链接】hive Multi-Agent Harness for Production AI 项目地址: https://gitcode.com/gh_mirrors/hive48/hive 本文基于 docs/internal/agent-usage-and-status-tracking.md 能力文档… · 2026/9/23 16:44:59

基于小程序的驾校报名系统源码解析与二次开发指南
基于小程序的驾校报名系统源码解析与二次开发指南

简介:这是一套面向高校计算机专业毕业设计与课程设计场景的驾校报名小程序完整源码,采用Java后端搭配微信小程序前端与MySQL数据库,适合需要快速搭建可运行项目、完成答辩或课程作业的学生与开发者。项目按管理员、用户、驾校教练三类角色划分… · 2026/9/23 18:07:09

基于OpenCV的车牌识别停车场管理系统:C++毕设完整实现与避坑指南
基于OpenCV的车牌识别停车场管理系统:C++毕设完整实现与避坑指南

简介:这份C毕业设计项目基于OpenCV实现车牌识别并搭建停车场管理系统,源码与论文齐备,面向计算机、通信、人工智能、自动化等专业学生及从业者,可作为课程设计、大作业或毕业设计的完整参考。项目在个人答辩中获得98分&#xff0c… · 2026/9/23 18:07:09

Hadoop图书推荐系统源码解析:Apriori算法与MapReduce实战
Hadoop图书推荐系统源码解析:Apriori算法与MapReduce实战

简介:这份资源是山东大学大数据课程设计的完整项目包,围绕基于Hadoop实现的图书推荐系统展开,适合大数据、计算机相关专业学生用于课程设计、期末大作业或毕业设计,也适合想入门推荐算法与分布式计算的新手参考。压缩包共78个文件… · 2026/9/23 18:07:02

基于PyTorch的Web恶意流量检测实战:从数据标签到模型部署
基于PyTorch的Web恶意流量检测实战:从数据标签到模型部署

简介:一套基于PyTorch搭建的Web恶意流量检测平台工程,面向网络安全研究人员与深度学习开发者,针对传统特征匹配难以识别新型攻击的痛点,提供从数据预处理、模型训练到可视化监测的完整解决方案。压缩包共76个文件,以39… · 2026/9/23 18:07:02

面试被问原理答不上来?一文搞懂魅族pro7发布会底层逻辑
面试被问原理答不上来?一文搞懂魅族pro7发布会底层逻辑

面试被问原理答不上来?一文搞懂魅族pro7发布会底层逻辑 面试官抛出“魅族pro7发布会”这个看似突兀的问题时,你愣住三秒,大脑一片空白。别慌,这不是考你手机参数,而是考察你透过现象看本质的系统思维。很多开发者死记硬背API文档,却不懂底层… · 2026/9/23 18:07:02

3个坑讲透dnf玩法:新手避坑指南与实战项目搭建
3个坑讲透dnf玩法:新手避坑指南与实战项目搭建

3个坑讲透dnf玩法:新手避坑指南与实战项目搭建 刚学完Python或Java语法,对着屏幕发呆,不知道第一行代码该敲什么?这种“会写Hello World却搭不起项目”的窘境,是绝大多数开发者入行时的第一道坎。很多 新手避坑… · 2026/9/23 18:07:02

3招搞定手机怎么下载微信面试难题实战项目解析
3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧
Win7无线热点配置工具源码解析:解决API失效的3个实战技巧

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧 Win7无线热点配置工具在Win10/11上跑不动?不是你的问题,是版本升级后 API 全变了。很多老项目里的 netsh wlan… · 2026/9/23 0:00:36

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码