SVG 學學就會了。


SVG 隨便學學就會了

這兩天閑來沒事把 Echart 換成 Rechart 感覺世界都清爽了。因為 rechart 使用 svg 來渲染,所以順帶學了下 SVG 感覺很輕松哦。

概念

SVG 是 w3c 的退出的規范。(就是 w3c 指定語法。各大廠商自己去實現)。SVG 渲染的是矢量圖(它之規定了圖像怎么畫,而不是規定那個像素畫什么顏色)。

優點

因為以上兩點(w3c, 矢量圖)所以他有兼容性好,不失真的優點。除此之外還有:

使用xml的格式規范(HTML 也是)。在瀏覽器上基本上可以看做是DOM節點來操作。(事件,渲染樣式)
svg 不同於位圖指定每一個像素的渲染,內部其實是用簡介的語法指定圖應該從哪畫到那怎么畫。本質上就是文本,所以很小。

這些優點決定了他很適合在前端畫一些簡單的圖。(畫復雜的就算了交給設計師吧)

Getting Started

在現在的瀏覽器使用 SVG 太簡單不過了。只需要在HTML中直接寫

  <!-- version prop in svg will be Deprecated -->
  <!-- xmlns is unnecessary for inner svg elements or inside HTML documents. -->
  <svg width="100" height="100">
    <line x1="0" y1="0" x2="100" y2="100" stroke="red"></line>
  </svg>
  • 可以清楚的看到 svg 的語法。svg 是 xml 的語法格式。svg 是定義一個容器。其定義一個圖的大小。圖的內容由其子元素來確定。

<svg> props

  • width | height 定義元素的大小

與 canvas 不同,width 和 height 是定義一個類似於窗口的顯示大小,可以在窗口外畫東西,只是你一般看不到。可以是svg顯示這個寬口外的圖,后面講。

svg 子元素

畫圖總離不開一些簡單的圖形,svg 對這些進行了封裝,成為以下的標簽。

<line x1="2" y1="4" x2="4" y5="7"></line>: 兩點確定一條線段,x1,y1,x2,y2 就是指定這兩個點的。
<rect x="2" y="4" width="100" rx="4" ry="4" height="100"></rect>: 畫長方形的,需要注意的是rx ry 是用來畫帶圓角的長方形的。就像css的border-radius;
<circle cx="13" cy="13" r="40"></circle>:cx, cy 確定圓心,r為半徑畫一個圓。
<ellipse cx="0" cy="0" rx="132" ry="test"></eliipse>: 這個是畫橢圓,rx, ry 是定義橢圓的x半徑, y軸半徑的。
<polygon points="0,0 3,3 4,4"></polygon>: 等價於你拿着筆按順序畫過經過的 points 中的各個點,最后回到第一個點。圍起來的圖形。

--- 以上就是一些常用的簡單圖了 ---

曲線(最復雜)

這個是普通 HTML CSS 沒辦法做到的。所以這個是學 SVG 中最高性價比的東西。

直接上例子

  <!-- 畫一條從(0,0)到(50,50)的線 -->
  <svg width="100" height="100">
    <path d="M0 0 L50 50"></path>
  </svg>

可以看到標簽是path,d為屬性。屬性d的值使用 Commandx y 這樣的語法格式。(注意Command后直接跟參數沒有空格)

指令 參數 說明
M x y 將點移動到 (x,y) 經過不划線
L x y 將點移動到 (x,y) 並划線
H y 將點的y坐標做變化x不變,並划線
V x 將點的x坐標做變化y不變,並划線
說明 x,y 上面的參數都是絕對值,線面都是相對值
m 參數都一樣 將點的個個坐標都添加上x,y的值,作用跟M一樣
l 參數都一樣 將點的個個坐標都添加上x,y的值,作用跟L一樣
h 參數都一樣 將點的個個坐標都添加上x的值,作用跟H一樣
v 參數都一樣 將點的個個坐標都添加上y的值,作用跟V一樣
z 沒有參數 將點移動到起點,並划線

