gpt4 book ai didi

javascript - Canvas Shiny 星星背景性能问题

转载 作者:行者123 更新时间:2023-11-29 17:15:18 30 4
gpt4 key购买 nike

我正在进行的实验存在问题。

我的计划是在整个页面上放置一个美丽而 Shiny 的星星背景。
通过使用精彩的教程(http://timothypoon.com/blog/2011/01/19/html5-canvas-particle-animation/),我设法获得了完美的背景。
我使用静态 Canvas 显示静态星星,使用动画 Canvas 显示 Shiny 的星星。

事实是它非常消耗内存!在chrome和Opera上,它运行非常平稳,但是在Firefox IE或平板电脑上,渲染每一帧等都一团糟。在高度很大的页面上,情况更糟。

因此,我进行了一些优化:

-使用缓冲 Canvas ,问题是createRadialGradient,每帧被调用1500次

-使用大缓冲 Canvas ,并为每个星星使用1个 Canvas ,并在初始化时仅调用createRadialGradient。

-删除缓冲 Canvas ,并将所有星星 Canvas 绘制到主 Canvas 上

最后的优化是我能达到的最佳效果,所以我写了一个小提琴,显示当前代码如何。

   //Buffering the star image
this.scanvas = document.createElement('canvas');
this.scanvas.width=2*this.r;
this.scanvas.height=2*this.r;
this.scon=this.scanvas.getContext('2d');
g = this.scon.createRadialGradient(this.r,this.r,0,this.r,this.r,this.r);
g.addColorStop(0.0, 'rgba(255,255,255,0.9)');
g.addColorStop(this.stop, 'rgba('+this.color.r+','+this.color.g+','+this.color.b+','+this.stop+')');
g.addColorStop(1.0, 'rgba('+this.color.r+','+this.color.g+','+this.color.b+',0)');
this.scon.fillStyle = g;
this.scon.fillRect(0,0,2*this.r,2*this.r);

那就是我需要你的地方:

-一种根据用户性能调整 Shiny 星星数量的方法

-优化技巧

在此先感谢大家的帮助,如果我犯了语法错误,我深表歉意,我的英语并不完美。

编辑
感谢您的反馈,
让我解释一下整个过程,
每个星星都有自己不同的渐变和大小,这就是为什么我将其存储在个人 Canvas 中的原因,只有通过使用drawImage在主 Canvas 上缩放 Canvas 才能实现 Shiny 效果。

我认为最好的方法是在缓冲 Canvas 中预先渲染50或100个不同的星星,然后随机选择并绘制一个星星,您不是吗?

EDIT2

根据术士的忠告,更新的小提琴是一颗预渲染的星星,其大小与当前尺寸匹配。星星不太漂亮,但整个过程运行起来更加流畅。

EDIT3

更新了小提琴以使用精灵表。华丽!!!!
 //generate the star strip
var len=(ttlm/rint)|0;
scanvas = document.createElement('canvas');
scanvas.width=len*2*r;
scanvas.height=2*r;
scon=scanvas.getContext('2d');
for(var i=0;i<len;i++){
var newo = (i/len);
var cr = r*newo;
g = scon.createRadialGradient(2*r*i+r,r,0,2*r*i+r,r,(cr <= 2 ? 2 : cr));
g.addColorStop(0.0, 'rgba(200,220,255,'+newo+')');
g.addColorStop(0.2, 'rgba(200,220,255,'+(newo*.7)+')');
g.addColorStop(0.4, 'rgba(150,170,205,'+(newo*.2)+')');
g.addColorStop(0.7, 'rgba(150,170,205,0)');
scon.fillStyle = g;
scon.fillRect(2*r*i,0,2*r,2*r);
}

编辑4(最终)

动态星星创作
function draw() {
frameTime.push(Date.now());
con.clearRect(0,0,WIDTH,HEIGHT);
for(var i = 0, len = pxs.length; i < len; i++) {
pxs[i].fade();
pxs[i].draw();
}
requestAnimationFrame(draw);
if(allowMore === true && frameTime.length == monitoredFrame)
{
if(getAvgTime()<threshold && pxs.length<totalStars )
{
addStars();
}
else
{
allowMore=false;
static=true;
fillpxs(totalStars-pxs.length,pxss);
drawstatic();
static=false;
}
}
}

这是更新和最后的小提琴,带有精灵表,动态的星星创建和一些优化。如果您看到其他任何内容,请随时更新。

POST EDIT 重新启用 meteor /原型(prototype)对象/摆脱Jquery

http://jsfiddle.net/macintox/K8YTu/32/

谢谢所有帮助过我的人,这真的很友善,也很有启发性,我希望它有时会有所帮助。

Aesdotjs。
PS:我很高兴。经过测试,该脚本可以在每个浏览器(甚至IE9)上顺利运行。亚塔!!

最佳答案

采用浏览器性能
要衡量用户设置的能力,您可以实现一个动态星型创建器,该星型创建器在某个阈值处停止。
例如,在您的代码中,您定义了要绘制的最小星形。然后在主循环中测量时间,如果绘制星星的时间少于最大阈值,则再增加10个星星(我只是在这里抛出一个数字)。
没有多少人知道 requestAnimationFrame 给它调用的函数一个参数(DOMHighResTimeStamp),自上次请求以来花费的时间以毫秒为单位。这将帮助您跟踪负载,并且我们知道60 fps约为每帧16.7毫秒,我们可以在此之下设置一些阈值以使其达到最佳状态,同时仍然为其他浏览器提供一些开销。
代码看起来像这样:

var minCount = 100,   /// minimum number of stars
batchCount = 10, /// stars to add each frame
threshold= 14, /// milliseconds for each frame used
allowMore = true; /// keep adding

/// generate initial stars
generateStarts(minCount);

/// timeUsed contains the time in ms since last requestAnimationFrame was called
function loop(timeUsed) {

if (allowMore === true && timeUsed < threshold) {
addMoreStars(batchNumber);
} else {
allowMore = false;
}

/// render stars

requestAnimationFrame(loop);
}
请注意,这有点简化。您将需要先进行几轮操作并测量平均值,以使这项工作更好,并且在添加星标时(由于其他浏览器操作)会达到峰值。
因此,添加星星,测量几轮,如果平均值低于阈值,则添加星星并重复。
最佳化
雪碧表
至于优化,精灵表是必经之路。而且它们不必只是星星(我将在下面尝试解释)。
渐变和弧度是此应用程序中昂贵的部分。即使预先渲染单个星星,由于插值等原因,调整这么多星星的大小也会产生成本。
当发生大量昂贵的操作时,最好妥协一下内存的使用并预渲染所有可能的内容。
例如:首先使用渐变和弧线渲染一颗大星星来渲染各种尺寸。
使用该星星将其他大小绘制为具有相同像元大小的星星带。
现在,使用精灵页面仅绘制星星数量的一半,并绘制精灵页面的裁剪部分(而不是调整大小)。然后将 Canvas 旋转90度,并在不同位置将其自身绘制在其顶部( Canvas 本身变成一个大的“sprite-sheet”)。
旋转90度并不像其他 Angular (优化0、90、180、270)那样使性能降低。这会给您一种幻想,那就是拥有实际的恒星数量,并且由于它已经旋转,因此我们无法轻松检测出重复的模式。
Canvas 的单​​个 drawImage操作比所有星星的许多小绘制操作要快。
(当然,您可以多次执行此操作,而不是只一次执行一次,直到刚开始看到模式之前的某个点-没有多少,什么大小的关键答案,因此找到合适的平衡始终是一项实验)。
整数
其他优化可以仅使用整数位置和大小。使用浮点数时,会激活子像素化,这非常昂贵,因为浏览器需要为偏移像素计算抗锯齿。
使用整数值可以有所帮助,因为不需要子像素化(但这并不意味着如果不是1:1尺寸就不会对图像进行插值)。
记忆界限
您还可以通过使用可在4上划分的大小和位置来帮助底层的低位位图处理一点点。这与内存复制和低级裁剪有关。您始终可以制作几个Sprite-sheet来改变可在4上划分的单元格中的位置。
此技巧在速度较慢的计算机(即典型的消费者指定的计算机)上更有值(value)。
关闭抗锯齿
关闭图像的抗锯齿功能。这将有助于性能,但会给星星带来一些粗糙的结果。要关闭图像抗锯齿功能,请执行以下操作:
ctx.webkitEnableImageSmoothing = false;
ctx.mozEnableImageSmoothing = false;
ctx.enableImageSmoothing = false;
这样,只要使用 drawImage渲染星星,您的性能就会得到明显改善。
缓存一切
缓存所有可以缓存的内容,包括星图和变量。
当您执行 stars.length时,浏览器的解析器需要首先找到 stars,然后遍历该树以找到 length-对于每个回合(在某些浏览器中可能已优化)。
如果首先将其缓存到变量 var len = stars.length中,则浏览器仅需要遍历树和分支一次,并且在循环中,只需查找本地作用域即可找到更快的变量 len
分辨率降低
您还可以将分辨率降低一半,即。做到目标尺寸的一半。在最后一步中,将渲染放大到全尺寸。最初将为您节省75%的渲染区域,但结果是分辨率较低。
在专业视频世界中,当物体被动画化(主要是移动)时,我们经常使用低分辨率,因为当物体移动时,眼睛/大脑会修补(或无法检测到)太多细节,因此并不那么引人注目。如果可以这样做,则必须进行测试-也许不是因为恒星实际上并没有移动,而是值得尝试获得第二个好处:提高性能。

关于javascript - Canvas Shiny 星星背景性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18662930/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com