wired-link 手绘风格链接组件:使用指南与源码实现解析
2026/9/23 15:37:41 网站建设 项目流程
  • UI组件
  • 前端

【免费下载链接】wired-elements

Collection of custom elements that appear hand drawn. Great for wireframes or a fun look.

项目地址:https://gitcode.com/gh_mirrors/wi/wired-elements
点击查看免费下载

wired-link 是 wired-elements 组件库中一个将原生<a>锚点/链接包装为手绘(hand-drawn)风格的 Web Component。它专门用于线框图(wireframe)原型或追求涂鸦视觉风格的页面,让普通超链接的底部下划线变成一条条带有抖动笔触的“手绘”线段。读完本文,你将掌握 wired-link 的安装引入方式、elevation/href/target三个核心属性与自定义下划线颜色的完整用法,并从源码层面理解其手绘下划线是如何基于 Rough.js 绘制出来的。

一、wired-link 是什么

wired-elements 是一套“看起来像手绘”的自定义元素集合(详见仓库 README.md),wired-link 正是其中的链接组件。与原生<a>相比,它保留了链接的所有语义与交互(可点击跳转、支持hreftarget),同时用抖动的 SVG 手绘线段替代浏览器默认的平滑下划线,实现 docs/wired-link.md 中所说的 "Hand-drawn sketchy Anchor/Link web component"。

从源码结构看,WiredLink类定义于 src/wired-link.ts,并作为聚合导出的一部分出现在 src/wired-elements.ts 的export * from './wired-link'中——这意味着你可以从wired-elements总入口一次性引入,也可以单独引入该模块。

二、安装与引入方式

wired-elements 以 npm 包形式发布,当前仓库版本为3.0.0-rc.7(见 package.json),是一个 ESM 模块包("type": "module"),依赖 lit 2.x 与 roughjs 4.x。

1. 通过 npm 安装

npm i wired-elements

2. 在 JavaScript/TypeScript 中按模块引入

// 方式一:从聚合入口引入 import { WiredLink } from 'wired-elements'; // 方式二:直接引入单个模块文件 import { WiredLink } from 'wired-elements/lib/wired-link.js';

两种方式等价,lib/目录为 TypeScript 源码经编译后的产物("outDir": "./lib",见 tsconfig.json)。引入后<wired-link>自定义元素即被注册,可直接在 HTML 中使用。

3. 通过 CDN 直接在 HTML 页面加载

<script type="module" src="https://unpkg.com/wired-elements/lib/wired-link.js?module"></script>

对于快速原型或纯静态演示场景,这种方式无需任何构建步骤。仓库中的 examples/link.html 即采用此思路(本地路径<script type="module" src="../lib/wired-link.js"></script>)演示了 wired-link 的三种典型用法。

三、基础用法

引入组件后,在 HTML 中直接书写<wired-link>标签即可:

<wired-link href="/more.html">Learn more</wired-link> <wired-link elevation="3" href="/more.html" target="_blank">Elevation</wired-link>
  • 第一行:使用默认样式的手绘链接,href指向/more.html
  • 第二行:通过elevation="3"将下划线加粗到 3 层笔触,并通过target="_blank"让链接在新窗口/新标签页打开。

在 examples/link.html 中可以看到更贴近实战的写法——把 wired-link 直接嵌进段落文字流中,与wired-buttonwired-input等其他组件联动,包括target="_blank"的“新标签页打开”示例。由于组件默认display: inline-block(见源码样式表),它可以像内联元素一样自然融入文本段落。

四、核心属性详解

wired-link 共暴露三个公开属性,全部在 src/wired-link.ts 中以 lit 装饰器声明:

属性类型默认值说明
elevationNumber1手绘下划线的层数(高度),取值范围 1~5(含两端)
hrefString链接指向的页面 URL
targetString链接的目标窗口,语义同原生<a>target

1. elevation —— 下划线“高度”

文档明确指出其为 1~5(含)之间的数字,默认 1。从源码实现看,该值会被强制收敛到合法区间:

const elev = Math.min(Math.max(1, this.elevation), 5);

这段逻辑同时出现在canvasSize()draw()中,意味着即使传入0100,实际生效值也会被钳制到 1~5。elevation的值决定了手绘下划线由多少条独立线段堆叠而成,值越大,链接下方的手绘“墨迹”越厚,视觉上越醒目。

2. href —— 跳转地址

即链接的目标 URL,最终被渲染到内部<a>元素的href属性上(见下文渲染模板)。不设置href时,渲染出的<a href="undefined">不会发生跳转,链接退化为纯视觉元素,适合仅用于装饰或占位场景。

3. target —— 打开方式

语义与原生<a>target完全一致,常用值如_blank(新标签页打开)、_self(当前页打开)。在渲染时未设置或为空字符串时,会渲染为target="",等价于默认的当前页行为。

五、自定义样式:手绘下划线颜色

wired-link 通过两个 CSS 通道控制颜色:

  • --wired-link-decoration-color:手绘下划线的颜色,默认值为blue。这是 wired-link 唯一对外暴露的自定义 CSS 属性(Custom CSS Property);
  • color:链接前景(文字)颜色。源码样式表中a, a:hover, a:visited { color: inherit; }表明文字颜色继承自宿主上下文,因此直接设置组件的color即可改变文字颜色,而无需分别处理:hover:visited等伪类。

典型用法:

