Skip to content

The Rendering Process

Evan Magoni edited this page Aug 25, 2014 · 6 revisions

Here is a more thorough explanation of what is happening "behind the scenes" when a document is loaded.

  1. The user loads a page containing the document viewer, and it is instantiated. An AJAX request is sent to the server whose URL is specified in the settings (iipServerURL), with the path to the requested document (objectData) and the zoom level sent as parameters (the initial zoom level can be set upon instantiation; otherwise, it is 2 by default).

  2. The server receives the AJAX request then gets the necessary data for the requested document (specifically, the document title, the maximum and average image dimensions at each zoom level and filenames of the images), processes it, and calculates things like the total height of all the images stacked together, the number of 256x256 (or less) tiles that are needed to show each image, and the dimensions of the images at this specific zoom level. It then outputs the data in JSON format, as in the following example below for a document with two pages, at the lowest possible zoom level (0):

{
    "item_title": "Test title",
    "dims": {
        "a_wid": 145.0,
        "mx_h": 99.0,
        "mx_w": 145.0,
        "t_wid": 4372.0,
        "t_hei": 2992.0,
        "a_hei": 99.0
        },
    "max_zoom": 4,
    "pgs":
        [{
            d: [{
                c: 1,
                r: 2,
                h: 277.8125,
                w: 177.875
            },
            {
                c: 2,
                r: 3,
                h: 555.625,
                w: 355.75
            }],
        m: 5,
        f: "bm_001.tif"
        },
        {
            d: [{
                c: 1,
                r: 2,
                h: 264,
                w: 163.6875
            },
            {
                c: 2,
                r: 3,
                h: 528,
                w: 327.375
            }],
        m: 5,
        f: "bm_002.tif"
        }]
}
As can be seen in this example, the three variables being returned are `item_title`, `dims` (an array holding various dimension-related data), and `pgs` (an array of all the pages). The variable names being returned are deliberately shortened to cut down on data transfer. Within `pgs`, we have an array of data for each page - the number of columns, the number of rows, the width and height of the image (all of these for each zoom level), the zoom level, the page ID (not really useful), and the image filename.
  1. Upon a successful request, the data returned by the request goes into the "success" callback function. Some relevant information (zoom level, total height, the array of pages etc) is stored in the settings array so that it can be accessed by other functions. Then, we loop through every page in the array of pages, and try to load it using a helper function. That helper function will first check if the page is near the viewport (within 100 pixels of it, top or bottom). If it is, it will load the page by looping through each row and column of tiles in the image, and then loading them as background images in a div. If it is not, it will not create a container or load images into the DOM, saving on downloading time until the user scrolls the viewport down.

  2. The actual tiles for the images are served by the IIPImage server, which can be on the same server, or on a different one. The URL used to access a tile might look like this:

    http://petrucci.musiclibs.net:9002/fcgi-bin/iipsrv.fcgi?FIF=/tmp/image-75.tif&JTL=2,0
    

    The filename (as an absolute path) is sent as the FIF GET parameter, and the JTL parameter allows one to retrieve a tile as a complete JFIF image. The syntax for the JTL parameter is JTL=res,tile where res is the resolution (i.e. zoom level - varies between 0 and 5) and tile is the tile number (with indexing beginning at 0). For more information, see the Internet Imaging Protocol Specification.

  3. Once all the pages have been appended to the DOM, the user will be automatically scrolled to the correct place. This isn't usually relevant for the initial AJAX request, but if the width of the page is larger than the width of the panel, then the user will be scrolled horizontally so that the page is centered in the viewport.

  4. Now that the script is done loading the pages, it idles and listens for several possible events to be fired. These events are as follows:

    • Scrolling vertically through the pages of the document: when a user attempts to scroll vertically within the document panel, either using the scrollwheel or by dragging the scrollbar, a function handling the scroll request is invoked. First, the direction of the scroll (up or down) is determined. Then, we loop through all the pages above (or below, if scrolling down) the last page that was loaded that are either in the viewport or below it (more relevant when the user is trying to go to a specific page). Only pages that are actually near the viewport will be loaded, due to performance considerations; pages that are in between the last loaded page and the page the user is trying to load will not load if they are not near the viewport.
    • Zooming in using the slider or buttons: this is enabled by default, but can be disabled if so wished. If enabled, +/- buttons are created. Whenever a user moves the slider, a helper function is invoked with the new zoom level passed as a parameter. This function stores the current vertical and horizontal scrolls, then fires off a new AJAX request using the new zoom level. Upon success, the document viewer will be cleared of its contents, and the pages at the new zoom level will be loaded.
    • Zooming in by double-clicking: a user can zoom in or out on a specific region, which will then be centered in the viewport, by double-clicking on it (holding the control [ctrl] key while double-clicking results in zooming out). Double-clicking calls a helper function which will figure out the desired new zoom as well the coordinates of the point that needs to be centered, set a boolean representing the double-click event to true, then fire off a new AJAX request using the new zoom level. The button label is then updated to reflect the new zoom level.
    • Going to a specific page: this is enabled by default, but can be disabled if so wished. If enabled, the user is provided with a small text box and a button permitting the user to enter a page number and jump directly to that page. If the number is not a valid page number (where the range of valid page numbers is from 1 to the number of pages in the array), then a Javascript alert window pops up with the relevant error message. If, however, the number is valid, the user will be scrolled to the requested page, with the scroll handler function taking care of loading the relevant pages. This can be done fairly quickly, because the height above each page is stored in an array, with the page ID being the index (see the Development notes for more on this). Scrolling in this case is accomplished through the scrollTop function in jQuery, and not the jQuery scrollTo() plugin; although using a plugin that automatically scrolls to a object on a page might have eliminated the need for an array holding the heights above pages, it would likely have had negative impacts on performance.