作者 | 阿里文娱无线开发专家 波涛

责编 | 夕颜

出品 | CSDN(ID:CSDNnews)

背景介绍

用户在大麦上购票,需要自行选座。在大型场馆下,如何让 10 万+座位绘制达到闪开?这需要技术在绘制上保证性能流程,在选座渲染上通过技术手段赋予更多可能性。因此,大麦引用 SVG 绘制技术,并根据业务场景下作了很多优化,本文是大麦在用户端的技术方案设计与应 用实践。

10 万+座位绘制面临以下挑战

  1. 如何丰富标签样式及属性;

  2. SVG 渲染性能优化;

  3. SVG 如何与业务场景结合;

  4. 如何将 CSS 能力应用到 SVGKit,保持(iOSAndroidH5)一致性。

大麦 C 端场景下 SVG 应用

1. SVG 介绍

可伸缩矢量图形 (Scalable Vector Graphics),用来定义用于网络的基于矢量的图形,使用 XML 格式定义图形,图像在放大或改变尺寸的情况下其图形质量不会有所损失,是万维网联 盟的标准, DOM 和 XSL 之类的 W3C 标准是一个整体,不失真,兼容现有图片能力前提还 支持矢量(浏览器兼容情况),通过浏览器很早版本支持情况在主流浏览器都支持,SVG 提供的 功能集涵盖了嵌套转换、裁剪路径、Alpha 通道、滤镜效果等能力,它还具备了传统图片没有 的矢量功能,在任何高清设备都很高清。

图 1 SVG 与其他格式图片比较

2. SVGKit 使用

浏览器默认就支持 SVG 渲染,属于 XML-Dom 家族系列,但是在移动端上并没有做原生支 持,还是按照 XML 进行的读取,支持的开源库也不多,在 IOS 上,目前 OC 版本 SvgKit 还不 错,官方 Github 也在继续维护,虽然更新较慢,通过几次 patch 提交 PR 还是很快 merge 的, 一些通用属性和控件支持的不够完善,需要进行定制开发,swift 版本的 macaw 也不错,在动画 效果上更加酷炫,目前也正在做 swift 效果迁移到 OC 中,渲染流程如下:

图 2 SVGKit 渲染加载流程图

1)SVGKit 有哪些标签?

circle = SVGCircleElement; 【圆形】clipPath = SVGClipPathElement;【层叠路径】 description = SVGDescriptionElement; 【描述】 ellipse = SVGEllipseElement; 【椭圆】g = SVGGElement; 【容器标签】line = SVGLineElement;【直线】 path = SVGPathElement;【路径】polygon = SVGPolygonElement;【多角形】 polyline = SVGPolylineElement;【多边形】 rect = SVGRectElement;【矩形】svg = SVGSVGElement;【SVG 容器标签】 switch = SVGSwitchElement;【选择】 text = SVGTextElement;【文本】textArea = TinySVGTextAreaElement;【区域文本】 title = SVGTitleElement;【标题】2)扩展基于三端统一 SVG 标签和属性

图 3 SVG 标签属性扩展大图

3)SVG 标签在 SVGKit 中渲染流程

a)SVGKit 核心渲染原理分析

视图 SVGKFastImageView.m 加载到窗口显示 核心中心处理类,主要加载 SVG 文件资源文件

类:SVGKimage : NSObjectSVGKParseResult* parsedSVG = [parser parseSynchronously]; // 解析 SVGKImage* finalImage = [[SVGKImage alloc] initWithParsedSVG:parsedSVG fromSource:source];

b)分析:

解析 SVG-到合成 ViewLayer初始化 SVGKSource source svg 资源实例 初始化 SVGSVGElement -> DomTree 初始化 SVGDocument -> DomDocument CALayerTree 最终合成的 Layer 树SVGKParser* parser = [SVGKParser newParserWithDefaultSVGKParserExtensions:source]; 开 始解析

