如何在生成正确 SVG 代码的 Sketch 应用程序中绘制圆环图

How to draw donut chart in sketch app, which generates correct SVG code

我对 Sketch 应用程序生成圆环图的方式几乎没有意见。

这就是我在 Sketch 应用程序中构建圆环图的方式

请参考截图跟随

  1. 我创建了一个 200px x 200px 的圆圈
  2. 空填充。行程 25(中心位置)。这将是空状态圆圈,所以我将其着色为灰色
  3. 我已经复制了这个基圆来创建我的第一个 50% 部分(总共 3 个,50%、25%、25%)
  4. 我的第一段50%,"Dash"的长度是314,看起来破折号是从6点钟位置画出来的,逆时针方向移动(这样会比较明显在其他部分)。但是,我更喜欢从 12' 开始 点钟顺时针方向移动。
  5. 复制圆圈以创建 25% 的第二个部分,等于 "Dash" 157 和 "Gap" 471。
  6. 由于圆形笔画的绘制方式(参见第 4 点),我应用了 90 度的变换
  7. 最后一段,和第二段类似,只是变换了180度
  8. 生成的 SVG 不代表在 Sketch 中绘制的内容 问题:

    • 如何确保最终 SVG 在 Sketch 应用程序中看起来与设计的一样
    • 在sketch中,如何保证笔划从12点钟的位置开始(我猜是用变换?)顺时针绘制。

