如何使用javascript在一定时间内上下移动画布元素

时间:2015-06-15 12:00:18

标签: javascript canvas

我试图让6个吉他琴弦在点击时移动。我尝试通过向上移动2.5 px和向下移动2.5 px 3秒来完成一个简单的动画。但我真的不知道该怎么做。

这是我尝试过的:

function onLoad(){ 
    snaren();
    snaarAanraken();
}

function snaren(){
    var c = document.getElementById("strings");
    var ctx = c.getContext("2d");
    for (var i=1;i<7;i++){ //drawing the 6 strings
        ctx.lineWidth = 3;
        ctx.beginPath();
        ctx.moveTo(0,42.5*i);
        ctx.lineTo(700,42.5*i);
        ctx.stroke();
    }   
}
function snaarAanraken(){
    var canvas = document.getElementById("strings");
    var ctx = canvas.getContext("2d");
    var canvasLeft = canvas.offsetLeft;
    var canvasTop = canvas.offsetTop;
    canvas.addEventListener('click', function(event) {
        var x = event.pageX - canvasLeft;
        var y = event.pageY - canvasTop;
        console.log(x, y);
        if (x >= 0 && x<= 700) {
            if (y >= 35 && y<= 50) {//check if clicked on first string
                var e = new Audio("e2.mp3");
                e.play();
                var canvas_y = 42.5;
                var bewegen = setInterval(function () {
                    if (canvas_y > 44) {
                        canvas_y = 40
                    }   
                    if (canvas_y < 41) {
                        canvas_y = 45;
                    }    
                    ctx.clearRect(0, 0, 700, 60);
                    ctx.lineWidth = 3;
                    ctx.beginPath();
                    ctx.moveTo(0,canvas_y);
                    ctx.lineTo(700,canvas_y);
                    ctx.stroke();
                    console.log(canvas_y);
                }, 100);
            clearInterval(bewegen, 3000); 
        }
}

2 个答案:

答案 0 :(得分:1)

对于吉他弦,您可以使用二次曲线和正弦函数。正弦函数的半径可以随时间控制。

还可以使用requestAnimationFrame进行良好的流体动画。你没有正确使用setTimeout(rAF也提供了一个高分辨率时间作为参数,你可以使用它代替Date.now或performance.now() - 未显示)。

实施例

var ctx = document.querySelector("canvas").getContext("2d");

(function play() {
  renderString(75, 20, 5000, function() {
    setTimeout(play, 250);
  });
})();

// provide y position, max radius, time in ms and a callback function for done
function renderString(y, max, ms, callback) {

  var w = ctx.canvas.width,
      h = ctx.canvas.height,
      f = 0,                                                // fake frequency (demo)
      startTime = Date.now();
  
  (function loop() {

    var t = 1 - ((Date.now() - startTime) / ms);            // normalized time progress
    ctx.clearRect(0, 0, w, h);                              // clear frame
    ctx.beginPath();                                        // new path
    ctx.moveTo(0, y);                                       // start of curve
    ctx.quadraticCurveTo(w * 0.5, y + getSine() * t, w, y); // quad. curve
    ctx.stroke();                                           // stroke it
       
    if (t > 0) requestAnimationFrame(loop);
    else callback();
  })();
                    
  function getSine() {
    return Math.sin((f=f+2)) * max;   // todo: use real frequency
  }
}
<canvas></canvas>

答案 1 :(得分:0)

在这里,我举了一个振动吉他弦的小例子。它等待2秒然后敲击弦,振动半秒钟。

您的代码中存在的问题是您正在向clearInterval添加时间变量,这是不可能的。如果您希望延迟清除间隔,则需要将其与setTimeout结合使用,类似于:

setTimeout(function() {
    clearInterval(bewegen);
},3000);

var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
c.width = 300;
c.height = 400;

var tremble = 2;

var myInterval;

function strum() {
    ctx.clearRect(0,0,c.width,c.height);
    
    drawString();
    
    ctx.beginPath();
    ctx.moveTo(0,50+tremble);
    ctx.lineTo(c.width,50+tremble);
    ctx.stroke();
    tremble*=-1;
}

function drawString() {
    ctx.beginPath();
    ctx.moveTo(0,50);
    ctx.lineTo(c.width,50);
    ctx.stroke();
}

drawString();

setTimeout(function() {
 myInterval = setInterval(strum,16);
    setTimeout(function() {
        clearInterval(myInterval);
        ctx.clearRect(0,0,c.width,c.height);
        drawString();        
    },500);
},2000);
<canvas id="canvas"></canvas>