我已经使用canvas标签完成了一个小小的全屏背景覆盖,但已经打到了性能墙。我所做的是创建一个名为#OverlayPic的容器,并将其设置为100%x 100%,display:none。在这个容器里面是我的canvas元素。
当被触发时,jQuery将图像加载到画布上并将像素信息作为数组获取。 switch语句接受用户为其所需的过滤器效果设置的选项。代码一切正常,但速度非常慢(我认为这主要是由于我的结构如何,但我不确定更好的方法)。
updateCanvas:function(onResize){
var img=new Image(); img.src=Main.ConSRC,
img.onload=function(){
var canvas=document.getElementById('Box_Canvas'),
ctx=canvas.getContext("2d"),
winW=$(window).width(), winH=$(window).height(),
imgW=this.width, imgH=this.height, smallestSide=Math.min(imgW,imgH);
// SETUP IMAGE PROPORTIONS
switch(smallestSide){
case imgW:
var width=winW,height=width*(imgW/imgH);
if(height < winH){ var height=winH, width=height*(imgW/imgH); };
break;
case imgH:
var height=winH,width=height*(imgW/imgH);
if(width < winW){ var width=winW, height=width*(imgH/imgW); };
break;
};
// DRAW IMAGE ON THE CANVAS
ctx.clearRect(0, 0, width*1.3, height*1.3 );
ctx.drawImage(img,0,0,width*1.3,height*1.3);
// IMAGE FILTERS
var imgdata=ctx.getImageData(0, 0, width, height), pix=imgdata.data, l=pix.length;
switch($this.data.bg_pic_filter){
// all filter code cases are here...
};
// APPLY THE FILER
ctx.putImageData(imgdata, 0, 0);
// FADE IN OVERLAY
if(!onResize){
Main.OBJ.$OverlayPic.fadeTo( $this.data.bg_pic_speed, $this.data.bg_pic_opacity);
};
};
},
此功能在2个地方被调用。
当用户单击指定的元素时,叠加淡入并且画布将加载过滤后的图像。
在窗口调整大小事件(onResize arg)上,为了维护已应用的过滤器,否则它只是默认返回原始图像?
有没有人有任何优化建议?谢谢!
答案 0 :(得分:1)
嗯,你看,你有一个巨大的图像,即使它只有600x600,仍然是36,000像素,所以即使你的//all filter code cases are here...
有类似的东西
case default:
var totalPixels = imagedata.data.length * .25; //divide by 4 now, since dividing is expensive compared to multiplication ( multiply by a decimal place is sometimes cheaper than dividing using /, most browsers have fixed this though[ this is important if you need to know multiple colors at once ] )
_data = imagedata.data
for( var i = totalPixels-1; i>=0; i-- ){
var index = i * 4 // this might be slower (creating a variable inside the loop) -- see next 2 lines
_data[i * 4] += 1 // these next 2 lines are identical
_data[index] += 1 // it might be faster to create an index, so you don't have to multiply, though usually multiplying is cheap and creating a variable inside a loop is expensive, so even if you have to multiple i * 4 a bunch, it might be faster than creating index
_data[index + 1] +=2 //green
_data[index + 2] +=2 //blue
_data[index + 3] +=2 //blue
}
所以,如你所见,你做了多次3600次X 4次(每个像素1次)
这是测试很重要的地方 - 比较相同的东西以提高不同浏览器的性能
使用/ 4除以有时比乘以小数* .25慢 如果你除以2的倍数,例如x / 2,你可以做x&gt;&gt; 1或x&lt;&lt; 1,称为按位移位,虽然有些浏览器已经增加了它们的倍增,实际上不再那么快了(chrome)
所有人都说,假设你不能使用web gl着色器。看,到目前为止,我们已经有了一个函数来循环遍历每个像素,一次一个,通过处理器,这是单线程和慢速。
来自https://github.com/mrdoob/three.js/ - THREE.js,它允许您使用着色器,这样您就可以通过视频卡一次渲染多个像素,这是获得更快速度的唯一方法触摸每个像素。这需要一个支持webGL的浏览器,这意味着你可能无论如何都支持画布,所以希望这个答案有效。