c)解析 XML 类 SVGKParser:NSObject 解析 SVG(XML)文件

+(SVGKParser ) newParserWithDefaultSVGKParserExtensions:(SVGKSource )source (SVGKParseResult*) parseSynchronously. 解析异常处理 XML 解析处理XML 解析过程 SAX// 每解析一个 Node 添加到 DOMTree 中. (SVGKParserStyles) SVGKParserDefsAndUse 【解析 useAndDefs 样式】 SVGKParserDOM 【解析 DOM】 SVGKParserGradient【解析渐变标签】 SVGKParserPatternsAndGradients【解析图案】 SVGKParserStyles【解析样式】SVGKParserSVG【解析 SVG 标签】d)解析 XML 中 CSS 样式类 SVGKParserStyles :标签解析到生成 Layer 层 1.类:SVGKParserDOM.m: SVGElement. 2.核心思想:SVG 标签渲染流程一、SVGKImage.m 渲染 核心思想:遍历 DOM 映射到 iOS layer 绘制3.生成 UILayer:-(CALayer *)newCALayerTreeCALayer* newLayerTree = [self newLayerWithElement:self.DOMTree]; CALayer sublayer = [self newLayerWithElement:(SVGElement )child]; [newLayerTree addlayer. Sublayer][element layoutLayer:layer]; [layer setNeedsDisplay];

4)SVGKit 分析总结

SVGKit 版本升级 2.X 升级 3.X-Release,升级后主要是一些属性的支持度更完善,包括 Text 富文本渲染,字体多样式支持,还有一些渲染上的优化,可通过 patch 提交 查看,比较一下 W3C 下 SVG 图在 2.X 分支及 3.X 分支的解析及渲染时间,性能能也有提升, 同时增加 image 图片加载 base64 图片,加载在线 URL 及本地资源图片,我们也在 SVGImageElement 中提供扩 展 API 增加 Webp 支持,因为 SVG 本身是为矢量图方案加入 PNG 等图存在一定模糊情况,不 过运营可能会在底图上做一些 Logo 展示,为了减少 SVG 编辑复杂度,做了一些 pngjpg 图的 嵌入,一般图片都不大,以下 API:展示 base64 运营位图片而设计的

 [NSData dataContentWithBase64Str:str]

3. 基于 CSS 着色能力

1)为什么用 CSS 着?

SVG 虽然是绘制图形,原理如同 HTML,是给每一个标签设置一个单独 style 好还是通过 CSS Id /class 映射好呢,这个思路和 HTML 处理 STYLE 样式是一样的,便于更改和维护,在 性能上也更好,同时增加了 important 属性,可以更好的配置样式,可做到运营侧根据样式 style 下发方式达到更改 SVG 图效果,可以做到更多活动效果及个性化需求。

2)SVG-CSS 着色渲染过程

SVG 标签基于 CSS 样式快速应用,通过遍历 DomTree,找到对应的 Node 节点,在给 node 节点设置 id 或者 class,然后局部刷新 Tree 父节点,实现换色,细节流程如下

图 4 CSS 着色原理与时序图

3)大麦端选座渲染效果

图 5 CSS 着色渲染效果

4)CSS 着色原理总结及性能比较 如何确定属性使用的是 CSS 颜色还是自带 style 属性?

当 SVG 在解析生成 DomTree 后,我们可以根据 CSSStyle 样式存储的 CSS 样式,给 Node 标签设置 id 及 class,当更改 nodeList 后,相当于树结构进行了修改,在绘制时候查找属性会根 据优先策略 id > class > 进行查找进行属性赋值,我们根据 CSS 属性 !important 来设置最高优 先级,这样就避免了此问题。

端侧渲染流程如下,左侧:是基于 node 遍历后修改,右侧是修改 id/class 方式【推荐】。性能比对:为了兼容 W3C 标准,端上增加了 CSS 特殊属性 important。

