PanoJS3 - An interactive JavaScript widget for panning and zooming a panoramic image stitched together dynamically from smaller tiles. This widget can be used for viewing images that are much larger than the available space in the browser viewport. Examples include panoramas, maps or high resolution document scans.
PanoJS3 supports all modern major web browsers:
PanoJS3 supports native navigation on most popular platforms:
PanoJS has gone through a couple of name changes. It was first named GSV2 when it was released as the next generation of the Giant Ass Image Viewer originally developed by Michal Migurski. It was then briefly known as GSIV and finally became PanoJS when it became a Google Code project created by Dan Allen. This third version brings many updates to usability, platform support and ease of use.
Use GitHub repository for contributing to the project and to see the source code online. You can also download the latest release in a ZIP package:
File | Size | Description |
---|---|---|
» panojs3.zip | 196KB | source code |
PanoJS3 1.0.0 (2011-01-14) by Dmitry Fedorov: * controls UI works for iPhone, iPad and Android * support for more events: scroll wheel for zoom, touch events (zoom, scroll) * support multiple instances * allow view scale beyond 100% * good full window support * pre-cache tiles in the first row outside of visible area * one line instantiator * google maps like controls - zoomin on double click * center on one click * fixed several problems showing tiles * small info text about the state: scale, etc... * thumbnail navigation * IE is again supported - partially, maybe somebody can help? * Use ExtJS for events * refactoring JavaScript classes * provide tile providers: imgcnv, bisque, zoomify and embedded python script PanoJS 1.0.2 (2009-01-01) by Dan Allen: * renamed project to PanoJS * change license to Apache License 2.0 * move project to Google Code * respect max zoom level when scaling to window * don't alert if max zoom size is exceeded when message is null GSIV 1.0.1 (2006-03-16) by Dan Allen: * added localization for two warning messages * fixed the TileUrlProvider checking in the constructor * added GSIV.isInstance to check for an instance of a class * fixed python script to allow for missing background color parameter GSIV 1.0.0 (2006-02-26) by Dan Allen: * completely new object-oriented design * use json options format * optimized performance (both in drag, rendering and zoom) * fixed rounding error in tile placement that lead to artifact lines * added upper zoom limit * added initial pan option * added observers that can send viewer events to listeners * double-click to recenter * smooth motion when repositioning * method to position absolutely (recenter on absolute point) * method to fit to window (resize) * additional options for file names and extensions * preloading image tiles (loading animation) * prevent from scrolling outside of original image boundary (uses blank tile) * throttle mouse move events to increase performance * cross-browser mouse cursor implementation that represent dragging * account for scroll offset of page when calculating coordinates * keyboard events for movement (initial attempt) * new tilemaker.py python script, using a cleaner design and additional options GSV 1.0 (2005) by Michal Migurski
PanoJS requires image tiles to be stored on a web server somewhere so it could fetch on request. You could use a free cross-platform command line utility Bio-Image Convert to split any image into tiles. It's available for Mac, Windows and Linux and is open source so you sould compile it for any other system. The example command line call is the following:
imgcnv -i MY_INPUT_IMAGE.jpg -o MY_OUT_FOLDER/MY_OUT_BASE_NAME.jpg -t jpeg -tile 256
After this, simply create a web page, copy all the PanoJS code in teh same folder and use something similar to the following JavaScript code to instantiate the viewer:
PanoJS.MSG_BEYOND_MIN_ZOOM = null; PanoJS.MSG_BEYOND_MAX_ZOOM = null; var viewer = null; function createViewer( viewer, dom_id, url, prefix, w, h ) { if (viewer) return; var MY_URL = url; var MY_PREFIX = prefix; var MY_TILESIZE = 256; var MY_WIDTH = w; var MY_HEIGHT = h; var myPyramid = new ImgcnvPyramid( MY_WIDTH, MY_HEIGHT, MY_TILESIZE); var myProvider = new PanoJS.TileUrlProvider('','',''); myProvider.assembleUrl = function(xIndex, yIndex, zoom) { return MY_URL + '/' + MY_PREFIX + myPyramid.tile_filename( zoom, xIndex, yIndex ); } viewer = new PanoJS(dom_id, { tileUrlProvider : myProvider, tileSize : myPyramid.tilesize, maxZoom : myPyramid.getMaxLevel(), imageWidth : myPyramid.width, imageHeight : myPyramid.height, blankTile : 'images/blank.gif', loadingTile : 'images/progress.gif' }); Ext.EventManager.addListener( window, 'resize', callback(viewer, viewer.resize) ); viewer.init(); }; createViewer( viewer, 'viewer', 'IMG_7474-7511', '256_', 16610, 8396 );