From 2d971af4458c79c9b69a3411a1623a1f75b673a4 Mon Sep 17 00:00:00 2001 From: zero41120 Date: Thu, 6 Feb 2020 13:46:14 -0800 Subject: [PATCH] 1540 Add feature to crop tiledImage with multiple polygons --- src/drawer.js | 32 ++++++++ src/tiledimage.js | 43 +++++++++++ test/demo/cropping-polygons.html | 128 +++++++++++++++++++++++++++++++ 3 files changed, 203 insertions(+) create mode 100644 test/demo/cropping-polygons.html diff --git a/src/drawer.js b/src/drawer.js index ff658aaf..4cd7ee4b 100644 --- a/src/drawer.js +++ b/src/drawer.js @@ -166,6 +166,38 @@ $.Drawer.prototype = { return this; }, + /** + * This function gets the top left point from the viewport using the pixel point + * @param {OpenSeadragon.Point} point - the pixel points to convert + */ + viewportCoordToDrawerCoord: function(point) { + var topLeft = this.viewport.pixelFromPointNoRotate(point, true); + return new $.Point( + topLeft.x * $.pixelDensityRatio, + topLeft.y * $.pixelDensityRatio + ); + }, + + /** + * This function will create multiple polygon paths on the drawing context by provided polygons, + * then clip the context to the paths. + * @param {(OpenSeadragon.Point[])[]} polygons - an array of polygons. A polygon is an array of OpenSeadragon.Point + * @param {Boolean} useSketch - Whether to use the sketch canvas or not. + */ + clipWithPolygons: function (polygons, useSketch) { + if (!this.useCanvas) { + return; + } + var context = this._getContext(useSketch); + context.beginPath(); + polygons.forEach(function (polygon) { + polygon.forEach(function (coord, i) { + context[i == 0 ? 'moveTo' : 'lineTo'](coord.x, coord.y); + }); + }); + context.clip(); + }, + /** * Set the opacity of the drawer. * @param {Number} opacity diff --git a/src/tiledimage.js b/src/tiledimage.js index 54cc84fe..2e829cd5 100644 --- a/src/tiledimage.js +++ b/src/tiledimage.js @@ -674,6 +674,27 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag this._setScale(height / this.normHeight, immediately); }, + /** + * Sets an array of polygons to crop the TiledImage during draw tiles. + * The render function will use the default non-zero winding rule. + * @param Polygons represented in an array of pair array in pixels. + * Example format: [ + * [[197,172],[226,172],[226,198],[197,198]], // First polygon + * [[328,200],[330,199],[332,201],[329,202]] // Second polygon + * ] + */ + setCroppingPolygons: function( polygons ) { + this._croppingPolygons = polygons; + }, + + /** + * Resets the cropping polygons, thus next render will remove all cropping + * polygon effects. + */ + resetCroppingPolygons: function() { + this._croppingPolygons = null; + }, + /** * Positions and scales the TiledImage to fit in the specified bounds. * Note: this method fires OpenSeadragon.TiledImage.event:bounds-change @@ -1932,6 +1953,28 @@ function drawTiles( tiledImage, lastDrawn ) { usedClip = true; } + if (tiledImage._croppingPolygons) { + tiledImage._drawer.saveContext(useSketch); + try { + var polygons = tiledImage._croppingPolygons.map(function (polygon) { + return polygon.map(function (pointPair) { + var point = tiledImage + .imageToViewportCoordinates(pointPair[0], pointPair[1], true) + .rotate(-tiledImage.getRotation(true), tiledImage._getRotationPoint(true)); + var clipPoint = tiledImage._drawer.viewportCoordToDrawerCoord(point); + if (sketchScale) { + clipPoint = clipPoint.times(sketchScale); + } + return clipPoint; + }); + }); + tiledImage._drawer.clipWithPolygons(polygons, useSketch); + } catch (e) { + $.console.error(e); + } + usedClip = true; + } + if ( tiledImage.placeholderFillStyle && tiledImage._hasOpaqueTile === false ) { var placeholderRect = tiledImage._drawer.viewportToDrawerRectangle(tiledImage.getBounds(true)); if (sketchScale) { diff --git a/test/demo/cropping-polygons.html b/test/demo/cropping-polygons.html new file mode 100644 index 00000000..0e523f4d --- /dev/null +++ b/test/demo/cropping-polygons.html @@ -0,0 +1,128 @@ + + + + OpenSeadragon Cropping PolygonList Demo + + + + + +

+ Simple demo page to show cropping with polygonList in a OpenSeadragon viewer. +

+
+ Click on Viewer to save polygon points +
+ + +
+
+ + +
+
+ + +
+ + + + + + + +