Rails 中使用 SVG

紅寶鐵軌客
Join to follow...
Follow/Unfollow Writer: 紅寶鐵軌客
By following, you’ll receive notifications when this author publishes new articles.
Don't wait! Sign up to follow this writer.
WriterShelf is a privacy-oriented writing platform. Unleash the power of your voice. It's free!
Sign up. Join WriterShelf now! Already a member. Login to WriterShelf.
寫程式中、折磨中、享受中 ......
774   0  
·
2018/01/24
·
4 mins read


要有好看的不發毛圖,就一定要使用向量圖,用 Adobe 的人,就一定知道 AI 跟 PhotoShop 的不同,在網頁中,就是要用 SVG,在 Rails 中要使用 SVG,其實很簡單,

方法一:植入法

其中最簡單的方法就是將 SVG 直接放在 views 中的 ERB 當中,舉個例子,這是我用 CorelDRAW X6 做個一個簡單的箭頭符號,唯一改的是加入了一個  Class="test"

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Creator: CorelDRAW X6 -->
<svg class="test" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="3.24899in" height="2.83576in" version="1.1" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd"
viewBox="0 0 2741 2392"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<style type="text/css">
<![CDATA[
.str0 {stroke:#373435;stroke-width:5.85835}
.fil0 {fill:darkcyan;fill-rule:nonzero}
]]>
</style>
</defs>
<g id="Layer_x0020_1">
<metadata id="CorelCorpID_0Corel-Layer"/>
<path class="fil0 str0" d="M3 1791l1367 0 0 595 1366 -1190 -1366 -1190 0 595 -1367 0 0 1190zm683 0m684 297m683 -297m0 -1190m-683 -297m-684 297m-683 595"/>
</g>
</svg>

然後在 CSS 中,就可以任意指定大小了,實務上,可以把這個 SVG 做成一個 partial,這樣就可以重複數用了,如果SVG 檔案不多,這是最簡單的使用法了。 

//test svg
svg.test {
width: 2rem;
height: 2rem;
 color: red;
}

這是結果:

 

方法二:當成檔案用

另外一個方法是把 SVG 的檔案放在 app/assets/images 中,這個好處是所有的影像擋都集中保管,既然是一個檔案,那就一定要讀取了,就加一個 helper 在 app/helpers/application_helper.rb

 # Rails SVG loader
def svg(name)
file_path = "#{Rails.root}/app/assets/images/#{name}.svg"
return File.read(file_path).html_safe if File.exists?(file_path)
'(not found)'
end

然後記得將 SVG 的 width 及 height 改成

width="inherit" height="inherit"

使用時,用個 CSS Class 包起來,這樣就可以改大小了。

<div class="svgtest">
<%= svg 'test_svg' %>
</div>

這樣就可以用 CSS 來改大小了。

.svgtest {
width: 4rem;
height: 4rem;
color: blue;
}

HTML:

test 2 on helper:
<div class="svgtest">
<%= svg 'test_svg' %>
</div>

秀個結果:

方法三:用 Gem

比較流行的是 inline-svg,寫 rails 最大的好處就是可以用 Gem,就看你喜不喜歡了,我是能少用就少用,但是用這個 Gem 是很方便的,只是它是用 Nokogiri,有人覺得慢,如果剛好有用,那就更適合了,這是他的網址,我覺得跟上面兩種也很像,主要的差別是用這個 Gem 可以在外設定 class 及其他 CSS style,看喜歡了。  這是另一篇類似的,使用類似的方法,但是用 assets。

方法四:用 Symbol 

這是參考這篇文章的,我是把 SVG 放在 ‘shared/test.html.erb' 中,大概會像這樣:(注意:我改了 stroke 及 fill 的設定為 currentColor)

<svg version="1.1" id="category-icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:none">
<symbol id="testsvg1" viewBox="0 0 2741 2392">
<defs>
<style type="text/css">
<![CDATA[
.str0 {stroke:currentColor;stroke-width:5.85835}
.fil0 {fill:currentColor;fill-rule:nonzero}
]]>
</style>
</defs>
<g id="Layer_x0020_1">
<metadata id="CorelCorpID_0Corel-Layer"/>
<path class="fil0 str0" d="M3 1791l1367 0 0 595 1366 -1190 -1366 -1190 0 595 -1367 0 0 1190zm683 0m684 297m683 -297m0 -1190m-683 -297m-684 297m-683 595"/>
</g>
</symbol>
</svg>

使用時就呼叫這 ID 就好了:

<div class="svgtest-container">
<div style="display: inline-block;">
test icon symbol:
</div>
<div style="display: inline-block; vertical-align: middle;">
<%= render 'shared/icons' %>
<div class="skill-category active">
<svg class="testsvg-icon">
<use xlink:href="#testsvg1"/>
</svg>
</div>
</div>
</div>

CSS 的設定會是這樣:

.testsvg-icon {
max-width: 2rem;
max-height: 2rem;
color-interpolation: sRGB;
flood-color: blue;
}
.svgtest-container {
color: blue;
}
.svgtest-container svg{
fill: currentColor;
}

如果有一堆 SVG,我覺得這是最好的方法,如果只有幾個,就不用了。 但是,如果你有好幾個 SVG 都是用同一個程式(例如:Corel Draw),你很快就會發現,奇怪,為什麼加入新的 SVG 後,其他的 SVG 不見了或是變色了?別擔心,還是那個 CDATA[ 中的問題,CDATA[ 裡面列了 class name 如 .str0,這些 SVG 的 class name 如果相同,就會亂了,最簡單的方法就是每個 SVG 用不同的 class name,改掉後,別忘了也要記得改 g 裡面的 path 的 class name: <path class="str0"... happy SVG!

HTML:

<div class="svgtest-container">
<div style="display: inline-block;">
test icon symbol:
</div>
<div style="display: inline-block; vertical-align: middle;">
<%= render 'shared/icons' %>
<div class="skill-category active">
<svg class="testsvg-icon">
<use xlink:href="#testsvg1"/>
</svg>
</div>
</div>
</div>

放個結果:

如果問我那個好,我覺得如果就一兩個 SVG,就用一號方法吧,如果很多,就用最後一個了,但,都各有其優點啦。 


WriterShelf™ is a unique multiple pen name blogging and forum platform. Protect relationships and your privacy. Take your writing in new directions. ** Join WriterShelf**
WriterShelf™ is an open writing platform. The views, information and opinions in this article are those of the author.


Article info

Categories:
Tags:
Date:
Published: 2018/01/24 - Updated: 2018/07/13
Total: 932 words


Share this article:
About the Author

很久以前就是個「寫程式的」,其實,什麼程式都不熟⋯⋯
就,這會一點點,那會一點點⋯⋯




Join the discussion now!
Don't wait! Sign up to join the discussion.
WriterShelf is a privacy-oriented writing platform. Unleash the power of your voice. It's free!
Sign up. Join WriterShelf now! Already a member. Login to WriterShelf.