图 6 SVG-Codec 总体性能提升对比

4. SVG 约束 DTD

1)背景介绍

当 SVG 生产端在制作 SVG 图,可能会用到 Adobe 等软件,有很多复杂属性及层叠,可能 会产生复杂 XML 格式,这样在渲染过程中会造成大量遍历,影响性能,也有一些特殊属性, 端上并没有支持,例如滤镜、动画,这样,我们就需要有一种约束来校验生产和渲染 SVG 能够 一致。

2)文档类型定义

(DTD)可定义合法的 XML 文档构建模块。它使用一系列合法的元素来定义文档的结构。

DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。

DTD 被定义在 xml 的 DOCTYPE 声明中。

3)定义一个名为 note 的 DTD

如果要使用内部定义,则在 xml 文件的 xml 版本声明头下面添加如下代码块:

// DTD 内容]> 如果要引用外部 DTD,那么它应通过下面的语法被封装在 一个 DOCTYPE 定义中: 例如,在 xml 文件的 xml 版本声明头下面添加如下代码块:

一个 DTD 的内容示例:

 

其中:

!ELEMENT note 定义 note 元素有四个元素:"to、from、heading、body"

!ELEMENT to 定义 to 元素为 "#PCDATA" 类型。

PCDATA 的意思是被解析的字符数据(parsed character data)。可想象为 XML 元素的开始 标签与结束标签之间的文本,PCDATA 是会被解析器解析的文本。这些文本将被解析器检查以 及标记,文本中的标签会被当作标记来处理,而实体会被展开,不过,被解析的字符数据不应 当包含任何 &、< 或者 > 字符;需要使用 &、< 以及 > 实体来分别替换它们。

4)例如在 DTD 中声明

它表示在和之间可以插入字符或者子标 签,CDATA 的意思是字符数据(character data, CDATA 是不会被解析器解析的文本。在这些文 本中的标签不会被当作标记来对待,其中的实体也不会被展开。

5)如何校验

在完成 DTD 文件的编写后,就是使用 DTD 了,1、 一般使用代码解析的方式,进行 DTD 对 xml 的规范性校验,首先在 svg 的头部加入:然后 在解析 svg 时,声明合法性校验例如,以 SAX 解析 XML 为例:

SAXParserFactory spf = SAXParserFactory.newInstance; spf.setValidating(true); // 关键设置SAXParser sp = spf.newSAXParser; XMLReader xr = sp.getXMLReader;XMLParser.SAXHandler handler = new XMLParser.SAXHandler; xr.setContentHandler(handler);xr.setErrorHandler(new SAXErrorHandler); // 输出校验出错的信息xr.setProperty("http://xml.org/sax/properties/lexical-handler

