根据提供的百分比值,使用颜色增加方形div

时间:2015-04-24 21:21:41

标签: html css animation canvas graph

我正在制作方形图动画。正方形应该在x / y轴(左上角)从零增长到它们确定的百分比大小。任何人都可以提供任何提示来实现这一目标吗?这是我到目前为止:http://jsfiddle.net/2n6kduL4/3/

进展从左到右发生。但它必须从左上角填充到右下角。

var canvas = document.getElementById('myProgress');
var myPerc = 500;
ctx = canvas.getContext('2d');

ctx.fillStyle = "rgb(255, 0, 0)"; //red

ctx.fillRect(0, 0, myPerc, 100);
ctx.save();
for (var i = 0; i < (myPerc * 0.5); i++) {
    ctx.fillStyle = "rgb(0, 255, 0)"; //greeen
    (function(i) {
        setTimeout(function() {
            ctx.fillRect(0, 0, +i, 100);
        }, 1000 * i);
    })(i);
}

1 个答案:

答案 0 :(得分:2)

您可以使用Penner的缓动函数和requestAnimationFrame时序循环

来实现动画+缓动的条形图

以下是:

在javascript对象中定义每个条形图栏:

// create some bar objects and put them in a bars[] array
var bars=[];
var bar1={x:0,y:20,width:1,height:50,fill:'red'};
var bar2={x:0,y:100,width:1,height:50,fill:'green'};
var bar3={x:0,y:180,width:1,height:50,fill:'blue'};
bars.push(bar1,bar2,bar3);

然后,您可以使用Penner的Easing方程将每个条形图设置为其结束宽度。以下是许多表示为javascript函数的Penner缓动算法中的一些。您所做的是在缓和期间输入当前经过的时间,起始值,总持续时间和所需的总值变化。 Penner函数根据当前时间返回当前(缓和)值。

// t: elapsed time inside duration, 
// b: beginning value,
// d: total duration
// c: total change from beginning value,
var easings={
  linear:function(t,b,c,d){return(c*t/d+b);},
  easeInQuint: function(t,b,c,d){return(c*(t/=d)*t*t*t*t+b);},
  easeOutQuint: function (t,b,c,d){return(c*((t=t/d-1)*t*t*t*t+1)+b);},
}

以下是示例代码和演示

代码创建了一个可重复使用的“动画类”,可用于在动画持续时间内简化您在上面创建的条形对象的属性值:

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

var Animation=( function(){
  // easings
  // t: elapsed time through duration, 
  // b: beginning value,
  // d: total duration
  // c: total change from beginning value,
  var easings={
    linear:function(t,b,c,d){return(c*t/d+b);},
    easeInQuint: function(t,b,c,d){return(c*(t/=d)*t*t*t*t+b);},
    easeOutQuint: function (t,b,c,d){return(c*((t=t/d-1)*t*t*t*t+1)+b);},
  }
  //
  function Animation(target,property,endingValue,duration,easing){
    this.target=target;
    this.property=property;
    this.endingValue=endingValue;
    this.duration=duration;
    this.easing=easing;
    this.beginningValue=target[property];
    this.totalChange=endingValue-target[property];
    this.startTime=null;
    this.isAnimating=false;
    if(easings[this.easing]==undefined){this.easing='linear';}
  };
  //
  Animation.prototype.animate=function(time){
    if(time>this.startTime+this.duration){
      this.target[this.property]=this.endingValue;
      this.isAnimating=false;
    }else{
      this.target[this.property]=easings[this.easing](
        time-this.startTime,this.beginningValue,this.totalChange,this.duration
      );
    }    
  };
  //
  Animation.prototype.run=function(){
    this.target[this.property]=this.beginningValue;
    this.startTime=performance.now();
    this.isAnimating=true;
  };
  //
  return(Animation);
})();

// create some bar objects and put them in a bars[] array
var bars=[];
var bar1={x:0,y:20,width:1,height:50,fill:'red'};
var bar2={x:0,y:100,width:1,height:50,fill:'green'};
var bar3={x:0,y:180,width:1,height:50,fill:'blue'};
bars.push(bar1,bar2,bar3);

// create some animations that widen the each bar to the desired
// width over 3000ms
var animations=[];
var bar1AnimateWidth=new Animation(bar1,'width',150,3000,'easeOutQuint');
var bar2AnimateWidth=new Animation(bar2,'width',85,3000,'easeOutQuint');
var bar3AnimateWidth=new Animation(bar3,'width',250,3000,'easeOutQuint');
animations.push(bar1AnimateWidth,bar2AnimateWidth,bar3AnimateWidth);

// start the requestAnimationFrame loop
requestAnimationFrame(animate);

// initialize each animation object and start each eased animation running
doAllAnimations();

function doAllAnimations(){
  for(var i=0;i<animations.length;i++){ animations[i].run(); }
}

function animate(time){

  // animate property values
  for(var i=0;i<animations.length;i++){
    var animation=animations[i];
    if(animation.isAnimating){animation.animate(time);}
  }

  // redraw all bars with their newly animated properties
  ctx.clearRect(0,0,cw,ch);
  for(var i=0;i<bars.length;i++){
    var bar=bars[i];
    ctx.fillStyle=bar.fill;
    ctx.fillRect(bar.x,bar.y,bar.width,bar.height);
  }

  // request another animation loop
  requestAnimationFrame(animate);
}

$('#rerun').click(function(){ doAllAnimations(); });
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Animate with easeOutQuint easing</h4>
<button id=rerun>Rerun</button>
<br>
<canvas id="canvas" width=300 height=300></canvas>