Is there an algorithm to determine if one or two images can be presented on screen? (singe page vs double page)

Given a known number of images with the same width to height ratio and dimensions, is there an algorithm that determines the best way to present them in a screen whose resolution may vary? Aka arrange them single page or double page.

For example, to determine if you can present two images on the screen or, given the width/height, to "detect" that only one would look better. To see if it's better to have them fit on width, with some blank space above and/or below them, or to fit on height, with blank space on the left/right.

I have made some attempts to determine such an algorithm of my own, but I'm not completely satisfied and I was hoping there might be a better solution or maybe some advices.

Unfortunately, it's not as simple as "width > height => two images otherwise one image", as I found out.

Summed up, right now I do all my calculations based on the image height first and then check if the screen width's is larger than 1.5 x my image width. Larger means I decrease the height to have two images fit, smaller means I only present one image. Still, I keep getting some undesired results for certain combinations of image sizes / screen resolutions.

If you stumbled upon the same problem and have some code or tips to spare, it would be greatly appreciated.

P.S. As you may figure out, this is about presenting a magazine.

[edit] I forgot to mention that I'm using javascript (vanilla, no plugins/frameworks) for the coding

Answers


You can use a kd-tree algorithm. A kd-tree hierarchical subdivide the screen into rectangles and uses a data structure similar to a binary tree to store the information. It's uses in many application for example to show the disk space. The Jquery plugin Masonry can do the same. I would also take a look at the Jquery plugin treemap.


To answer my own question, it seems there isn't such an algorithm or at least I wasn't able to find one. The kd-tree suggested is a waaaaaaaaaaaaay too complicated overkill solution to be practical.

In the end, I settled for the one I came up with myself:

  • first I check the window height, to see if the largest image fits. If it doesn't, I check if a certain percentage (75%) does. If it's still to large, I downsize the heights
  • once I determine a height that fits, I check if two images fit in the total width. If they do, this means I have a double-page mode, otherwise is single page mode

Here is a vanilla javascript implementation

var selCase = 0; //an "ok" var
//pageH = array with page heights
//pageW = array with page widths
//currentWH = window height
//currentWW = windowWidth

 for(i = pageH.length - 1; i >= 0; i--) {
    if(!selCase) {
        if(pageH[i] <= currentWH) { //if the page height is lower than the total height
            if(pageW[i] * 2 <= currentWW) { //if we have room for double pages
                currentMode = 'L';
                currentPW = pageW[i];
                currentPH = pageH[i];
                selCase = 11;
            }else {
                if(currentWW > currentWH) { //if the width is bigger, double-page mode is prefered
                    if((pageW[i] * 1.5) >= (currentWW - 20)) { //there wouldn't be much space left for double-pages 
                        currentMode = 'P';
                        currentPW = pageW[i];
                        currentPH = pageH[i];
                        selCase = 12;
                    } // else: the height fits, but not the width so a smaller height is required
                }else { //standard portrait mode
                    if(pageW[i] <= (currentWW - 20)) {
                        currentMode = 'P';
                        currentPW = pageW[i];
                        currentPH = pageH[i];
                        selCase = 13;
                    }
                }
            }   
        }else { //we check to see if maybe we can shrink the page a little to fit in the total height
            var sPerc; //scale percentage
            sPerc = currentWH * 100 / pageH[i];
            if(sPerc >= perc) {
                var newW = pageW[i] * sPerc / 100; 
                if(newW * 2 <= (currentWW - 20)) { //if we have room for two also-scaled pages
                    currentMode = 'L';
                    currentPW = Math.floor(newW);
                    currentPH = currentWH;
                    selCase = 21; 
                }else { 
                    if(currentWW > currentWH) { //same as before
                        if((newW * 1.5) >= (currentWW - 20)) { //only one scaled page fits
                            currentMode = 'P';
                            currentPW = Math.floor(newW);
                            currentPH = currentWH;
                            selCase = 22;
                        }
                    }else {
                        if(newW < (currentWW - 20)) {
                            currentMode = 'P';
                            currentPW = Math.floor(newW);
                            currentPH = currentWH;
                            selCase = 23;
                        }
                    }
                }
            }
        }
    }       
}

Need Your Help

jQuery modal dialog on ajaxStart event

jquery ajax jquery-ui modal-dialog

I'm trying to use a jQuery UI modal dialog as a loading indicator via the ajaxStart, ajaxStop / ajaxComplete events. When the page fires, an Ajax handler loads some data, and the modal dialog shows...

It is possible to pass query as a parameter to SSRS Report?

reporting-services axapta

I have to generate a report for a list page, than means from the listpage, I will create a button that call the report.