From fc56c4e2efc6a0130b36f96e7ef327cf10184a57 Mon Sep 17 00:00:00 2001 From: Philip Giuliani Date: Wed, 8 Apr 2015 20:13:56 +0200 Subject: [PATCH 01/18] Add method to draw a placeholder --- src/drawer.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/drawer.js b/src/drawer.js index 1f18f102..b8d87aba 100644 --- a/src/drawer.js +++ b/src/drawer.js @@ -287,6 +287,16 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{ this.context.clip(); }, + // private + drawPlaceholder: function(rect) { + if (!this.useCanvas) { + return; + } + + this.context.fillRect(rect.x, rect.y, rect.width, rect.height); + this.context.fillStyle = "#000000"; + }, + // private drawDebugInfo: function( tile, count, i ){ if ( this.useCanvas ) { From 67785336423d05524cd7cce32e3f870ce912d94e Mon Sep 17 00:00:00 2001 From: Philip Giuliani Date: Wed, 8 Apr 2015 20:14:13 +0200 Subject: [PATCH 02/18] Call drawPlaceholder when no tiles are drawn --- src/tiledimage.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/tiledimage.js b/src/tiledimage.js index 405989b7..48ed29b1 100644 --- a/src/tiledimage.js +++ b/src/tiledimage.js @@ -1157,7 +1157,7 @@ function drawTiles( tiledImage, lastDrawn ){ position, tileSource; - var usedClip = false; + var needsRestore = false; if (tiledImage._clip) { tiledImage._drawer.saveContext(); var box = tiledImage.imageToViewportRectangle(tiledImage._clip, true); @@ -1168,7 +1168,20 @@ function drawTiles( tiledImage, lastDrawn ){ size.x * $.pixelDensityRatio, size.y * $.pixelDensityRatio); tiledImage._drawer.setClip(box); - usedClip = true; + needsRestore = true; + } + + if ( lastDrawn.length === 0 ) { + tiledImage._drawer.saveContext(); + var box = tiledImage.getBounds(true); + var topLeft = tiledImage.viewport.pixelFromPoint(box.getTopLeft(), true); + var size = tiledImage.viewport.deltaPixelsFromPoints(box.getSize(), true); + box = new OpenSeadragon.Rect(topLeft.x * $.pixelDensityRatio, + topLeft.y * $.pixelDensityRatio, + size.x * $.pixelDensityRatio, + size.y * $.pixelDensityRatio); + tiledImage._drawer.drawPlaceholder(box); + needsRestore = true; } for ( i = lastDrawn.length - 1; i >= 0; i-- ) { @@ -1203,7 +1216,7 @@ function drawTiles( tiledImage, lastDrawn ){ } } - if (usedClip) { + if ( needsRestore ) { tiledImage._drawer.restoreContext(); } } From 50e46b104e0e4c4f5ab06030fdd44fa9311829f7 Mon Sep 17 00:00:00 2001 From: Philip Giuliani Date: Wed, 8 Apr 2015 21:45:38 +0200 Subject: [PATCH 03/18] Extract rect calculation --- src/tiledimage.js | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/tiledimage.js b/src/tiledimage.js index 48ed29b1..464f2477 100644 --- a/src/tiledimage.js +++ b/src/tiledimage.js @@ -1155,32 +1155,36 @@ function drawTiles( tiledImage, lastDrawn ){ viewer, viewport, position, - tileSource; + tileSource, + needsRestore = false; - var needsRestore = false; - if (tiledImage._clip) { - tiledImage._drawer.saveContext(); - var box = tiledImage.imageToViewportRectangle(tiledImage._clip, true); + // TODO: Move this function + var boxToDrawerRectangle = function( box ) { var topLeft = tiledImage.viewport.pixelFromPoint(box.getTopLeft(), true); var size = tiledImage.viewport.deltaPixelsFromPoints(box.getSize(), true); - box = new OpenSeadragon.Rect(topLeft.x * $.pixelDensityRatio, + + return new $.Rect( + topLeft.x * $.pixelDensityRatio, topLeft.y * $.pixelDensityRatio, - size.x * $.pixelDensityRatio, - size.y * $.pixelDensityRatio); - tiledImage._drawer.setClip(box); + size.x * $.pixelDensityRatio, + size.y * $.pixelDensityRatio + ); + }; + + if ( tiledImage._clip ) { + tiledImage._drawer.saveContext(); + var box = tiledImage.imageToViewportRectangle(tiledImage._clip, true); + var clipRect = boxToDrawerRectangle(box); + + tiledImage._drawer.setClip(clipRect); needsRestore = true; } if ( lastDrawn.length === 0 ) { tiledImage._drawer.saveContext(); - var box = tiledImage.getBounds(true); - var topLeft = tiledImage.viewport.pixelFromPoint(box.getTopLeft(), true); - var size = tiledImage.viewport.deltaPixelsFromPoints(box.getSize(), true); - box = new OpenSeadragon.Rect(topLeft.x * $.pixelDensityRatio, - topLeft.y * $.pixelDensityRatio, - size.x * $.pixelDensityRatio, - size.y * $.pixelDensityRatio); - tiledImage._drawer.drawPlaceholder(box); + var placeholderRect = boxToDrawerRectangle( tiledImage.getBounds(true) ); + + tiledImage._drawer.drawPlaceholder(placeholderRect); needsRestore = true; } @@ -1189,10 +1193,10 @@ function drawTiles( tiledImage, lastDrawn ){ tiledImage._drawer.drawTile( tile, tiledImage._drawingHandler ); tile.beingDrawn = true; - if( tiledImage.debugMode ){ - try{ + if( tiledImage.debugMode ) { + try { tiledImage._drawer.drawDebugInfo( tile, lastDrawn.length, i ); - }catch(e){ + } catch(e) { $.console.error(e); } } From 4523454ff1f2d41d3b39fdfc5d091bf7d95cb3f4 Mon Sep 17 00:00:00 2001 From: Philip Giuliani Date: Thu, 9 Apr 2015 13:44:55 +0200 Subject: [PATCH 04/18] Add option to define the fillStyle of the placeholder --- src/drawer.js | 4 ++-- src/openseadragon.js | 6 +++++- src/tiledimage.js | 34 ++++++++++++++++++---------------- src/viewer.js | 3 ++- 4 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/drawer.js b/src/drawer.js index b8d87aba..3ebb54ca 100644 --- a/src/drawer.js +++ b/src/drawer.js @@ -288,13 +288,13 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{ }, // private - drawPlaceholder: function(rect) { + drawPlaceholder: function(rect, fillStyle) { if (!this.useCanvas) { return; } + this.context.fillStyle = fillStyle || "#FFFFFF"; this.context.fillRect(rect.x, rect.y, rect.width, rect.height); - this.context.fillStyle = "#000000"; }, // private diff --git a/src/openseadragon.js b/src/openseadragon.js index 8d231cbe..e0ff9c9b 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -206,6 +206,9 @@ * @property {Number} [opacity=1] * Opacity of the drawer (1=opaque, 0=transparent) * + * @property {String|Object} [placeholderFillStyle=null] + * Draws a colored rectangle behind the tile if it is not loaded yet. + * * @property {Number} [degrees=0] * Initial rotation. * @@ -262,7 +265,7 @@ * Possible subproperties (Numbers, in screen coordinates): left, top, right, bottom. * * @property {Number} [imageLoaderLimit=0] - * The maximum number of image requests to make concurrently. By default + * The maximum number of image requests to make concurrently. By default * it is set to 0 allowing the browser to make the maximum number of * image requests in parallel as allowed by the browsers policy. * @@ -1017,6 +1020,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){ // APPEARANCE opacity: 1, + placeholderFillStyle: null, //REFERENCE STRIP SETTINGS showReferenceStrip: false, diff --git a/src/tiledimage.js b/src/tiledimage.js index 464f2477..14f342f0 100644 --- a/src/tiledimage.js +++ b/src/tiledimage.js @@ -65,6 +65,7 @@ * @param {Boolean} [options.alwaysBlend] - See {@link OpenSeadragon.Options}. * @param {Number} [options.minPixelRatio] - See {@link OpenSeadragon.Options}. * @param {Boolean} [options.debugMode] - See {@link OpenSeadragon.Options}. + * @param {String|Object} [options.placeholderFillStyle] - See {@link OpenSeadragon.Options}. * @param {String|Boolean} [options.crossOriginPolicy] - See {@link OpenSeadragon.Options}. */ $.TiledImage = function( options ) { @@ -126,21 +127,22 @@ $.TiledImage = function( options ) { coverage: {}, // A '3d' dictionary [level][x][y] --> Boolean. lastDrawn: [], // An unordered list of Tiles drawn last frame. lastResetTime: 0, // Last time for which the tiledImage was reset. - _midDraw: false, // Is the tiledImage currently updating the viewport? - _needsDraw: true, // Does the tiledImage need to update the viewport again? + _midDraw: false, // Is the tiledImage currently updating the viewport? + _needsDraw: true, // Does the tiledImage need to update the viewport again? //configurable settings - springStiffness: $.DEFAULT_SETTINGS.springStiffness, - animationTime: $.DEFAULT_SETTINGS.animationTime, - minZoomImageRatio: $.DEFAULT_SETTINGS.minZoomImageRatio, - wrapHorizontal: $.DEFAULT_SETTINGS.wrapHorizontal, - wrapVertical: $.DEFAULT_SETTINGS.wrapVertical, - immediateRender: $.DEFAULT_SETTINGS.immediateRender, - blendTime: $.DEFAULT_SETTINGS.blendTime, - alwaysBlend: $.DEFAULT_SETTINGS.alwaysBlend, - minPixelRatio: $.DEFAULT_SETTINGS.minPixelRatio, - debugMode: $.DEFAULT_SETTINGS.debugMode, - crossOriginPolicy: $.DEFAULT_SETTINGS.crossOriginPolicy + springStiffness: $.DEFAULT_SETTINGS.springStiffness, + animationTime: $.DEFAULT_SETTINGS.animationTime, + minZoomImageRatio: $.DEFAULT_SETTINGS.minZoomImageRatio, + wrapHorizontal: $.DEFAULT_SETTINGS.wrapHorizontal, + wrapVertical: $.DEFAULT_SETTINGS.wrapVertical, + immediateRender: $.DEFAULT_SETTINGS.immediateRender, + blendTime: $.DEFAULT_SETTINGS.blendTime, + alwaysBlend: $.DEFAULT_SETTINGS.alwaysBlend, + minPixelRatio: $.DEFAULT_SETTINGS.minPixelRatio, + debugMode: $.DEFAULT_SETTINGS.debugMode, + crossOriginPolicy: $.DEFAULT_SETTINGS.crossOriginPolicy, + placeholderFillStyle: $.DEFAULT_SETTINGS.placeholderFillStyle }, options ); @@ -1148,7 +1150,7 @@ function compareTiles( previousBest, tile ) { return previousBest; } -function drawTiles( tiledImage, lastDrawn ){ +function drawTiles( tiledImage, lastDrawn ) { var i, tile, tileKey, @@ -1180,11 +1182,11 @@ function drawTiles( tiledImage, lastDrawn ){ needsRestore = true; } - if ( lastDrawn.length === 0 ) { + if ( tiledImage.placeholderFillStyle && lastDrawn.length === 0 ) { tiledImage._drawer.saveContext(); var placeholderRect = boxToDrawerRectangle( tiledImage.getBounds(true) ); - tiledImage._drawer.drawPlaceholder(placeholderRect); + tiledImage._drawer.drawPlaceholder(placeholderRect, tiledImage.placeholderFillStyle); needsRestore = true; } diff --git a/src/viewer.js b/src/viewer.js index 7b269350..562b50b2 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -1294,7 +1294,8 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, alwaysBlend: _this.alwaysBlend, minPixelRatio: _this.minPixelRatio, crossOriginPolicy: _this.crossOriginPolicy, - debugMode: _this.debugMode + debugMode: _this.debugMode, + placeholderFillStyle: _this.placeholderFillStyle }); _this.world.addItem( tiledImage, { From da819ac15acfbb45e3c2d9b172935a941fa97bbd Mon Sep 17 00:00:00 2001 From: Philip Giuliani Date: Thu, 9 Apr 2015 14:25:07 +0200 Subject: [PATCH 05/18] Add possibility to draw gradients and images --- src/drawer.js | 8 +++++++- src/openseadragon.js | 2 +- src/tiledimage.js | 2 +- test/demo/fitboundswithconstraints.html | 8 ++++++++ 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/drawer.js b/src/drawer.js index 3ebb54ca..6d989efd 100644 --- a/src/drawer.js +++ b/src/drawer.js @@ -293,7 +293,13 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{ return; } - this.context.fillStyle = fillStyle || "#FFFFFF"; + if ( typeof fillStyle === "function" ) { + this.context.fillStyle = fillStyle(this.context); + } + else { + this.context.fillStyle = fillStyle; + } + this.context.fillRect(rect.x, rect.y, rect.width, rect.height); }, diff --git a/src/openseadragon.js b/src/openseadragon.js index e0ff9c9b..ec5b0ed5 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -206,7 +206,7 @@ * @property {Number} [opacity=1] * Opacity of the drawer (1=opaque, 0=transparent) * - * @property {String|Object} [placeholderFillStyle=null] + * @property {String|Function} [placeholderFillStyle=null] * Draws a colored rectangle behind the tile if it is not loaded yet. * * @property {Number} [degrees=0] diff --git a/src/tiledimage.js b/src/tiledimage.js index 14f342f0..c13b4568 100644 --- a/src/tiledimage.js +++ b/src/tiledimage.js @@ -65,7 +65,7 @@ * @param {Boolean} [options.alwaysBlend] - See {@link OpenSeadragon.Options}. * @param {Number} [options.minPixelRatio] - See {@link OpenSeadragon.Options}. * @param {Boolean} [options.debugMode] - See {@link OpenSeadragon.Options}. - * @param {String|Object} [options.placeholderFillStyle] - See {@link OpenSeadragon.Options}. + * @param {String|Function} [options.placeholderFillStyle] - See {@link OpenSeadragon.Options}. * @param {String|Boolean} [options.crossOriginPolicy] - See {@link OpenSeadragon.Options}. */ $.TiledImage = function( options ) { diff --git a/test/demo/fitboundswithconstraints.html b/test/demo/fitboundswithconstraints.html index 51889d88..7e9ba1bd 100644 --- a/test/demo/fitboundswithconstraints.html +++ b/test/demo/fitboundswithconstraints.html @@ -67,6 +67,14 @@ Height: 3448 } } + }, + placeholderFillStyle: "#FF0000", + placeholderFillStyle: function(context) { + var gradient = context.createLinearGradient(0,0,1000,0); + gradient.addColorStop(0,"black"); + gradient.addColorStop(1,"red"); + + return gradient; } }); _viewer.addHandler("open", function() { From 36597d50727d6bd76456cf32f630a9306c6e34fd Mon Sep 17 00:00:00 2001 From: Philip Giuliani Date: Thu, 9 Apr 2015 14:27:19 +0200 Subject: [PATCH 06/18] Revert my test --- test/demo/fitboundswithconstraints.html | 8 -------- 1 file changed, 8 deletions(-) diff --git a/test/demo/fitboundswithconstraints.html b/test/demo/fitboundswithconstraints.html index 7e9ba1bd..51889d88 100644 --- a/test/demo/fitboundswithconstraints.html +++ b/test/demo/fitboundswithconstraints.html @@ -67,14 +67,6 @@ Height: 3448 } } - }, - placeholderFillStyle: "#FF0000", - placeholderFillStyle: function(context) { - var gradient = context.createLinearGradient(0,0,1000,0); - gradient.addColorStop(0,"black"); - gradient.addColorStop(1,"red"); - - return gradient; } }); _viewer.addHandler("open", function() { From 1a230d8b9f4d532bd96de5d0df4c421aed53ad88 Mon Sep 17 00:00:00 2001 From: Philip Giuliani Date: Thu, 9 Apr 2015 19:57:28 +0200 Subject: [PATCH 07/18] Add viewportToDrawerRectangle to Drawer --- src/drawer.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/drawer.js b/src/drawer.js index 6d989efd..32c0c3d5 100644 --- a/src/drawer.js +++ b/src/drawer.js @@ -232,6 +232,22 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{ } }, + /** + * Translates from OpenSeadragon viewer rectangle to drawer rectangle. + * @param {OpenSeadragon.Rect} rectangle - The rectangle in viewport coordinate system. + */ + viewportToDrawerRectangle: function(rectangle) { + var topLeft = this.viewport.pixelFromPoint(rectangle.getTopLeft(), true); + var size = this.viewport.deltaPixelsFromPoints(rectangle.getSize(), true); + + return new $.Rect( + topLeft.x * $.pixelDensityRatio, + topLeft.y * $.pixelDensityRatio, + size.x * $.pixelDensityRatio, + size.y * $.pixelDensityRatio + ); + }, + /** * Draws the given tile. * @param {OpenSeadragon.Tile} tile - The tile to draw. From 5958c50d627592c61a6d19e0de90571a69269dbf Mon Sep 17 00:00:00 2001 From: Philip Giuliani Date: Thu, 9 Apr 2015 19:57:55 +0200 Subject: [PATCH 08/18] Update tiledImage to use the new function of the drawer --- src/tiledimage.js | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/src/tiledimage.js b/src/tiledimage.js index c13b4568..d008f6e4 100644 --- a/src/tiledimage.js +++ b/src/tiledimage.js @@ -1158,36 +1158,25 @@ function drawTiles( tiledImage, lastDrawn ) { viewport, position, tileSource, - needsRestore = false; - - // TODO: Move this function - var boxToDrawerRectangle = function( box ) { - var topLeft = tiledImage.viewport.pixelFromPoint(box.getTopLeft(), true); - var size = tiledImage.viewport.deltaPixelsFromPoints(box.getSize(), true); - - return new $.Rect( - topLeft.x * $.pixelDensityRatio, - topLeft.y * $.pixelDensityRatio, - size.x * $.pixelDensityRatio, - size.y * $.pixelDensityRatio - ); - }; + contextSaved = false; if ( tiledImage._clip ) { tiledImage._drawer.saveContext(); - var box = tiledImage.imageToViewportRectangle(tiledImage._clip, true); - var clipRect = boxToDrawerRectangle(box); + contextSaved = true; + var box = tiledImage.imageToViewportRectangle(tiledImage._clip, true); + var clipRect = tiledImage._drawer.viewportToDrawerRectangle(box); tiledImage._drawer.setClip(clipRect); - needsRestore = true; } if ( tiledImage.placeholderFillStyle && lastDrawn.length === 0 ) { - tiledImage._drawer.saveContext(); - var placeholderRect = boxToDrawerRectangle( tiledImage.getBounds(true) ); + if ( !contextSaved ) { + tiledImage._drawer.saveContext(); + contextSaved = true; + } + var placeholderRect = tiledImage._drawer.viewportToDrawerRectangle(tiledImage.getBounds(true)); tiledImage._drawer.drawPlaceholder(placeholderRect, tiledImage.placeholderFillStyle); - needsRestore = true; } for ( i = lastDrawn.length - 1; i >= 0; i-- ) { @@ -1222,7 +1211,7 @@ function drawTiles( tiledImage, lastDrawn ) { } } - if ( needsRestore ) { + if ( contextSaved ) { tiledImage._drawer.restoreContext(); } } From f8503bd6ac3cc115ab3aad58451c766bce196ed7 Mon Sep 17 00:00:00 2001 From: Philip Giuliani Date: Fri, 10 Apr 2015 14:31:08 +0200 Subject: [PATCH 09/18] Add placeholderFillStyle option to tiledImage --- src/openseadragon.js | 2 +- src/tiledimage.js | 2 +- src/viewer.js | 9 +++++++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/openseadragon.js b/src/openseadragon.js index ec5b0ed5..b46a641e 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -206,7 +206,7 @@ * @property {Number} [opacity=1] * Opacity of the drawer (1=opaque, 0=transparent) * - * @property {String|Function} [placeholderFillStyle=null] + * @property {String|CanvasGradient|CanvasPattern|Function} [placeholderFillStyle=null] * Draws a colored rectangle behind the tile if it is not loaded yet. * * @property {Number} [degrees=0] diff --git a/src/tiledimage.js b/src/tiledimage.js index d008f6e4..da40bde7 100644 --- a/src/tiledimage.js +++ b/src/tiledimage.js @@ -65,7 +65,7 @@ * @param {Boolean} [options.alwaysBlend] - See {@link OpenSeadragon.Options}. * @param {Number} [options.minPixelRatio] - See {@link OpenSeadragon.Options}. * @param {Boolean} [options.debugMode] - See {@link OpenSeadragon.Options}. - * @param {String|Function} [options.placeholderFillStyle] - See {@link OpenSeadragon.Options}. + * @param {String|CanvasGradient|CanvasPattern|Function} [options.placeholderFillStyle] - See {@link OpenSeadragon.Options}. * @param {String|Boolean} [options.crossOriginPolicy] - See {@link OpenSeadragon.Options}. */ $.TiledImage = function( options ) { diff --git a/src/viewer.js b/src/viewer.js index 562b50b2..a73ef24b 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -1206,6 +1206,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, * and "source" properties. * @param {Boolean} [options.collectionImmediately=false] If collectionMode is on, * specifies whether to snap to the new arrangement immediately or to animate to it. + * @param {String|CanvasGradient|CanvasPattern|Function} [options.placeholderFillStyle] - See {@link OpenSeadragon.Options}. * @fires OpenSeadragon.World.event:add-item * @fires OpenSeadragon.Viewer.event:add-item-failed */ @@ -1217,6 +1218,10 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, this._hideMessage(); + $.extend ( true, options, { + placeholderFillStyle: _this.placeholderFillStyle + }); + var myQueueItem = { options: options }; @@ -1284,6 +1289,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, width: queueItem.options.width, height: queueItem.options.height, clip: queueItem.options.clip, + placeholderFillStyle: queueItem.options.placeholderFillStyle, springStiffness: _this.springStiffness, animationTime: _this.animationTime, minZoomImageRatio: _this.minZoomImageRatio, @@ -1294,8 +1300,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, alwaysBlend: _this.alwaysBlend, minPixelRatio: _this.minPixelRatio, crossOriginPolicy: _this.crossOriginPolicy, - debugMode: _this.debugMode, - placeholderFillStyle: _this.placeholderFillStyle + debugMode: _this.debugMode }); _this.world.addItem( tiledImage, { From ff6e604b943eed40e3523b8cb5e2b0e1ecc3bb0c Mon Sep 17 00:00:00 2001 From: Philip Giuliani Date: Fri, 10 Apr 2015 16:20:54 +0200 Subject: [PATCH 10/18] Add comment --- src/drawer.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/drawer.js b/src/drawer.js index 32c0c3d5..c9c94214 100644 --- a/src/drawer.js +++ b/src/drawer.js @@ -235,6 +235,7 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{ /** * Translates from OpenSeadragon viewer rectangle to drawer rectangle. * @param {OpenSeadragon.Rect} rectangle - The rectangle in viewport coordinate system. + * @return {OpenSeadragon.Rect} Rectangle in drawer coordinate system. */ viewportToDrawerRectangle: function(rectangle) { var topLeft = this.viewport.pixelFromPoint(rectangle.getTopLeft(), true); From e3ae7b56f15e892085aa5d550d8e99f2172e76e9 Mon Sep 17 00:00:00 2001 From: Philip Giuliani Date: Sat, 11 Apr 2015 19:01:09 +0200 Subject: [PATCH 11/18] :docs: Document placeholderFillStyle --- src/openseadragon.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/openseadragon.js b/src/openseadragon.js index b46a641e..a73295a8 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -208,6 +208,8 @@ * * @property {String|CanvasGradient|CanvasPattern|Function} [placeholderFillStyle=null] * Draws a colored rectangle behind the tile if it is not loaded yet. + * You can pass a CSS color value like "#FF8800". + * When passing a function the canvas context is available as argument which is useful when you draw a gradient or pattern. * * @property {Number} [degrees=0] * Initial rotation. @@ -1016,10 +1018,10 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){ navigatorRotate: true, // INITIAL ROTATION - degrees: 0, + degrees: 0, // APPEARANCE - opacity: 1, + opacity: 1, placeholderFillStyle: null, //REFERENCE STRIP SETTINGS From 425acc38f9155b1bf4d69e9c47e247277492a6f4 Mon Sep 17 00:00:00 2001 From: Philip Giuliani Date: Mon, 13 Apr 2015 18:59:13 +0200 Subject: [PATCH 12/18] Fix overwriting the tiledImage options --- src/viewer.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/viewer.js b/src/viewer.js index a73ef24b..57ad0f1f 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -1218,9 +1218,9 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, this._hideMessage(); - $.extend ( true, options, { - placeholderFillStyle: _this.placeholderFillStyle - }); + if (options.placeholderFillStyle === undefined) { + options.placeholderFillStyle = this.placeholderFillStyle; + } var myQueueItem = { options: options From 3ce7024e97797fc092bfbdf617ff80f380a86e37 Mon Sep 17 00:00:00 2001 From: Philip Giuliani Date: Mon, 13 Apr 2015 19:02:04 +0200 Subject: [PATCH 13/18] Revert to usedClip --- src/tiledimage.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/tiledimage.js b/src/tiledimage.js index da40bde7..cea8d2b1 100644 --- a/src/tiledimage.js +++ b/src/tiledimage.js @@ -1160,23 +1160,24 @@ function drawTiles( tiledImage, lastDrawn ) { tileSource, contextSaved = false; + var usedClip = false; if ( tiledImage._clip ) { tiledImage._drawer.saveContext(); - contextSaved = true; var box = tiledImage.imageToViewportRectangle(tiledImage._clip, true); var clipRect = tiledImage._drawer.viewportToDrawerRectangle(box); tiledImage._drawer.setClip(clipRect); + + usedClip = true; } if ( tiledImage.placeholderFillStyle && lastDrawn.length === 0 ) { - if ( !contextSaved ) { - tiledImage._drawer.saveContext(); - contextSaved = true; - } + tiledImage._drawer.saveContext(); var placeholderRect = tiledImage._drawer.viewportToDrawerRectangle(tiledImage.getBounds(true)); tiledImage._drawer.drawPlaceholder(placeholderRect, tiledImage.placeholderFillStyle); + + tiledImage._drawer.restoreContext(); } for ( i = lastDrawn.length - 1; i >= 0; i-- ) { @@ -1211,7 +1212,7 @@ function drawTiles( tiledImage, lastDrawn ) { } } - if ( contextSaved ) { + if ( usedClip ) { tiledImage._drawer.restoreContext(); } } From 6677953d87423144b0d8679bc6ce359f3bc242ca Mon Sep 17 00:00:00 2001 From: Philip Giuliani Date: Mon, 13 Apr 2015 19:05:23 +0200 Subject: [PATCH 14/18] Save and restore inside of the drawer --- src/drawer.js | 4 +++- src/tiledimage.js | 4 ---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/drawer.js b/src/drawer.js index c9c94214..bfbc38c4 100644 --- a/src/drawer.js +++ b/src/drawer.js @@ -310,14 +310,16 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{ return; } + + this.saveContext(); if ( typeof fillStyle === "function" ) { this.context.fillStyle = fillStyle(this.context); } else { this.context.fillStyle = fillStyle; } - this.context.fillRect(rect.x, rect.y, rect.width, rect.height); + this.restoreContext(); }, // private diff --git a/src/tiledimage.js b/src/tiledimage.js index cea8d2b1..039a4f7f 100644 --- a/src/tiledimage.js +++ b/src/tiledimage.js @@ -1172,12 +1172,8 @@ function drawTiles( tiledImage, lastDrawn ) { } if ( tiledImage.placeholderFillStyle && lastDrawn.length === 0 ) { - tiledImage._drawer.saveContext(); - var placeholderRect = tiledImage._drawer.viewportToDrawerRectangle(tiledImage.getBounds(true)); tiledImage._drawer.drawPlaceholder(placeholderRect, tiledImage.placeholderFillStyle); - - tiledImage._drawer.restoreContext(); } for ( i = lastDrawn.length - 1; i >= 0; i-- ) { From 6b1580824ae4808f2966ad1aa07a12263fa9d078 Mon Sep 17 00:00:00 2001 From: Philip Giuliani Date: Tue, 14 Apr 2015 19:43:41 +0200 Subject: [PATCH 15/18] Remove contextSaved --- src/tiledimage.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tiledimage.js b/src/tiledimage.js index 039a4f7f..94c87cb1 100644 --- a/src/tiledimage.js +++ b/src/tiledimage.js @@ -1157,8 +1157,7 @@ function drawTiles( tiledImage, lastDrawn ) { viewer, viewport, position, - tileSource, - contextSaved = false; + tileSource; var usedClip = false; if ( tiledImage._clip ) { From 21d32b59f5f6e57cc6d5620f10c189bec334a5aa Mon Sep 17 00:00:00 2001 From: Philip Giuliani Date: Wed, 15 Apr 2015 13:32:41 +0200 Subject: [PATCH 16/18] Pass tiledImage and context to the placeholderFillStyle function --- src/drawer.js | 12 +++--------- src/openseadragon.js | 2 +- src/tiledimage.js | 11 ++++++++++- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/drawer.js b/src/drawer.js index bfbc38c4..a38aed0a 100644 --- a/src/drawer.js +++ b/src/drawer.js @@ -310,16 +310,10 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{ return; } - - this.saveContext(); - if ( typeof fillStyle === "function" ) { - this.context.fillStyle = fillStyle(this.context); - } - else { - this.context.fillStyle = fillStyle; - } + this.context.save(); + this.context.fillStyle = fillStyle; this.context.fillRect(rect.x, rect.y, rect.width, rect.height); - this.restoreContext(); + this.context.restore(); }, // private diff --git a/src/openseadragon.js b/src/openseadragon.js index a73295a8..3e3cffbd 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -209,7 +209,7 @@ * @property {String|CanvasGradient|CanvasPattern|Function} [placeholderFillStyle=null] * Draws a colored rectangle behind the tile if it is not loaded yet. * You can pass a CSS color value like "#FF8800". - * When passing a function the canvas context is available as argument which is useful when you draw a gradient or pattern. + * When passing a function the tiledImage and canvas context are available as argument which is useful when you draw a gradient or pattern. * * @property {Number} [degrees=0] * Initial rotation. diff --git a/src/tiledimage.js b/src/tiledimage.js index 94c87cb1..88f7857c 100644 --- a/src/tiledimage.js +++ b/src/tiledimage.js @@ -1172,7 +1172,16 @@ function drawTiles( tiledImage, lastDrawn ) { if ( tiledImage.placeholderFillStyle && lastDrawn.length === 0 ) { var placeholderRect = tiledImage._drawer.viewportToDrawerRectangle(tiledImage.getBounds(true)); - tiledImage._drawer.drawPlaceholder(placeholderRect, tiledImage.placeholderFillStyle); + + var fillStyle = null; + if ( typeof tiledImage.placeholderFillStyle === "function" ) { + fillStyle = tiledImage.placeholderFillStyle(tiledImage, tiledImage._drawer.context); + } + else { + fillStyle = tiledImage.placeholderFillStyle; + } + + tiledImage._drawer.drawPlaceholder(placeholderRect, fillStyle); } for ( i = lastDrawn.length - 1; i >= 0; i-- ) { From 9df77ee91577643ae28b50b9a02583f38682c02c Mon Sep 17 00:00:00 2001 From: Philip Giuliani Date: Wed, 15 Apr 2015 13:40:12 +0200 Subject: [PATCH 17/18] Return early in `drawDebugInfo` --- src/drawer.js | 148 +++++++++++++++++++++++++------------------------- 1 file changed, 75 insertions(+), 73 deletions(-) diff --git a/src/drawer.js b/src/drawer.js index a38aed0a..2f6cabfe 100644 --- a/src/drawer.js +++ b/src/drawer.js @@ -318,80 +318,82 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{ // private drawDebugInfo: function( tile, count, i ){ - if ( this.useCanvas ) { - this.context.save(); - this.context.lineWidth = 2 * $.pixelDensityRatio; - this.context.font = 'small-caps bold ' + (13 * $.pixelDensityRatio) + 'px arial'; - this.context.strokeStyle = this.debugGridColor; - this.context.fillStyle = this.debugGridColor; - - if ( this.viewport.degrees !== 0 ) { - this._offsetForRotation( tile, this.canvas, this.context, this.viewport.degrees ); - } - - this.context.strokeRect( - tile.position.x * $.pixelDensityRatio, - tile.position.y * $.pixelDensityRatio, - tile.size.x * $.pixelDensityRatio, - tile.size.y * $.pixelDensityRatio - ); - - var tileCenterX = (tile.position.x + (tile.size.x / 2)) * $.pixelDensityRatio; - var tileCenterY = (tile.position.y + (tile.size.y / 2)) * $.pixelDensityRatio; - - // Rotate the text the right way around. - this.context.translate( tileCenterX, tileCenterY ); - this.context.rotate( Math.PI / 180 * -this.viewport.degrees ); - this.context.translate( -tileCenterX, -tileCenterY ); - - if( tile.x === 0 && tile.y === 0 ){ - this.context.fillText( - "Zoom: " + this.viewport.getZoom(), - tile.position.x * $.pixelDensityRatio, - (tile.position.y - 30) * $.pixelDensityRatio - ); - this.context.fillText( - "Pan: " + this.viewport.getBounds().toString(), - tile.position.x * $.pixelDensityRatio, - (tile.position.y - 20) * $.pixelDensityRatio - ); - } - this.context.fillText( - "Level: " + tile.level, - (tile.position.x + 10) * $.pixelDensityRatio, - (tile.position.y + 20) * $.pixelDensityRatio - ); - this.context.fillText( - "Column: " + tile.x, - (tile.position.x + 10) * $.pixelDensityRatio, - (tile.position.y + 30) * $.pixelDensityRatio - ); - this.context.fillText( - "Row: " + tile.y, - (tile.position.x + 10) * $.pixelDensityRatio, - (tile.position.y + 40) * $.pixelDensityRatio - ); - this.context.fillText( - "Order: " + i + " of " + count, - (tile.position.x + 10) * $.pixelDensityRatio, - (tile.position.y + 50) * $.pixelDensityRatio - ); - this.context.fillText( - "Size: " + tile.size.toString(), - (tile.position.x + 10) * $.pixelDensityRatio, - (tile.position.y + 60) * $.pixelDensityRatio - ); - this.context.fillText( - "Position: " + tile.position.toString(), - (tile.position.x + 10) * $.pixelDensityRatio, - (tile.position.y + 70) * $.pixelDensityRatio - ); - - if ( this.viewport.degrees !== 0 ) { - this._restoreRotationChanges( tile, this.canvas, this.context ); - } - this.context.restore(); + if ( !this.useCanvas ) { + return; } + + this.context.save(); + this.context.lineWidth = 2 * $.pixelDensityRatio; + this.context.font = 'small-caps bold ' + (13 * $.pixelDensityRatio) + 'px arial'; + this.context.strokeStyle = this.debugGridColor; + this.context.fillStyle = this.debugGridColor; + + if ( this.viewport.degrees !== 0 ) { + this._offsetForRotation( tile, this.canvas, this.context, this.viewport.degrees ); + } + + this.context.strokeRect( + tile.position.x * $.pixelDensityRatio, + tile.position.y * $.pixelDensityRatio, + tile.size.x * $.pixelDensityRatio, + tile.size.y * $.pixelDensityRatio + ); + + var tileCenterX = (tile.position.x + (tile.size.x / 2)) * $.pixelDensityRatio; + var tileCenterY = (tile.position.y + (tile.size.y / 2)) * $.pixelDensityRatio; + + // Rotate the text the right way around. + this.context.translate( tileCenterX, tileCenterY ); + this.context.rotate( Math.PI / 180 * -this.viewport.degrees ); + this.context.translate( -tileCenterX, -tileCenterY ); + + if( tile.x === 0 && tile.y === 0 ){ + this.context.fillText( + "Zoom: " + this.viewport.getZoom(), + tile.position.x * $.pixelDensityRatio, + (tile.position.y - 30) * $.pixelDensityRatio + ); + this.context.fillText( + "Pan: " + this.viewport.getBounds().toString(), + tile.position.x * $.pixelDensityRatio, + (tile.position.y - 20) * $.pixelDensityRatio + ); + } + this.context.fillText( + "Level: " + tile.level, + (tile.position.x + 10) * $.pixelDensityRatio, + (tile.position.y + 20) * $.pixelDensityRatio + ); + this.context.fillText( + "Column: " + tile.x, + (tile.position.x + 10) * $.pixelDensityRatio, + (tile.position.y + 30) * $.pixelDensityRatio + ); + this.context.fillText( + "Row: " + tile.y, + (tile.position.x + 10) * $.pixelDensityRatio, + (tile.position.y + 40) * $.pixelDensityRatio + ); + this.context.fillText( + "Order: " + i + " of " + count, + (tile.position.x + 10) * $.pixelDensityRatio, + (tile.position.y + 50) * $.pixelDensityRatio + ); + this.context.fillText( + "Size: " + tile.size.toString(), + (tile.position.x + 10) * $.pixelDensityRatio, + (tile.position.y + 60) * $.pixelDensityRatio + ); + this.context.fillText( + "Position: " + tile.position.toString(), + (tile.position.x + 10) * $.pixelDensityRatio, + (tile.position.y + 70) * $.pixelDensityRatio + ); + + if ( this.viewport.degrees !== 0 ) { + this._restoreRotationChanges( tile, this.canvas, this.context ); + } + this.context.restore(); }, // private From 0d056145a39d1ff89885436789492a5ed246108a Mon Sep 17 00:00:00 2001 From: Philip Giuliani Date: Wed, 15 Apr 2015 18:31:56 +0200 Subject: [PATCH 18/18] :lipstick: Rename to drawRectangle --- src/drawer.js | 2 +- src/tiledimage.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/drawer.js b/src/drawer.js index 2f6cabfe..e14c14e3 100644 --- a/src/drawer.js +++ b/src/drawer.js @@ -305,7 +305,7 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{ }, // private - drawPlaceholder: function(rect, fillStyle) { + drawRectangle: function(rect, fillStyle) { if (!this.useCanvas) { return; } diff --git a/src/tiledimage.js b/src/tiledimage.js index 88f7857c..eebfa0af 100644 --- a/src/tiledimage.js +++ b/src/tiledimage.js @@ -1181,7 +1181,7 @@ function drawTiles( tiledImage, lastDrawn ) { fillStyle = tiledImage.placeholderFillStyle; } - tiledImage._drawer.drawPlaceholder(placeholderRect, fillStyle); + tiledImage._drawer.drawRectangle(placeholderRect, fillStyle); } for ( i = lastDrawn.length - 1; i >= 0; i-- ) {