作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
编辑:仅出现在 Firefox 中! (我使用的是 22.0)请参阅底部的浏览器比较。
我试图通过复制像素数据并逐步将 alpha 值从 255 更改为 0(背景为黑色),在 Canvas 上创建“淡入黑色”效果。
function fadeToBlack () {
if(typeof this.recursion === 'undefined' || this.recursion === 0) {
this.recursion = 1;
this.imageData = this.ctx.getImageData(0, 0, this.width, this.height);
this.imageDataArray = this.imageData.data;
this.pixelCount = this.imageDataArray.length/4;
this.fadeToBlack();
}
else if (this.recursion <= 15){
console.time('Change alpha ' + this.recursion);
for (var i = 0; i < this.pixelCount; i++){
this.imageDataArray[i * 4 + 3] = 255 - 255 / 15 * this.recursion;
}
console.timeEnd('Change alpha ' + this.recursion);
this.ctx.putImageData(this.imageData, 0, 0);
this.recursion++;
setTimeout(function(){
this.fadeToBlack();
}.bind(this), 50);
}
else {
this.recursion = 0;
}
};
我认为这会非常昂贵(1280 * 1024 = 1310720 次迭代!),但正如您从下面的控制台日志中看到的,除了第一次迭代之外,它的速度出奇的快。
Change alpha 1: 543ms
Change alpha 2: 16ms
Change alpha 3: 6ms
Change alpha 4: 16ms
...
奇怪的是,如果我只是延迟 fadeToBlack
的第二次迭代(像素操作的第一次迭代)...
function fadeToBlack () {
if(typeof this.recursion === 'undefined' || this.recursion === 0) {
this.recursion = 1;
this.imageData = this.ctx.getImageData(0, 0, this.width, this.height);
this.imageDataArray = this.imageData.data;
this.pixelCount = this.imageDataArray.length/4;
//This is the only difference!
setTimeout(function(){
this.fadeToBlack();
}.bind(this), 0);
}
else if (this.recursion <= 15){
console.time('Change alpha ' + this.recursion);
for (var i = 0; i < this.pixelCount; i++){
this.imageDataArray[i * 4 + 3] = 255 - 255 / 15 * this.recursion;
}
console.timeEnd('Change alpha ' + this.recursion);
this.ctx.putImageData(this.imageData, 0, 0);
this.recursion++;
setTimeout(function(){
this.fadeToBlack();
}.bind(this), 50);
}
else {
this.recursion = 0;
}
};
神奇的事情发生了。
Change alpha 1: 16ms
Change alpha 2: 16ms
Change alpha 3: 6ms
Change alpha 4: 6ms
...
那么这里到底发生了什么?
编辑:我在多个浏览器中对此进行了测试,以下是所有 15 次迭代的结果(以毫秒为单位)。
Browser |Recursive |Asynchronous
=========+===========+============
Firefox |1652† |1136
Chrome |976 |978
Opera |12929 |13855
IE |855 |854
†第一次迭代非常昂贵(500ms)。
最佳答案
我认为这将函数之间的跳转减少了一半,因为您只调用一次直到函数终止(当使用 setTimeout 使用异步调用时),但是如果您通过从内部调用来使用递归,它将在该点停止并且跳转到下一个调用,依此类推,直到完成最后一个调用,然后逐渐递归,从停止处调用前一个函数,继续使用递归的返回值并返回到前一个函数,我可以查看绩效和方法方面的出价差异。我想问一下它是否会给出与我怀疑的结果相同的结果。
TL;DR setTimeout:异步调用(独立),递归:同步(依赖)。
图形演示:
关于javascript - Firefox 的递归成本高昂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17397165/
我是一名优秀的程序员,十分优秀!