OpenHarmony三方组件:XmlGraphicsBatik
简介
XmlGraphicsBatik项目用于处理可缩放矢量图形(SVG)格式的图像,例如显示、生成、解析或者操作图像。
支持SVG图像的显示,可显示静态及动态SVG图像;
支持快捷生成SVG图像文件;
支持操作SVG图像进行颜色、样式、内容的修改;
支持将SVG图像的xml文本解析为可操作对象。
下载安装
npm install @ohos/XmlGraphicsBatik --save
OpenHarmony npm 环境配置等更多内容,请参考 如何安装OpenHarmony npm包 。
使用说明
对SVG图像进行生成、操作、解析等操作均依赖于SVGManager管理类
使用本库需要预先在MainAbility.ts 中预制文件路径:globalThis.filesDir = this.context.filesDir;
import {SVGManager} from '@ohos/XmlGraphicsBatik';
private svgManager: SVGManager = SVGManager.getInstance();
1. 显示SVG图像
// Iamge组件支持显示media资源文件 及 工程目录中的SVG图片
Image($r('app.media.svgSample'))
.width(150)
.height(150)
Image('file://' + globalThis.filesDir + '/svg.svg')
.width(150)
.height(150)
2. 生成SVG图像文件
2.1 创建SVG文件声明及子标签
// 创建SVG 对象:声明及SVG标签
this.svgManager.createSVGDeclares();
// 获取SVG标签对应的对象
var svgTagObj = this.svgManager.getSVGRoot();
// 构建SVG中的rect节点
var rect: SVGRect = new SVGRect();
rect.setX(50);
rect.setY(50);
rect.setRX(20);
rect.setRY(20);
rect.setWidth(100);
rect.setHeight(100);
rect.addAttribute('style', 'fill:rgb(255,0,255);stroke-width:2;stroke:rgb(0,0,0)')
// 输出标准格式rect对象
var rectObj = rect.toObj();
// 构建固定格式的节点描述对象
var svgFormatForRect: SVGSpecifiedFormat = new SVGSpecifiedFormat();
svgFormatForRect.setElementType(SVGAttrConstants.ATTR_VALUE_ELEMENT);
svgFormatForRect.setElementName('rect');
svgFormatForRect.setAttributes(rectObj);
if (svgTagObj) {
// 为SVG标签添加固定格式的Rect子标签
this.svgManager.addChildNode(svgTagObj, svgFormatForRect.toObj());
consoleInfo('Test svg: add svg svgTotalRoot', JSON.stringify(this.svgManager.getSVGTotalObj()));
}
// 获取整个SVG文件对应的对象
var svgTotalObj = this.svgManager.getSVGTotalObj();
var success = function () {
consoleInfo('saveFile', 'success');
}
// 将SVG文件对象保存为.svg格式文件,文件保存在 /project's path/files中
this.svgManager.saveSVG('svg.svg', svgTotalObj, success);
结果
add svg svgTotalRoot: {"declaration":{"attributes":{"version":"1.0","encoding":"utf-8","standalone":"yes"}},"elements":[{"type":"element","name":"svg","attributes":{"xmlns":"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink"},"elements":[{"type":"element","name":"rect","attributes":{"x":50,"y":50,"rx":20,"ry":20,"width":100,"height":100,"style":"fill:rgb(255,0,255);stroke-width:2;stroke:rgb(0,0,0)"}}]}]}
2.2 手动创建SVG文件及子标签
// 清空已存在的SVG根
this.svgXMLRoot = this.svgManager.getSVGTotalObj();
this.svgManager.removeByKey(this.svgXMLRoot, SVGAttrConstants.ATTR_KEY_DECLARATION);
this.svgManager.removeByKey(this.svgXMLRoot, SVGAttrConstants.ATTR_KEY_ELEMENTS);
// 构建SVG标签对应的对象
var svg: SVGRoot = new SVGRoot();
svg.setXMLNS(XMLConstants.XMLNS_NAMESPACE_URI_SVG);
svg.setXMLNSLink(XMLConstants.XLINK_NAMESPACE_URI);
svg.setSvgId('svgRoot');
svg.setXMLSpace(false);
svg.setWidth(250);
svg.setHeight(250);
svg.setViewBox(10, 10, 250, 250);
var svgObj = svg.toObj();
var svgSpecifiedFormat: SVGSpecifiedFormat = new SVGSpecifiedFormat();
svgSpecifiedFormat.setElementType(SVGAttrConstants.ATTR_VALUE_ELEMENT);
svgSpecifiedFormat.setElementName('svg');
svgSpecifiedFormat.setAttributes(svgObj);
// 构建SVG标签内的Rect子标签的对象
var rect: SVGRect = new SVGRect();
rect.setX(50);
rect.setY(50);
rect.setRX(20);
rect.setRY(20);
rect.setWidth(100);
rect.setHeight(100);
rect.addAttribute('style', 'fill:rgb(0,0,255);stroke-width:2;stroke:rgb(0,0,0)')
var rectObj = rect.toObj();
var svgFormatForRect: SVGSpecifiedFormat = new SVGSpecifiedFormat();
svgFormatForRect.setElementType(SVGAttrConstants.ATTR_VALUE_ELEMENT);
svgFormatForRect.setElementName('rect');
svgFormatForRect.setAttributes(rectObj);
svgSpecifiedFormat.setElements(svgFormatForRect.toObj());
if (this.svgXMLRoot) {
// 构建SVG文件声明
var declarationAttrs: object = Object.create(null);
declarationAttrs['version'] = '1.0';
declarationAttrs['encoding'] = 'utf-8';
declarationAttrs['standalone'] = 'no';
var declarationObj: object = Object.create(null);
declarationObj[SVGAttrConstants.ATTR_KEY_ATTRIBUTES] = declarationAttrs
this.svgXMLRoot[SVGAttrConstants.ATTR_KEY_DECLARATION] = declarationObj;
this.svgManager.addChildNode(this.svgXMLRoot, svgSpecifiedFormat.toObj());
consoleInfo('Test svg: add line svgTotalRoot', JSON.stringify(this.svgManager.getSVGTotalObj()));
}
结果
Test svg: add svg svgTotalRoot: {"declaration":{"attributes":{"version":"1.0","encoding":"utf-8","standalone":"no"}},"elements":[{"type":"element","name":"svg","attributes":{"xmlns":"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","id":"svgRoot","xml:space":"default","width":250,"height":250,"viewBox":{"x":10,"y":10,"width":250,"height":250}},"elements":[{"type":"element","name":"rect","attributes":{"x":50,"y":50,"rx":20,"ry":20,"width":100,"height":100,"style":"fill:rgb(0,0,255);stroke-width:2;stroke:rgb(0,0,0)"}}]}]}
3. 操作SVG图像对象
3.1 修改已存在的子标签的属性
// 获取SVG根标签对应的操作对象
var svgRoot = this.svgManager.getSVGRoot();
if (!svgRoot) {
consoleInfo('Test rect: update attr for rect1', 'svg tag is null');
return false;
}
// 根据主键获取对应的属性值
var svgElements = this.svgManager.getValueForKey(svgRoot, SVGAttrConstants.ATTR_KEY_ELEMENTS);
if (!svgElements) {
consoleInfo('Test rect: update attr for rect1', `svg tag's elements is null`);
return false;
}
if (typeof svgElements !== SVGAttrConstants.TYPEOF_OBJECT || !Array.isArray(svgElements)) {
consoleInfo('Test rect: update attr for rect1', `the elements's type of svg tag is not array`);
return;
}
var rectResult = null;
try {
svgElements.forEach((item) => {
if (typeof item === SVGAttrConstants.TYPEOF_OBJECT) {
var nameValue: string = this.svgManager.getValueForKey(item, SVGAttrConstants.ATTR_KEY_NAME);
if (nameValue === 'rect') {
rectResult = item;
throw 'has got rect,jump out';
}
}
})
} catch (e) {
if (!rectResult) {
consoleInfo('Test rect: update attr for rect1', 'rect not exist');
return;
}
if (typeof rectResult === SVGAttrConstants.TYPEOF_OBJECT) {
var rectAttributes = rectResult[SVGAttrConstants.ATTR_KEY_ATTRIBUTES];
rectAttributes['x'] = 20;
rectAttributes['y'] = 20;
rectAttributes['rx'] = 10;
rectAttributes['ry'] = 50;
rectAttributes['width'] = 80;
rectAttributes['height'] = 80;
// 为标签添加/设置属性键值对
this.svgManager.setAttribute(rectAttributes, 'style', 'fill:rgb(0,255,0);stroke-width:10;stroke:rgb(0,255,255)');
this.allAttrRectObj = rectResult;
}
consoleInfo('Test rect: update attr for rect1 svgTotalObj', JSON.stringify(this.svgManager.getSVGTotalObj()));
}
3.2 移除属性键值对
var attrs = this.svgManager.getValueForKey(rectOriginData, SVGAttrConstants.ATTR_KEY_ATTRIBUTES);
if (!attrs) {
consoleInfo('test remove ' + firstAttrName, 'rect1 has no attributes');
return;
}
this.svgManager.removeByKey(attrs, firstAttrName);
4. 解析SVG图像文件
this.svgManager.parse('svg.svg', (parseXMLResultObj) =>{
this.svgJson = parseXMLResultObj;
})
结果
{"declaration":{"attributes":{"version":"1.0","encoding":"utf-8"}},"elements":[{"type":"element","name":"svg","attributes":{"id":"svgRoot","space":"default","width":"250","height":"250","viewBox":"10 10 250 250 "},"elements":[{"type":"element","name":"rect","attributes":{"x":"50","y":"50","rx":"20","ry":"20","width":"100","height":"100","style":"fill:rgb(0,0,255);stroke-width:2;stroke:rgb(0,0,0)"}}]}]}
接口说明
- 获取SVG管理类实例
static getInstance(): SVGManager
2.获取整个SVG文件对应的可以操作对象
getSVGTotalObj(): object
3.创建SVG文件声明及SVG根标签
createSVGDeclares(): object
4.获取SVG根标签对应的可操作对象
getSVGRoot(obj: Object = this.svgObj): object
5.添加子标签(不覆盖原子标签)
addChildNode(parentObj: Object, childPropertyValue: Object): boolean
6.设置子标签(覆盖原子标签)
setChildNode(parentObj: Object, childPropertyValue: Object): boolean
7.通过主键获取对应属性值
getValueForKey(parentObj: Object, key: string): any
8.根据主键移除键值对
removeByKey(parentObj: Object, key: string): void
9.为对象设置属性或子节点(覆盖原有键值对)
setAttribute(parentObj: Object, key: string, value: string): void
10.创建文件夹
createFolder(path: string): void
11.获取文件根路径
getFilePath(onSuccess: (filesDir: string) => void): void
12.保存SVG文件
saveSVG(fileName: string, fileContent: string | Object, onSuccess?: () => void, onFailed?: (number, Error) => void): void
13.解析SVG文件
parse(fileName: string, onSuccess: (result: string) => void, onFailed?: (error: Error) => void): void
兼容性
支持 OpenHarmony API version 9 及以上版本。
目录
/XmlGraphicsBatik # 工程根目录
├── entry # 示例代码文件夹
├── XmlGraphicsBatik # 三方库源码文件夹
│ └── src
│ ├── index.ets # 对外暴露文件的存放目录
│ ├── package.json # 项目介绍
│ └──main/ets/batik
│ ├── SVGManager.ets # SVG处理管理核心类
│ ├── SVGXMLChecker.ets # 检查SVG文本是否合规
│ ├── StringReader.ets # 读取SVG文本字符串工具类
│ └── constants
│ ├── RegexConstants.ets # 正则表达式常量类
│ ├── SVGAttrConstants.ets # SVG标准格式主键常量类
│ ├── SVGXMLConstants.ets # SVG文件常量类
│ └── XMLConstants.ets # XML文件常量类
│ └── svggen
│ ├── SVGSpecifiedFormat.ets # SVG文件对应的可操作对象标准格式构造类
│ ├── SVGDeclares.ets # SVG文件声明构造类
│ ├── SVGRoot.ets # SVG文件根标签构造类
│ ├── SVGCircle.ets # Ciecle子标签构造类
│ ├── SVGEllipse.ets # Ellipse子标签构造类
│ ├── SVGLine.ets # Line子标签构造类
│ ├── SVGPath.ets # Path子标签构造类
│ ├── SVGRect.ets # Rect子标签构造类
│ └── SVGPolygonAndPolyLine.ets # Polygon 及 PolyLine子标签构造类
│ └── util
│ ├── LogUtil.ets # 日志打印工具类
│ ├── ObjOrArrayUtil.ets # 可操作对象及Array处理工具类
│ └── XMLRules.ets # XML文件固定规则工具类
贡献代码
使用过程中发现任何问题都可以提 Issue 给我们,当然,我们也非常欢迎你给我们发 PR 。
开源协议
本项目基于 Apache License 2.0 协议,请自由地享受和参与开源。
文章转载自:https://gitee.com/openharmony-tpc/XmlGraphicsBatik