如何使圆圈中的每个字段大小相同且可单击?

3 html javascript css svelte

对于以下代码: REPL

如何以简单的方式使圆的每个区域大小相同?由于显而易见的原因,顶部和底部的字段目前比其他字段更大。

我可以使用相对位置和绝对位置进行一些复杂的计算,但我想知道是否有一个简单的解决方案可以解决我的问题?

它应该是这样的: 在此输入图像描述

Cor*_*rrl 5

这是一个变量<svg>解决方案REPL
\n不幸的是,并不是每个字段都可以单独单击,我刚刚看到您在评论中提到了这一点。这是一个至关重要的事实,您可以将其添加到您的问题中。

\n

编辑:通过更改为fill: none;实际上每个字段都可以单独单击,谢谢@herrstrietzel

\n
<script>\n    const size = 300\n    let strokeWidth = 25\n    let gap = 20\n\n    $: circumference = Math.PI * (size - strokeWidth)\n    $: r = size/2 - strokeWidth/2\n\n    let pieces = [\n        {stroke: \'teal\'},\n        {stroke: \'magenta\'},\n        {stroke: \'orange\'},\n    ]\n\n    let color = \'#1411DF\'\n</script>\n\n<div style:width="{size}px">\n    <svg width={size} height={size} style="transform: rotate({-90+(gap/2/r/Math.PI*180)}deg)">\n        {#each pieces as piece, index}\n        {@const ownLength = circumference / pieces.length - gap}\n        <circle r={r}\n                        cx={size/2}\n                        cy={size/2}\n                        style:stroke-width={strokeWidth}\n                        style:stroke={piece.stroke}\n                        style:stroke-dasharray="{ownLength} {circumference}"\n                        style="fill: none; transform-origin: center;"\n                        style:transform="rotate({index * 360 / pieces.length}deg)"\n                        on:click="{() => console.log(piece.stroke)}"\n                        />\n        {/each}\n    </svg>\n\n    <input type="color" bind:value={color}>\n    <button on:click={() => pieces = [...pieces, {stroke: color}]}>\n        add piece\n    </button>\n\n    <label>\n        stroke-width:\n        <input type="range" bind:value={strokeWidth} min="1" max={size/5}>\n        {strokeWidth}\n    </label>\n\n    <label>\n        gap:\n        <input type="range" bind:value={gap} min="1" max={size/5}>\n        {gap}\n    </label>\n\n</div>\n\n<style>\n    circle:hover {\n        stroke: black !important;\n    }\n    div {\n        margin: 0 auto;\n        display: flex;\n        flex-direction: column;\n        align-items: center;\n    }\n    svg {\n        display: block;\n        margin-bottom: 2rem;\n    }\n    label {\n        width: 100%;\n        font-size: .9rem;\n        padding: 1rem 0;\n    }\n    input {\n        padding: 0;\n    }\n</style>\n
Run Code Online (Sandbox Code Playgroud)\n

并受到 HB 答案的启发,使用路径元素REPL提供了不同的解决方案

\n
<script>\n    let colors = [\'teal\', \'DarkOrchid\', \'orange\']\n    let color = \'#2E15D1\'\n\n    const size = 300\n    let strokeWidth = 10\n    let gap = 10 // degree\n\n    $: r = size/2 - strokeWidth/2\n\n    $: deg = (180 - (360 / colors.length) + gap) / 2\n    $: x = r * Math.cos(rad(deg))\n    $: y = r * Math.sin(rad(deg))\n\n    function rad(angle) {\n        return angle * Math.PI / 180;\n    } \n</script>\n\n<div style:width="{size}px">\n    <svg width={size} height={size} viewbox="{-size/2} {-size/2} {size} {size}" xmlns="http://www.w3.org/2000/svg">\n        {#each colors as color, index}\n        <path d="M -{x} -{y} A {r} {r} 0 0 1 {x} -{y}"\n                    style="fill: none;"\n                    style:stroke={color}\n                    style:stroke-width="{strokeWidth}"\n                    style:transform="rotate({360 / colors.length * index}deg)"\n                    on:click="{() => console.log(color)}"\n                    />\n        {/each}\n<!--        <circle cx="0" cy="0" {r} fill="none" stroke="black"></circle> -->\n<!--        <circle cx="0" cy="0" r="2"></circle> -->\n    </svg>\n\n    <input type="color" bind:value={color}>\n    <button on:click={() => colors = [...colors, color]}>\n        add piece\n    </button>\n\n    <label>\n        stroke-width:\n        <input type="range" bind:value={strokeWidth} min="1" max={size/5}>\n        {strokeWidth}\n    </label>\n\n    <label>\n        gap:\n        <input type="range" bind:value={gap} min="1" max={(360/colors.length)-1}>\n        {gap}\xc2\xb0\n    </label>\n\n</div>\n\n<style>\n    div {\n        margin: 0 auto;\n        display: flex;\n        flex-direction: column;\n        align-items: center;\n    }\n    svg {\n        margin: 2rem;\n        /*      transform: rotate(180deg); */\n    }\n    path:hover {\n        stroke: black !important;\n    }\n    input {\n        padding: 0;\n        margin: .4rem;\n    }\n    label {\n        display: grid;\n        align-items: center;\n        grid-template-columns: 1fr max-content 1fr;\n        font-size: .9rem;\n        white-space: nowrap;\n    }\n</style>\n
Run Code Online (Sandbox Code Playgroud)\n