user465627
user465627

Reputation: 13

ipad safari stops running code events (canvases with 1 image object) out of memory

(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>

Upvotes: 1

Views: 513

Answers (1)

oscar
oscar

Reputation: 11

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

Upvotes: 1

Related Questions