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 : 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 渲染的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言怎么删除字符串中的指定字符_Jav
- 下一篇: python循环输入字典_python