画布 SVG 管理
画布 Web SDK 支持提供 SvgManager 来管理画布中使用的 svg 资源,主要原理是在 document.body 中添加 <svg>
标签,然后将每一个 svg 的内容放到 <symbol>
中,为每个 <symbol>
添加 id,然后在使用的时候使用 <use>
标签,可以重复利用 symbol 中的 svg 图标。
初始化加载
在页面加载完成后的时候可以执行统一加载,这会创建一个 svg container DOM,这个容器在当前项目全局只会创建一次,后续的所有操作都是基于这个容器,如果您不想创建容器,每个方法都支持传入自定义容器,保证是 svg
就可以。
import { SvgManager } from '@plaso-infi/whiteboard-sdk';
const ICON_PREFIX = 'default-';
const DEFAULT_ICON = {
[`${ICON_PREFIX}setting`]: `<g fill-rule="evenodd" fill="none"><path d="M0 0h24v24H0z"/><path data-follow-fill="currentColor" fill="currentColor" d="M4 4h16a1 1 0 0 1 0 2H4a1 1 0 1 1 0-2Zm0 7h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2Zm0 7h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2Z"/></g>`,
[`${ICON_PREFIX}no-background`]: `<g fill="none" fill-rule="evenodd"><path d="M0 0h24v24H0z"/><path data-follow-fill="currentColor" d="M20.868 7.374A9.957 9.957 0 0 1 22 12c0 5.523-4.477 10-10 10a9.957 9.957 0 0 1-4.626-1.132l1.502-1.5c.96.407 2.016.632 3.124.632a8 8 0 0 0 7.367-11.124l1.501-1.502Zm-1.09-3.152a1 1 0 0 1 0 1.414L5.636 19.778a1 1 0 1 1-1.414-1.414L18.364 4.222a1 1 0 0 1 1.414 0ZM12 2a9.96 9.96 0 0 1 4.626 1.132l-1.502 1.5A8 8 0 0 0 4.633 15.124l-1.501 1.503A9.957 9.957 0 0 1 2 12C2 6.477 6.477 2 12 2Z" fill="currentColor" fill-rule="nonzero"/></g>`,
};
useEffect(() => {
SvgManager.load(DEFAULT_ICON);
}, []);
执行完后 svg container 下面会挂载所有的 svg 资源到 svg container 的 <symbol>
并增加相应的 id,如果您不想增加一个 svg container 可以直接使用 add
方法。
关于 prefix ,这个没有强制规定都是由外部自己定,但是一定要保证传入的 Map 的 key 值,一定要和使用 use
的时候传入 id 的值保持一致!
使用
在 React 环境中封装一个组件,来做 <use>
<SvgIcon icon={`${prefix}setting`} className={styles.icon} onClick={onSettingBtnClick} />
SvgIcon 这个组件已经从 Web SDK 导出,可以直接使用
import React from 'react';
import { classnames } from '@/utils';
import styles from './index.module.less';
type PropT = {
className?: string;
style?: React.CSSProperties;
title?: string;
icon: string;
onClick?: any;
[key: string]: any;
};
export const SvgIcon: React.FC<PropT> = ({ className, style, title, icon, onClick, ...rest }) => {
return (
<svg
style={style}
className={classnames(className, styles.icon)}
aria-hidden='true'
onClick={onClick}
{...rest}
>
<use xlinkHref={`#${icon}`}>
<title>{title || ''}</title>
</use>
</svg>
);
};
通过 <use>
标签上的 xlinkHref 属性可以全局查找 <symbol>
与之对应的那个 svg 图标。
在其他框架可以根据这段代码封装相应的组件来做渲染,原生 HTML 环境则可以直接使用
<svg
aria-hidden="true"
onClick={onClick}
>
<use xlinkHref='#upload'>
<title>上传</title>
</use>
</svg>
API
注意:所有 API 需要传入的 icons 都是一个对象,对象的 key 是生成
<symbol id='upload'>
的时候的 id 值,也是使用的时候<use xlinkHref='#upload'>
的 xlinkHref 值;对象的 value 是去掉<svg>
标签后剩余的内容部分!
可以随时在运行时做添加、替换操作实时生效,每个 API 都支持传入自定义的 SVG 资源容器,如果不传则根据 API 的不同区寻找或者创建容器。
interface Icon {
[key: string]: string;
}
add
批量添加 svg 资源,如果在当前 svgContainer 发现有 id 相等的 <symbol>
内容会被替换,如果不想被替换可以考虑增加 prefix,如果想要全局替换请使用 replace 方法。
定义
/**
* @param icons svg 的id和内容的map
* @param svgContainer 想要查找替换的svg symbol容器,如果没有传尝试寻找 id 为 plaso-websdk-svg-container 的容器,如果没有找到会 使用 plaso-websdk-svg-container 为 id 创建
*/
add(icons: Icon, svgContainer?: SVGElement)
示例
SvgManager.add({
['setting']: `<g fill="none" fill-rule="evenodd"><path d="M0 0h24v24H0z"/><path data-follow-fill="currentColor" d="M19.062 5.9a1 1 0 1 1 1.533 1.284l-9.481 11.163a1 1 0 0 1-1.39.14l-5.872-4.924A1 1 0 1 1 5.101 12l5.106 4.313 8.855-10.414Z" fill="currentColor" fill-rule="nonzero"/></g>`,
});