ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

wired-elements 手绘风日历组件 wired-calendar 实战指南:属性、事件与源码实现解析

wired-elements 手绘风日历组件 wired-calendar 实战指南:属性、事件与源码实现解析 UI组件前端【免费下载链接】wired-elementsCollection of custom elements that appear hand drawn. Great for wireframes or a fun look.项目地址https://gitcode.com/gh_mirrors/wi/wired-elements点击查看免费下载wired-calendar是 wired-elements 组件库中一款采用手绘线框风格hand-drawn wireframe渲染的日历选择器非常适合用于原型wireframe设计或追求趣味性的界面。本指南以官方文档 docs/wired-calendar.md 为主体结合仓库源码 src/wired-calendar.ts 与可运行示例 examples/calendar.html带你掌握 wired-calendar 的安装引入、全部属性与事件、CSS 变量定制方法并深入理解其背后的 roughjs 手绘渲染与日期计算原理。一、wired-calendar 是什么wired-elements 是一组看起来像手绘草图的自定义元素Custom Elements官方 README 将其定位为Collection of custom elements that appear hand drawn. Great for wireframes or a fun look.。wired-calendar 正是其中用于日期选择的组件它在一个手绘矩形卡片内呈现单月日历支持月份切换、日期范围限制、禁用态、多语言表头以及基于红色草图圆圈的选中态高亮。它的典型应用场景包括原型阶段快速搭建带日期选择的线框图需要视觉趣味性的个人项目或内部工具作为学习 LitElement roughjs 手绘组件实现思路的参考案例。二、安装与引入2.1 通过 npm 安装将 wired-elements 添加到 JavaScript 项目中npm i wired-elements安装完成后当前仓库对应的包信息见 package.json组件基于lit^2.0.0-rc.1与roughjs^4.3.1构建构建产物输出到lib/目录。2.2 按需导入模块在代码中导入WiredCalendar类import { WiredCalendar } from wired-elements/lib/wired-calendar.js;说明虽然 src/wired-elements.ts 提供了聚合入口main/module均指向lib/wired-elements.js但从该文件的 re-export 列表可以推断wired-calendar并未包含在聚合入口中因此官方文档推荐直接导入单个模块文件lib/wired-calendar.js。2.3 通过 CDN 直接加载也可以将模块脚本直接加载到 HTML 页面中script typemodule srchttps://unpkg.com/wired-elements/lib/wired-calendar.js?module/script2.4 在 HTML 中使用引入后在页面中放置标签即可wired-calendar selectedJul 4, 2019 /wired-calendar这是文档给出的最小可用用法传入selectedJul 4, 2019后日历会自动预选中该日期。仓库示例 examples/calendar.html 中还展示了更丰富的组合例如同时设置日期范围、多语言与initialswired-calendar idcalendar2 elevation1 firstdateApr 15, 2019 lastdateJul 15, 2019 selectedJul 4, 2019 localefr initials /wired-calendar三、属性Properties详解以下为文档列出的全部属性并结合源码逐项深入说明。属性类型默认值说明elevationNumber源码默认 3文档标注 11–5含之间的数字设置日历卡片的立体高度selectedString无可选可被Date解析的字符串预选并高亮某个日期firstdateString无可选可被Date解析的字符串有效日期的下限lastdateString无可选可被Date解析的字符串有效日期的上限localeString浏览器 locale仅用于渲染表头的 BCP 47 语言标签如es-MX、fr、dedisabledBooleanfalse禁用日历选择器initialsBooleanfalse星期几使用首字母如S、M而非缩写如SunvalueObject无包含选中Date对象及对应格式化文本的 JavaScript 对象formatFunction见下文获取/设置将Date对象格式化为文本的 JavaScript 函数源码中对应的属性声明位于 src/wired-calendar.ts。3.1 elevation手绘卡片的厚度elevation控制日历外框手绘阴影的层数。源码在updated()中对取值做了钳制处理const elev Math.min(Math.max(1, this.elevation), 5);即超出 1–5 范围的值会被强制收敛到合法区间。绘制时每增加 1 层会在矩形右下侧叠加一条透明度递减的手绘线opacity从 85% 起每层递减 10%从而形成手绘纸片的立体感。注意文档标注 elevation 默认值为 1但当前仓库源码 src/wired-calendar.ts 中声明为elevation 3使用时请以实际源码版本为准。3.2 selected预选日期selected接受任何能被 JavaScriptDate构造函数解析的字符串例如Jul 4, 2019。组件在初始化时会用new Date(this.selected)解析出日期以该日期所在月份作为当前展示月份firstOfMonthDate取当月 1 日在refreshSelection()中通过字符串比较day.value this.selected逐格标记选中状态src/wired-calendar.ts。由于选中匹配是字符串级比较因此传入的selected字符串应尽量与format的输出格式保持一致才能保证正确高亮。默认format输出形如Jul 4, 2019月份英文简称 日 年。3.3 firstdate / lastdate日期范围限制这两个属性分别限定可选日期的下界与上界解析后保存在私有变量fDate/lDate中src/wired-calendar.ts。其作用体现在两个层面日期禁用isDateOutOfRange(day)src/wired-calendar.ts判断某天是否越界。同时给出上下界时day fDate || lDate day即判定越界只给出其中一侧时按单侧判断。越界的日期单元格会被标记为disabled点击不生效月份导航限制onPrevClick()/onNextClick()在翻页前会检查前一月/下一月是否会越过fDate/lDate所在月份从而阻止用户翻出有效范围。3.4 locale仅作用于表头渲染locale是 BCP 47 语言标签如es-MX、fr、de。文档特别强调该属性只用于渲染日历表头月份名与星期名所有内部和外部的日期处理不受 locale 影响。源码localizeCalendarHeaders()src/wired-calendar.ts的实现印证了这一点未显式设置时依次探测navigator.systemLanguage、navigator.browserLanguage、navigator.languages兜底为en当 locale 不是en/en-US时使用Date.prototype.toLocaleString(locale, { weekday: short })与{ month: long }重新生成本地化表头文本关键的内部日期比较所用的months_short数组如Jan、Feb…保持en-US不变注释明确警告 month shorts are used inen-USinternally. Do not change.。因此无论界面显示什么语言format输出与selected匹配逻辑始终基于英文月份简称这也是示例注释中特别说明参数日期不受 locale 影响的原因。3.5 disabled整体禁用disabled为true时组件添加wired-disabled类表现为半透明opacity: 0.5、pointer-events: none、鼠标光标变为默认同时tabIndex被设为 -1从 Tab 键序中移除恢复时还原src/wired-calendar.ts。需要说明的是这与 3.3 节中单日 disabled 不同前者禁用整个组件后者只禁用范围外的日期。3.6 initials星期首字母模式initials为true时星期表头只显示首字母如S、M、T…否则显示weekdays_short数组中的短名称如Sun、Mon。该判断发生在渲染阶段this.initials ? d[0] : dsrc/wired-calendar.ts。3.7 value选中结果对象value是一个包含两个字段的 JavaScript 对象{ date: Date, // 被选中的 Date 对象 text: string // 对应的格式化文本由 format 函数输出 }用户每次选中日期后组件会更新value并触发selected事件因此这是读取当前选中结果的主要途径详见第五节。3.8 format自定义日期格式化函数format属性可读写用于控制日期文本的呈现。默认实现为(d: Date) this.months_short[d.getMonth()] d.getDate() , d.getFullYear()即输出Jul 4, 2019这类格式。它同时参与两件事生成每个日期单元格的value字符串用于选中匹配作为value.text的内容。示例 examples/calendar.html 展示了配合使用方式myCalendar4.format(today)先生成今天的格式化文本再交给公开方法setSelectedDate()完成程序化选中。3.9 公开方法 setSelectedDate()文档未单独列出但示例中实际使用的方法是setSelectedDate(formatedDate)src/wired-calendar.ts。传入一个日期字符串即可myCalendar4.setSelectedDate(Jul 4, 2019);方法内部会更新selected、将视图定位到对应月份、重算日历并触发selected事件适合在按钮或其他控件中做程序化日期选择。四、自定义 CSS 变量文档定义了 4 个可用于主题化的 CSS 变量变量作用默认值--wired-calendar-bg日历背景色白色--wired-calendar-color日历手绘线条颜色黑色--wired-calendar-selected-color选中日期的草图圆圈颜色红色--wired-calendar-dimmed-color不属于当月的灰显日期字体颜色灰色此外从源码样式src/wired-calendar.ts可以发现第 5 个可用变量--wired-calendar-disabled-color默认lightgray用于超出firstdate/lastdate范围的禁用日期字体颜色文档未列出但实际可用。示例 examples/calendar.html 中给出了完整的自定义样式写法.custom { --wired-calendar-bg: yellow; --wired-calendar-color: red; --wired-calendar-selected-color: black; --wired-calendar-dimmed-color: brown; width: 260px; height: 260px; font-size: 18px; }注意除颜色变量外组件的最终渲染尺寸还受元素本身width/height与font-size影响见 6.2 节的尺寸计算逻辑。五、事件Events文档定义了唯一的事件selected当用户或通过setSelectedDate选中某个日期时触发。从源码 src/wired-calendar.ts 可以看到事件派发细节this.value { date: new Date(this.selected), text: this.selected }; fireEvent(this, selected, { selected: this.selected });其中fireEvent来自 src/wired-base.ts派发的是标准CustomEvent并带有bubbles: true与composed: true因此事件会冒泡且能穿透 Shadow DOM在外部直接监听即可。监听方式myCalendar4.addEventListener(selected, () { const selectedObject myCalendar4.value; // selectedObject.date 是 JavaScript Date 对象 // selectedObject.text 是格式化后的日期文本 console.log(selectedObject.text); });六、完整实战示例仓库中的 examples/calendar.html 是官方提供的完整演示包含三种静态用法和一组带 JavaScript 交互的用法。其中交互部分的核心逻辑如下wired-calendar idcalendar4 elevation5 firstdateApr 15, 2019 lastdateJul 15, 2019 localees-MX initials /wired-calendar p idcalendar4-resultSelect a date in the calendar/p wired-button idbtn-todayToday/wired-button wired-button idbtn-updateUpdate/wired-button p idcalendar4-updateNo updated yet/pconst myCalendar4 document.getElementById(calendar4); // 方式一事件驱动 —— 监听 selected 事件读取 value myCalendar4.addEventListener(selected, () { let selectedObject myCalendar4.value; // selectedObject.date 为 Date 对象selectedObject.text 为格式化文本 let formatedDate selectedObject.text; document.getElementById(calendar4-result).innerHTML formatedDate brsmallNote: Internal date handling not affected by locale./small; }); // 方式二非事件驱动 —— 通过 value 属性轮询读取 document.getElementById(btn-update).addEventListener(click, () { const selectedObject myCalendar4.value; if (selectedObject selectedObject.date) { myCalendar4update.innerHTML selectedObject.date.toLocaleDateString(); } else { myCalendar4update.innerHTML No date selected yet.; } }); // 方式三程序化设置 —— 使用 format setSelectedDate document.getElementById(btn-today).addEventListener(click, () { let today new Date(); let formatedDate myCalendar4.format(today); // 传入任何 JavaScript Date 可解析的格式均可 myCalendar4.setSelectedDate(formatedDate); });该示例同时展示了三种典型交互路径监听事件、直接读取value属性、调用公开方法程序化设值覆盖了组件对外的主要编程接口。七、源码实现解析手绘日历是如何画出来的7.1 整体渲染结构组件基于 LitElement内部模板由一个table和两个 SVG overlay 构成src/wired-calendar.ts第一行表头上一月 / 月份年份标题 /下一月第二行表头七个星期名initials为 true 时取首字母数据区按周循环生成tr每周 7 个td日期单元格日历外框覆盖在表格之上的svg.calendar用于绘制手绘矩形边框与立体边线选中态选中单元格内部再嵌一个svg.selected用于绘制手绘红色椭圆。7.2 roughjs 手绘绘制所有手绘感都来自 src/wired-lib.ts 对 roughjs 的封装。以日历外框为例updated()中src/wired-calendar.ts先清空 SVG再用rectangle()绘制粗糙矩形边框随后按elevation叠加半透明边线形成立体厚度选中日期则用ellipse()画一个红色手绘椭圆stroke-width: 2.5圈住数字。每个元素都使用组件初始化时生成的随机种子randomSeed()见 src/wired-base.ts保证每次刷新后线条抖动形状一致。7.3 尺寸计算getCalendarSize()src/wired-calendar.ts读取元素实际包围盒若宽或高小于 180px 则回退为 320px保证最小可读尺寸computeCellsizes()src/wired-calendar.ts按比例分配空间两行表头合计占高度的 25%剩余 75% 按周数均分给每周列宽为总宽除以 7 再减去 2px 边框间距组件在connectedCallback()中注册了 200ms 防抖的resize监听窗口变化时自动重算src/wired-calendar.ts。7.4 月份网格计算computeCalendar()src/wired-calendar.ts以当月 1 日往前偏移到周日为起点按 7 天为一周循环填充整月网格不属于当月的日期标记为dimmed灰显同时为每个单元格生成value格式化日期字符串、text日数字与disabled是否越界标记。monthYear表头文本随firstOfMonthDate变化。7.5 生命周期与禁用态组件设置roledialog角色firstUpdated()connectedCallback()中依次完成表头本地化、初始条件设置、日历计算与选中刷新随后通过setTimeout(() this.updated())触发首次手绘渲染disconnectedCallback()中移除 resize 监听禁用态通过wired-disabled类实现opacity: 0.5、pointer-events: none焦点态下 SVG 线条加粗至 1.5。八、注意事项与常见问题日期字符串格式selected、firstdate、lastdate接受任何 JavaScriptDate可解析的格式但selected与默认format输出做字符串级匹配建议保持格式一致例如Jul 4, 2019locale 只影响外观无论locale设为哪种语言内部日期解析、格式化与比较始终基于固定的英文月份简称这是设计上的刻意行为elevation 范围虽然文档标注 1–5源码会对超出范围的值自动钳制到 1–5但传入合法值仍是推荐做法默认值差异文档中 elevation 默认值标注为 1而当前仓库源码默认值为 3请以所安装版本的实际行为为准禁用语义disabled禁用整个组件firstdate/lastdate只禁用范围外的日期两者可组合使用。九、深入阅读组件官方文档docs/wired-calendar.md核心源码实现src/wired-calendar.ts可运行示例examples/calendar.html手绘绘制封装roughjssrc/wired-lib.ts事件与随机种子工具src/wired-base.ts项目构建与依赖配置package.jsonwired-calendar 以 MIT 协议开源详见仓库 LICENSE其文档贡献者包括 Eduardo Martinez。结合本文的属性说明、示例代码与源码解析你可以直接在页面中嵌入一个手绘风格的日期选择器并通过selected事件、value属性与 CSS 变量快速接入业务逻辑与视觉定制。赞分享UI组件前端【免费下载链接】wired-elementsCollection of custom elements that appear hand drawn. Great for wireframes or a fun look.项目地址https://gitcode.com/gh_mirrors/wi/wired-elements点击查看免费下载相关推荐pi-subagents 社区生态插件市场与第三方集成的展望 - 构建强大的AI代理协作平台pi subagents 社区生态插件市场与第三方集成的展望 构建强大的AI代理协作平台 在AI代理快速发展的今天 pi subagents 作为Pi生态中人工智能AI Agent多智能体Agent 编排代码智能体终极wired-elements开发指南20个手绘风格组件属性与事件详解终极wired elements开发指南20个手绘风格组件属性与事件详解 wired elements是一套独特的手绘风格Web组件库通过简单的HTML标签UI组件前端MiniMax-H3-Realism-People-LoRA训练幕后176个精选视频片段如何塑造逼真人物MiniMax H3 Realism People LoRA训练幕后176个精选视频片段如何塑造逼真人物 MiniMax H3 Realism People人工智能大模型媒体生成LoRA创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进