Javascript 向svg饼图添加填充动画

Javascript 向svg饼图添加填充动画,javascript,jquery,html,css,svg,Javascript,Jquery,Html,Css,Svg,我想用一个动态的、未知的加载值来设置饼图的动画。假设我尽快检索该值,并将其转换为四舍五入的百分比: var percentage = Math.round(sum * 100 / total); 然后我把我的价值放在那里: <div class="pie animated" id="pie-get-percentage"></div> $('#pie-get-percentage').html(percentage); CSS .pie-wrapper {

我想用一个动态的、未知的加载值来设置饼图的动画。假设我尽快检索该值,并将其转换为四舍五入的百分比:

var percentage = Math.round(sum * 100 / total);
然后我把我的价值放在那里:

<div class="pie animated" id="pie-get-percentage"></div>

$('#pie-get-percentage').html(percentage);
CSS

.pie-wrapper {
    .pie {
        width: 100px;
        height: 100px;
        display: inline-block;
        margin: 10px;
        transform: rotate(-90deg);
    }
    svg {
        background: $primary;
        border-radius: 50%;
    }
    circle {
        fill: $primary;
        stroke: $secondary;
        stroke-width: 32;
    }
    @keyframes grow {
        to {
            stroke-dasharray: 100 100
        }
    }
    .pie.animated {
        animation: grow 2s linear;
    }
}
正如你所看到的,我认为我必须简单地摆弄
.pie.animated
CSS规则,但到目前为止,我还无法将动画设置到我的动态值,只有完整的循环

基本上,如果我的值是42%,我会尝试将我的圈扩大到SVG的42%。但问题是我不能真正赋予CSS动画一个动态值。也许我需要使用内联CSS,但我不确定它是否适用于动画关键帧


jsiddle是

我使用了jsiddle的JQuery部分,这就是我的结局

<div class="pie">60%</div>

<div class="pie">90%</div>

<div class="pie">12%</div>
60%
90%
12%
这个想法很简单。我每次都使用javascript间隔计时器调用计数计时器。我还添加了一些max-val、inc-val和其他相关变量,使其能够工作

function $$(selector, context) {
    context = context || document;
    var elements = context.querySelectorAll(selector);
    return Array.prototype.slice.call(elements);
} 

function count(){
    var isUsed = false;
 $$('.pie').forEach(function(pie) {
    var p = parseFloat(pie.textContent);

    if(pie.maxValue == null){
         pie.maxValue = p;
         pie.incValue = p / 100.0;
         pie.lastValue = 0;
    }
    else
        pie.lastValue = pie.lastValue + pie.incValue;

   if(pie.lastValue <= pie.maxValue){
        var NS = "http://www.w3.org/2000/svg";
        var svg = document.createElementNS(NS, "svg");
        var circle = document.createElementNS(NS, "circle");
        var title = document.createElementNS(NS, "title");

        circle.setAttribute("r", 16);
        circle.setAttribute("cx", 16);
        circle.setAttribute("cy", 16);
        circle.setAttribute("stroke-dasharray", pie.lastValue + " 100");

        svg.setAttribute("viewBox", "0 0 32 32");
        title.textContent = pie.textContent;
        pie.textContent = '';
        svg.appendChild(title);
        svg.appendChild(circle);
        pie.appendChild(svg);

       isUsed = true;
   }

});
    if(isUsed)
        window.setTimeout(function() {  count(); }, 30);
}

window.setTimeout(function() {  count(); }, 30);

count();
函数$$(选择器,上下文){
上下文=上下文| |文档;
var elements=context.querySelectorAll(选择器);
返回Array.prototype.slice.call(元素);
} 
函数计数(){
var isUsed=假;
$$('.pie').forEach(函数(pie){
var p=parseFloat(pie.textContent);
如果(pie.maxValue==null){
pie.maxValue=p;
pie.incValue=p/100.0;
pie.lastValue=0;
}
其他的
pie.lastValue=pie.lastValue+pie.incValue;

如果(pie.lastValue)可能是其他人提供了更好的主意。请将jquery代码和html复制到您自己的JSFIDLE中以查看输出。谢谢,这一点不错,但有一个明显的“口吃”在更高的值上。所以我将计数间隔除以10。这对性能是否合适?是的,我更改了几次以生成平滑动画。所有数字都是任意的:)可以改进的一点是使用setTimeout而不是setInterval。这是因为它将调用计数()函数,即使它们达到最大值。让我看看是否可以更改它并更新答案;)
function $$(selector, context) {
    context = context || document;
    var elements = context.querySelectorAll(selector);
    return Array.prototype.slice.call(elements);
} 

function count(){
    var isUsed = false;
 $$('.pie').forEach(function(pie) {
    var p = parseFloat(pie.textContent);

    if(pie.maxValue == null){
         pie.maxValue = p;
         pie.incValue = p / 100.0;
         pie.lastValue = 0;
    }
    else
        pie.lastValue = pie.lastValue + pie.incValue;

   if(pie.lastValue <= pie.maxValue){
        var NS = "http://www.w3.org/2000/svg";
        var svg = document.createElementNS(NS, "svg");
        var circle = document.createElementNS(NS, "circle");
        var title = document.createElementNS(NS, "title");

        circle.setAttribute("r", 16);
        circle.setAttribute("cx", 16);
        circle.setAttribute("cy", 16);
        circle.setAttribute("stroke-dasharray", pie.lastValue + " 100");

        svg.setAttribute("viewBox", "0 0 32 32");
        title.textContent = pie.textContent;
        pie.textContent = '';
        svg.appendChild(title);
        svg.appendChild(circle);
        pie.appendChild(svg);

       isUsed = true;
   }

});
    if(isUsed)
        window.setTimeout(function() {  count(); }, 30);
}

window.setTimeout(function() {  count(); }, 30);

count();