HTML5使用SVG圖像時(shí)viewBox屬性怎么用

小編給大家分享一下HTML5使用SVG圖像時(shí)viewBox屬性怎么用,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

南平網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián),南平網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為南平近1000家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站制作要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的南平做網(wǎng)站的公司定做!

viewBox屬性是用于指定用戶SVG圖像的坐標(biāo)系統(tǒng)的原點(diǎn)以及尺寸的。所有在SVG內(nèi)繪制的內(nèi)容都是相對(duì)于這個(gè)坐標(biāo)系統(tǒng)完成的。因?yàn)镾VG畫布在所有方向都是無限延長的,你甚至可以在這個(gè)坐標(biāo)系統(tǒng)的邊界之外的地方繪制圖形;但是這些相對(duì)于SVG視窗定位的圖形,也可以由用戶坐標(biāo)系的位置來控制。

viewBox屬性使用四個(gè)參數(shù)來指定坐標(biāo)系原點(diǎn)的位置以及它的尺寸:x y width height。初始情況下,這個(gè)坐標(biāo)系等同于初始化的視窗坐標(biāo)系(由SVG圖像的width和height確定),而且它的原點(diǎn)是在(0, 0)——即SVG的左上角。

通過改變x和y這兩個(gè)參數(shù)的值,可以調(diào)整原點(diǎn)的位置。改變width和height的值,可以改變坐標(biāo)系統(tǒng)的尺寸。只使用viewBox屬性,就可以幫你擴(kuò)展或裁剪SVG畫布。跟著示例一起閱讀。

重要提示:在本文章中,我不會(huì)改變viewBox在SVG視窗內(nèi)的默認(rèn)行為(比例和位置)。因?yàn)?,根?jù)屬性的默認(rèn)行為,viewBox的內(nèi)容會(huì)被盡可能地完全包含在視窗內(nèi),然后放置在中心位置。不過,使用preserveAspectratio屬性可以讓你自由地改變viewBox的尺寸和位置,但是在這篇文章中,這不是必需的技術(shù),所以我們也不會(huì)在這里深入講解。
使用viewBox裁剪SVG,即使用viewBox屬性制作Art Direction的SVG

前陣子,我的一個(gè)客戶要求把他網(wǎng)站的SVG頭像按照不同的屏幕尺寸設(shè)置成不同的大小,從而使得它只有一小部分是在小屏幕上可見的,在中等的屏幕尺寸上可以看到再大一點(diǎn)的部分,然后在大屏幕上可以看到完整的內(nèi)容。當(dāng)時(shí)我腦子里首先出現(xiàn)的想法就是,他的要求其實(shí)是使用viewBox屬性來裁剪SVG圖像,然后根據(jù)不同的屏幕尺寸,顯示他想要看到的圖像的某部分。

通過改變SVG坐標(biāo)系統(tǒng)的尺寸和原點(diǎn)位置,我們可以把SVG進(jìn)行裁剪,并顯示我們希望在視窗中顯示的那部分內(nèi)容。

我們來看看如何實(shí)現(xiàn)。

假設(shè)我們有如下這張完整的SVG圖像,然后我們想要把它裁剪成小屏幕的尺寸。這張圖是Freepik設(shè)計(jì)的可免費(fèi)使用的房屋矢量圖,該圖片有Creative Commons Attribution 3.0 Unported協(xié)議的許可授權(quán)。為了簡(jiǎn)單起見,我們先假設(shè)圖像只是要被裁剪成在中小屏幕上顯示的內(nèi)容,以及大屏幕上顯示的完整的內(nèi)容,如下所示。
HTML5使用SVG圖像時(shí)viewBox屬性怎么用

左邊的圖的是我們將要使用viewBox屬性裁剪的完整的圖片,右邊的圖是我們希望在小屏幕上顯示的區(qū)域。

現(xiàn)在,通過改變viewBox屬性的值來裁剪SVG。有一些需要考慮的內(nèi)容,我們等下會(huì)講到。但是首先,我們要改變坐標(biāo)系統(tǒng),讓它匹配上面的圖片中虛框矩形區(qū)域的內(nèi)容。,通過調(diào)整系統(tǒng)的原點(diǎn)以及width和height的值,我們可以改變它初始的0 0 800 800參數(shù)值。

但是我們要如何獲知新坐標(biāo)和新尺寸呢?重點(diǎn)是不要經(jīng)過大量重復(fù)的實(shí)驗(yàn)和錯(cuò)誤。