(媽媽(M)拉(L)我看湖(H)南衛(V)視。真是智(Z)障。

下面真的搞曲線了

接觸過曲線的都知道貝塞爾曲線,SVG 畫曲線也玩不出花來肯定是用貝塞爾曲線的。

Codepen

  <svg width="100" height="100">
    <path d="M0 0 Q0 100, 100 100"></path>
  <svg>

畫貝塞爾曲線一般需要3個參數,但是畫圖的語言,一般會記錄上一個點,所以SVG的命令就是 Qx y,targetX targetY

指令 參數 說明
Q x y,targetX targetY 以(x, y)為切點,上一個點位起點,(targetX, targetY)為終點畫一條貝塞爾曲線
T targetX targetY 以上條貝塞爾曲線的弧度畫一條到(targetX, targetY)的貝塞爾曲線,如果上一條划線不是貝塞爾那就是畫一條直線

騰訊QT語音的兩個字的靈感不會是從這里來的吧。

當然還有三次貝塞爾曲線的。語法類似。

指令 參數 說明
C x y, x2 y2,targetX targetY 以(x, y),(x2,y2)為3次貝塞爾的曲線參數,上一個點位起點,(targetX, targetY)為終點畫一條貝塞爾曲線
S targetX targetY 類比上一個

用QT語音打CS????

樣式的定義

SVG畫的線部分已經結束了,接下來我們上色,跟描邊。

上面的全部標簽都可以分為兩部分,一部分是線,已經線包圍起來的內容。

線的樣式可以在標簽上用stroke來定義, 包圍起來的內容用fill。

  • stroke 有 stroke stroke-width stroke-linecap stroke-opacity等
  • fill 有 fill fill-opacity fill-rule 等

svg fill & stroke

  <svg width="100" height="100">
    <circle
      width="100" height="100" x="0" y="0"
      stroke="red" stroke-width="2" stroke-linecap="round" stroke-opacity="0.8" stroke-linejoin="round"
      fill="green" fill-opacity="0.8"
    ></circle>
  </svg>

圖形的復用

就這么老老實實的搬一般就夠用了,但是這程序最重要的就是少搬磚,多偷懶。

有時候我們可能一個圖中有了很多個相同的圖,這時候就copy就慘了。偷懶第一招。

  <svg width="100" height="100">
    <defs>
      <g id="ahole">
        <rect x="0" y="0" width="50" height="50" id="rect1"></rect>
        <circle
          width="100" height="100" x="0" y="0"
          stroke="red" stroke-width="2" stroke-linecap="round" stroke-opacity="0.8" stroke-linejoin="round"
          fill="green" fill-opacity="0.8"
          id="circle1"
        ></circle>
      </g>
    </defs>
    <use href="#ahole"/>
    <use href="#rect1" x="123123"/>
    <!-- you can add any props you want to replace the svg element you used -->
    <use href="#circle1" y="123123"/>
  </svg>

解析:defs 就是定義聲明不會在svg中划出。g是將其子元素統統打包,方便use的時候使用。use 就是調用啦,通過href:#id的方式來指定使用哪一個小圖形,你可以在use的標簽中使用任何屬性來替掉你use的標簽原來的屬性。這里要說明,use 不一定只能應用 defs 中定義的,只要在上下文前,有用id命名的都可以。

偷懶第二招

上面這招只能在同一個svg中使用,但是我們想在每一個svg中使用呢。比如UI庫中的icon可能有大量的svg,這是用引用一個就畫一個svg顯然有點浪費。

  <svg style="display: none;">
    <symbol id="beaker">
      <!-- <path>s and whatever other shapes in here -->  
      <rect width="40" height="100" x="0" y="0" fill="red"></rect>
    </symbol>
  </svg>

  <svg width="100" height="100" style="border:solid 1px green">
    <use href="#beaker"></use>
  </svg>

解析:把包含symbol的svg隱藏,並注入大量要使用的svg圖,后面的svg就可以簡單的通過use來應用了。(這里的svg版本都是最新的,以前版本的語法可能需要xmlns:href等復雜的寫法,我選擇擁抱最新)

與CSS的結合

我們可以通過給svg元素添加class,並在 css 中設置樣式。

🌰

  <css>
  .rect {
    fill: green;
    x: 20px;
  }
  </css>
  <svg fill="red">
    <rect x="0" y="0" width="100" height="100" class="rect"></rect>
  </svg>

個人建議:css 雖然可以設置定位的屬性,但是最好還是不要使用定位,不然維護起來會很麻煩,盡量只是用css來定義顏色樣式。另外結合 css3 的 transform 和 animation 能實現很好的動畫效果。

總結: 入門款就是這個樣子了,后面有時間再跟新進階版。包括 preserveAspectRatio filter text 動畫等知識。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM