Grow square div with color based on the percentage value provided

与世无争的帅哥 提交于 2020-01-02 21:57:15

问题


I am working on a square graph animation. The squares should grow from zero on the x/y axis(top left corner) to their determined percent size with ease. Can anyone provide me any hints to accomplish this? This is what I have so far: http://jsfiddle.net/2n6kduL4/3/

The progress is happening from left to right. But it has to fill from the left top corner to the right bottom corner.

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:


You can achieve your animated + eased barchart using Penner's Easing functions and the requestAnimationFrame timing loop

Here's how:

Define each of your barchart bars in javascript objects:

// 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);

Then you can animate each bar to its ending width using Penner's Easing equations. Here are a few of the many Penner easing algorithms expressed as javascript functions. What you do is feed in the current elapsed time, beginning value, total time duration and total value change desired during the easing. The Penner functions return to you the current (eased) value based on the current time.

// 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);},
}

Here is example code and a Demo

The code creates a reusable "Animation Class" that can be used to ease the property values of the bar objects you created above over the animation duration:

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>


来源:https://stackoverflow.com/questions/29857717/grow-square-div-with-color-based-on-the-percentage-value-provided

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!