有幾種方式。因?yàn)槲覀円呀?jīng)在圖形編輯器中(我的示例使用的是AI),我們可以使用編輯器的面板來獲取元素的位置和尺寸。

我畫這個(gè)虛線的矩形框,除了用來表示我想要在小屏幕上顯示的內(nèi)容,還有一個(gè)原因就是:我們可以獲取這個(gè)矩形的位置和尺寸,然后把它們作為viewBox的值來使用。使用AI的變換面板(如下圖),我們獲取了我們需要的這些值。通過選擇矩形,并點(diǎn)擊右上角的變換鏈接,我們得到了如下圖所示的面板,包括我們所需要的x, y, width和height值。
HTML5使用SVG圖像時(shí)viewBox屬性怎么用

這個(gè)AI中的變換面板可以用來獲取選中矩形的位置和尺寸的值

你可能注意到了,上面的值并不是整數(shù),所以我們需要手動(dòng)修改。根據(jù)上面的信息,我們把viewBox的值改成 0 200 512 512。

因?yàn)樾碌膙iewBox的寬高比和SVG視窗的寬高比是一樣的(都是正方形),viewBox內(nèi)的內(nèi)容將會(huì)擴(kuò)大,并且只有被選中的區(qū)域會(huì)在視窗中顯示。改變viewBox的值之后,結(jié)果如圖:
HTML5使用SVG圖像時(shí)viewBox屬性怎么用

新裁剪的SVG。只有我們指定使用viewBox屬性的位置在視窗中是可見的。藍(lán)色邊框表示SVG的視窗。

在這一點(diǎn)上,有一個(gè)問題需要解決:

如果被裁剪區(qū)域(即viewBox)的寬高比 != SVG視窗的寬高比?

在這種情況下,將會(huì)有明顯的溢出。明顯的溢出,我指的不是超出SVG視窗邊界的延伸,而是viewBox定義的相對(duì)于新用戶坐標(biāo)系統(tǒng)的溢出。下圖作了相應(yīng)的說明。

HTML5使用SVG圖像時(shí)viewBox屬性怎么用

如果viewBox的寬高比和視窗的寬高比不同,SVG中的內(nèi)容會(huì)溢出用戶坐標(biāo)系統(tǒng),結(jié)果可能會(huì)是這樣。

黑色邊框代表新的用戶坐標(biāo)系,藍(lán)色邊框是SVG視窗。

上邊右圖中的黑色邊框是viewBox定義的區(qū)域。根據(jù)viewBox在視窗內(nèi)的默認(rèn)行為,它會(huì)被居中并盡可能放大,來保證自身內(nèi)容盡可能地包含在視窗(藍(lán)色邊框)中。

因?yàn)镾VG畫布從概念上來說,在所有方向都是無限延伸的,你可以在用戶坐標(biāo)系統(tǒng)邊界之外繪制圖形,內(nèi)容會(huì)直接溢出移動(dòng),如上圖所示。

如果你改變了SVG視窗的寬高比(SVG的width和height),來讓它們適應(yīng)viewBox的寬高比,你就不會(huì)看到溢出了,因?yàn)関iewBox的縮放是適應(yīng)視窗的,和前面的示例一樣。

但是,在某些情況下,你可能不能或根本不想改變SVG的寬高比。比如說,如果你是使用SVG sprite作為一組圖像來顯示頁面上圖片的。在大多數(shù)情況下,圖像都有一個(gè)固定的寬高比——而且你并不想改變改變圖像的尺寸,就為了適應(yīng)它里面的某一張小圖的內(nèi)容?;蛘呖赡苣闱度肓艘粋€(gè)圖標(biāo)系統(tǒng),并希望所有的圖標(biāo)在同一個(gè)時(shí)間都保持相同的尺寸。

為了剪掉多余的東西(比如說,sprite上的部分其它圖標(biāo),在視窗中顯示),你可以使用<clipPath>來把多余的部分裁剪掉。裁剪路徑可以是一個(gè)覆蓋了整個(gè)viewBox區(qū)域的<rect>元素,然后將該元素應(yīng)用到root SVG。

但是,還有一點(diǎn)要記?。捍_保<rect>的x和y屬性和viewBox的保持一致,除非rect將被相對(duì)定位于原來的/初始化的系統(tǒng)的原點(diǎn),那么SVG最終被裁剪的內(nèi)容也是不確定的。

CSS Code復(fù)制內(nèi)容到剪貼板

  1. <svg xmlns="http://w3.org/2000/svg" viewBox="vx vy width height" clip-path="url(#clipper)" width=".." height="..">   

  2.     <!-- SVG content here -->   

  3.     <clipPath id="clipper">   

  4.         <rect x="vx" y="vy" width="100%" height="100%"></rect>   

  5.     </clipPath>   

  6. </svg>  

