wired-icon-button 手绘图标按钮组件:安装、配置与源码实现解析
2026/9/24 19:17:15 网站建设 项目流程
  • 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-icon-button是 wired-elements 组件库中一个以"手绘素描风格"呈现的圆形图标按钮:它由 RoughJS 生成手绘椭圆边框,中心通过 slot 承载任意图标内容(例如 Material Icons 的mwc-icon),非常适合用于线框图(wireframe)、原型草图或追求手绘趣味风格的界面。本文以 docs/wired-icon-button.md 为骨架,完整覆盖其安装、导入、属性、CSS 变量与事件用法,并结合 src/wired-icon-button.ts 及 examples/icon-button.html 等仓库源码,深入讲解它的渲染原理、样式系统与可扩展用法,读完即可直接上手使用与二次定制。

组件是什么

根据 docs/wired-icon-button.md 的定义,wired-icon-button是一个"手绘素描风格的圆形按钮,中心放置一张图片"。这里的"图片"并非限制为<img>,也可以是由图标字体或图标 Web Component 渲染的图标,比如@material/mwc-icon(Material Web Components 的图标组件)。

在 src/wired-icon-button.ts 中,它通过@customElement('wired-icon-button')注册为原生自定义元素,继承自 src/wired-base.ts 中封装的WiredBase抽象基类,依赖 roughjs 与 lit 两个核心库(见 package.json)。

安装与引入

通过 npm 安装

在项目根目录执行:

npm i wired-elements

安装后,wired-icon-button会随wired-elements包一起提供(该包同时导出WiredButtonWiredInput等全套手绘组件,src/wired-elements.ts 中可见export * from './wired-icon-button'等统一导出)。

模块方式导入

在你的 JavaScript / TypeScript 代码中:

import { WiredIconButton } from 'wired-elements'; // 或按需单独引入,体积更小 import { WiredIconButton } from 'wired-elements/lib/wired-icon-button.js';

直接通过 CDN 加载

无需构建工具,直接在 HTML 页面中加载 ES Module:

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

注:以上路径以当前仓库wired-elements包(版本3.0.0-rc.7,见 package.json)为准,发布到 npm 后即可通过上述方式引用。

基础用法

引入组件后,直接在 HTML 中使用自定义标签即可:

<wired-icon-button> <mwc-icon>favorite</mwc-icon> </wired-icon-button> <wired-icon-button class="red"> <mwc-icon>favorite</mwc-icon> </wired-icon-button>

其中<mwc-icon>是 Material Design 的图标组件(需要额外引入@material/mwc-icon)。你也可以放入任意 HTML 内容——凡是能通过 slot 分发的内容都会被渲染在圆形手绘按钮的中央。

仓库的 examples/icon-button.html 给出了一个可直接运行的完整示例:它通过 Google Fonts 加载 Material Icons 字体,再引入@material/mwc-icon与本组件,页面中依次展示了默认样式、红色文字(.red)、粉色背景(.pinkbg)、大图标(.big)以及禁用态(disabled)五种形态。

属性(Properties)

disabled— 是否禁用按钮。默认值为false

<wired-icon-button disabled> <mwc-icon>favorite</mwc-icon> </wired-icon-button>

在 src/wired-icon-button.ts 第 8 行,它被声明为响应式布尔属性并反射到 DOM:

@property({ type: Boolean, reflect: true }) disabled = false;

reflect: true意味着当属性变化时,disabled会同步反映为 HTML attribute,便于通过 CSS 选择器匹配。渲染层通过?disabled="${this.disabled}"disabled透传给内部的原生<button>元素(第 63 行)。对应的禁用样式见第 38~43 行:

button[disabled] { opacity: 0.6 !important; background: rgba(0, 0, 0, 0.07); cursor: default; pointer-events: none; }

禁用后按钮呈现半透明、浅灰底且不响应鼠标事件的视觉效果。由于内部是真正的<button>元素,键盘焦点管理、表单语义等原生能力天然可用。

自定义 CSS 变量

组件通过两个 CSS 自定义属性暴露样式定制入口:

变量作用默认值
--wired-icon-size图标(slot 内容)的数字字号24(px)
--wired-icon-bg-color按钮背景色未设置(透明)

调整图标大小

在 src/wired-icon-button.ts 第 53~56 行,slot 内容的字号直接绑定该变量:

button ::slotted(*) { position: relative; font-size: var(--wired-icon-size, 24px); }

示例(对应 examples/icon-button.html 中的.big类):

<style> .big { --wired-icon-size: 40px; padding: 16px; } </style> <wired-icon-button class="big"> <mwc-icon>favorite</mwc-icon> </wired-icon-button>

设置背景色

--wired-icon-bg-colorWiredBase提供的基础样式(src/wired-base.ts 的BaseCSS)消费:

#overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; pointer-events: none; }

叠加层#overlay覆盖整个按钮区域但pointer-events: none,不拦截点击事件,手绘 SVG 绘制在其上。示例中的.pinkbg即通过该变量实现粉色背景:

<style> .pinkbg { color: red; --wired-icon-bg-color: pink; } </style> <wired-icon-button class="pinkbg"> <mwc-icon>favorite</mwc-icon> </wired-icon-button>

