OpenHarmony三方组件:XmlGraphicsBatik

Handpc
发布于 2023-3-17 10:48
浏览
0收藏

简介

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)"}}]}]}

接口说明

  1. 获取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​


XmlGraphicsBatik-master.zip 116.77K 0次下载
已于2023-3-17 10:49:01修改
收藏
回复
举报
回复
    相关推荐