當(dāng)然,裁剪多余的部分也就意味著你仍然在使用不同的寬高比,還是需要解決內(nèi)容兩邊多出的空白。如果SVG是一個(gè)連續(xù)的場(chǎng)景,像我們前面的那個(gè)例子,那就沒必要了,因?yàn)槟氵€需要調(diào)整視窗的寬高比。如果SVG是一組圖標(biāo),并且你只是在不同的視窗中使用一次,這可能就不是問題了。

這里有一點(diǎn)重要的東西要記住,viewBox的寬高比最好還是和視窗的寬高比保持一致;另外,你需要設(shè)置固定來避免SVG中任何不確定的多余的空白出現(xiàn)。

所以,viewBox可以用來裁剪SVG,并根據(jù)需要只展示SVG的某部分內(nèi)容。但是它要如何應(yīng)用于實(shí)例呢?

在響應(yīng)式設(shè)計(jì)中的Art Directing SVG

這部分沒有什么需要補(bǔ)充的內(nèi)容,除了實(shí)際過程的代碼。所以,假設(shè)你有如上所示的SVG,并且想要把它作為頭像,比如說,在中小尺寸的屏幕上你只想顯示裁剪下來的那部分內(nèi)容,然后在大屏幕上顯示完整的頭像。

改變SVG視窗的width和height值,我們可以使用CSS。但是改變viewBox的值,目前我們需要使用JavaScript。

并非所有的SVG屬性,CSS屬性都可以等同使用;只有一組具有和CSS屬性相同效果的屬性才可以在CSS中設(shè)置。你可以在這個(gè)表格中查看這組可以作為CSS屬性的SVG屬性的概述。在SVG2中,很多屬性(如x, y, cx, cy, r等等)都可以被添加到這個(gè)列表中;但是這些都是我們現(xiàn)在可以使用的屬性。

為了展示SVG的不同部分,需要基于不同媒體查詢改變viewBox的值,你可以使用Modernizr,查找媒體查詢條件,然后在JavaScript中對(duì)應(yīng)更改viewBox的值。示例如下:

CSS Code復(fù)制內(nèi)容到剪貼板

  1. // 獲取root <svg>的引用   

  2. var svgRoot = ...; // 取決于你如何嵌入并引用SVG   

  3. // 定義viewBox的參數(shù)值   

  4. var vbValue = '0 200 512 512';   

  5. // 使用Modernizr的媒體查詢檢索來改變viewBox的值   

  6. if (Modernizr.mq('(max-width: 700px)')) {   

  7.    svgRoot.setAttribute('viewBox', vbValue);   

  8. }   

  9. // 其它的尺寸情況  

這是可以運(yùn)行的,但是如果我們可以使用CSS來完成這個(gè)效果豈不更贊?

使用CSS的viewBox屬性來裁剪SVG

免責(zé)聲明:在寫這篇文章的時(shí)候,并沒有CSSviewBox屬性。這只是一個(gè)用來解釋為什么這個(gè)屬性有用,以及我想象的它如何被使用的示例。

理想情況下,我們可以這樣使用它:

CSS Code復(fù)制內(nèi)容到剪貼板

  1. <style>   

  2.   

  3. @media screen and (max-width: 700px) {   

  4.     svg {          

  5.         viewBox: 0 200 512 512;    

  6.     }    

  7. }   

  8.   

  9. /* etc. */  

  10.   

  11. </style>  

這些樣式會(huì)被放進(jìn)(或取出)SVG中,然后SVG將會(huì)根據(jù)視窗的尺寸調(diào)整其viewBox值。讓它成為頁面視窗(內(nèi)聯(lián)<svg>)的情況),或是通過其它任何引用SVG的元素的尺寸確定的視窗(這可以給我們一些近乎相同的元素查詢)。

不過,這在目前是不可能實(shí)現(xiàn)的,因?yàn)镃SS中還沒有viewBox屬性。

前陣子,我就這個(gè)問題詢問了一個(gè)SVG規(guī)范的編輯,他說我可以根據(jù)實(shí)際使用情況和實(shí)例,向SVGWG提建議。后來在Twitter上進(jìn)行了一些討論,我才發(fā)現(xiàn)在幾年前已經(jīng)有一個(gè)相似的SVGWG proposal thread。當(dāng)初的提議今天仍然存在,所以我希望,能夠通過一些實(shí)際使用示例,推進(jìn)這個(gè)提議,并在不久的將來可以實(shí)現(xiàn)。如果你也想要在CSS中看到viewBox屬性,請(qǐng)幫助實(shí)現(xiàn)這一目標(biāo),推動(dòng)這個(gè)提議的轉(zhuǎn)發(fā)和評(píng)論。

