无需使用HTML5画布,实现动态渲染圆形扇区的方法
P粉731861241
P粉731861241 2023-09-02 10:43:07
[CSS3讨论组]
<p>我正在制作一个幸运轮盘,我需要根据扇区数量创建一个轮盘或圆圈,并填充奖品名称。</p> <p>我已经完成了固定扇区数量的圆圈的代码。这是一个包含6个扇区的圆圈的示例。</p> <p> <pre class="brush:css;toolbar:false;">.wheel_container { position: relative; --wheel-size: 360px; width: var(--wheel-size); height: var(--wheel-size); margin-bottom: 2.4em; } .wheel { display: flex; justify-content: center; position: relative; overflow: hidden; width: 100%; height: 100%; border-radius: 50%; background-color: aquamarine; --segment-deg: 60deg; } .wheel div { display: flex; justify-content: center; align-items: center; position: absolute; width: calc((2 * 3.141592653589793 * (var(--wheel-size) / 2)) / 6); height: 50%; clip-path: polygon(0 0, 50% 100%, 100% 0); transform-origin: bottom; writing-mode: vertical-rl; } .wheel div &gt; span { font-weight: 500; font-size: 1rem; text-align: center; color: rgba(0, 0, 0, 0.7); } .wheel div:nth-child(1) { background-color: beige; transform: rotate(calc(-1 * var(--segment-deg) / 2)); } .wheel div:nth-child(2) { background-color: blueviolet; transform: rotate(calc(-3 * var(--segment-deg) / 2)); } .wheel div:nth-child(3) { background-color: crimson; transform: rotate(calc(-5 * var(--segment-deg) / 2)); } .wheel div:nth-child(4) { background-color: orange; transform: rotate(calc(-7 * var(--segment-deg) / 2)); } .wheel div:nth-child(5) { background-color: violet; transform: rotate(calc(-9 * var(--segment-deg) / 2)); } .wheel div:nth-child(6) { background-color: yellow; transform: rotate(calc(-11 * var(--segment-deg) / 2)); }</pre> <pre class="brush:html;toolbar:false;">&lt;div class='wheel_container'&gt; &lt;div class='wheel'&gt; &lt;div&gt;&lt;span&gt;苹果&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;榴莲&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;香蕉&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;芒果&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;草莓&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;菠萝蜜&lt;/span&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;</pre> </p> <p>我尝试通过计算轮盘的周长除以扇区数量来确定<code>.wheel div</code>的<code>width</code>属性。但是,这不起作用,因为<code>clip-path</code>中的多边形不是弯曲的,而包含它的<code>&lt;div&gt;</code>仍然是一个盒子。</p> <p>我可以通过在<code>&lt;div&gt;</code>的宽度上添加一些像素来实现我想要的6个扇区圆圈的效果。</p> <p> <pre class="brush:css;toolbar:false;">.wheel_container { position: relative; --wheel-size: 360px; width: var(--wheel-size); height: var(--wheel-size); margin-bottom: 2.4em; } .wheel { display: flex; justify-content: center; position: relative; overflow: hidden; width: 100%; height: 100%; border-radius: 50%; background-color: aquamarine; --segment-deg: 60deg; } .wheel div { display: flex; justify-content: center; align-items: center; position: absolute; /* Modification */ width: calc((2 * 3.141592653589793 * ((var(--wheel-size) + 37px) / 2)) / 6); height: 50%; clip-path: polygon(0 0, 50% 100%, 100% 0); transform-origin: bottom; writing-mode: vertical-rl; } .wheel div&gt;span { font-weight: 500; font-size: 1rem; text-align: center; color: rgba(0, 0, 0, 0.7); } .wheel div:nth-child(1) { background-color: beige; transform: rotate(calc(-1 * var(--segment-deg) / 2)); } .wheel div:nth-child(2) { background-color: blueviolet; transform: rotate(calc(-3 * var(--segment-deg) / 2)); } .wheel div:nth-child(3) { background-color: crimson; transform: rotate(calc(-5 * var(--segment-deg) / 2)); } .wheel div:nth-child(4) { background-color: orange; transform: rotate(calc(-7 * var(--segment-deg) / 2)); } .wheel div:nth-child(5) { background-color: violet; transform: rotate(calc(-9 * var(--segment-deg) / 2)); } .wheel div:nth-child(6) { background-color: yellow; transform: rotate(calc(-11 * var(--segment-deg) / 2)); }</pre> <pre class="brush:html;toolbar:false;">&lt;div class='wheel_container'&gt; &lt;div class='wheel'&gt; &lt;div&gt;&lt;span&gt;苹果&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;榴莲&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;香蕉&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;芒果&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;草莓&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;span&gt;菠萝蜜&lt;/span&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;</pre> </p> <p>但是,适用于6个扇区的代码无法适用于8个扇区等等...</p> <p>我认为解决方案可能在使用<code>clip-path</code>的SVG填充规则中。然而,我对SVG的了解仅限于此处,我需要一些帮助。其他解决方案也受欢迎。</p>
P粉731861241
P粉731861241

全部回复(1)
P粉460377540

您遇到的问题是计算 .wheel div 的宽度和高度的方式不正确。如果高度是圆的半径:--radius: calc(var(--wheel-size) / 2 );,那么宽度就是 width: calc( 2 * var(--radius ) / 1.732);,其中 1.732 是 Math.sqrt(3)。这适用于一个有 6 个部分的轮子,其中三角形(用于剪切路径)是等边三角形。