Sketch 生成的代码 (https://jsfiddle.net/BrightPixels/932w6j9d/)

<?xml version="1.0" encoding="UTF-8"?>
<svg width="226px" height="226px" viewBox="0 0 226 226" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <!-- Generator: Sketch 45.2 (43514) - http://www.bohemiancoding.com/sketch -->
    <title>donut-chart</title>
    <desc>Created with Sketch.</desc>
    <defs></defs>
    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="iPad" transform="translate(-236.000000, -213.000000)" stroke-width="25">
            <g id="donut-chart" transform="translate(249.000000, 226.000000)">
                <circle id="base" stroke="#D8D8D8" cx="100" cy="100" r="100"></circle>
                <circle id="segment1" stroke="#FFD900" stroke-dasharray="314,314" cx="100" cy="100" r="100"></circle>
                <circle id="segment2" stroke="#64B445" stroke-dasharray="157,471" transform="translate(100.000000, 100.000000) rotate(90.000000) translate(-100.000000, -100.000000) " cx="100" cy="100" r="100"></circle>
                <circle id="segment3" stroke="#004FB6" stroke-dasharray="157,471" transform="translate(100.000000, 100.000000) rotate(180.000000) translate(-100.000000, -100.000000) " cx="100" cy="100" r="100"></circle>
            </g>
        </g>
    </g>
</svg>  

SVG 中 <circle> 的破折号图案始终从 3 点钟的位置开始。从你的例子来看,Sketch 似乎认为它从 12 点钟的位置开始——至少对于黄色的是这样。我很困惑为什么第二个和第三个似乎是在 3 点开始。

要使其在 SVG 中看起来正确,您需要将黄色的旋转 -90 度。这会将它 "back" 从 3 点旋转到 12 点。

<?xml version="1.0" encoding="UTF-8"?>
<svg width="226px" height="226px" viewBox="0 0 226 226" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <!-- Generator: Sketch 45.2 (43514) - http://www.bohemiancoding.com/sketch -->
    <title>donut-chart</title>
    <desc>Created with Sketch.</desc>
    <defs></defs>
    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="iPad" transform="translate(-236.000000, -213.000000)" stroke-width="25">
            <g id="donut-chart" transform="translate(249.000000, 226.000000)">
                <circle id="base" stroke="#D8D8D8" cx="100" cy="100" r="100"></circle>
                <circle id="segment1" stroke="#FFD900" stroke-dasharray="314,314" cx="100" cy="100" r="100" transform="translate(100, 100) rotate(-90) translate(-100, -100) "></circle>
                <circle id="segment2" stroke="#64B445" stroke-dasharray="157,471" transform="translate(100.000000, 100.000000) rotate(90.000000) translate(-100.000000, -100.000000) " cx="100" cy="100" r="100"></circle>
                <circle id="segment3" stroke="#004FB6" stroke-dasharray="157,471" transform="translate(100.000000, 100.000000) rotate(180.000000) translate(-100.000000, -100.000000) " cx="100" cy="100" r="100"></circle>
            </g>
        </g>
    </g>
</svg>  

虽然我没有对 Sketch 的解释。

我建议使用两种方法来构建它,并且都不依赖于旋转变换。变换(尤其是从设计工具与其他属性(如 stroke-dasharray 或蒙版)一起导出时)可能会导致问题。

方法一:

如果这是一个不需要更改的静态图形,您可以简单地在 Sketch 中采用这种方法:

• 创建 3 个相同的圆形图层,带有黄色、绿色和蓝色边框。
• 对于每个圆,使用剪刀工具从圆中删除线段。*例如,对于蓝色图层,您可以使用剪刀工具删除其线段中的所有线段。我还写了一篇关于 how to use the Scissors tool 的文章。
• 请注意,此方法不使用旋转变换。它应该可以轻松且相同地从 Sketch 导出到 SVG。

* 线段是任意两个向量点之间的路径,因此如果您希望圆的一部分在任意点(例如:4 点钟方向)结束,其中没有'如果还没有矢量点,您可以进入“编辑”模式并沿着路径单击以在此处添加矢量点。

方法二:

如果这是一个动态图形,根据真实数据(如饼图)变化,笔画破折号是个好主意,但我建议做一些直接在 SVG 中工作:

• 在 Sketch 中创建相同的圆层(只有一个)。
• 这种笔划破折号的使用方式很大程度上依赖于1.圆的起点,2.圆的路径方向。我们可以通过在圆圈上进入编辑模式(return 键)在 Sketch 中找出这些;选择的矢量点是起点,点击tab键将循环通过沿路径方向移动的其他点。基于 Sketch 的默认圆圈,我们需要进行以下调整以获得从 12 点开始并顺时针移动的圆圈:
• 将圆旋转 180°,然后单击工具栏中的“拼合”(或在菜单栏中,通过“图层”>“合并”>“拼合”)。除了移除旋转变换之外,这会将其变成自定义路径而不是标准圆。它将作为 <path> 元素而不是 <circle> 导出到 SVG。
• 路径方向目前是逆时针方向,所以如果你想要它是顺时针方向,你也应该去图层>路径>反转顺序来切换路径方向。现在我们有了我们想要的圆路径——不需要在 SVG 中旋转。

• 导出为 SVG 后,我建议将代码复制到 CodePen 中,我已经这样做了 here in this demo。首先,将 <path> 元素移动到 <defs> 区域,以便您可以轻松地为每个彩色段克隆它。
• 创建 3 个 <use> 元素引用 <path>,每个元素都有自己的描边颜色。如果您不熟悉如何执行此操作,请参阅我的 CodePen link。
• 向每个 <use> 元素添加一个 stroke-dasharray 属性。它们应该有 2 个值:1. 您要创建的线段的长度,以及 2. 破折号之间的间隙的长度——应该等于或大于路径本身的长度。在这种情况下,路径长度约为 628,可以使用我在该 CodePen 中包含的 Javascript 的一点点来计算(打开控制台以查看结果数字)。在本例中,绿色和蓝色圆圈占据了圆路径的 1/4,因此它们的 stroke-dasharray 应该是 157, 628
• 因为这些破折号都从路径的开头开始,所以我们需要对它们进行偏移。我们不需要为此使用旋转变换——相反,我建议使用 stroke-dashoffset,它正是出于这个原因而创建的。偏移量采用一个数值:它在 相反 方向移动破折号的距离作为路径。这意味着我们需要使用负值在与路径相同的方向上移动。要将绿色部分偏移半个圆,该属性应为 stroke-dashoffset="-314"
• 这种方法的好处是您可以轻松地使用 Javascript 或 CSS calc() 轻松地为这些设置 stroke-dasharraystroke-dashoffset 值彩色片段,并根据新数据更新它们。

哇哦—动态图表!