From 035f35a26a13888fb0b28cae31e22ac0a4a73921 Mon Sep 17 00:00:00 2001 From: Sean Nichols Date: Thu, 25 May 2017 12:10:54 -0400 Subject: [PATCH 1/2] Synchronize opacity and composite operation of TiledImages in navigator --- src/navigator.js | 20 ++++++++++ src/tiledimage.js | 4 ++ test/modules/navigator.js | 82 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+) diff --git a/src/navigator.js b/src/navigator.js index 12273b79..4c9848cf 100644 --- a/src/navigator.js +++ b/src/navigator.js @@ -347,8 +347,18 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /* _this._matchBounds(myItem, original); } + function matchOpacity() { + _this._matchOpacity(myItem, original); + } + + function matchCompositeOperation() { + _this._matchCompositeOperation(myItem, original); + } + original.addHandler('bounds-change', matchBounds); original.addHandler('clip-change', matchBounds); + original.addHandler('opacity-change', matchOpacity); + original.addHandler('composite-operation-change', matchCompositeOperation); } }); @@ -376,6 +386,16 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /* myItem.setWidth(bounds.width, immediately); myItem.setRotation(theirItem.getRotation(), immediately); myItem.setClip(theirItem.getClip()); + }, + + // private + _matchOpacity: function(myItem, theirItem) { + myItem.setOpacity(theirItem.opacity); + }, + + // private + _matchCompositeOperation: function(myItem, theirItem) { + myItem.setCompositeOperation(theirItem.compositeOperation); } }); diff --git a/src/tiledimage.js b/src/tiledimage.js index 31a763c5..def57fae 100644 --- a/src/tiledimage.js +++ b/src/tiledimage.js @@ -771,10 +771,12 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag /** * @param {Number} opacity Opacity the tiled image should be drawn at. + * @fires OpenSeadragon.TiledImage.event:opacity-change */ setOpacity: function(opacity) { this.opacity = opacity; this._needsDraw = true; + this.raiseEvent('opacity-change'); }, /** @@ -828,10 +830,12 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag /** * @param {String} compositeOperation the tiled image should be drawn with this globalCompositeOperation. + * @fires OpenSeadragon.TiledImage.event:composite-operation-change */ setCompositeOperation: function(compositeOperation) { this.compositeOperation = compositeOperation; this._needsDraw = true; + this.raiseEvent('composite-operation-change'); }, // private diff --git a/test/modules/navigator.js b/test/modules/navigator.js index c58560a6..3f75f9f4 100644 --- a/test/modules/navigator.js +++ b/test/modules/navigator.js @@ -844,6 +844,88 @@ viewer.addHandler('open', openHandler); }); + asyncTest('Item opacity is synchronized', function() { + + viewer = OpenSeadragon({ + id: 'example', + prefixUrl: '/build/openseadragon/images/', + tileSources: ['/test/data/testpattern.dzi', '/test/data/testpattern.dzi'], + springStiffness: 100, // Faster animation = faster tests + showNavigator: true + }); + + var navOpenHandler = function(event) { + if (viewer.navigator.world.getItemCount() === 2) { + viewer.navigator.world.removeHandler('add-item', navOpenHandler); + + setTimeout(function() { + // Test initial formation + for (var i = 0; i < 2; i++) { + equal(viewer.navigator.world.getItemAt(i).getOpacity(), + viewer.world.getItemAt(i).getOpacity(), 'opacity is the same'); + } + + // Try changing the opacity of one + viewer.world.getItemAt(1).setOpacity(0.5); + equal(viewer.navigator.world.getItemAt(1).getOpacity(), + viewer.world.getItemAt(1).getOpacity(), 'opacity is the same after change'); + + start(); + }, 1); + } + }; + + var openHandler = function() { + viewer.removeHandler('open', openHandler); + viewer.navigator.world.addHandler('add-item', navOpenHandler); + // The navigator may already have added the items. + navOpenHandler(); + }; + + viewer.addHandler('open', openHandler); + }); + + asyncTest('Item composite operation is synchronized', function() { + + viewer = OpenSeadragon({ + id: 'example', + prefixUrl: '/build/openseadragon/images/', + tileSources: ['/test/data/testpattern.dzi', '/test/data/testpattern.dzi'], + springStiffness: 100, // Faster animation = faster tests + showNavigator: true + }); + + var navOpenHandler = function(event) { + if (viewer.navigator.world.getItemCount() === 2) { + viewer.navigator.world.removeHandler('add-item', navOpenHandler); + + setTimeout(function() { + // Test initial formation + for (var i = 0; i < 2; i++) { + equal(viewer.navigator.world.getItemAt(i).getCompositeOperation(), + viewer.world.getItemAt(i).getCompositeOperation(), 'composite operation is the same'); + } + + // Try changing the composite operation of one + viewer.world.getItemAt(1).setCompositeOperation('multiply'); + equal(viewer.navigator.world.getItemAt(1).getCompositeOperation(), + viewer.world.getItemAt(1).getCompositeOperation(), 'composite operation is the same after change'); + + start(); + }, 1); + } + }; + + var openHandler = function() { + viewer.removeHandler('open', openHandler); + viewer.navigator.world.addHandler('add-item', navOpenHandler); + // The navigator may already have added the items. + navOpenHandler(); + }; + + viewer.addHandler('open', openHandler); + }); + asyncTest('Viewer options transmitted to navigator', function() { viewer = OpenSeadragon({ From 1fb25f3e41438dc977f30b058cfac82bec952977 Mon Sep 17 00:00:00 2001 From: Sean Nichols Date: Tue, 30 May 2017 14:52:45 -0400 Subject: [PATCH 2/2] Add documentation for opacity-change and composite-operation-change - Add early exit to setOpacity/setCompositeOperation when new value is the same as current --- src/tiledimage.js | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/tiledimage.js b/src/tiledimage.js index def57fae..d705240b 100644 --- a/src/tiledimage.js +++ b/src/tiledimage.js @@ -774,9 +774,25 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag * @fires OpenSeadragon.TiledImage.event:opacity-change */ setOpacity: function(opacity) { + if (opacity === this.opacity) { + return; + } + this.opacity = opacity; this._needsDraw = true; - this.raiseEvent('opacity-change'); + /** + * Raised when the TiledImage's opacity is changed. + * @event opacity-change + * @memberOf OpenSeadragon.TiledImage + * @type {object} + * @property {Number} opacity - The new opacity value. + * @property {OpenSeadragon.TiledImage} eventSource - A reference to the + * TiledImage which raised the event. + * @property {?Object} userData - Arbitrary subscriber-defined object. + */ + this.raiseEvent('opacity-change', { + opacity: this.opacity + }); }, /** @@ -833,9 +849,25 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag * @fires OpenSeadragon.TiledImage.event:composite-operation-change */ setCompositeOperation: function(compositeOperation) { + if (compositeOperation === this.compositeOperation) { + return; + } + this.compositeOperation = compositeOperation; this._needsDraw = true; - this.raiseEvent('composite-operation-change'); + /** + * Raised when the TiledImage's opacity is changed. + * @event composite-operation-change + * @memberOf OpenSeadragon.TiledImage + * @type {object} + * @property {String} compositeOperation - The new compositeOperation value. + * @property {OpenSeadragon.TiledImage} eventSource - A reference to the + * TiledImage which raised the event. + * @property {?Object} userData - Arbitrary subscriber-defined object. + */ + this.raiseEvent('composite-operation-change', { + compositeOperation: this.compositeOperation + }); }, // private