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

Jon*_*upe 1 javascript canvas coordinates easing

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

您可以在jsfiddle本网站找到我的项目.

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();
Run Code Online (Sandbox Code Playgroud)

提前致谢!

小智 6

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

p = p1 + (p2 - p1) * t
Run Code Online (Sandbox Code Playgroud)

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}
Run Code Online (Sandbox Code Playgroud)

缓动函数有几种变体,上面是立方体.您可以在这里找到更多以及流行的Penner版本.

对于你的情况,你会只更新y2与新的目标值使用旧y2y1,然后线性插值/它们之间轻松使用相同的每个x点t值.

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

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
}
Run Code Online (Sandbox Code Playgroud)
<canvas></canvas>
Run Code Online (Sandbox Code Playgroud)