Skip to content

简单的饼图

基于 transform 方案

用伪元素覆盖上去,通过旋转决定露出多大扇形区

一个负的延时值是合法的。与 0s 的延时类似,它意味着动画会立即开始播放,但会自动前进到延时值的绝对值处,就好像动画在过去已经播放了指定的时间一样。因此实际效果就是动画跳过指定时间而从中间开始播放了

用负的动画延时来直接跳至动画中的任意时间点,并且定格在那里,以此来实现按照比率来显示饼图

这里的动画永远处于暂停状态,指定的持续时间并不会产生任何副作用

css
.box {
    position: relative;
    width: 100px;
    line-height: 100px;
    border-radius: 50%;
    background: yellowgreen;
    background-image: linear-gradient(to right, transparent 50%, #655 0);
    color: transparent;
    text-align: center;
}

@keyframes spin {
    to { transform: rotate(.5turn); }
}
@keyframes bg {
    50% { background: #655; }
}

.box::after {
    content: '';
    position: absolute;
    top: 0; left: 50%;
    width: 50%;
    height: 100%;
    border-radius: 0 100% 100% 0 / 50%;
    background-color: inherit;
    transform-origin: left;
    animation: spin 50s linear infinite, bg 100s step-end infinite;
    animation-play-state: paused;
    animation-delay: -60s; /* 通过此控制比例 */
}
js
// 通过 js 控制比例
box.style.animatinoDelay = '-' + 比例 + 's';

svg 解决方案

主要是 stroke-dasharray 可使描边有间隔,可以把间隔设为周长,然后改变描边的周长,即可形成对应比率的饼图(和进度条实现相似)

html
<svg viewBox="0 0 32 32">
    <circle r="16" cx="16" cy="16" />
</svg>
css
svg {
    width: 100px;
    height: 100px;
    transform: rotate(-90deg);
    background: yellowgreen;
    border-radius: 50%;
}

circle {
    fill: yellowgreen;
    stroke: #655;
    stroke-width: 32; /* 这个是半径占满整个圆 */
    stroke-dasharray: 38 100; /* 可得比率为 38% 的扇区 */
}