diff --git a/changelog.txt b/changelog.txt
index 3ddcd4bd..e416df23 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -36,6 +36,7 @@ OPENSEADRAGON CHANGELOG
* New Viewport method for managing homeBounds as well as constraints: setHomeBounds
* Viewport.open supports positioning config properties
* For multi-image open, drawing isn't started until all tileSources have been opened
+ * You can specify a clip area for each image (only works on browsers that support the HTML5 canvas) (#594)
* Margins option to push the home region in from the edges of the Viewer (#505)
* Rect and Point toString() functions are now consistent: rounding values to nearest hundredth
* Overlays appear in the DOM immediately on open or addOverlay (#507)
diff --git a/src/drawer.js b/src/drawer.js
index 77f078ad..1f18f102 100644
--- a/src/drawer.js
+++ b/src/drawer.js
@@ -258,6 +258,35 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{
}
},
+ // private
+ saveContext: function() {
+ if (!this.useCanvas) {
+ return;
+ }
+
+ this.context.save();
+ },
+
+ // private
+ restoreContext: function() {
+ if (!this.useCanvas) {
+ return;
+ }
+
+ this.context.restore();
+ },
+
+ // private
+ setClip: function(rect) {
+ if (!this.useCanvas) {
+ return;
+ }
+
+ this.context.beginPath();
+ this.context.rect(rect.x, rect.y, rect.width, rect.height);
+ this.context.clip();
+ },
+
// private
drawDebugInfo: function( tile, count, i ){
if ( this.useCanvas ) {
diff --git a/src/tiledimage.js b/src/tiledimage.js
index 9431502a..405989b7 100644
--- a/src/tiledimage.js
+++ b/src/tiledimage.js
@@ -52,6 +52,9 @@
* @param {Number} [options.y=0] - Top position, in viewport coordinates.
* @param {Number} [options.width=1] - Width, in viewport coordinates.
* @param {Number} [options.height] - Height, in viewport coordinates.
+ * @param {OpenSeadragon.Rect} [options.clip] - An area, in image pixels, to clip to
+ * (portions of the image outside of this area will not be visible). Only works on
+ * browsers that support the HTML5 canvas.
* @param {Number} [options.springStiffness] - See {@link OpenSeadragon.Options}.
* @param {Boolean} [options.animationTime] - See {@link OpenSeadragon.Options}.
* @param {Number} [options.minZoomImageRatio] - See {@link OpenSeadragon.Options}.
@@ -72,6 +75,8 @@ $.TiledImage = function( options ) {
$.console.assert( options.viewer, "[TiledImage] options.viewer is required" );
$.console.assert( options.imageLoader, "[TiledImage] options.imageLoader is required" );
$.console.assert( options.source, "[TiledImage] options.source is required" );
+ $.console.assert(!options.clip || options.clip instanceof $.Rect,
+ "[TiledImage] options.clip must be an OpenSeadragon.Rect if present");
$.EventSource.call( this );
@@ -84,6 +89,12 @@ $.TiledImage = function( options ) {
this._imageLoader = options.imageLoader;
delete options.imageLoader;
+ if (options.clip instanceof $.Rect) {
+ this._clip = options.clip.clone();
+ }
+
+ delete options.clip;
+
var x = options.x || 0;
delete options.x;
var y = options.y || 0;
@@ -443,6 +454,36 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
this._setScale(height / this.normHeight, immediately);
},
+ /**
+ * @returns {OpenSeadragon.Rect|null} The TiledImage's current clip rectangle,
+ * in image pixels, or null if none.
+ */
+ getClip: function() {
+ if (this._clip) {
+ return this._clip.clone();
+ }
+
+ return null;
+ },
+
+ /**
+ * @param {OpenSeadragon.Rect|null} newClip - An area, in image pixels, to clip to
+ * (portions of the image outside of this area will not be visible). Only works on
+ * browsers that support the HTML5 canvas.
+ */
+ setClip: function(newClip) {
+ $.console.assert(!newClip || newClip instanceof $.Rect,
+ "[TiledImage.setClip] newClip must be an OpenSeadragon.Rect or null");
+
+ if (newClip instanceof $.Rect) {
+ this._clip = newClip.clone();
+ } else {
+ this._clip = null;
+ }
+
+ this._needsDraw = true;
+ },
+
// private
_setScale: function(scale, immediately) {
var sameTarget = (this._scaleSpring.target.value === scale);
@@ -1116,6 +1157,20 @@ function drawTiles( tiledImage, lastDrawn ){
position,
tileSource;
+ var usedClip = false;
+ if (tiledImage._clip) {
+ tiledImage._drawer.saveContext();
+ var box = tiledImage.imageToViewportRectangle(tiledImage._clip, 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.setClip(box);
+ usedClip = true;
+ }
+
for ( i = lastDrawn.length - 1; i >= 0; i-- ) {
tile = lastDrawn[ i ];
tiledImage._drawer.drawTile( tile, tiledImage._drawingHandler );
@@ -1147,6 +1202,10 @@ function drawTiles( tiledImage, lastDrawn ){
});
}
}
+
+ if (usedClip) {
+ tiledImage._drawer.restoreContext();
+ }
}
}( OpenSeadragon ));
diff --git a/src/viewer.js b/src/viewer.js
index 155174d4..7b269350 100644
--- a/src/viewer.js
+++ b/src/viewer.js
@@ -1195,6 +1195,9 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
* @param {Number} [options.y=0] The Y position for the image in viewport coordinates.
* @param {Number} [options.width=1] The width for the image in viewport coordinates.
* @param {Number} [options.height] The height for the image in viewport coordinates.
+ * @param {OpenSeadragon.Rect} [options.clip] - An area, in image pixels, to clip to
+ * (portions of the image outside of this area will not be visible). Only works on
+ * browsers that support the HTML5 canvas.
* @param {Function} [options.success] A function that gets called when the image is
* successfully added. It's passed the event object which contains a single property:
* "item", the resulting TiledImage.
@@ -1280,6 +1283,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
y: queueItem.options.y,
width: queueItem.options.width,
height: queueItem.options.height,
+ clip: queueItem.options.clip,
springStiffness: _this.springStiffness,
animationTime: _this.animationTime,
minZoomImageRatio: _this.minZoomImageRatio,
diff --git a/test/demo/m2/index.html b/test/demo/m2/index.html
index ca46fedd..fc838579 100644
--- a/test/demo/m2/index.html
+++ b/test/demo/m2/index.html
@@ -7,7 +7,7 @@
-
+