这将是一个需要mousemove事件的东西,每次鼠标移动时都会在Canvas上绘制一个新的线路径.随着时间的推移,这条路径将变得更加透明,直到它消失为止.当然,新的路径总是不透明的,所以有一个连续的运动.
我想出了一种方法,我可以用requestanimationframe来做到这一点.基本上每次发生新的mousemove事件时,我都会将鼠标路径坐标添加到名为mousePathArray的对象数组中.该对象将携带路径坐标和“animationStage”计数器.此计数器将基本确定路径在“动画”的该阶段的透明度. (后期阶段意味着更透明.)
然后每个动画帧我将调用一个函数,它将遍历数组中的所有对象并根据它们的坐标和animationStage计数器绘制线条,将计数器增加1并在animationStage计数器到达结束时删除数组对象数字(可能是50或其他).
这一切都可以完成,但听起来不是全部,只需引入一个setInterval函数就可以轻松完成,每次鼠标移动时都会调用setInterval.
那么值得做多远呢?是不是更快或者只是更好的JS练习不一起使用setInterval和rAF?
写完所有这些之后,我实际上编写了上面讨论过的仅限rAF的代码.粘贴这里太长了,但规则需要它.这是jsfiddle:http://jsfiddle.net/06f7zefn/2/
(我知道有很多低效率和可能很糟糕的编码练习,但是对我来说,我已经5天了!我可以制作一个isDrawing?boolean,而不是在每一帧上调用animate(),我可以只需执行ctx.moveTo()一次,其余为LineTo(),而不必每次迭代都移动到(),因为一个点来自另一个点离开的位置)
如果我能够理解我正在谈论的主要想法,那就是我要求你的意见.而不是让与时间相关的所有内容都来自rAF调用,而不是在这里使用setInterval或setTimeout更好吗?
var canvas = document.createElement('canvas'); canvas.width = window.innerWidth; canvas.height = window.innerHeight; document.body.appendChild(canvas); var ctx = canvas.getContext('2d'); var currentPosX,currentPosY,prevPosX,prevPosY; var mousePathArray = []; canvas.addEventListener ('mousemove',mouSEOp); function mouSEOp (mouseEvent) { prevPosX = currentPosX; prevPosY = currentPosY; currentPosX = mouseEvent.clientX; currentPosY = mouseEvent.clientY; mousePathArray.push( { x1: currentPosX,x2: prevPosX,y1: currentPosY,y2: prevPosY,animStage: 0 }); } function animate () { var anims = mousePathArray.length; if (anims!=0) { for (i=0; i<anims; i++) { if (mousePathArray[i].animStage == 20) { mousePathArray.splice(i,1); i--; anims--; continue; } drawLine(mousePathArray[i].x1,mousePathArray[i].x2,mousePathArray[i].y1,mousePathArray[i].y2,1 - (mousePathArray[i].animStage * 0.05)); mousePathArray[i].animStage ++; } } } function drawLine (x1,x2,y1,y2,alpha) { ctx.beginPath(); ctx.moveTo(x1,y1); ctx.lineTo(x2,y2); ctx.strokeStyle = "rgba(150,20,150," + alpha +")"; ctx.stroke(); } animloop(); function animloop(){ window.requestAnimationFrame(animloop); gameLoop(); } function gameLoop() { ctx.clearRect(0,canvas.width,canvas.height); animate(); }
解决方法
makeHeavyDomMovements(); setTimeout(function () { //with 3000 timeout I'm sure any device has made my changes makeNextMove(); },3000);
正确的方法是:
makeHeavyDomMovements(). then(function () { makeNextMove(); });
如果你想在将来做一些事情,比如100分钟后响应用户操作,最好使用setTimeout,或者如果你想在浏览器队列中放置一些东西,你应该使用setTimeout(或者如果需要的话,使用worker).
它与setInterval相同,如果你习惯于每隔x毫秒做一些事情,那么你正确地使用它并且这是不错的做法,这是setInterval的错误用法:
var dbInterval = setInterval(function () { if (dbIsReady()) { clearInterval(dbInterval); fireReadyEvent(); } },300);
这里是setInterval的常规用法:
setInterval(function () { runSync(); },600000);
使用环境工具而不是那些工具本身的方式会影响不良做法和良好做法.