diff --git a/src/drawer.js b/src/drawer.js index 833d1fe6..9f92c664 100644 --- a/src/drawer.js +++ b/src/drawer.js @@ -46,10 +46,8 @@ 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 ); //console.error( 'USE_CANVAS ' + USE_CANVAS ); @@ -777,6 +775,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 +807,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 +992,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 +1164,7 @@ function drawTiles( drawer, lastDrawn ){ } else { if ( USE_CANVAS ) { - tile.drawCanvas( drawer.context ); + tile.drawCanvas( drawer.context, drawer.source ); } else { tile.drawHTML( drawer.canvas ); } diff --git a/src/navigator.js b/src/navigator.js index 833b916e..722ea49d 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 = 0.8; style.overflow = 'hidden'; }( this.element.style, this.borderWidth)); diff --git a/src/openseadragon.js b/src/openseadragon.js index 8e3b41be..a939ab53 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -1348,11 +1348,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; @@ -1644,18 +1640,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: diff --git a/src/tile.js b/src/tile.js index 527b64bc..0876fa51 100644 --- a/src/tile.js +++ b/src/tile.js @@ -111,10 +111,7 @@ $.Tile.prototype = { */ drawHTML: function( 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; } @@ -146,7 +143,7 @@ $.Tile.prototype = { * @function * @param {Canvas} context */ - drawCanvas: function( context ) { + drawCanvas: function (context, tileSource) { var position = this.position, size = this.size, @@ -154,10 +151,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; @@ -181,12 +175,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; @@ -201,10 +204,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(); diff --git a/src/tilesource.js b/src/tilesource.js index 1e6a26a4..a780891d 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. + * @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, diff --git a/src/viewer.js b/src/viewer.js index 624431e4..fb0a8836 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -1456,7 +1456,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;