用几个点创建SVG圆

时间:2021-06-30 07:55:48

标签: css svg

我需要创建一个 30 点的 SVG 圆并在中心显示当前小时数。

我已经有半圈了,但我不知道如何完成。

代码:

 <svg version="1.1" width="140px" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 49.35 23.93" style="enable-background:new 0 0 49.35 23.93;" xml:space="preserve">
    <style type="text/css">
        .st0{fill:#000;}
        .st1{font-family:'ArboriaBook';}
        .st2{font-size:12px;}
    </style>
    <g>
        <path class="st0" d="M1.96,23.43c-0.44-0.06-0.71-0.39-0.66-0.81c0.05-0.42,0.4-0.66,0.84-0.61c0.43,0.05,0.72,0.37,0.66,0.81
            C2.74,23.24,2.39,23.48,1.96,23.43z"></path>
        <path class="st0" d="M2.9,18.83c-0.42-0.15-0.62-0.53-0.48-0.93c0.14-0.4,0.53-0.57,0.95-0.42c0.41,0.14,0.62,0.51,0.48,0.93
            C3.71,18.8,3.31,18.97,2.9,18.83z"></path>
        <path class="st0" d="M4.77,14.52c-0.38-0.23-0.5-0.65-0.28-1.01c0.21-0.36,0.63-0.45,1.01-0.22c0.37,0.22,0.51,0.62,0.28,1.01
            C5.57,14.66,5.14,14.74,4.77,14.52z"></path>
        <path class="st0" d="M7.47,10.69c-0.33-0.3-0.35-0.73-0.07-1.04c0.28-0.31,0.71-0.31,1.04-0.01c0.32,0.29,0.37,0.71,0.07,1.04
            C8.22,10.99,7.79,10.98,7.47,10.69z"></path>
        <path class="st0" d="M10.9,7.48c-0.26-0.36-0.2-0.79,0.14-1.03c0.34-0.24,0.76-0.16,1.02,0.2c0.25,0.35,0.22,0.77-0.14,1.03
            C11.58,7.92,11.15,7.83,10.9,7.48z"></path>
        <path class="st0" d="M14.92,5.02c-0.18-0.41-0.03-0.81,0.35-0.98c0.38-0.17,0.77,0,0.95,0.4c0.18,0.39,0.05,0.8-0.35,0.98
            C15.49,5.6,15.09,5.42,14.92,5.02z"></path>
        <path class="st0" d="M19.32,3.46c-0.09-0.43,0.13-0.8,0.54-0.89s0.76,0.16,0.85,0.59c0.09,0.42-0.11,0.8-0.54,0.89
            C19.76,4.13,19.41,3.88,19.32,3.46z"></path>
        <path class="st0" d="M23.94,2.82c0-0.44,0.29-0.76,0.71-0.76c0.42,0,0.71,0.3,0.72,0.75c0,0.43-0.27,0.76-0.71,0.76
            C24.24,3.57,23.95,3.25,23.94,2.82z"></path>
        <path class="st0" d="M28.66,3.13c0.09-0.44,0.44-0.68,0.85-0.6s0.63,0.44,0.55,0.88c-0.08,0.42-0.42,0.69-0.85,0.6
            C28.8,3.93,28.58,3.55,28.66,3.13z"></path>
        <path class="st0" d="M33.18,4.39c0.17-0.41,0.57-0.58,0.96-0.42c0.39,0.17,0.53,0.56,0.36,0.97c-0.17,0.4-0.55,0.59-0.96,0.42
            C33.15,5.2,33.01,4.79,33.18,4.39z"></path>
        <path class="st0" d="M37.33,6.54c0.25-0.37,0.68-0.45,1.02-0.21c0.35,0.24,0.4,0.66,0.15,1.02c-0.25,0.35-0.66,0.46-1.02,0.21
            C37.14,7.32,37.08,6.89,37.33,6.54z"></path>
        <path class="st0" d="M40.98,9.51c0.32-0.31,0.75-0.3,1.04,0s0.26,0.73-0.06,1.03c-0.31,0.3-0.74,0.32-1.04,0
            C40.63,10.24,40.67,9.8,40.98,9.51z"></path>
        <path class="st0" d="M43.94,13.13c0.38-0.23,0.8-0.14,1.02,0.21c0.22,0.36,0.11,0.77-0.27,1c-0.37,0.23-0.79,0.16-1.02-0.21
            C43.45,13.77,43.57,13.36,43.94,13.13z"></path>
        <path class="st0" d="M46.11,17.28c0.42-0.15,0.81,0.02,0.96,0.42s-0.05,0.77-0.47,0.92c-0.41,0.15-0.81,0-0.96-0.42
            C45.5,17.81,45.7,17.43,46.11,17.28z"></path>
        <path class="st0" d="M47.38,21.82c0.44-0.06,0.79,0.19,0.85,0.61c0.06,0.42-0.21,0.75-0.65,0.81c-0.43,0.06-0.79-0.17-0.85-0.61
            C46.68,22.22,46.96,21.88,47.38,21.82z"></path>
    </g>
    <text id="current_time" transform="matrix(1 0 0 1 11.2994 20.3894)" class="st0 st1 st2">09:54</text>
    </svg>

enter image description here

2 个答案:

答案 0 :(得分:1)

您可以只创建一个点,使用 <use> 多次重复使用,然后使用 basic trigonometry 为它们提供正确的坐标

然后使用 (0,0)text-anchor="middle" 在中心 alignment-baseline="middle" 添加文本

svg {
  width: 160px;
}
<svg viewBox="-52 -52 104 104" xmlns="http://www.w3.org/2000/svg">
    
   <!-- radius (r) of outer circle is 50, center is (0,0) -->
   <style>
      circle, text { fill: #9bc }

      text { font-family: system-ui; }
   </style>
   
   <!-- basic shape -->
   <defs>
      <circle r="2" id="dot"/>
   </defs>
   
   <!-- x = r * sin(-90),  y = r * cos(-90)  -->
   <use xlink:href="#dot"  x="-50" y="0" />
   
   <!-- x = r * sin(-78),  y = r * cos(-78)  -->
   <use xlink:href="#dot"  x="-48.907" y="-10.39" />
   
   <!-- x = r * sin(-66),  y = r * cos(-66)  -->
   <use xlink:href="#dot"  x="-45.677" y="-20.33" />
   
   
   <!-- continue by increasing the angle of 12° for
        the remaining 27 points, up to 270°
     -->

   <use xlink:href="#dot" x="-40.451" y="-29.389" />
   <use xlink:href="#dot" x="-33.457" y="-37.157" />
   <use xlink:href="#dot" x="-25.000" y="-43.301" />
   <use xlink:href="#dot" x="-15.451" y="-47.553" />
   <use xlink:href="#dot" x="-5.226" y="-49.726" />
   <use xlink:href="#dot" x="5.226" y="-49.726" />
   <use xlink:href="#dot" x="15.451" y="-47.553" />
   <use xlink:href="#dot" x="25.000" y="-43.301" />
   <use xlink:href="#dot" x="33.457" y="-37.157" />
   <use xlink:href="#dot" x="40.451" y="-29.389" />
   <use xlink:href="#dot" x="45.677" y="-20.337" />
   <use xlink:href="#dot" x="48.907" y="-10.396" />
   <use xlink:href="#dot" x="50.000" y="0" />
   <use xlink:href="#dot" x="48.907" y="10.396" />
   <use xlink:href="#dot" x="45.677" y="20.337" />
   <use xlink:href="#dot" x="40.451" y="29.389" />
   <use xlink:href="#dot" x="33.457" y="37.157" />
   <use xlink:href="#dot" x="25.000" y="43.301" />
   <use xlink:href="#dot" x="15.451" y="47.553" />
   <use xlink:href="#dot" x="5.226" y="49.726" />
   <use xlink:href="#dot" x="-5.226" y="49.726" />
   <use xlink:href="#dot" x="-15.451" y="47.553" />
   <use xlink:href="#dot" x="-25.000" y="43.301" />
   <use xlink:href="#dot" x="-33.457" y="37.157" />
   <use xlink:href="#dot" x="-40.451" y="29.389" />
   <use xlink:href="#dot" x="-45.677" y="20.337" />
   <use xlink:href="#dot" x="-48.907" y="10.396" />


   <text text-anchor="middle" alignment-baseline="middle" 
         x="0" y="0">12:34</text>

</svg>

我用一个简单的脚本自动生成了坐标列表

var useNodes ="";
for (i = -90; i < 270; i = i + 12) {
   var angle = Math.abs(i) * (Math.PI / 180);
   var x = (Math.sin(angle) * 50).toFixed(3);
   var y = (Math.cos(angle) * 50).toFixed(3);
   useNodes +='<use xlink:href="#dot" x="'+ x + '" y="'+ y +'" />\n'
}

console.log(useNodes);

答案 1 :(得分:1)

欺骗系统的一个简单方法是,您可以简单地使用 <circle> 元素的笔划并设置破折号数组,使破折号尽可能短,而不是绘制 30 个点。这并不能保证点是完美的圆形,但可能足够接近您的需要。

建议使用 JS 来设置正确的破折号数组值。但是,您当然可以在 CSS 中使用近似值。

请参阅下面的概念验证:

const circumference = 2 * Math.PI * 20;
const dots = 30;

document.querySelector('svg circle').setAttribute('stroke-dasharray', `0.1 ${circumference / dots - 0.1}`);
<svg version="1.1" width="300" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 50 50" xml:space="preserve">
    <style type="text/css">
        .st0{fill:#000;}
        .st1{font-family:'ArboriaBook';}
        .st2{font-size:12px;}
        circle {
          stroke: black;
          stroke-width: 2;
          stroke-linecap: round;
          fill: none;
        }
        text {
          text-anchor: middle;
        }
    </style>
    <circle cx="25" cy="25" r="20"></circle>
    <text id="current_time" class="st0 st1 st2" x="25" y="25" dy="0.25em">09:54</text>
</svg>

相关问题