标签: svg

  • 使用 SVG 制作扇形

    使用 SVG 制作扇形

    有时候我们需要制作扇形,比如图形化数据生成饼图的时候。使用 HTML + CSS 做不到,必须借助 SVG 帮助。经过一些摸索,大概方式如下:

    0. 创建 SVG

    我们需要一个 SVG,然后在里面画一个园:

    <svg xmlns="http://www.w3.org/2000/svg" height="600" width="600" viewBox="0 0 20 20">
      <circle r="5" cx="10" cy="10" />
    </svg>

    这里,我创建了一个 SVG,并且以 10,10 位圆心,画了一个半径为 5 的圆。SVG 的视窗只需要显示这个圆,所以是 0 0 20 20 的正方形。widthheight 用来定义网页中 SVG 的尺寸,SVG 是矢量图形,可以实现内容的无损缩放,所以即使显示尺寸比图形尺寸大很多,也不用担心出现锯齿。

    1. 用边框画圆形

    接下来,我们用给圆加边框的方式来做圆形。

    <circle
      r="5"
      cx="10"
      cy="10"
      fill="transparent"
      stroke="tomato"
      stroke-linecap="butt"
      stroke-width="10"
    ></circle>

    首先,我们用 fill="transparent" 清理掉圆形内部的颜色,然后用 stroke="tomato" 给边框加上橙色。接下来,我们通过 stroke-width="10" 设置边框宽度为 10,这也是矩形半径。

    此时,屏幕上会出现一个橙色的正圆。

    2. 画扇形

    画扇形的方式有很多,比如画两条半径然后画弧形再填充颜色。但是利用边框画扇形最简单。

    用边框画扇形说白了,其实是结合圆环和虚线,需要有扇形的地方,就填充颜色;不需要扇形的地方,就用虚线的空白。这里要用到 stroke-dasharray 属性,它的规则很简单,奇数为实偶数为虚,所以我们只要计算扇形所需的弧形长度,然后剩下的填充周长即可。

    在我们这里,就是 stroke-dasharray=”calc(10 * 3.1415926 * 1/6) 31.415926",即取绘制一个 1/6 大小的扇形。

    3. 修改位置

    修改位置需要使用 stroke-dashoffset 属性,它会把图形从原来的位置移动若干距离,正的就往起点移动,负的就往终点移动。

    在我们这里,就是 stroke-dashoffset="calc(-10 * 3.1415926 * 1/6)",将第二个扇形移到第一个扇形的旁边。

    4. 其它+已知问题+扩展阅读

    最终效果:https://codepen.io/meathill/pen/yLMQqBQ?editors=1000

    这些属性,也可以使用 CSS 样式替换,效果一样。

    Safari 问题比较多,首先半圆就不是半圆,其次偏移也不对,不知道是否只支持 CSS。

  • Bootstrap 发布图表库 Bootstrap Icons 1.0,该准备切换到 SVG 了

    Bootstrap 发布图表库 Bootstrap Icons 1.0,该准备切换到 SVG 了

    Bootstrap 团队一边开发 Bootstrap 5,一边发布了 Bootstrap Icons 1.0(以下简称 BI)。官方全文见此:Bootstrap Icons v1.0.0。这个版本里包含 1100 个图标,涵盖范围很广,全免费(MIT),可以自由使用、修改。

    真正引起我注意的是,这个仓库不再使用 Webfont,而是全部使用 SVG。官方文档 介绍了三种使用方式:

    1. 直接嵌入 SVG 代码
    2. <svg> 中引用 BI 库并配合 <use> 使用
    3. 通过 bootstrap-icons/icons/*.svg 直接使用

    如果你非常怀念 Webfont 方式,可以用(3)结合 CSS background-image 的方式近似的模拟。

    其实,GitHub 很早以前就开始从 Webfont(Icon font) 向 SVG 切换了,他们还特地写了篇博客解释这件事情:Delivering Octicons with SVG,在里面列举了六个理由:

    1. Icon font 本身存在一些渲染问题,Webkit 内核的浏览器会使其边缘模糊,不利于辨识
    2. Icon font 一般会延后加载,而字体在完成加载之前无法判定大小,所以加载完成之后,需要重新计算布局并且重新进行渲染,造成不必要的性能损耗
    3. 可用性。参考这篇 Slide:Death to Icon Fonts,每十个人当中就有一个人存在阅读障碍,他们很难使用普通字体,必须使用专为他们设计的特殊字体,而这个时候,icon font 就会变成没有意义的方块。对使用阅读器的人更甚:icon font 是一种 hack,通常来说,我们并不会真的写文字进去,所以在他们看起来,图标会变得完全不可读。
    4. 合适的图标尺寸
    5. 方便重构字体文件
    6. 方便制作动画

    所以,如今 Bootstrap 放弃 webfont,使用 SVG 作为主要格式,应该说是大势所趋。这几年使用 Webfont,的确很方便,给开发带来很大的效率提升,但与此同时,也存在不少问题:

    1. fontawesome 体积越来越大,现在一组字体要 1M+,加载很耗时,但是拆分非常困难,即使只用几个图标,也需要加载整个字体库
    2. 无法对图标进行稍微复杂的操作,比如双色,或者特定部位的动画
    3. 放大之后,图标比较丑,也不好加工
    4. 前面说过的那些问题

    所以未来我和我厂也要慢慢从 webfont 切回 SVG。这样也有助于提升我厂产品的可用性。其实,互联网行业的可用性一直都做得不错,软件开发目前也算是残障人士最有机会获得体面收入的机会,所以,我辈仍需努力呀。

  • 用 SVG 画五角星

    用 SVG 画五角星

    先上代码:

    See the Pen draw a star by Meathill (@meathill) on CodePen.


    话说前两日想起来填坑,需要用五角星做示例。正好前几天买了本 SVG 的书,就想试一下。这篇文章记录其中几个要点。

    多边形 <polygon>

    在 SVG 中,画多边形要用到 <polygon>,它有一个属性 points 可以用来定义各个点的座标。有了它我们就可以连点成线做出想要的多边形了。

    创建 SVG 元素

    以前直接使用 document.createElement() 就能创建出想要的元素,然而 SVG 并非普通的文档,所以要小小的变动一下,使用命名空间来创建合适的元素:

    var svg = document.getElementById('svg')
      , ns = svg.namespaceURI
      , star = document.createElementNS(ns, 'polygon');
    

    先取到页面中写好的 SVG 节点,然后取得它的命名空间,最后借由它创建需要的元素。

    使用 JS 操作元素

    SVG 元素都是 SVGElement,对他们进行操作是需要一点技巧的。

    比如,向对变形增加顶点就需要

    var point = svg.createSVGPoint();
    point.x = 10;
    point.y = 10;
    star.points.appendItem(point);
    

    总结

    整体说来 SVG 操作还是蛮简单的,将来可能简单的绘图都直接用代码写了。