mousemove(画布)后动画停止

时间:2016-02-09 11:46:01

标签: javascript animation canvas

我创建了一个脚本,当X更大时,画布圈跟随鼠标。但是你可以看到它只在鼠标移动过程中起作用。当鼠标停止时,我无法找到使圆圈移动的方法。另外,我是否使用正确的逻辑来制作此代码?

Heres一个片段:



canvas = document.getElementById('canvas'),
	ctx = canvas.getContext('2d');

var PI = Math.PI;
window.requestAnimFrame = (function(){
	return window.requestAnimationFrame       || // La forme standardisée
   window.webkitRequestAnimationFrame || // Pour Chrome et Safari
   window.mozRequestAnimationFrame    || // Pour Firefox
   window.oRequestAnimationFrame      || // Pour Opera
   window.msRequestAnimationFrame     || // Pour Internet Explorer
   function(callback){                   // Pour les élèves du dernier rang
	   window.setTimeout(callback, 1000 / 60);
   };
})();
function pos(canvas, evt) {
	var rect = canvas.getBoundingClientRect();
	return {
	  x: evt.clientX - rect.left,
	  y: evt.clientY - rect.top
	};
  }

function elm_fixe() {
	ctx.fillStyle = "rgba(050, 155, 255, 1)";
	ctx.fillRect(0, 0, 30, 30, 1);

	for (var x = 0, y = 0, alpha = 1; alpha >= 0; alpha -= 0.1, x += 40) {          
		 ctx.fillStyle = "rgba(050, 155, 255, " + alpha + ")";
		ctx.fillRect(x, 0, 30, 30);
	}
} 

function cercle(x, y) {
	ctx.fillStyle = "red";
	ctx.beginPath();
	ctx.arc(x, y, 30, 0, PI * 2, true);
	ctx.fill();
}


var x = 250,
	y = 250;


function bouger(e) {
	console.log(e.clientX)
	if ( pos(canvas, e).x > x) {
		x += 1;
	};
		 
}

function draw(e) {
	ctx.clearRect(0, 0, 800, 500);
	bouger(e);
	cercle(x, y);
	elm_fixe();
}




/*       window.requestAnimFrame(function() { 
	canvas.addEventListener('mousemove', function(e) {
		window.requestAnimFrame(function() { draw(e) });           
	});
}
);
*/     

	window.addEventListener('mousemove', function(e) {

		draw(e);
	});

<canvas height="500" width="800" id="canvas"></canvas>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

首先,在尝试使用它时,重点是完成手头的任务,所以我删除了固定的绘制元素,因为这很容易。

您遇到的主要问题是您只更新 onmousemove ,这可能会妨碍您。最好的办法就是将鼠标坐标存储在一个单独的对象中,这里我已经这样做了:

var mouse   = {x: 0, y: 0};

之后,只需在mousemove事件触发时更新坐标。现在我们记住了位置,这意味着将来你实际上可以从一点到另一点动画这个圆圈,因为它不依赖于事件来实际知道这些值。

实际上不再需要requestAnimationFrame的填充,几乎每个浏览器都支持它,除了一些较旧的浏览器。

&#13;
&#13;
var canvas 	= document.getElementById('canvas');
var ctx 	= canvas.getContext('2d');
var mouse	= {x: 0, y: 0};

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

function circle() {
  ctx.fillStyle = "red";
  ctx.beginPath();
  ctx.arc(mouse.x, mouse.y, 30, 0, Math.PI * 2, true);
  ctx.fill();
}

function draw(e) {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  circle();
  window.requestAnimationFrame(draw);
}   

document.addEventListener('mousemove', function(e) {
  mouse.x = e.pageX > mouse.x ? e.pageX : mouse.x;
  mouse.y = e.pageY > mouse.y ? e.pageY : mouse.y;
});

window.requestAnimationFrame(draw);
&#13;
html, body { height: 100%; }
body { overflow: hidden; padding: 0; margin: 0;}
&#13;
<canvas id="canvas"></canvas>
&#13;
&#13;
&#13;

为了将来的显而易见,重命名某些功能可能会更好。很久以前,我也学到了很难用英语保留你的函数名,主要是因为编程恰好是基于英语的。这样,该站点上的每个用户都可以破译函数可能执行的操作,未来的开发人员将能够在不了解法语的情况下调试代码。例如,我会将circle重命名为类似drawCircleAtMousePosition的东西 - 它只是满口,但没有人可以混淆这个功能的作用。

使用存储变量的另一个好处是,您可以在pos事件中执行localiseCoordinatesTo(canvas)(这是一个非常糟糕的函数名称 - 可能是onmousemove),所以你永远不必在以后考虑这个问题。

更新:动画

这是一个使用非常简单的线性插值来实现从一个地方到另一个地方的圆形动画的实现:

&#13;
&#13;
var canvas 	= document.getElementById('canvas');
var ctx 	= canvas.getContext('2d');
// We will need a from value, a to value, and store a time;
var mouse	= {from: {x: 0, y: 0}, to: {x: 0, y: 0}, time: Date.now()};
// As well as a duration
var duration = 1000;

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

function position(){
  // This will calculate the position
  var time = Date.now(), progress;
  if(time > mouse.time + duration) 
    return mouse.to;
  else
    progress = (time - mouse.time) / duration;
  return {
    x: mouse.from.x + (mouse.to.x - mouse.from.x) * progress,
    y: mouse.from.y + (mouse.to.y - mouse.from.y) * progress
  }
}

function circle() {
  ctx.fillStyle = "red";
  ctx.beginPath();
  var pos = position();
  ctx.arc(pos.x, pos.y, 30, 0, Math.PI * 2, true);
  ctx.fill();
}

function draw(e) {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  circle();
  window.requestAnimationFrame(draw);
}

document.addEventListener('mousemove', function(e) {
  // Update FROM to the current position
  mouse.from = position();
  // Reassign the to values
  mouse.to.x = e.pageX > mouse.to.x ? e.pageX : mouse.to.x;
  mouse.to.y = e.pageY > mouse.to.y ? e.pageY : mouse.to.y;
  // Update the animation start time.
  mouse.time = Date.now();
});

window.requestAnimationFrame(draw);
&#13;
html, body { height: 100%; }
body { overflow: hidden; padding: 0; margin: 0;}
&#13;
<canvas id="canvas"></canvas>
&#13;
&#13;
&#13;