如何在两个y坐标之间缓和?

时间:2015-05-15 11:40:10

标签: javascript canvas coordinates easing

对于学校作业,我们必须在Javascript中制作图表。 老师想看一些动画图。所以我在一周内建立了关于我的推文的图表,但是找不到如何在两个y坐标之间缓和。

您可以找到我的项目here on jsfiddleon this website

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var form = document.getElementById("form");
var data = [];
var huidigeYpos = [];
var nieuweYpos = [];
var count = [];
var snelheid = 0;

function init(){
    ctx.fillStyle="rgb(255,255,255)";
    ctx.fillRect(0,0,canvas.width,canvas.height);
    ctx.translate(0, 445);

    for(var i = 0; i < 7; i++){
        data[i] = form[i].value*30;
    }

    draw();
}

function draw(){
    ctx.fillStyle="rgb(255,255,255)";
    ctx.fillRect(0,0,canvas.width,-canvas.height);
    ctx.beginPath();    
    ctx.moveTo(0,0);
    for(var i = 0; i <= 750; i += 125){
        ctx.lineTo(i,-data[i/125]);
        huidigeYpos.push((data[i/125]));
    }
    if(huidigeYpos.length > 7){
        huidigeYpos.splice(0, 7);
    }
    ctx.lineTo(750,0);
    ctx.closePath();
    ctx.fillStyle="#0084FF";    
    ctx.fill();
}

function invullen(){
    for(var i = 0; i < 7; i++){
        data[i] = form[i].value*30;
    }
    draw();
}

function drawRandomGraph(){ 

    for(var i = 0; i < 7; i++){
        form[i].value = Math.round(Math.random()*10);
        nieuweYpos.push(form[i].value*30);
    }
    if(nieuweYpos.length > 7){
        nieuweYpos.splice(0, 7);
    }
    invullen();
}

init();

提前致谢!

2 个答案:

答案 0 :(得分:5)

您可以将插值与缓动功能结合使用。两点之间的标准插值,即lerping,很简单:

p = p1 + (p2 - p1) * t

其中t在[0,1]

范围内

通过为t注入缓动函数(也在[0,1]范围内),可以简化转换:

...
y = y1 + (y2 - y1) * easeInOut(t);
...

function easeInOut(t) {return t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1}

有几个variations缓动函数,上面是立方体。您可以找到更多here以及热门的Penner版本。

对于您的情况,您只需使用新目标值更新y2,使用旧y2作为y1,然后使用相同t在每个x点之间使用lerp / ease {1}}值。

下面的演示展示了如何使用它们,根据需要进行集成。

实施例

var ctx = document.querySelector("canvas").getContext("2d"),
    y1 = 10, y2 = 140,                   // source and destination positions
    current = 0, max = 50, delta = 1;    // counters for calculating/animating t

(function loop() {

  // calc t
  current += delta;
  var t = current / max;                 // normalize so we get [0, 1]
  if (t <= 0 || t >= 1) delta = -delta;  // to ping-pong the animation for demo
  
  // calc lerp linear
  var yl = lerp(y1, y2, t),              // linear
      ye = lerp(y1, y2, easeInOut(t));   // with easing
  
  // draw some graphics to show (linear : easing)
  ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
  ctx.fillRect(20, yl - 10, 20, 20);
  ctx.fillRect(50, ye - 10, 20, 20);
  
  requestAnimationFrame(loop);
})();

function lerp(p1, p2, t) {
  return p1 + (p2 - p1) * t
}

function easeInOut(t) {
  return t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1
}
<canvas></canvas>

答案 1 :(得分:0)

试试这个,注意:我删除不必要的代码

&#13;
&#13;
ALTER PROCEDURE [dbo].[GetReport] 

@fromDate datetime,
@toDate datetime,
@Branches varchar (500) = null

AS
BEGIN

SET NOCOUNT ON; 

select * from customers where

(customers.CreatedDate between @fromDate and @toDate) and

(@Branches is null or CONVERT(varchar(500), customers.branches_ID) in(@Branches )) -- This part is not working for me


END
&#13;
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var form = document.getElementById("form");
var data = [];
var max = 0;

function init(){
  max = 0;
  for(var i = 0; i < 7; i++){
    data[i] = form[i].value*30;
    //find max y
    if(data[i]>max) max=data[i];
  }
  draw();
}

function draw(){
  ctx.fillStyle="rgb(255,255,255)";
  ctx.fillRect(0,0,canvas.width,canvas.height);
  ctx.beginPath();	
  ctx.moveTo(0,canvas.height);

  //i change this, relative to size of canvas
  for(var i = 0; i < data.length; i++){
    ctx.lineTo(canvas.width*i/(data.length-1), (canvas.height-canvas.height*data[i]/max));
  }
  ctx.lineTo(750,canvas.height);
  ctx.closePath();
  ctx.fillStyle="#0084FF";	
  ctx.fill();
}

init();

//adding even click
document.getElementById("mybutton").onclick = init;
&#13;
*{
  margin:0;
  padding:0;
  font-family: 'montserratregular';
}
body{
  background:url('../assets/img/blue.png');
  font-size: 62.5%;
}
.outer {
  display: table;
  position: absolute;
  height: 100%;
  width: 100%;
}
.middle {
  display: table-cell;
  vertical-align: middle;
}
.inner {
  width:750px;
  height:760px;
  margin-left:auto;
  margin-right:auto;
  border-radius: 5px;
  overflow:hidden;
}
#title, #formtitle{
  width:870px;
  height:45px;
  background-color:white;
  padding-top:30px;
  padding-left:30px;
  text-transform: uppercase;
}
h1, h2{
  font-size: 1.4em;
}
.form{
  width:750px;
  height:165px;
  background-color: #EDF1F4;
  padding-top:30px;
  padding-bottom:30px;
}
#form{
  width:690px;	
  overflow:auto;
  margin-left:auto;
  margin-right:auto;
}
form input{
  height:45px;
  width:94px;
  margin-right:5px;
  border:none;
  text-align: center;
  outline:none;
  float:left;
  margin-bottom:15px;

}
input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button { 
  -webkit-appearance: none; 
  margin: 0; 

}
button{
  height:45px;
  width:690px;
  margin-left:auto;
  margin-right:auto;
  display:block;
  color:white;
  text-transform: uppercase;
  background-color: #1E2831;
  border:none;
  outline:none;
}
button:hover{
  background-color: #0084FF;

}
.last{
  margin:0;
}
form label{
  margin:0;
  padding:0;
}
&#13;
&#13;
&#13;