一唱星、柵格圖形和矢量圖形
柵格圖形:也稱位圖喊衫,圖像由一組二維像素網(wǎng)格表示跌造。
Canvas 2d API 就是一款柵格圖形 API。通過(guò) Canvas API 繪制圖形族购,其實(shí)是更新 Canvas 的像素壳贪。PNG 和 JPEG 是兩種柵格圖形的格式。即 PNG 和 JPEG 圖像中的數(shù)據(jù)也同樣代表著像素寝杖。
矢量圖形:圖像由數(shù)學(xué)描述的幾何形狀表示违施。矢量圖像包括使用高級(jí)幾何形狀(比如線和形狀)繪制圖像所需的全部信息。
SVG 是矢量圖形的一種瑟幕,同 HTML 一樣磕蒲,SVG 是一種文件格式,有自己的 API只盹。SVG 同 DOM API 結(jié)合形成了一種矢量圖形 API辣往。盡管可以將 PNG 等柵格圖形嵌入到 SVG 中,但從根本上講殖卑,SVG 是一種矢量格式站削。
二、理解 SVG
SVG 的本質(zhì)特征是它基于 XML孵稽。HTML5 引入了內(nèi)連 SVG钻哩,所以 SVG 元素可以直接出現(xiàn)在 HTML 標(biāo)記中屹堰。
SVG 和 Canvas 的重要差異:
(1)SVG 繪制的文本可選,而 Canvas 不能(因?yàn)?Canvas 文本用像素繪制街氢,是圖像的一部分)扯键;
(2)SVG 上的文本是可搜索的,Canvas 上的文本無(wú)法被搜索引擎獲取珊肃。
HTML 是用來(lái)定義頁(yè)面結(jié)構(gòu)的聲明性語(yǔ)言荣刑,而 SVG 是用來(lái)創(chuàng)建視覺(jué)結(jié)構(gòu)的語(yǔ)言。通過(guò) DOM API 伦乔,你可以與 SVG 和 HTML 進(jìn)行交互厉亏。SVG 文檔是元素構(gòu)成的樹(shù)狀結(jié)構(gòu),同 HTML 一樣烈和,它支持腳本操作和添加樣式爱只,還可以向 SVG 元素添加事件處理函數(shù)。
圖形 API 設(shè)計(jì)方面存在兩個(gè)派系:
一是即時(shí)模式(immediate-mode):圖形提供了繪圖接口招刹,由 API 接口調(diào)用引起的繪制行為會(huì)即時(shí)發(fā)生恬试。如 Canvas。
二是保留模式(retained-mode):在保留模式圖形中疯暑,有一個(gè)與場(chǎng)景中的視覺(jué)對(duì)象對(duì)應(yīng)的模型训柴,它會(huì)隨著時(shí)間的推移而保留下來(lái)「菊可以使用 API 操作場(chǎng)景圖形幻馁,當(dāng)其改變時(shí),圖形引擎會(huì)重繪場(chǎng)景越锈。SVG 是一種保留模式圖形仗嗦,其場(chǎng)景圖形就是文檔。用于操作 SVG 的 API 是 W3C DOM API甘凭。
SVG 文檔在呈現(xiàn)時(shí)會(huì)保留構(gòu)成它的矢量信息儒将,縮放 SVG 時(shí),渲染程序會(huì)立即重繪所有構(gòu)成圖像的線條对蒲。所以钩蚊,縮放 SVG 不會(huì)導(dǎo)致其質(zhì)量下降。而 Canvas 縮放時(shí)圖像會(huì)模糊蹈矮,原因是圖像由像素組成砰逻,且只能在更高分辨率下重新采樣。
三泛鸟、使用 SVG 創(chuàng)建 2D 圖形
(1)在頁(yè)面中添加 SVG
添加內(nèi)聯(lián) SVG 到 HTML 頁(yè)面中如同添加其他元素一樣簡(jiǎn)單蝠咆。svg 標(biāo)簽的開(kāi)始標(biāo)記和結(jié)束標(biāo)記之間,可以添加一些形狀和其他視覺(jué)對(duì)象。還可以在 HTML 中以靜態(tài)圖像的方式引用 SVG 文件刚操,例如:
<code>
<img src="example.svg">
</code>
不過(guò)這種方式的缺點(diǎn)是:SVG 文檔不能像內(nèi)聯(lián) SVG 內(nèi)容那樣集成到 DOM 中闸翅,即無(wú)法編寫(xiě)與 SVG 元素進(jìn)行交互的腳本。
(2)簡(jiǎn)單的形狀
SVG 語(yǔ)言包含了基本的形狀元素菊霜,如矩形坚冀、圓形和橢圓。形狀元素的尺寸和位置被定義成了屬性鉴逞。如:矩形的屬性有 width 和 height记某。圓形有一個(gè)表示半徑的 r 屬性。和 css 一樣构捡,距離單位包括 px,em 等液南。
示例:
<code><svg width="200" height="200">
<rect x="10" y="10" width="100" height="80" stroke="red" fill="#ccc" />
<circle cx="120" cy="80" r="40" stroke="#00f" fill="none" stroke-width="8" />
</svg>
</code>
SVG 繪制形狀對(duì)象時(shí)是按對(duì)象在文檔中出現(xiàn)的順序進(jìn)行的。
SVG 實(shí)用的坐標(biāo)系統(tǒng)與 Canvas API 相同勾徽,svg 元素的左上角位置的坐標(biāo)是(0,0)滑凉。
(3)變換 SVG 元素
SVG 中有些組織元素,可用于將多個(gè)元素結(jié)合起來(lái)喘帚,使它們作為一個(gè)整體進(jìn)行變換或鏈接畅姊。<g> 元素代表“組”(group)。組可以用來(lái)結(jié)合多個(gè)相關(guān)的元素啥辨。組內(nèi)成員可由通用 ID 來(lái)引用。此外盯腌,組也可以作為一個(gè)一個(gè)整體進(jìn)行變換溉知。示例:
<code><svg width="200" height="200">
<g transform="translate(-10, 350)"
stroke-width="20"
stroke-linejoin="round">
<path d="M0,0 Q170,-50 260, -190 Q310, -250 410,-250"
fill="none" />
</g>
</svg>
</code>
(4)復(fù)用內(nèi)容
SVG 中的 <defs> 元素用于定義留待將來(lái)使用的內(nèi)容(折合 react/vue 中的組件功能類似)。SVG 中的 <use> 元素用于鏈接到 <defs> 元素定義的內(nèi)容腕够。借助這兩個(gè)元素级乍。可以多次復(fù)用同一內(nèi)容帚湘,消除冗余玫荣。
示例:
<code><svg width="200" height="200">
<defs>
<g id="shapeGroup">
<rect x="10" y="10" width="100" height="80" stroke="red" fill="#ccc" />
<circle cx="120" cy="80" r="40" stroke="#00f" fill="none" stroke-width="8" />
</g>
</defs>
<use xlink:href="#shapeGroup" transform="translate(20,0) scale(0.5)" />
<use xlink:href="#shapeGroup" transform="translate(50,0) scale(0.7)" />
<use xlink:href="#shapeGroup" transform="translate(80,0) scale(0.25)" />
</svg>
</code>
(5)圖案和漸變
圖案類似于 Canvas 中的背景圖做法。漸變也分為線性漸變和放射性漸變大诸,和 Canvas 類似捅厂。
示例:
<code><svg width="200" height="200">
<defs>
<pattern id="GravelPattern" patternUnits="userSpaceOnUse" x="0" y="0" width="100" height="67" viewBox="0 0 100 67">
<image x="0" y="0" width="100" height="67" xlink:href:"gravel.jpg"></image>
</pattern>
<linearGradient id="Gradient">
<stop offset="0%" stop-color="#000"></stop>
<stop offset="100%" stop-color="#f00"></stop>
</linearGradient>
</defs>
<rect x="10" y="10" width="100" height="80" stroke="red" fill="url(#Gradient)" />
<circle cx="120" cy="80" r="40" stroke="#00f" fill="url(#GravelPattern)" stroke-width="8" />
</svg>
</code>
(6)SVG 路徑
SVG 不僅包含簡(jiǎn)單的形狀,還包含自由形態(tài)的路徑资柔。path 元素有一個(gè) d 屬性焙贷。d 代表數(shù)據(jù)(data)。在 d 屬性的值中贿堰,你能夠指定一系列的路徑繪制命令辙芍。每條命令都可能帶有坐標(biāo)參數(shù)。一些命令的含義為:M 代表移至(moveto),L 代表劃線至(lineto),Q 代表二次曲線故硅, Z 代表閉合曲線庶灿。
(7)SVG 文本
示例:
<code><svg width="200" height="200">
<text x="10" y="80" font-family="Droid Sans" stroke="#00f" fill="#00f" font-size="18px">
hello SVG
</text>
</svg>
</code>
四、組合場(chǎng)景
完整示例:
<code><svg width="400" height="600">
<defs>
<pattern id="GravelPattern" patternUnits="userSpaceOnUse" x="0" y="0" width="100" height="67" viewBox="0 0 100 67">
<image x="0" y="0" width="100" height="67" xlink:href="gravel.jpg"></image>
</pattern>
<linearGradient id="TrunkGradient">
<stop offset="0%" stop-color="#663300"></stop>
<stop offset="40%" stop-color="#996600"></stop>
<stop offset="100%" stop-color="#552200"></stop>
</linearGradient>
<rect x="-5" y="-50" width="10" height="50" id="Trunk"></rect>
<path d="M-25, -50
L-10, -80
L-20, -80
L-5, -110
L-15, -110
L0, -140
L15, -110
L5, -110
L20, -80
L10, -80
L25, -50
Z" id="Canopy"></path>
<linearGradient id="CanopyShadow" x="0" y="0" x2="0" y2="100%">
<stop offset="0%" stop-color="#000" stop-opacity=".5"></stop>
<stop offset="20%" stop-color="#000" stop-opacity="0"></stop>
</linearGradient>
<g id="Tree">
<use xlink:href="#Trunk" fill="url(#TrunkGradient)"></use>
<use xlink:href="#Trunk" fill="url(#CanopyShadow)"></use>
<use xlink:href="#Canopy" fill="none" stroke="#663300" stroke-linejoin="round" stroke-width="4px"></use>
<use xlink:href="#Canopy" fill="#339900" stroke="none"></use>
</g>
<g id="TreeShadow">
<use xlink:href="#Trunk" fill="#000"></use>
<use xlink:href="#Canopy" fill="000" stroke="none"></use>
</g>
</defs>
<g transform="translate(-10, 350)" stroke-width="20" stroke="url(#GravelPattern)" stroke-linejoin="round">
<path d="M0,0 Q170,-50 260, -190 Q310, -250 410,-250" fill="none"></path>
</g>
<text y="60" x="200" font-family="impact" font-size="60px" fill="#996600" text-anchor="middle">
Happy Trails!
</text>
<use xlink:href="#TreeShadow" transform="translate(130, 250) matrix(1, 0, -0.5, 1, 0, 0) scale(1, 0.6)" opacity="0.2"></use>
<use xlink:href="#Tree" transform="translate(130, 250)"></use>
<use xlink:href="#TreeShadow" transform="translate(260, 500) matrix(1, 0, -0.5, 1, 0, 0) scale(2, 1.2)" opacity="0.2"></use>
<use xlink:href="#Tree" transform="translate(260, 500) scale(2)"></use>
</svg>
</code>