CSS 饼图动画从 40% 到 60%

CSS pie chart animation from 40% to 60%

我尝试在 CSS 中制作一个动态饼图,它工作得很好,除非我想从小于 50% 到大于 50% 设置动画,反之亦然。

这是一个代码笔(我没有找到如何在堆栈工具中使用 SCSS):http://codepen.io/mbrillaud/pen/NNgqYE

有什么技巧可以避免这种影响吗?

HTML

<div class="wrapper">
  <div class="pie percent-10" id="pie"></div>
  <div class="border"></div>
</div>
<div class="buttons">
  <button data-value="10">10%</button>
  <button data-value="20">20%</button>
  <button data-value="30">30%</button>
  <button data-value="40">40%</button>
  <button data-value="50">50%</button>
  <button data-value="60">60%</button>
  <button data-value="70">70%</button>
  <button data-value="80">80%</button>
  <button data-value="90">90%</button>
  <button data-value="100">100%</button>
</div>

CSS

@import 'compass';
body {
  background-color: #2c333b;
}
.wrapper {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100px;
  @include transform(translate(-50%, -50%));
  .pie,
  .border {
    box-sizing: border-box;
    position: absolute;
    top: 0;
    left: 0;
    width: 100px;
    height: 100px;
    border-radius: 50%;
  }
  .pie {
    background-color: #FDDED9;
    background-image: linear-gradient(to right, transparent 50%, #ff4081 0);
    &::before {
        content: '';
        display: block;
        top: 0;
        left: 50%;
        width: 50%;
        margin-left: 50%;
        height: 100%;
        border-radius: 0 100% 100% 0 / 50%;
        background-color: inherit;
        transform-origin: left;
        transition: transform .2s linear;
    }
    &.percent-10::before {
        transform: rotate(.1turn);
    }
    &.percent-20::before {
        transform: rotate(.2turn);
    }
    &.percent-30::before {
        transform: rotate(.3turn);
    }
    &.percent-40::before {
        transform: rotate(.4turn);
    }
    &.percent-50::before {
        transform: rotate(.5turn);
    }
    &.percent-60::before {
        transform: rotate(.1turn);
        background-color: #ff4081;
    }
    &.percent-70::before {
        transform: rotate(.2turn);
        background-color: #ff4081;
    }
    &.percent-80::before {
        transform: rotate(.3turn);
        background-color: #ff4081;
    }
    &.percent-90::before {
        transform: rotate(.4turn);
        background-color: #ff4081;
    }
    &.percent-100::before {
        transform: rotate(.5turn);
        background-color: #ff4081;
      }

  }
  .border {
    border: 5px solid #FDDED9
  }
}

JS

$(document).ready(function() {

  var $pie = $('#pie'),
      className;

  $('button').on('click', function() {
    className = $pie.attr('class').match(/percent[\w-]*\b/);
    $pie
      .removeClass(className[0])
      .addClass('percent-' + $(this).data('value'));
  });
});

您使用的方法非常适合静态饼图,但永远无法很好地在 50% 标记之间设置动画。我个人更喜欢走 SVG 路线。

Lea Verou 写了一篇关于如何处理这样的事情的好文章: https://www.smashingmagazine.com/2015/07/designing-simple-pie-charts-with-css/

它基本上归结为创建一个 <circle> 应用一个与圆本身一样宽的 stroke 并使用 CSS 操纵 stroke-dasharray 属性。

HTML

<svg width="100" height="100" class="svg">
    <circle r="50" cx="50" cy="50" class="circle"/>
    <circle id="pie" r="22.5" cx="50" cy="50" class="circle  percent-10"/>
</svg>

SCSS

// circumference = 2π * radius
// so in this case circumference = 2π × 22.5 ≈ 141):
 $circumference: 141;

.svg {

    /* Appearance */
    transform: rotate(-90deg);
}

.circle {

    /* Appearance */
    fill: #fdded9;
}

#pie {

    /* Appearance */
    stroke: #ff4081;
    stroke-dasharray: 0 $circumference;
    stroke-width: 45;
    transition: stroke-dasharray .2s linear;

    &.percent-10 { stroke-dasharray: ($circumference * 0.1) $circumference; }
    &.percent-20 { stroke-dasharray: ($circumference * 0.2) $circumference; }
    &.percent-30 { stroke-dasharray: ($circumference * 0.3) $circumference; }
    &.percent-40 { stroke-dasharray: ($circumference * 0.4) $circumference; }
    &.percent-50 { stroke-dasharray: ($circumference * 0.5) $circumference; }
    &.percent-60 { stroke-dasharray: ($circumference * 0.6) $circumference; }
    &.percent-70 { stroke-dasharray: ($circumference * 0.7) $circumference; }
    &.percent-80 { stroke-dasharray: ($circumference * 0.8) $circumference; }
    &.percent-90 { stroke-dasharray: ($circumference * 0.9) $circumference; }
    &.percent-100 { stroke-dasharray: ($circumference * 1) $circumference; }
}

我现在对您的代码唯一担心的是它的可扩展性不是很好。我认为基于 data-attribute.

使用 JavaScript 动态设置 stroke-dasharray 可能是更好的方法

JavaScript

$('button').on('click', function(){

    var CIRCUMFERENCE = 141,
        percentage = Number($(this).data('value')),
        factor = percentage / 100,
        strokeDashArray = (CIRCUMFERENCE * factor) + ' ' + CIRCUMFERENCE);

    $pie.css('stroke-dasharray', strokeDashArray;
});

这里有一个基于您的原始代码的 CodePen,因此您可以看到它的实际效果: http://codepen.io/rvmook/pen/LNLGoE