# `bricks.Svg` 与相关组件技术文档 本文件为 `bricks.Svg` 及其派生类(`StatedSvg` 和 `MultipleStateIcon`)的详细技术说明文档。这些类用于在网页中动态加载、渲染和控制 SVG 图标的行为,支持颜色设置、闪烁动画、URL 动态更新以及状态切换功能。 --- ## 模块结构 ```js var bricks = window.bricks || {}; ``` 所有组件均挂载于全局命名空间 `bricks` 下,并通过 `bricks.Factory.register()` 注册为可实例化的 UI 组件。 --- ## 1. `bricks.Svg` 类 ### 简介 `bricks.Svg` 是一个继承自 `bricks.VBox` 的类,用于显示并控制单个 SVG 图标的可视化行为。它支持从远程 URL 加载 SVG 内容,动态着色、闪烁动画等特性。 ### 继承关系 ```js class Svg extends bricks.VBox ``` --- ### 构造函数:`constructor(opts)` #### 参数 | 参数 | 类型 | 必需 | 默认值 | 描述 | |------|------|------|--------|------| | `opts.rate` | Number | 否 | `1` | 缩放比例,影响宽度和高度 | | `opts.url` | String | 否 | - | SVG 文件的 URL 地址 | | `opts.blink` | Boolean | 否 | `false` | 是否启用闪烁效果 | | `opts.color` | String (CSS Color) | 否 | 由 `bricks.app.get_color()` 获取 | SVG 填充颜色 | | `opts.blinkcolor` | String (CSS Color) | 否 | 由 `bricks.app.get_bgcolor()` 获取 | 闪烁时的颜色 | | `opts.blinktime` | Number | 否 | `0.5` | 闪烁间隔时间(秒) | > ⚠️ 注意:`opts.cwidth` 和 `opts.cheight` 将被自动设为 `opts.rate`,实现等比缩放。 #### 行为说明 - 调用父类 `super(opts)` 初始化容器。 - 若未指定 `color` 或 `blinkcolor`,则使用应用级默认前景/背景色。 - 若提供了 `url`,调用 `set_url(url)` 加载 SVG 内容。 - 支持动态尺寸(`dynsize: true`)。 --- ### 方法列表 #### `set_url(url)` 从指定 URL 加载 SVG 内容并插入到 DOM。 ##### 参数 - `url` (String | null):SVG 文件路径或网址;若为 `null` 或空,则清空内容。 ##### 流程 1. 清除当前内容(若无 `url`)。 2. 使用 `fetch()` 请求 SVG 文本。 3. 验证响应是否以 ` ✅ 安全提示:仅允许标准 `` 标签开头的内容,避免注入风险。 --- #### `set_color(color)` 设置 SVG 的填充颜色,并立即重新渲染。 ##### 参数 - `color` (String):合法 CSS 颜色值(如 `"red"`, `"#00ff00"`, `"rgb(255,0,0)"`) ##### 行为 - 更新 `this.color` - 调用 `set_colored_svg(color)` --- #### `set_blinkcolor(color)` 设置闪烁状态下的颜色。 ##### 参数 - `color` (String):目标闪烁颜色 ##### 行为 - 更新 `this.blinkcolor` - 自动补全 `blinktime` 为 `0.5`(如果尚未设置) --- #### `set_colored_svg(color)` 将模板中的 `{color}` 占位符替换为实际颜色值,并更新 DOM。 ##### 参数 - `color` (String):要应用的颜色 ##### 实现 ```js var svgText = bricks.obj_fmtstr({color: color}, this.svgText); this.dom_element.innerHTML = svgText; ``` > 📌 依赖 `bricks.obj_fmtstr` 实现字符串模板替换(类似 `{color}` → `"#ff0000"`) --- #### `start_blink()` 启动周期性颜色闪烁动画。 ##### 条件 - 必须设置了 `blinktime > 0` - 必须定义了 `blinkcolor` ##### 行为 - 若当前没有运行任务(`!this.blink_task`),调用 `_blink()` 启动首次切换。 --- #### `_blink()` 私有方法:执行一次颜色切换,并安排下一次调用。 ##### 逻辑 - 当前颜色是正常色 → 切换为 `blinkcolor` - 当前颜色是 `blinkcolor` → 切换回正常 `color` - 使用 `schedule_once(fn, delayInSeconds)` 安排下次执行(避免阻塞主线程) > 🔁 此方法形成递归循环,直到 `end_blink()` 被调用。 --- #### `end_blink()` 停止闪烁动画。 ##### 行为 - 设置 `this.blink_task = null`,中断 `_blink()` 的递归调度链。 --- #### `set_ancent_color(e)` 从父元素的计算样式中获取文本颜色,并设置为 SVG 颜色。 ##### 应用场景 适用于希望图标跟随上下文主题色的情况。 ##### 实现 ```js var pstyle = getComputedStyle(this.parent); this.set_color(pstyle.color); ``` --- ## 2. `bricks.StatedSvg` 类 ### 简介 继承自 `bricks.Svg`,支持多个状态(state),每个状态对应不同的 SVG 资源。点击可按顺序切换状态。 ### 构造函数:`constructor(opts)` #### 扩展参数 | 参数 | 类型 | 必需 | 描述 | |------|------|------|------| | `opts.states` | Array<{state: String, url: String}> | 是 | 状态数组,每项包含状态名与对应的 SVG URL | | `opts.state` | String | 否 | 初始状态;若不提供,默认取第一个状态 | #### 初始化行为 - 设置初始状态 `this.curstate` - 调用 `set_state(state)` 加载对应 SVG - 绑定 `click` 事件处理器 `trigger` --- ### 方法列表 #### `trigger(event)` 处理点击事件,顺序切换到下一个状态(循环)。 ##### 事件处理 - `stopPropagation()` 和 `preventDefault()` 阻止冒泡与默认行为 ##### 切换逻辑 - 查找当前状态索引 `i` - 下一状态索引:`k = i + 1`,若已达末尾则回到 `0` - 调用 `set_state(states[k].state)` - 触发 `state_changed` 事件 --- #### `set_state(state)` 切换到指定状态。 ##### 参数 - `state` (String):目标状态名称 ##### 行为 - 若已处于该状态,直接返回 - 遍历 `this.states` 查找匹配项 - 找到后调用 `set_url(s.url)` - 广播 `state_changed` 事件 - 若未找到匹配项,清除 SVG 内容(`set_url(null)`) --- ## 3. `bricks.MultipleStateIcon` 类 ### 简介 另一种多状态图标实现方式,使用对象字典管理 URL 映射,适合命名清晰的状态切换(如开关、模式选择等)。 ### 构造函数:`constructor(opts)` #### 参数 | 参数 | 类型 | 必需 | 描述 | |------|------|------|------| | `opts.urls` | Object | 是 | 状态名到 SVG URL 的映射表,例如 `{on: 'on.svg', off: 'off.svg'}` | | `opts.state` | String | 是 | 初始状态键名 | #### 初始化流程 - 从 `urls[state]` 提取初始 URL - 调用 `super(opts)` 创建基础 SVG - 记录 `this.urls` 和当前 `this.state` - 绑定 `click` 事件到 `change_state` --- ### 方法列表 #### `change_state(event)` 点击时切换到下一个状态(按 `Object.keys(urls)` 顺序循环)。 ##### 流程 - 获取所有状态键名数组 - 查找当前 `state` 的索引 - 计算下一索引(越界则归零) - 调用 `set_state(newState)` - 触发 `state_changed` 事件 --- #### `set_state(state)` 设置当前状态并加载对应 SVG。 ##### 参数 - `state` (String):目标状态键名 ##### 行为 - 更新 `this.state` - 调用 `set_url(this.urls[state])` --- ## 工厂注册 以下三类组件均已向 `bricks.Factory` 注册,可在声明式模板中使用: ```js bricks.Factory.register('Svg', bricks.Svg); bricks.Factory.register('StatedSvg', bricks.StatedSvg); bricks.Factory.register('MultipleStateIcon', bricks.MultipleStateIcon); ``` 这意味着可以通过如下方式创建实例(假设框架支持): ```html
``` --- ## 使用示例 ### 示例 1:基础彩色 SVG ```js const icon = new bricks.Svg({ url: '/icons/home.svg', color: 'green', blink: true, blinkcolor: 'yellow', blinktime: 0.8 }); document.body.appendChild(icon.dom_element); ``` ### 示例 2:三态切换图标(StatedSvg) ```js const light = new bricks.StatedSvg({ states: [ { state: 'red', url: '/svg/red.svg' }, { state: 'yellow', url: '/svg/yellow.svg' }, { state: 'green', url: '/svg/green.svg' } ], state: 'red' }); light.on('state_changed', (state) => { console.log('Current state:', state); }); ``` ### 示例 3:双态图标(MultipleStateIcon) ```js const toggle = new bricks.MultipleStateIcon({ urls: { on: '/icons/power-on.svg', off: '/icons/power-off.svg' }, state: 'off' }); toggle.on('state_changed', s => console.log('Power is now:', s)); ``` --- ## 注意事项与最佳实践 | 项目 | 建议 | |------|------| | **安全性** | 不要加载不可信来源的 SVG,尤其是含 `