<style> .red-link { --wired-link-decoration-color: #e53935; color: #c62828; } </style> <wired-link class="red-link" href="/more.html">红色的手绘链接</wired-link>

从 src/wired-base.ts 的BaseCSS可以看到,所有 wired 组件的 SVG path 默认stroke: currentColorstroke-width: 0.7,而 wired-link 在 src/wired-link.ts 的组件级样式中覆盖了 path 的描边色为stroke: var(--wired-link-decoration-color, blue),并将stroke-opacity设为0.45——这就是下划线呈半透明蓝色的来源。

值得一提的无障碍细节:源码还为聚焦态单独设置了样式a:focus path { stroke-opacity: 1; },即键盘 Tab 聚焦到链接时,下划线会从不透明度 0.45 提升到 1,形成清晰的焦点指示。

六、实现原理:手绘下划线从何而来

wired-link 的手绘效果完全建立在Rough.js(手绘风格图形库)与 lit 的渲染管线之上,其核心流程在 src/wired-link.ts 中只有两个方法,逻辑非常精巧。

1. 渲染模板:真实<a>+ SVG 覆盖层

render(): TemplateResult { return html` <a href="${this.href}" target="${this.target || ''}"> <slot></slot> <div id="overlay"><svg></svg></div> </a> `; }

组件内部渲染一个真实的<a>元素以保留语义与原生跳转行为,文字内容通过<slot>投射;下划线则绘制在一个覆盖层<div id="overlay">内的空<svg>上。BaseCSS(src/wired-base.ts)规定#overlay为绝对定位、铺满宿主、pointer-events: none,因此手绘 SVG 不会拦截鼠标事件,链接点击照常生效。同时a的样式被显式重置为text-decoration: none; border: none;,确保浏览器默认下划线被完全移除,只保留手绘覆盖层。

2. 画布尺寸:elevation 参与高度计算

canvasSize()负责计算 SVG 画布大小:

protected canvasSize(): Point { if (this.anchor) { const size = this.anchor.getBoundingClientRect(); const elev = Math.min(Math.max(1, this.elevation), 5); const w = size.width; const h = size.height + ((elev - 1) * 2); return [w, h]; } return this.lastSize; }

画布宽度等于链接文字的实际渲染宽度,高度则在文字高度基础上额外增加(elevation - 1) * 2像素,为多层下划线预留纵向空间。这里的this.anchor是通过@query('a')获取的内部锚点元素。

3. 绘制:逐层叠加手绘线段

draw()是手绘效果的关键:

protected draw(svg: SVGSVGElement, size: Point) { const elev = Math.min(Math.max(1, this.elevation), 5); const s = { width: size[0], height: size[1] - ((elev - 1) * 2) }; for (let i = 0; i < elev; i++) { line(svg, 0, s.height + (i * 2) - 2, s.width, s.height + (i * 2) - 2, this.seed); line(svg, 0, s.height + (i * 2) - 2, s.width, s.height + (i * 2) - 2, this.seed); } }

要点有三:

  • 循环绘制elevation是多少,就在链接底部水平位置循环画多少条线段,每条线段纵向间距 2px,elevation越大下划线越“粗”;
  • 双重绘制:同一位置的线段被调用line()两次,配合 Rough.js 的随机抖动,两条近似但略有偏差的线段叠加出更明显的“手绘复笔”质感;
  • 种子随机this.seed来自WiredBase构造时的Math.floor(Math.random() * 2 ** 31)(见 src/wired-base.ts),使每次渲染的抖动笔迹都不同,这正是手绘随机感的来源。

line()函数定义于 src/wired-lib.ts 的 L100-L102,内部调用 Rough.js 的roughLine生成带随机偏移的 OpSet,再转换为 SVG<path>节点插入覆盖层。当宿主尺寸变化(如窗口缩放、文字换行)时,WiredBase.updated()会触发wiredRender()重绘:先比较新旧尺寸,变化时才清空 SVG 子节点并重新draw(),避免无谓的重绘开销。

4. 焦点管理

WiredLink重写了focus()方法,将焦点委托给内部<a>锚点:

focus() { if (this.anchor) { this.anchor.focus(); } else { super.focus(); } }

这保证了原生键盘导航(Tab 键聚焦)与无障碍辅助技术能够像对待普通链接一样对待 wired-link,聚焦后下划线不透明度提升的样式正是为此设计的。

七、注意事项与最佳实践

  1. 属性取值elevation会被钳制到 1~5,传入其他数值虽不会报错,但超出部分不会生效;推荐直接使用合法区间值。
  2. 必须提供可见内容<slot>是空的话链接没有可点击区域,务必在标签内书写文字或嵌入其他可渲染内容。
  3. 颜色对比度:默认下划线为半透明蓝色(stroke-opacity: 0.45),在浅色背景上若观感过淡,可通过--wired-link-decoration-color加深颜色。
  4. 配合其他 wired 组件:wired-link 与wired-buttonwired-card等组件视觉风格统一,适合整体采用手绘风格的原型或趣味性页面(参考 examples/link.html 的联动示例)。
  5. 安装方式与版本:仓库当前版本为3.0.0-rc.7(预发布版本),如线上环境建议关注正式版本发布情况;模块使用 ESM 格式,旧式浏览器需配合构建工具或原生 ESM 支持。

八、许可证

wired-link 随 wired-elements 整体以 MIT License 开源,版权所有者为 Preet Shihn。可在仓库根目录的 LICENSE 文件中查看完整的许可条款。


参考文件索引

  • 官方文档:docs/wired-link.md
  • 组件实现:src/wired-link.ts
  • 基类与渲染管线:src/wired-base.ts
  • 手绘线条工具:src/wired-lib.ts
  • 使用示例:examples/link.html
  • 聚合导出:src/wired-elements.ts
  • 包配置:package.json
  • UI组件
  • 前端

【免费下载链接】wired-elements

Collection of custom elements that appear hand drawn. Great for wireframes or a fun look.

项目地址:https://gitcode.com/gh_mirrors/wi/wired-elements
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询