如何使用 SVG 做图标

本贴最后更新于 2567 天前,其中的信息可能已经时移世易

好吧,不的不说太久没写文章了,都不知道自己在忙些啥,感觉最近又 get 了一些新技能,很想和大家分享一下。


感觉很久以前,应该是 2010 年左右,在 svg 和 canvas 之间,我鄙视了一把 svg,可是如今我却不得不去学习它。真是世事难料,就好比有人花了 2K 个比特币买了个🍕

SVG Sprite

背景

https://hacpai.com/article/1464879728790 之后,决定把 font icon 换为 svg,具体可参见这个 issue. 但是由于当时该到一半的时候总觉得缺点什么,就停止了移植。直到我遇见了 SVG Sprite 以后,才下定了决心,再复杂也要迁移。然后花了 20 个小时才移植完。

介绍

通俗的说就是把单个 svg 合并到一大个 svg 文件里面,有点类似以前的雪碧图。

使用方式和 CSS 差不多,分为内联、嵌入、链接、导入。个人比较中意链接,写法如下:

symbol.svg

<svg>
  <defs>
	<symbol id="logo" viewBox="0 0 16 16">
	  <path d="M14 18v13l-5-5-6 6-3-3 6-6-5-5zM32 3l-6 6 5 5h-13v-13l5 5 6-6z"></path>
	</symbol>
  </defs>
</svg>  

demo.html

<svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="symbol.svg#logo"></use></svg>

这是我感觉最完美的解决方案,然而当今都是静态资源分离的年代。Chrome 说这不安全

Unsafe attempt to load URL https://static.ld246.com/js/symbol-defs.svg from frame with URL https://hacpai.com. Domains, protocols and ports must match.

工具

IconMoon

  1. 导入或选择自己需要的图标
  2. 点击左下角 Generate SVG & More
  3. 依次点击下载
  4. 打开压缩包中的 symbol-defs.svg 文件,复制 <symbol ... </symbol> 贴入你的 symbol.svg 中即可使用

爬坑

把 symbol.svg 改为 symbol.js,修改其中后,在 html 总引入该 js 即可

symbol.js

document.body.insertAdjacentHTML("afterBegin", `
<svg>
  <defs>
	<symbol id="logo" viewBox="0 0 16 16">
	  <path d="M14 18v13l-5-5-6 6-3-3 6-6-5-5zM32 3l-6 6 5 5h-13v-13l5 5 6-6z"></path>
	</symbol>
  </defs>
</svg>  
`);

SVG animate, Path

要赶回去,先上代码吧。不懂的自己 google

<svg width="70" height="70" viewBox="0 0 70 70" xmlns="http://www.w3.org/2000/svg" stroke="#ff4544">
    <g fill="none" fill-rule="evenodd">
        <g transform="translate(1 1)" stroke-width="19">
            <circle cx="21" cy="21" r="0.0001">
                <animate attributeName="cx"
                     begin="0s" dur="3.6s"
                     values="21;7;21;21;35;49;49;55;35;35;35;35;35;55;49;49;35;21;21"
                     repeatCount="indefinite"
                     calcMode="linear" />
             <animate attributeName="cy"
                     begin="0s" dur="3.6s"
                     from="21" to="21"
                     values="21;35;49;49;35;21;21;15;21;21;35;49;49;55;49;49;35;21;21"
                     repeatCount="indefinite"
                     calcMode="linear" />
            </circle>
            <circle cx="35" cy="49" r="0.0001">
                <animate attributeName="cx"
                     begin="0s" dur="3.6s"
                     values="35;35;35;35;15;21;21;35;49;49;63;49;49;35;21;21;15;35;35"
                     calcMode="linear"
                     repeatCount="indefinite"
                     calcMode="linear" />  
                <animate attributeName="cy"
                     begin="0s" dur="3.6s"
                     from="49" to="49"
                     values="49;35;21;21;15;21;21;35;49;49;35;21;21;35;49;49;55;49;49"
                     repeatCount="indefinite"
                     calcMode="linear" />
            </circle>
            <circle cx="49" cy="21" r="0.0001">
                <animate attributeName="cx"
                     from="49" to="49"
                     begin="0s" dur="3.6s"
                     values="49;63;49;49;55;35;35;15;21;21;7;21;21;15;35;35;55;49;49"
                     repeatCount="indefinite"
                     calcMode="linear" />
               <animate attributeName="cy"
                     begin="0s" dur="3.6s"
                     values="21;35;49;49;55;49;49;55;49;49;35;21;21;15;21;21;15;21;21"
                     repeatCount="indefinite"
                     calcMode="linear" />
            </circle>
        </g>
    </g>
</svg>

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
请输入回帖内容 ...
Vanessa
我们终此一生,就是要摆脱他人的期待,找到真正的自己。 昆明