在您的示例中,宽度等于半径。这是不够的,因为 div 超出了圆形,并且您根据 div 的大小计算了剪切路径。

为了了解发生了什么,请删除 border-radius: 50%;,并向轮子添加一个半透明的未剪切的部分(clip-path: none;)

console.log(Math.sqrt(3))
*{margin:0;padding:0}


.wheel_container {
  position: relative;
  
  --wheel-size: 360px;
  width: var(--wheel-size);
  height: var(--wheel-size);
  
  margin-bottom: 2.4em;
}

.wheel {
  display: flex;
  justify-content: center;
  
  position: relative;
  overflow: hidden;
  
  width: var(--wheel-size);
  height: var(--wheel-size);
  
  border-radius: 50%;
  background-color: aquamarine;
  --segment-deg: 60deg;
}

.wheel div {
  display: flex;
  justify-content: center;
  align-items: center;
  
  position: absolute;
  
  
  --radius: calc(var(--wheel-size) / 2 );
  height: var(--radius);
  
  width: calc( 2 * var(--radius ) / 1.732);
  clip-path: polygon(0 0, 50% 100%, 100% 0);
  
  transform-origin: bottom;
  writing-mode: vertical-rl;
}

.wheel div > span {
  font-weight: 500;
  font-size: 1rem;
  text-align: center;
  color: rgba(0, 0, 0, 0.7);
}

.wheel div:nth-child(1) {
  background-color: beige;
  transform: rotate(calc(-1 * var(--segment-deg) / 2));
}

.wheel div:nth-child(2) {
  background-color: blueviolet;
  transform: rotate(calc(-3 * var(--segment-deg) / 2));
}

.wheel div:nth-child(3) {
  background-color: crimson;
  transform: rotate(calc(-5 * var(--segment-deg) / 2));
}

.wheel div:nth-child(4) {
  background-color: orange;
  transform: rotate(calc(-7 * var(--segment-deg) / 2));
}

.wheel div:nth-child(5) {
  background-color: violet;
  transform: rotate(calc(-9 * var(--segment-deg) / 2));
}

.wheel div:nth-child(6) {
  background-color: yellow;
  transform: rotate(calc(-11 * var(--segment-deg) / 2));
}


..wheel div {transform:none!important}
<div class='wheel_container'>
  <div class='wheel'>
    <div><span>Apple</span></div>
    <div><span>Durian</span></div>
    <div><span>Banana</span></div>
    <div><span>Mango</span></div>
    <div><span>Strawberry</span></div>
    <div><span>Jackfruit</span></div>
  </div>
</div>

为了进行 8 个部分的轮子,您将需要一个 --segment-deg:45 和不同的 .wheel div 的宽度。我使用的是 width: calc( 2 * var(--radius ) / 2.414);,其中 2.414 是 (180 - 45) / 2 的正切值。

let a = 67.5;
const rad = Math.PI / 180;

console.log((Math.tan( a * rad)))
*{margin:0;padding:0}


.wheel_container {
  position: relative;
  
  --wheel-size: 360px;
  width: var(--wheel-size);
  height: var(--wheel-size);
  
  margin-bottom: 2.4em;
}

.wheel {
  display: flex;
  justify-content: center;
  
  position: relative;
  overflow: hidden;
  
  width: var(--wheel-size);
  height: var(--wheel-size);
  
  border-radius: 50%;
  background-color: aquamarine;
  --segment-deg: 45deg;
}

.wheel div {
  display: flex;
  justify-content: center;
  align-items: center;
  
  position: absolute;
  
  
  --radius: calc(var(--wheel-size) / 2 );
  height: var(--radius);
  
  width: calc( 2 * var(--radius ) / 2.414);
  clip-path: polygon(0 0, 50% 100%, 100% 0);
  
  transform-origin: bottom;
  writing-mode: vertical-rl;
}

.wheel div > span {
  font-weight: 500;
  font-size: 1rem;
  text-align: center;
  color: rgba(0, 0, 0, 0.7);
}

.wheel div:nth-child(1) {
  background-color: beige;
  transform: rotate(calc(-1 * var(--segment-deg) / 2));
}

.wheel div:nth-child(2) {
  background-color: blueviolet;
  transform: rotate(calc(-3 * var(--segment-deg) / 2));
}

.wheel div:nth-child(3) {
  background-color: crimson;
  transform: rotate(calc(-5 * var(--segment-deg) / 2));
}

.wheel div:nth-child(4) {
  background-color: orange;
  transform: rotate(calc(-7 * var(--segment-deg) / 2));
}

.wheel div:nth-child(5) {
  background-color: violet;
  transform: rotate(calc(-9 * var(--segment-deg) / 2));
}

.wheel div:nth-child(6) {
  background-color: yellow;
  transform: rotate(calc(-11 * var(--segment-deg) / 2));
}


.wheel div:nth-child(7) {
  background-color: red;
  transform: rotate(calc(-13 * var(--segment-deg) / 2));
}

.wheel div:nth-child(8) {
  background-color: blue;
  transform: rotate(calc(-15 * var(--segment-deg) / 2));
}
<div class='wheel_container'>
  <div class='wheel'>
    <div><span>Apple</span></div>
    <div><span>Durian</span></div>
    <div><span>Banana</span></div>
    <div><span>Mango</span></div>
    <div><span>Strawberry</span></div>
    <div><span>Jackfruit</span></div>
    
    <div><span>red</span></div>
    <div><span>blue</
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号