Skip to content

The Rendering Process

evan magoni edited this page May 28, 2014 · 6 revisions

This documentation is outdated and in need of review.

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

  1. The user loads the document viewer page. A specific document is requested, in the form of an ID, most likely through a GET parameter (e.g. documentviewer.php?document=9001 would load the document with the ID 9001).

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

  3. The server receives the AJAX request then gets the necessary data for the requested document ID (specifically, the document title, and the maximum dimensions 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},
    "pgs": [{"c": 1.0, "r": 1.0, "t_til": 1.0, "w": 145.0, "h": 99.0,
    "z": 0, "id": 1, "fn": "testimage-1.tif"}, {"c": 1.0, "r": 1.0,
    "t_til": 1.0, "w": 145.0, "h": 99.0, "z": 0, "id": 2, "fn":
    "testimage-2.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 total number of tiles, the width and height of the image, the zoom level, the page ID (not really useful), and the image filename.

  4. 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 load a placeholder for the page by the same process as above, only loading a blank image named blank.gif instead of the actual background image, to improve efficiency.

  5. 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 would 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, see the Internet Imaging Protocol Specification.

  6. 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.

  7. 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: this is enabled by default, but can be disabled if so wished. If enabled, a slider is created (using the jQuery UI slider plugin), with the initial value set to the initial zoom specified in the settings. Whenever a user moves the slider, a helper function is invoked with the new zoom level passed as a parameter. This function will store the current vertical and horizontal scrolls, then fire 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 alt-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 slider 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 that might have eliminated the need for an array holding the heights above pages, it would likely have had negative impacts on performance.