當(dāng)使用viewBox完成SVG Art-Direction的時(shí)候,需要記住的東西

在做我的客戶的項(xiàng)目的時(shí)候,我花了一分鐘不到的時(shí)間來按照對(duì)方的要求對(duì)頭像進(jìn)行art-direct。但是,這最終分出了三個(gè)獨(dú)立的SVG,而不是不同屏幕尺寸上的相同SVG不同viewBox。

我們選擇三個(gè)SVG的原因是,完整SVG的尺寸太大,在移動(dòng)端達(dá)到了100kb以上的大小。最初的SVG是200kb左右的,我可以通過優(yōu)化SVG來把文件壓縮到接近一半的大小,但是對(duì)于移動(dòng)設(shè)備來說,圖片還是太大了,所以最后我們只能使用三張不同大小的圖像。art-directing SVG的時(shí)候,需要記住的就是:性能問題。如果你的SVG太大了,不要使用viewBox來art-direct。

現(xiàn)在,如果你選擇使用三個(gè)不同的SVG圖像,也有多種可能的方式可以完成&mdash;&mdash;這取決于你嵌入SVG的方法,也取決于你想要完成什么、不想完成什么。

使用<picture>元素來完成不同SVG圖像是最理想的方式。它不僅能夠根據(jù)瀏覽器為我們提供不同的可供選擇的SVG,而且還不需要使用JavaScript,還可以讓我們對(duì)不支持它的瀏覽器(IE8及以下)提供多種優(yōu)化的降級(jí)圖像。<picture>對(duì)于使用SVG是非常有用的,你可以在這篇文章中閱讀所有SVG fallback的內(nèi)容。

但是如前面所說,如果你想要有動(dòng)畫或交互效果的SVG,<picture>不是最佳選擇。就像使用<img>嵌入SVG,SVG不能被添加樣式和動(dòng)畫,除非樣式和動(dòng)畫是在<svg>文件中定義的,SVG不能添加腳本(出于安全考慮),也不能有任何交互(CSS或JS)&mdash;&mdash;比如說,懸停,不會(huì)有交互效果。

所以,我總是說:SVG為我們提供了很多選項(xiàng),可以讓我們完成幾乎所有的事情;你需要做一個(gè)權(quán)衡、要主次分明、有時(shí)甚至需要作出妥協(xié),基于此作出最佳的選擇。但是對(duì)于性能,永不妥協(xié)才有利于發(fā)展!

在我們結(jié)束之前,因?yàn)槲覀兲岬搅耸褂胿iewBox屬性改變SVG畫布尺寸的問題,我們來看看另一個(gè)例子,我們可以借助這個(gè)屬性來幫我們?cè)谔幚鞸VG時(shí)節(jié)省一些時(shí)間和精力。

使用viewBox擴(kuò)展SVG畫布

正如viewBox屬性可以用于縮放SVG,它也可以用來擴(kuò)展SVG畫布。

幾周前我創(chuàng)建了一個(gè)可以生成SVG圓形菜單的工具。我創(chuàng)建了幾個(gè)例子來演示如何使用JavaScript讓生成的菜單動(dòng)起來。demo使用<object>元素嵌入到應(yīng)用程序頁面上。<object>的邊界定義了SVG視窗的邊界,任何在這些邊界之外的內(nèi)容都是溢出,而且默認(rèn)隱藏。

需要注意的是“邊界之外”指的是在SVG中的內(nèi)容,它還是在無窮大的SVG畫布上的,但是超過了由視窗定義的無窮大的矩形

譯者注:關(guān)于SVG畫布、視窗的內(nèi)容可閱讀w3cplus上的相關(guān)文章。
創(chuàng)建的菜單,SVG的尺寸是恰好可以將菜單包含進(jìn)去,而沒有再大一些。避免了菜單周圍任何多余的空白。

我給某個(gè)菜單應(yīng)用了一個(gè)彈跳動(dòng)畫,作為菜單動(dòng)畫的示例。這個(gè)彈跳效果“拉長了”各菜單項(xiàng),也導(dǎo)致了菜單項(xiàng)在它們彈跳的時(shí)候會(huì)單獨(dú)切出來(即溢出)。
HTML5使用SVG圖像時(shí)viewBox屬性怎么用