d3 svg path添加文本_10 倍高清不花!大麦端选座 SVG 渲染相关推荐

  1. 10 倍高清不花!大麦端选座 SVG 渲染

    作者 | 阿里文娱无线开发专家 波涛 责编 | 夕颜 出品 | CSDN(ID:CSDNnews) 背景介绍 用户在大麦上购票,需要自行选座.在大型场馆下,如何让 10 万+座位绘制达到闪开?这需要技 ...

  2. d3 svg path添加文本_数据可视化——D3展现数据最炫丽的一面

    热情的或--有温度的"1" 大家好,大家肯定很好奇,数据能是什么样子嘛,不就是干巴巴的1.2.3-!哟,这个火热的"1"好像是挺绚丽的啊,但对不起,这只是数字, ...

  3. d3 svg path添加文本_D3.js 力导向图的显示优化

    D3.js 作为一个前端,说到可视化除了听过 D3.js 的大名,常见的可视化库还有 ECharts.Chart.js,这两个库功能也很强大,但是有一个共同特点是封装层次高,留给开发者可设计和控制的部 ...

  4. DAVSE VCC-H900 20倍高清会议摄像机

    1.Sony 20倍高性能机芯                                                                             2.采用1/2. ...

  5. python matplotlib输出矢量图svg(可插入word,仍为高清)

    import matplotlib.pyplot as plt x=[1,2,3,4,5] y=[2.4,8.2,9.3,1.3,2.0] plt.scatter(x,y) plt.savefig(f ...

  6. MHD-20HDMI高清20倍视频会议摄像头

    产品概述:    MHD-20HDMI是本公司***一款带高智能人机对话.可自定义菜单编程和操作信息显示:可吊顶,具备自动翻转功能:内置20倍光学变倍.自动聚焦进口高清一体化机芯,具备高速云台功能.9 ...

  7. php 在线选座,基于jQuery实现在线选座之高铁版_jquery

    效果图展示: 除了电影院在线选座,我们还会接触到飞机机舱选座,当然也有汽车票火车票选座的.假如有一天买火车票也提供在线选座,那么今天我来给大家介绍下如何使用jQuery选座插件完成高铁列车座位布置.选 ...

  8. 用html制作一个中国高铁网页,基于jQuery实现在线选座之高铁版

    效果图展示: 除了电影院在线选座,我们还会接触到飞机机舱选座,当然也有汽车票火车票选座的.假如有一天买火车票也提供在线选座,那么今天我来给大家介绍下如何使用jQuery选座插件完成高铁列车座位布置.选 ...

  9. jQuery在线选座系统(高铁版)

    除了电影院在线选座,我们还会接触到飞机机舱选座,当然也有汽车票火车票选座的.假如有一天买火车票也提供在线选座,那么今天我来给大家介绍下如何使用jQuery选座插件完成高铁列车座位布置.选座.不同等级座 ...

最新文章

  1. (素材源码)猫猫学IOS(十六)UI之XIB自定义Cell实现团购UI
  2. java占位符填充_实现java中的占位符
  3. java redis快速入门_SpringDataRedis快速入门
  4. 计算机vb基础知识,2018年计算机二级考试VB基础知识:参数的传递
  5. 一篇文章了解Liquid模版引擎
  6. qt linux 添加库文件路径,linux下qt使用第三方库的那些事
  7. LeetCode LCS 02. 完成一半题目(计数+排序)
  8. linux查看pid 对应的程序_资深程序员总结:分析 Linux 进程的 6 个方法,我全都告诉你...
  9. 修复IE6重复字符Bug
  10. sublime中html自动对齐,sublime text怎么对齐HTML代码
  11. 2.Jenkins 2 权威指南 --- 基础知识
  12. protel9s【硬件课程设计】
  13. word解除限制编辑(亲测有效)
  14. 编程术语晦涩_晦涩的编程语言的乐趣
  15. 使用CoreImage实现素描滤镜
  16. ChineseGLUE:为中文NLP模型定制的自然语言理解基准
  17. 低版本cad如何打开高版本图纸?不用升级软件也可以搞定
  18. 手撸 SpringBoot DDD 微服务脚手架
  19. python 分类变量xgboost_python小白之路:第十九章 XGBoost
  20. WIN7下ADS使用详解

热门文章

  1. Lotus Notes基础知识
  2. 汤家凤高等数学基础手写笔记-不定积分
  3. 安卓来电归属地_如何做一名突出的iPhone用户?安卓勿进!
  4. 明日科技的python书籍怎么样_零基础学习Python不可错过的5本书籍
  5. matlab求一个方程组的系数矩阵,【求解】matlab求解非齐次方程组,但是系数矩阵是复数,求帮忙...
  6. 统计输入字符串中英文单词的个数
  7. python 合并 循环list_阿里巴巴鼎力推荐,Python入门至精通,24招加速你的Python
  8. echarts setoption方法_在Vue和React中使用ECharts的多种方法
  9. mysql 锁机制 mvcc_轻松理解MYSQL MVCC 实现机制
  10. linux 系统监控 php,Linux系统资源监控命令简介