From 1e5b9b98e039408dca420e42fb576f8a5bdc121c Mon Sep 17 00:00:00 2001 From: cskwg Date: Mon, 10 Jun 2013 11:50:45 +0300 Subject: [PATCH 1/9] Update openseadragon.js modified console to make it easy to break into the debugger when errors happen. --- src/openseadragon.js | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/openseadragon.js b/src/openseadragon.js index ee5e0dac..45c10bb7 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -1341,11 +1341,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){ request.open( "GET", options.url, options.async ); request.send( null ); } catch (e) { - $.console.log( - "%s while making AJAX request: %s", - e.name, - e.message - ); + $.console.log(e.name + " while making AJAX request: " + e.message); request.onreadystatechange = null; request = null; @@ -1637,18 +1633,19 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){ * @static * @private */ - var nullfunction = function( msg ){ - //document.location.hash = msg; - }; - - $.console = window.console || { - log: nullfunction, - debug: nullfunction, - info: nullfunction, - warn: nullfunction, - error: nullfunction + // modified to make it easy to break into the debugger when errors happen. + var logfunction = function (msg) { + if (window.console) return window.console.log(msg); + window.alert(msg); }; - + $.console = { + log: function (msg) { logfunction(msg); }, + debug: function (msg) { logfunction(msg); }, + info: function (msg) { logfunction(msg); }, + warn: function (msg) { logfunction(msg); }, + error: function (msg) { logfunction(msg); } + }; + // Adding support for HTML5's requestAnimationFrame as suggested by acdha. // Implementation taken from matt synder's post here: From 8464be164dc7e9d191b8b7b5465845c5b4b1f414 Mon Sep 17 00:00:00 2001 From: cskwg Date: Mon, 10 Jun 2013 11:51:48 +0300 Subject: [PATCH 2/9] Update viewer.js only added a comment related to performance. --- src/viewer.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/viewer.js b/src/viewer.js index 84588565..d6468a66 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -1455,7 +1455,8 @@ function onContainerEnter( tracker, position, buttonDownElement, buttonDownAny ) // Page update routines ( aka Views - for future reference ) /////////////////////////////////////////////////////////////////////////////// -function updateMulti( viewer ) { +// TODO: this is called about once every 15 ms. Is this correct? +function updateMulti(viewer) { var beginTime; From 4d5ccb2007f874f6fadb79390538b273b7803659 Mon Sep 17 00:00:00 2001 From: cskwg Date: Mon, 10 Jun 2013 11:53:51 +0300 Subject: [PATCH 3/9] Update drawer.js Added fixTile. This makes it possible to modify a tile after it has been loaded. Besides that, modified some logging statements to make them more compatible. --- src/drawer.js | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/drawer.js b/src/drawer.js index 833d1fe6..ef8e5851 100644 --- a/src/drawer.js +++ b/src/drawer.js @@ -46,10 +46,12 @@ var DEVICE_SCREEN = $.getWindowSize(), ( BROWSER == $.BROWSERS.IE && BROWSER_VERSION >= 9 ) ), - USE_CANVAS = SUBPIXEL_RENDERING && - !( DEVICE_SCREEN.x <= 400 || DEVICE_SCREEN.y <= 400 ) && - !( navigator.appVersion.match( 'Mobile' ) ) && - $.isFunction( document.createElement( "canvas" ).getContext ); + // always use canvas when it is available. + USE_CANVAS = $.isFunction( document.createElement( "canvas" ).getContext ); + //USE_CANVAS = SUBPIXEL_RENDERING && + // !( DEVICE_SCREEN.x <= 400 || DEVICE_SCREEN.y <= 400 ) && + // !( navigator.appVersion.match( 'Mobile' ) ) && + // $.isFunction( document.createElement( "canvas" ).getContext ); //console.error( 'USE_CANVAS ' + USE_CANVAS ); @@ -777,6 +779,10 @@ function loadTile( drawer, tile, time ) { if( drawer.viewport.collectionMode ){ drawer.midUpdate = false; onTileLoad( drawer, tile, time ); + } else if ( drawer.source.virtualMode ) { + tile.loading = true; + tile.loaded = false; + tile.image = null; } else { tile.loading = drawer.loadImage( tile.url, @@ -805,19 +811,22 @@ function onTileLoad( drawer, tile, time, image ) { $.console.warn( "Tile load callback in middle of drawing routine." ); return; } else if ( !image && !drawer.viewport.collectionMode ) { - $.console.log( "Tile %s failed to load: %s", tile, tile.url ); + $.console.log( "Tile " + tile + " failed to load: " + tile.url ); if( !drawer.debugMode ){ tile.exists = false; return; } } else if ( time < drawer.lastResetTime ) { - $.console.log( "Ignoring tile %s loaded before reset: %s", tile, tile.url ); + $.console.log( "Ignoring tile " + tile + " loaded before reset: " + tile.url ); return; } tile.loaded = true; tile.image = image; - + // give the application an opportunity to modify the just-loaded tile. + if ( drawer.fixTile ) { + drawer.fixTile( drawer, tile ); + } insertionIndex = drawer.tilesLoaded.length; @@ -987,10 +996,7 @@ function isCovered( coverage, level, x, y ) { */ function setCoverage( coverage, level, x, y, covers ) { if ( !coverage[ level ] ) { - $.console.warn( - "Setting coverage for a tile before its level's coverage has been reset: %s", - level - ); + $.console.warn( "Setting coverage for a tile before its level's coverage has been reset: " + level ); return; } @@ -1162,7 +1168,7 @@ function drawTiles( drawer, lastDrawn ){ } else { if ( USE_CANVAS ) { - tile.drawCanvas( drawer.context ); + tile.drawCanvas( drawer.context, drawer.source ); } else { tile.drawHTML( drawer.canvas ); } From affc770b715403d8410ae332c20e51d72e67d7b2 Mon Sep 17 00:00:00 2001 From: cskwg Date: Mon, 10 Jun 2013 11:55:21 +0300 Subject: [PATCH 4/9] Update navigator.js Only modified the transparency to make the Navigator completely opaque. --- src/navigator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/navigator.js b/src/navigator.js index c09566f8..fa3a301c 100644 --- a/src/navigator.js +++ b/src/navigator.js @@ -102,7 +102,7 @@ $.Navigator = function( options ){ style.border = borderWidth + 'px solid #555'; style.padding = '0px'; style.background = '#000'; - style.opacity = 0.8; + style.opacity = 1.0; style.overflow = 'hidden'; }( this.element.style, this.borderWidth)); From 25f62cee4b241534bb6737eb379b436d2309f02d Mon Sep 17 00:00:00 2001 From: cskwg Date: Mon, 10 Jun 2013 12:11:37 +0300 Subject: [PATCH 5/9] Update tile.js Added the code required to implement virtual images and computed tiles. The important parts are the call to "this.cacheTile" and the "rendered" handling. The "rendered" handling makes it possible to modify a tile after it has been loaded. The starting point is the method "fixTile" (drawer.js), this makes it possible to modify a tile. For performance reasons it always generates a canvas context, no DOM image. So the extra "rendered" if-statement is required to detect this. There is no performance problem, because the image would have been converted to a canvas context anyway. The "cacheTile" method is used by one or more invisible instances of OpenSeadragon to collect tiles. These are then processed and accumulated to build the virtual image. They are stored within the TILE_CACHE and the tileMatrix of the visible instance of OpenSeadragon. This visible instance is the one which displays the virtual image. Some changes were required in drawer.js (loadTile) to support this. The following code is required to force appropriate painting and updating for the virtual image: // updateDrawer: function ( drawer, tile, target ) { try { var newtile = drawer.tilesMatrix[tile.level][tile.x][tile.y]; newtile.image = target; newtile.loading = false; newtile.loaded = true; drawer.updateAgain = true; drawer.lastDrawn.push( newtile ); } catch ( ex ) { console.log( ex ); } }, And that method must be called for the viewer and the navigator: mi.updateDrawer( osdMain.drawer, tile, target ); mi.updateDrawer( osdMain.navigator.drawer, tile, target ); --- src/tile.js | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/tile.js b/src/tile.js index 5b380087..71ccbb11 100644 --- a/src/tile.js +++ b/src/tile.js @@ -114,10 +114,7 @@ $.Tile.prototype = { var containerSize = $.getElementSize( container ); if ( !this.loaded || !this.image ) { - $.console.warn( - "Attempting to draw tile %s when it's not yet loaded.", - this.toString() - ); + $.console.warn("Attempting to draw tile " + this.toString() + " when it's not yet loaded."); return; } @@ -171,7 +168,7 @@ $.Tile.prototype = { * @function * @param {Canvas} context */ - drawCanvas: function( context ) { + drawCanvas: function (context, tileSource) { var position = this.position, size = this.size, @@ -179,10 +176,7 @@ $.Tile.prototype = { canvas; if ( !this.loaded || !( this.image || TILE_CACHE[ this.url ] ) ){ - $.console.warn( - "Attempting to draw tile %s when it's not yet loaded.", - this.toString() - ); + $.console.warn("Attempting to draw tile " + this.toString() + " when it's not yet loaded."); return; } context.globalAlpha = this.opacity; @@ -206,12 +200,21 @@ $.Tile.prototype = { } if( !TILE_CACHE[ this.url ] ){ - canvas = document.createElement( 'canvas' ); - canvas.width = this.image.width; - canvas.height = this.image.height; - rendered = canvas.getContext('2d'); - rendered.drawImage( this.image, 0, 0 ); + // Is this already a canvas context ? + if ( this.image && this.image.lineTo ) { + rendered = this.image; + } else { + canvas = document.createElement( 'canvas' ); + canvas.width = this.image.width; + canvas.height = this.image.height; + rendered = canvas.getContext( '2d' ); + rendered.drawImage( this.image, 0, 0 ); + } TILE_CACHE[ this.url ] = rendered; + // give the application the opportunity to cache this tile + if ( this.cacheTile ) { + this.cacheTile( TILE_CACHE, this.url, tileSource, this ); + } //since we are caching the prerendered image on a canvas //allow the image to not be held in memory this.image = null; @@ -226,10 +229,10 @@ $.Tile.prototype = { 0, rendered.canvas.width, rendered.canvas.height, - position.x, - position.y, - size.x, - size.y + this.position.x, + this.position.y, + this.size.x, + this.size.y ); //rendered.restore(); From a1e876447b5ffbaf87e878846cd57d18bcc66a84 Mon Sep 17 00:00:00 2001 From: cskwg Date: Tue, 11 Jun 2013 20:15:21 +0200 Subject: [PATCH 6/9] Update drawer.js Removes the commented code. --- src/drawer.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/drawer.js b/src/drawer.js index ef8e5851..9f92c664 100644 --- a/src/drawer.js +++ b/src/drawer.js @@ -48,10 +48,6 @@ var DEVICE_SCREEN = $.getWindowSize(), // always use canvas when it is available. USE_CANVAS = $.isFunction( document.createElement( "canvas" ).getContext ); - //USE_CANVAS = SUBPIXEL_RENDERING && - // !( DEVICE_SCREEN.x <= 400 || DEVICE_SCREEN.y <= 400 ) && - // !( navigator.appVersion.match( 'Mobile' ) ) && - // $.isFunction( document.createElement( "canvas" ).getContext ); //console.error( 'USE_CANVAS ' + USE_CANVAS ); From 3e69ad323e4725be0713250abfd9d00cc1439046 Mon Sep 17 00:00:00 2001 From: cskwg Date: Tue, 11 Jun 2013 21:20:44 +0300 Subject: [PATCH 7/9] Update tilesource.js --- src/tilesource.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tilesource.js b/src/tilesource.js index 1e6a26a4..9a0ab6d4 100644 --- a/src/tilesource.js +++ b/src/tilesource.js @@ -82,6 +82,8 @@ * The minimum pyramid level this tile source supports or should attempt to load. * @property {Number} maxLevel * The maximum pyramid level this tile source supports or should attempt to load. + * @propert yr} maxLevel + * The maximum pyramid level this tile source supports or should attempt to load. */ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLevel ) { var _this = this, From 9d246af681e6d36da4d4085358c9640a077e982c Mon Sep 17 00:00:00 2001 From: cskwg Date: Tue, 11 Jun 2013 20:22:49 +0200 Subject: [PATCH 8/9] Update tilesource.js Added a comment for virtualMode --- src/tilesource.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tilesource.js b/src/tilesource.js index 9a0ab6d4..a780891d 100644 --- a/src/tilesource.js +++ b/src/tilesource.js @@ -82,8 +82,8 @@ * The minimum pyramid level this tile source supports or should attempt to load. * @property {Number} maxLevel * The maximum pyramid level this tile source supports or should attempt to load. - * @propert yr} maxLevel - * The maximum pyramid level this tile source supports or should attempt to load. + * @property {Boolean} virtualMode + * Indicates, that the tiles are not retrieved from a server but provided on the client side. */ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLevel ) { var _this = this, From 77a3ef881b8d14051fb6529de2dc76c6f1125c65 Mon Sep 17 00:00:00 2001 From: cskwg Date: Tue, 11 Jun 2013 20:34:21 +0200 Subject: [PATCH 9/9] Update navigator.js Changed style.opacity back to its previous value. --- src/navigator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/navigator.js b/src/navigator.js index fa3a301c..54d1f73d 100644 --- a/src/navigator.js +++ b/src/navigator.js @@ -102,7 +102,7 @@ $.Navigator = function( options ){ style.border = borderWidth + 'px solid #555'; style.padding = '0px'; style.background = '#000'; - style.opacity = 1.0; + style.opacity = 0.8; style.overflow = 'hidden'; }( this.element.style, this.borderWidth));