起初,由于SVG視窗是由<object>元素定義的,所以視窗和菜單本身是一樣大的,菜單項(xiàng)上的彈跳效果導(dǎo)致了這些菜單項(xiàng)在彈跳的時(shí)候溢出。

這些可愛的彈跳動(dòng)畫應(yīng)用于那些使用彈跳時(shí)間函數(shù)從0開始放大到100%的項(xiàng)目(即該項(xiàng)目最初是不可見的,縮小狀態(tài)),這個(gè)效果就是如果項(xiàng)目彈跳到超過了100%的大小,那就把它縮回到100%。這個(gè)效果會(huì)導(dǎo)致項(xiàng)目在彈跳超過SVG邊界的時(shí)候溢出。

下圖展示了縮放菜單項(xiàng)在放大到超過<object>的邊界(灰色邊框)的時(shí)候的效果,其中,<object>用于嵌入這個(gè)縮放菜單項(xiàng)。
HTML5使用SVG圖像時(shí)viewBox屬性怎么用

上方的示意圖展示了菜單項(xiàng)放大到溢出SVG視窗邊界時(shí)的效果?;疑吙虮硎維VG視窗的邊框(即<object>元素)。

給<object>設(shè)置overflow: visible也不能解決問題,因?yàn)?lt;object>和<iframe>實(shí)際上是相似的。我們需要做的是擴(kuò)展<object>創(chuàng)建的視窗內(nèi)的SVG畫布,使得縮放的項(xiàng)目有足夠的“反彈”空間,而不會(huì)超過它的邊界。我們可以使用viewBox屬性來完成它。

為了延長SVG畫布,只需簡(jiǎn)單增加它的尺寸。因此,我們使用的是700 x 500px的尺寸,而不是500 x 250這個(gè)SVG菜單的原始尺寸。這還會(huì)讓畫布在視窗中顯示的高度增加100px,而視窗中的畫布寬度會(huì)增加200px。我根據(jù)這些菜單項(xiàng)在彈跳效果需要放大的空間來確定這些值。根據(jù)您的SVG以及您要完成的具體內(nèi)容,這些值并不要求一致。

現(xiàn)在,為了確保菜單是放置在視窗的中心的,我們需要把坐標(biāo)系統(tǒng)的位置往負(fù)方向分別移動(dòng)100px(即向上和向左)。把這個(gè)移動(dòng)應(yīng)用到坐標(biāo)系統(tǒng)的原點(diǎn)上,和把一個(gè)平移轉(zhuǎn)換應(yīng)用到系統(tǒng)中的菜單上是一樣的。結(jié)果是菜單會(huì)在視窗中保持居中。
HTML5使用SVG圖像時(shí)viewBox屬性怎么用

在該圖中,藍(lán)色邊框表示SVG視窗邊界(即<object>元素),灰色邊框表示用戶坐標(biāo)系統(tǒng)的初始尺寸。藍(lán)色數(shù)字和箭頭表示視窗中的坐標(biāo)系統(tǒng)的擴(kuò)展。

在延長用戶坐標(biāo)系統(tǒng)尺寸的同時(shí),你也增加了畫布在視窗中可見區(qū)域的面積。這樣做的結(jié)果是畫布的內(nèi)容會(huì)顯得略小&mdash;&mdash;這根據(jù)你把畫布放大了多少而定。但是對(duì)于菜單來說,這樣的結(jié)果是可以接受的。

下面的屏幕記錄顯示了擴(kuò)展SVG畫布的結(jié)果,以及在SVG邊界內(nèi)的菜單動(dòng)畫效果。
HTML5使用SVG圖像時(shí)viewBox屬性怎么用

一旦SVG畫布被擴(kuò)展,菜單項(xiàng)就有足夠的空間來進(jìn)行縮放,在應(yīng)用彈跳效果的時(shí)候也不會(huì)再因?yàn)橐绯霰患羟小?/p>

通過改變viewBox屬性的四個(gè)參數(shù)值來延伸SVG畫布,這樣所有問題以及菜單項(xiàng)被剪切的問題都可以解決。viewBox確實(shí)非常棒~~

以上是“HTML5使用SVG圖像時(shí)viewBox屬性怎么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

當(dāng)前題目:HTML5使用SVG圖像時(shí)viewBox屬性怎么用
網(wǎng)站鏈接:http://muchs.cn/article28/gedpjp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導(dǎo)航、電子商務(wù)、、關(guān)鍵詞優(yōu)化網(wǎng)站策劃、手機(jī)網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

手機(jī)網(wǎng)站建設(shè)