ipad safari 因内存不足而停止运行代码事件(具有 1 个图像对象的画布)
(是的,我来自瑞典,所以我的英语可能不太好;)
我在 iPad 上的记忆力有问题。此代码不会使浏览器崩溃,但它只是停止。在某些时候,它永远不会进入 Image 对象上的任何事件处理程序。我不知道为什么..?我已经搜索了论坛并用谷歌搜索了几天有关解决方法的信息。但它们并不真正符合我想要实现的目标(?)。 (因为我只有 1 个 Image 对象)。
我创建的内容如下:
1 个用户可见的主画布。
我在上面画画的其他 16 幅画布。
1 我用来加载图像的图像对象。
所有图像均为带 alpha 的 png,尺寸为 900x373 像素。所有画布都具有相同的尺寸。
其他 16 张画布上绘制了 8 个图像。
这样做的目的是能够旋转具有可互换层的对象。 (1 个角度是来自不同角度的对象,因此当主循环运行时它看起来像是在旋转。)旋转应该由触摸/鼠标控制,但这应该演示我想要实现的目标。
我知道这是很多需要查看的代码,而且它可能也不是最好的编写代码,因为我是 javascript 的新手。不过,它在我的 Chrome 笔记本电脑上运行良好。
我读过一些关于保存对 imageObjects 的引用的事件的内容,因此它们不会被 GC 处理。但这是否意味着我只有一个 Image 对象? 我还尝试使用 jquery 语法添加和删除侦听器,但没有成功。
如果有人花时间回答这个问题,我们将不胜感激。
问候奥斯卡。
变量的初始化:
var drawingCanvas = null;
var context = null;
var numAngles = 8;
var angleStep = 32/ numAngles;
var canvasAngles = [];
var loadStatus = {};
var basePath = "assets_900/";
var layerPaths = [];
var layerPathsA = ["black/","v16/","f86/","fA00049/","fA00340/","fTG02/","fTG02/","fTJ02/"];
var layerPathsB = ["red/","v16/","f86/","fA00049/","fA00340/","fTG02/","fTG02/","fTJ02/"];
var layerPathsC = ["black/","v16/","f86/","fR134/","fA00340/","fTG02/","fTG02/","fTJ02/"];
var layerPathsD = ["red/","v16/","f86/","fR134/","fA00340/","fTG02/","fTG02/","fTJ02/"];
var layerPathsArr = [layerPathsA,layerPathsB,layerPathsC,layerPathsD];
layerPathsCounter = 0;
var numLayers = layerPaths.length;
var imageInit = null;
var SW = 900; //1920
var SH = 373; //796
var loopcounter = 0;
首先设置画布和其他东西:
layerPaths = layerPathsArr[0];
drawingCanvas = document.getElementById('myDrawing');
context = drawingCanvas.getContext('2d');
for(var i = 0; i < numAngles; i++){
var canvas = document.createElement('canvas');
var canvasContext = canvas.getContext('2d');
canvasContext.createImageData(SW, SH);
canvas.height = SH;
canvas.width = SW;
canvasAngles.push(canvas);
}
这将初始化循环,然后它永远不会停止,它将继续直到移动 safari 崩溃:
loadImage(0,0,0);
这是一个加载图像的循环: 当它加载 8 个图像时,它会将它们绘制在 16 个画布之一上,然后该画布将绘制在可见画布上。然后它加载一个新角度和 8 个新图像,依此类推...
function loadImage(pathIndex,layerIndex,angleIndex){
if(layerIndex < layerPaths.length ){
//logger.log("path :" + pathIndex +" lajr : "+ layerIndex + " angl: " + angleIndex);
imageInit = new Image();
imageInit.onload = function(){
var canvas = canvasAngles[angleIndex];
var canvasContext = canvas.getContext('2d');
canvasContext.drawImage(imageInit,0, 0);
imageInit.onload = null;
imageInit.onerror = null;
imageInit.onabort = null;
imageInit.src = "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";
imageInit = null;
delete imageInit;
loadImage(pathIndex,layerIndex+1,angleIndex);
}
imageInit.onerror = function(){
logger.log("Error loading, retrying....");
loadImage(pathIndex,layerIndex,angleIndex);
}
imageInit.onabort = function(){
logger.log("Error loading (aborted)");
}
var path = "";
if(pathIndex < 10){
path = basePath + layerPaths[layerIndex] + "img000"+ pathIndex + ".png";
}else{
path = basePath + layerPaths[layerIndex] + "img00"+ pathIndex + ".png";
}
imageInit.src = path;
}else{
displayAngle(angleIndex);
if(angleIndex > numAngles-2){
logger.log("turns : " + loopcounter++ +" C: " + layerPathsCounter);
clearCanvases();
loadImage(0,0,0);
layerPathsCounter++;
if(layerPathsCounter > layerPathsArr.length-1){
layerPathsCounter = 0;
}
layerPaths = layerPathsArr[layerPathsCounter];
}else{
loadImage(pathIndex+angleStep,0,angleIndex+1);
}
}
}
这里有几个辅助函数:
function clearCanvases(){
for(var i = 0; i < numAngles; i++){
var canvas = canvasAngles[i];
var canvasContext = canvas.getContext('2d');
canvasContext.clearRect(0,0,drawingCanvas.width, drawingCanvas.height);
}
}
function displayAngle(index){
context.clearRect(0,0,drawingCanvas.width, drawingCanvas.height);
var canvas = canvasAngles[index];
context.drawImage(canvas,0,0);
}
HTML:
<body >
<canvas id="myDrawing" width="900" height="373">
<p>Your browser doesn't support canvas. (HEHE)</p>
</canvas>
</body>
(Yeah I'm from sweden so my english might not be perfect ;)
I have troubles with memory on the ipad. This code does not crash the broser, but it just stops. At some point it never goes in to any of the event handlers on the Image object. I have no clue why..? I have searched the forum and googled for a couple of days about workarounds. But they don't really fit what I am trying to achieve(?). (Because I only have 1 Image object).
What I have created is as follows:
1 main canvas which is visible to the user.
16 other canvases which I draw on.
1 Image Object which I load images with.
all images are pngs with alpha and have the following dimension 900x373 px. All the canvases have the same dimensions.
On the 16 other canvases there are drawn 8 images.
The purpose of this is to be able to rotate an object which has interchangable layers.
(1 angle is an object from a different angle, so it will look like it's rotating when the main loop runs.) The rotation is supposed to be controlled by touch/mouse but this should demonstrate what I want to achieve.
I know that this is a lot of code to look through and it might not be the best written code either since I'm a novice at javascript. However it does work fine on my laptop in chrome.
I've read something about events holding references to imageObjects and therefore they would not get GC'd. But does that imply here when I only have one Image Object ?
I also tried adding and removing the listeners with jquery syntax but no success.
It would be much appreciated if anyone would take the time to answer this.
Regards Oscar.
initialization of variables:
var drawingCanvas = null;
var context = null;
var numAngles = 8;
var angleStep = 32/ numAngles;
var canvasAngles = [];
var loadStatus = {};
var basePath = "assets_900/";
var layerPaths = [];
var layerPathsA = ["black/","v16/","f86/","fA00049/","fA00340/","fTG02/","fTG02/","fTJ02/"];
var layerPathsB = ["red/","v16/","f86/","fA00049/","fA00340/","fTG02/","fTG02/","fTJ02/"];
var layerPathsC = ["black/","v16/","f86/","fR134/","fA00340/","fTG02/","fTG02/","fTJ02/"];
var layerPathsD = ["red/","v16/","f86/","fR134/","fA00340/","fTG02/","fTG02/","fTJ02/"];
var layerPathsArr = [layerPathsA,layerPathsB,layerPathsC,layerPathsD];
layerPathsCounter = 0;
var numLayers = layerPaths.length;
var imageInit = null;
var SW = 900; //1920
var SH = 373; //796
var loopcounter = 0;
first setup of canvases and other stuf:
layerPaths = layerPathsArr[0];
drawingCanvas = document.getElementById('myDrawing');
context = drawingCanvas.getContext('2d');
for(var i = 0; i < numAngles; i++){
var canvas = document.createElement('canvas');
var canvasContext = canvas.getContext('2d');
canvasContext.createImageData(SW, SH);
canvas.height = SH;
canvas.width = SW;
canvasAngles.push(canvas);
}
this will init the loop, and then it will never stop, it will jsut continue until mobile safari crashes:
loadImage(0,0,0);
this is a loop that loads images:
when it has loaded 8 images it draws them on one of the 16 canvases and then that canvas gets drawn on the visible canvas. then it loads a new angle and 8 new images , and so on...
function loadImage(pathIndex,layerIndex,angleIndex){
if(layerIndex < layerPaths.length ){
//logger.log("path :" + pathIndex +" lajr : "+ layerIndex + " angl: " + angleIndex);
imageInit = new Image();
imageInit.onload = function(){
var canvas = canvasAngles[angleIndex];
var canvasContext = canvas.getContext('2d');
canvasContext.drawImage(imageInit,0, 0);
imageInit.onload = null;
imageInit.onerror = null;
imageInit.onabort = null;
imageInit.src = "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";
imageInit = null;
delete imageInit;
loadImage(pathIndex,layerIndex+1,angleIndex);
}
imageInit.onerror = function(){
logger.log("Error loading, retrying....");
loadImage(pathIndex,layerIndex,angleIndex);
}
imageInit.onabort = function(){
logger.log("Error loading (aborted)");
}
var path = "";
if(pathIndex < 10){
path = basePath + layerPaths[layerIndex] + "img000"+ pathIndex + ".png";
}else{
path = basePath + layerPaths[layerIndex] + "img00"+ pathIndex + ".png";
}
imageInit.src = path;
}else{
displayAngle(angleIndex);
if(angleIndex > numAngles-2){
logger.log("turns : " + loopcounter++ +" C: " + layerPathsCounter);
clearCanvases();
loadImage(0,0,0);
layerPathsCounter++;
if(layerPathsCounter > layerPathsArr.length-1){
layerPathsCounter = 0;
}
layerPaths = layerPathsArr[layerPathsCounter];
}else{
loadImage(pathIndex+angleStep,0,angleIndex+1);
}
}
}
heres a couple of helper functions :
function clearCanvases(){
for(var i = 0; i < numAngles; i++){
var canvas = canvasAngles[i];
var canvasContext = canvas.getContext('2d');
canvasContext.clearRect(0,0,drawingCanvas.width, drawingCanvas.height);
}
}
function displayAngle(index){
context.clearRect(0,0,drawingCanvas.width, drawingCanvas.height);
var canvas = canvasAngles[index];
context.drawImage(canvas,0,0);
}
HTML :
<body >
<canvas id="myDrawing" width="900" height="373">
<p>Your browser doesn't support canvas. (HEHE)</p>
</canvas>
</body>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
似乎您只能在一个选项卡中加载 ~6.5 mb。据我所知,没有办法释放这些内存(?)
这将在 ipad 上加载大约 13 500kb 的图像,然后停止..,
http://www.roblaplaca.com/examples/ipadImageLoading/img.html
It seems like you can only load ~6.5 mb in one tab. And as far as I know there is no way to free up this memory (?)
this will load about 13 500kb imqages on an ipad and then stop..,
http://www.roblaplaca.com/examples/ipadImageLoading/img.html