d3 svg path添加文本_10 倍高清不花!大麦端选座 SVG 渲染
作者 | 阿里文娱无线开发专家 波涛
责编 | 夕颜
出品 | CSDN(ID:CSDNnews)
背景介绍
用户在大麦上购票,需要自行选座。在大型场馆下,如何让 10 万+座位绘制达到闪开?这需要技术在绘制上保证性能流程,在选座渲染上通过技术手段赋予更多可能性。因此,大麦引用 SVG 绘制技术,并根据业务场景下作了很多优化,本文是大麦在用户端的技术方案设计与应 用实践。
10 万+座位绘制面临以下挑战
如何丰富标签样式及属性;
SVG 渲染性能优化;
SVG 如何与业务场景结合;
如何将 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 : NSObject
SVGKParseResult* 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 *)newCALayerTree
CALayer* 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 渲染相关推荐
- 10 倍高清不花!大麦端选座 SVG 渲染
作者 | 阿里文娱无线开发专家 波涛 责编 | 夕颜 出品 | CSDN(ID:CSDNnews) 背景介绍 用户在大麦上购票,需要自行选座.在大型场馆下,如何让 10 万+座位绘制达到闪开?这需要技 ...
- d3 svg path添加文本_数据可视化——D3展现数据最炫丽的一面
热情的或--有温度的"1" 大家好,大家肯定很好奇,数据能是什么样子嘛,不就是干巴巴的1.2.3-!哟,这个火热的"1"好像是挺绚丽的啊,但对不起,这只是数字, ...
- d3 svg path添加文本_D3.js 力导向图的显示优化
D3.js 作为一个前端,说到可视化除了听过 D3.js 的大名,常见的可视化库还有 ECharts.Chart.js,这两个库功能也很强大,但是有一个共同特点是封装层次高,留给开发者可设计和控制的部 ...
- DAVSE VCC-H900 20倍高清会议摄像机
1.Sony 20倍高性能机芯 2.采用1/2. ...
- 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 ...
- MHD-20HDMI高清20倍视频会议摄像头
产品概述: MHD-20HDMI是本公司***一款带高智能人机对话.可自定义菜单编程和操作信息显示:可吊顶,具备自动翻转功能:内置20倍光学变倍.自动聚焦进口高清一体化机芯,具备高速云台功能.9 ...
- php 在线选座,基于jQuery实现在线选座之高铁版_jquery
效果图展示: 除了电影院在线选座,我们还会接触到飞机机舱选座,当然也有汽车票火车票选座的.假如有一天买火车票也提供在线选座,那么今天我来给大家介绍下如何使用jQuery选座插件完成高铁列车座位布置.选 ...
- 用html制作一个中国高铁网页,基于jQuery实现在线选座之高铁版
效果图展示: 除了电影院在线选座,我们还会接触到飞机机舱选座,当然也有汽车票火车票选座的.假如有一天买火车票也提供在线选座,那么今天我来给大家介绍下如何使用jQuery选座插件完成高铁列车座位布置.选 ...
- jQuery在线选座系统(高铁版)
除了电影院在线选座,我们还会接触到飞机机舱选座,当然也有汽车票火车票选座的.假如有一天买火车票也提供在线选座,那么今天我来给大家介绍下如何使用jQuery选座插件完成高铁列车座位布置.选座.不同等级座 ...
最新文章
- (素材源码)猫猫学IOS(十六)UI之XIB自定义Cell实现团购UI
- java占位符填充_实现java中的占位符
- java redis快速入门_SpringDataRedis快速入门
- 计算机vb基础知识,2018年计算机二级考试VB基础知识:参数的传递
- 一篇文章了解Liquid模版引擎
- qt linux 添加库文件路径,linux下qt使用第三方库的那些事
- LeetCode LCS 02. 完成一半题目(计数+排序)
- linux查看pid 对应的程序_资深程序员总结:分析 Linux 进程的 6 个方法,我全都告诉你...
- 修复IE6重复字符Bug
- sublime中html自动对齐,sublime text怎么对齐HTML代码
- 2.Jenkins 2 权威指南 --- 基础知识
- protel9s【硬件课程设计】
- word解除限制编辑(亲测有效)
- 编程术语晦涩_晦涩的编程语言的乐趣
- 使用CoreImage实现素描滤镜
- ChineseGLUE:为中文NLP模型定制的自然语言理解基准
- 低版本cad如何打开高版本图纸?不用升级软件也可以搞定
- 手撸 SpringBoot DDD 微服务脚手架
- python 分类变量xgboost_python小白之路:第十九章 XGBoost
- WIN7下ADS使用详解
热门文章
- Lotus Notes基础知识
- 汤家凤高等数学基础手写笔记-不定积分
- 安卓来电归属地_如何做一名突出的iPhone用户?安卓勿进!
- 明日科技的python书籍怎么样_零基础学习Python不可错过的5本书籍
- matlab求一个方程组的系数矩阵,【求解】matlab求解非齐次方程组,但是系数矩阵是复数,求帮忙...
- 统计输入字符串中英文单词的个数
- python 合并 循环list_阿里巴巴鼎力推荐,Python入门至精通,24招加速你的Python
- echarts setoption方法_在Vue和React中使用ECharts的多种方法
- mysql 锁机制 mvcc_轻松理解MYSQL MVCC 实现机制
- linux 系统监控 php,Linux系统资源监控命令简介