標籤:

用 SVG 畫小水滴

原圖來自 用Sketch畫小水滴 - Work harder - 知乎專欄. 這是他的一個 SVG port (但不保證完美還原). (時間所限沒畫腳; 手部估計原圖是 Bezier 曲線,但是因為不曉得控制點在哪裡,這裡畫成圓弧了)

工具: Visual Studio. 一個支持 SVG 的喜歡的瀏覽器 (我才不說 IE 很好用)。

參考資料:

查 MSDN:

  • path element
  • radialGradient element

W3C:

  • Gradients and Patterns

步驟:

分析一下原圖。水滴的形狀由 270° 弧 DACE 和兩個三次 Bezier 曲線 DB 和 CB 組成。

這是 Yuki 的原圖的一部分。D 和 E 是我在這裡標的序號,ABC 是原有的。紅色圓圈表示控制點。

紅色圓圈表示曲線 DB 和 EB 的另外兩個控制點。

如果從 D 開始,就可以先畫弧到 E, 再畫三次 Bezier 曲線到 B, 再畫三次 Bezier 曲線回到 D. path 元素支持弧和 Bezier 曲線。

對應的 SVG 標記如下:

<path fill="#72b5fc" d="M 100 120 a 140 140 0 1 0 198 0 c -26 -26 -44 -48 -44 -90 c -42 28 -128 64 -154 90" />n

渲染結果如圖:

然後還要填充一個漸變色。因為沒有原始數據,這裡的漸變節點都是根據渲染圖估計的。

定義好漸變及其 id, 並且把他放到 defs 元素裡面。

<defs>n <radialGradient id="test" gradientUnits="userSpaceOnUse" r="210" gradientTransform="translate(-46 -28)">n <stop offset="1%" stop-color="#72f2c7"/>n <stop offset="65%" stop-color="#75d5f1"/>n <stop offset="82%" stop-color="#75a1f3"/>n <stop offset="87%" stop-color="#7c99f4"/>n <stop offset="97%" stop-color="#d997ff"/>n </radialGradient>n</defs>n

當然半徑和變換以及各個漸變節點的位置和顏色都是試了幾百萬次估計的,我也估計不準 QwQ.

接下來水滴的 fill 屬性就可以改為這個漸變色了:

<path fill="url(#test)" d="M 100 120 a 140 140 0 1 0 198 0 c -26 -26 -44 -48 -44 -90 c -42 28 -128 64 -154 90" />n

渲染結果:

我做的是那個旋轉 10 度的版本,所以給水滴再加一個 transform. SVG 中默認的 transform-origin 貌似是左上角,所以旋轉完後再平移一下。

<path d="M100,120 a140,140 0 1 0 198,0 c-26,-26 -44,-48 -44,-90 c-42,28 -128,64 -154,90" fill="url(#test)" transform="translate(40 -20) rotate(10)"/>n

這一步做完後題圖的水滴部分就做完了。

嘴巴和手腳仍然採用 path 來做,眼睛和腮紅則用 circle. 由於層疊的關係 (我 SVG 不好不會以除 DOM 順序以外的方法控制層疊順序),右手 (圖片左側的那隻: 動物如果腹面朝向觀察者,則左右與觀察者的相反) 的出現順序在水滴本體之前。配色均來自對原圖取色。

完整源碼如下:

<?xml version="1.0" encoding="utf-8"?>n<svg xmlns="http://www.w3.org/2000/svg" width_="400" height="400">n <defs>n <radialGradient id="test" gradientUnits="userSpaceOnUse" r="210" gradientTransform="translate(-46 -28)">n <stop offset="1%" stop-color="#72f2c7"/>n <stop offset="65%" stop-color="#75d5f1"/>n <stop offset="82%" stop-color="#75a1f3"/>n <stop offset="87%" stop-color="#7c99f4"/>n <stop offset="97%" stop-color="#d997ff"/>n </radialGradient>n </defs>n <path d="M74,263 a50,50 0 0 1 -18,40 a2,2 0 0 1 -4,-4 a47,47 0 0 0 17,-36 a2.5,2.5 0 0 1 5,0" fill="#4d5cb1"/>n <path d="M100,120 a140,140 0 1 0 198,0 c-26,-26 -44,-48 -44,-90 c-42,28 -128,64 -154,90" fill="url(#test)" transform="translate(40 -20) rotate(10)"/>n <circle r="8" fill="#4d5cb1" cx="140" cy="210"/>n <circle r="8" fill="#4d5cb1" cx="210" cy="210"/>n <circle r="10" fill="#ffc6d7" cx="124" cy="232"/>n <circle r="10" fill="#ffc6d7" cx="226" cy="232"/>n <path d="M160,230a22,22 0 0 0 30,0a3.5,3.5 0 0 0 -5,-5a15,15 0 0 1 -20,0a3.5,3.5 0 0 0 -5,5" fill="#4d5cb1"/>n <path d="M321,263 a50,50 0 0 0 18,40 a2,2 0 0 0 4,-4 a47,47 0 0 1 -17,-36 a2.5,2.5 0 0 0 -5,0" fill="#4d5cb1"/>n</svg>n

以上。


推薦閱讀:

SVG 與 HTML5 的 canvas 各有什麼優點,哪個更有前途?
數據可視化第一步,SVG【小概念】
外刊君談中國第三屆CSS大會
如何製作 svg 格式的 圖標字體?

TAG:SVG |