颜色跟随 currentColor

值得一提的是,手绘边框描边颜色并非由专门变量控制,而是继承currentColor(见 src/wired-base.ts 中path { stroke: currentColor; })。因此给wired-icon-button设置color即可改变手绘圆圈的线条颜色,示例中的.red { color: red; }正是利用了这一机制。

事件(Events)

click— 按钮被点击时触发。

由于组件内部渲染的是原生<button>元素(src/wired-icon-button.ts 第 63 行),click事件是浏览器原生事件,无需手动派发。使用方式:

const btn = document.querySelector('wired-icon-button'); btn.addEventListener('click', () => { console.log('icon button clicked'); });

或者在 HTML 中直接绑定:

<wired-icon-button onclick="alert('clicked')"> <mwc-icon>favorite</mwc-icon> </wired-icon-button>

disabledtrue时,原生<button>与样式中的pointer-events: none会共同阻止 click 事件的触发。

渲染原理:从 WiredBase 到手绘椭圆

wired-icon-button的手绘边框并非静态图片,而是运行时由 RoughJS 生成的 SVG。理解其原理有助于正确使用与排查尺寸问题。

模板结构

render()输出的模板(src/wired-icon-button.ts 第 61~70 行):

<button ?disabled="${this.disabled}"> <slot @slotchange="${this.wiredRender}"></slot> <div id="overlay"> <svg></svg> </div> </button>

关键点:<slot>负责分发用户放置的图标内容;<div id="overlay">内的<svg>是手绘椭圆绘制的画布;slotchange事件触发时会重新渲染手绘边框,保证图标尺寸变化后边框能自适应。

尺寸计算与绘制

组件继承WiredBase(src/wired-base.ts),实现两个抽象方法:

  1. canvasSize():取内部<button>getBoundingClientRect()宽高作为画布尺寸(第 72~78 行);
  2. draw(svg, size):取宽高中的较小值min,将 SVG 设为正方形,并在中心调用ellipse()绘制手绘椭圆(第 80~85 行):
protected draw(svg: SVGSVGElement, size: Point) { const min = Math.min(size[0], size[1]); svg.setAttribute('width', `${min}`); svg.setAttribute('height', `${min}`); ellipse(svg, min / 2, min / 2, min, min, this.seed); }

ellipse()定义于 src/wired-lib.ts 第 108~112 行,内部调用roughEllipse并返回 RoughJS 生成的<path>节点;this.seed是组件实例创建时随机生成的 31 位整数(src/wired-base.ts 第 38 行),用于控制手绘笔画的随机抖动——这也解释了为什么每个组件实例的"手绘感"都不完全一样。

渲染触发机制

WiredBase.updated()在每次属性/状态更新后自动调用wiredRender()wiredRender()会对比当前画布尺寸与上次记录值,仅在尺寸变化时重绘 SVG 并清除旧节点,避免无谓的 DOM 操作(src/wired-base.ts 第 44~59 行)。绘制完成后组件会添加wired-rendered类,配合BaseCSS:hostopacity: 0过渡到1的规则,实现"先隐藏、绘制完成再显示"的平滑呈现,避免闪烁。

交互反馈细节

源码中还有两处值得注意的交互细节(src/wired-icon-button.ts):

  • 按下时手绘路径微缩(第 44~46 行):button:active path { transform: scale(0.97) translate(1.5%, 1.5%); },模拟实体按钮被按下的效果;
  • 键盘聚焦时描边加粗(第 47~49 行):button:focus path { stroke-width: 1.5; },提升无障碍可访问性。

进阶:与 wired-icon 组合使用

mwc-icon外,wired-icon-button还可以与仓库中的实验性组件wired-icon(位于 experimental/wired-icon)组合,把手绘风格延伸到图标本身:wired-icon能将任意 SVG 图标转换为手绘版本,正好契合 icon button 的"手绘按钮 + 图标"场景。在wired-icon-button内部放置wired-icon,并利用--wired-icon-size控制图标显示尺寸,即可得到内外全部手绘的统一视觉风格。

许可协议

wired-icon-button随 wired-elements 项目以 MIT License 开源,版权归作者 Preet Shihn 所有(见 docs/wired-icon-button.md 与 package.json 的 license 字段)。

小结

wired-icon-button是一个实现简洁但细节完整的手绘图标按钮组件:

  • 用法:安装wired-elements后,以<wired-icon-button>标签 + slot 内容即可使用,支持 npm 模块导入与 CDN 直接加载;
  • 定制disabled属性控制禁用态,--wired-icon-size控制图标字号,--wired-icon-bg-color控制背景色,color继承机制控制手绘描边颜色;
  • 事件:原生click事件即点即用;
  • 原理:基于WiredBase+ RoughJS 的 SVG 运行时绘制,具备自适应重绘、按下反馈与键盘聚焦样式。

想要更完整地查看所有组件用法,可以参考仓库中的 examples/icon-button.html 示例,以及 docs 目录下其他组件的 API 文档。

  • 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),仅供参考

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

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

立即咨询