/* global QUnit, module, Util, $, console, test, asyncTest, start, ok, equal, testLog */ ( function() { var viewer; module( "Overlays", { setup: function() { var example = $( '
' ).appendTo( "#qunit-fixture" ); var fixedOverlay = $( '' ).appendTo( example ); fixedOverlay.width( 70 ); fixedOverlay.height( 60 ); testLog.reset(); }, teardown: function() { resetTestVariables(); } } ); var resetTestVariables = function() { if ( viewer ) { viewer.close(); } }; function waitForViewer( handler, count ) { if ( typeof count !== "number" ) { count = 0; } var ready = viewer.isOpen() && viewer.drawer !== null && !viewer.drawer.needsUpdate() && Util.equalsWithVariance( viewer.viewport.getBounds( true ).x, viewer.viewport.getBounds().x, 0.000 ) && Util.equalsWithVariance( viewer.viewport.getBounds( true ).y, viewer.viewport.getBounds().y, 0.000 ) && Util.equalsWithVariance( viewer.viewport.getBounds( true ).width, viewer.viewport.getBounds().width, 0.000 ); if ( ready ) { handler(); } else if ( count < 50 ) { count++; setTimeout( function() { waitForViewer( handler, count ); }, 100 ); } else { console.log( "waitForViewer:" + viewer.isOpen( ) + ":" + viewer.drawer + ":" + viewer.drawer.needsUpdate() ); handler(); } } asyncTest( 'Overlays via viewer options', function() { viewer = OpenSeadragon( { id: 'example-overlays', prefixUrl: '/build/openseadragon/images/', tileSources: [ '/test/data/testpattern.dzi', '/test/data/testpattern.dzi' ], springStiffness: 100, // Faster animation = faster tests overlays: [ { x: 0.1, y: 0.4, width: 0.09, height: 0.09, id: "overlay" } ] } ); viewer.addHandler( 'open', openHandler ); function openHandler() { viewer.removeHandler( 'open', openHandler ); equal( viewer.overlays.length, 1, "Global overlay should be added." ); equal( viewer.currentOverlays.length, 1, "Global overlay should be open." ); viewer.addHandler( 'open', openPageHandler ); viewer.goToPage( 1 ); } function openPageHandler() { viewer.removeHandler( 'open', openPageHandler ); equal( viewer.overlays.length, 1, "Global overlay should stay after page switch." ); equal( viewer.currentOverlays.length, 1, "Global overlay should re-open after page switch." ); viewer.addHandler( 'close', closeHandler ); viewer.close(); } function closeHandler() { viewer.removeHandler( 'close', closeHandler ); equal( viewer.overlays.length, 1, "Global overlay should not be removed on close." ); equal( viewer.currentOverlays.length, 0, "Global overlay should be closed on close." ); start(); } } ); asyncTest( 'Page Overlays via viewer options', function() { viewer = OpenSeadragon( { id: 'example-overlays', prefixUrl: '/build/openseadragon/images/', tileSources: [ { Image: { xmlns: "http://schemas.microsoft.com/deepzoom/2008", Url: "/test/data/testpattern_files/", Format: "jpg", Overlap: "1", TileSize: "254", Size: { Width: 1000, Height: 1000 } }, overlays: [ { x: 0.1, y: 0.4, width: 0.09, height: 0.09, id: "overlay" } ] }, { Image: { xmlns: "http://schemas.microsoft.com/deepzoom/2008", Url: "/test/data/testpattern_files/", Format: "jpg", Overlap: "1", TileSize: "254", Size: { Width: 1000, Height: 1000 } } } ], springStiffness: 100 // Faster animation = faster tests } ); viewer.addHandler( 'open', openHandler ); function openHandler() { viewer.removeHandler( 'open', openHandler ); equal( viewer.overlays.length, 0, "No global overlay should be added." ); equal( viewer.currentOverlays.length, 1, "Page overlay should be open." ); viewer.addHandler( 'open', openPageHandler ); viewer.goToPage( 1 ); } function openPageHandler() { viewer.removeHandler( 'open', openPageHandler ); equal( viewer.overlays.length, 0, "No global overlay should be added after page switch." ); equal( viewer.currentOverlays.length, 0, "No page overlay should be opened after page switch." ); viewer.addHandler( 'close', closeHandler ); viewer.close(); } function closeHandler() { viewer.removeHandler( 'close', closeHandler ); equal( viewer.overlays.length, 0, "No global overlay should be added on close." ); equal( viewer.currentOverlays.length, 0, "Page overlay should be closed on close." ); start(); } } ); asyncTest( 'Overlays via addOverlay method', function() { viewer = OpenSeadragon( { id: 'example-overlays', prefixUrl: '/build/openseadragon/images/', tileSources: [ '/test/data/testpattern.dzi', '/test/data/testpattern.dzi' ], springStiffness: 100 // Faster animation = faster tests } ); viewer.addHandler( 'open', openHandler ); function openHandler() { viewer.removeHandler( 'open', openHandler ); equal( viewer.overlays.length, 0, "No global overlay should be added." ); equal( viewer.currentOverlays.length, 0, "No overlay should be open." ); var rect = new OpenSeadragon.Rect( 0.1, 0.1, 0.1, 0.1 ); var overlay = $( "" ).prop( "id", "overlay" ).get( 0 ); viewer.addOverlay( overlay, rect ); equal( viewer.overlays.length, 0, "No manual overlay should be added as global overlay." ); equal( viewer.currentOverlays.length, 1, "A manual overlay should be open." ); viewer.addHandler( 'open', openPageHandler ); viewer.goToPage( 1 ); } function openPageHandler() { viewer.removeHandler( 'open', openPageHandler ); equal( viewer.overlays.length, 0, "No global overlay should be added after page switch." ); equal( viewer.currentOverlays.length, 0, "Manual overlay should be removed after page switch." ); viewer.addHandler( 'close', closeHandler ); viewer.close(); } function closeHandler() { viewer.removeHandler( 'close', closeHandler ); equal( viewer.overlays.length, 0, "No global overlay should be added on close." ); equal( viewer.currentOverlays.length, 0, "Manual overlay should be removed on close." ); start(); } } ); asyncTest( 'Overlays size in pixels', function() { viewer = OpenSeadragon( { id: 'example-overlays', prefixUrl: '/build/openseadragon/images/', tileSources: '/test/data/testpattern.dzi', springStiffness: 100, // Faster animation = faster tests overlays: [ { px: 13, py: 120, width: 124, height: 132, id: "overlay" }, { px: 400, py: 500, id: "fixed-overlay", placement: "TOP_LEFT" } ] } ); function checkOverlayPosition( contextMessage ) { var viewport = viewer.viewport; var expPosition = viewport.imageToViewerElementCoordinates( new OpenSeadragon.Point( 13, 120 ) ).apply( Math.floor ); var actPosition = $( "#overlay" ).position(); equal( actPosition.left, expPosition.x, "X position mismatch " + contextMessage ); equal( actPosition.top, expPosition.y, "Y position mismatch " + contextMessage ); var zoom = viewport.viewportToImageZoom( viewport.getZoom( true ) ); var expectedWidth = Math.ceil( 124 * zoom ); var expectedHeight = Math.ceil( 132 * zoom ); equal( $( "#overlay" ).width(), expectedWidth, "Width mismatch " + contextMessage ); equal( $( "#overlay" ).height( ), expectedHeight, "Height mismatch " + contextMessage ); expPosition = viewport.imageToViewerElementCoordinates( new OpenSeadragon.Point( 400, 500 ) ).apply( Math.floor ); actPosition = $( "#fixed-overlay" ).position(); equal( actPosition.left, expPosition.x, "Fixed overlay X position mismatch " + contextMessage ); equal( actPosition.top, expPosition.y, "Fixed overlay Y position mismatch " + contextMessage ); equal( $( "#fixed-overlay" ).width(), 70, "Fixed overlay width mismatch " + contextMessage ); equal( $( "#fixed-overlay" ).height( ), 60, "Fixed overlay height mismatch " + contextMessage ); } waitForViewer( function() { checkOverlayPosition( "after opening using image coordinates" ); viewer.viewport.zoomBy( 1.1 ).panBy( new OpenSeadragon.Point( 0.1, 0.2 ) ); waitForViewer( function() { checkOverlayPosition( "after zoom and pan using image coordinates" ); viewer.viewport.goHome(); waitForViewer( function() { checkOverlayPosition( "after goHome using image coordinates" ); start(); } ); } ); } ); } ); asyncTest( 'Overlays size in points', function() { viewer = OpenSeadragon( { id: 'example-overlays', prefixUrl: '/build/openseadragon/images/', tileSources: '/test/data/testpattern.dzi', springStiffness: 100, // Faster animation = faster tests overlays: [ { x: 0.2, y: 0.1, width: 0.5, height: 0.1, id: "overlay" }, { x: 0.5, y: 0.6, id: "fixed-overlay", placement: "TOP_LEFT" } ] } ); function checkOverlayPosition( contextMessage ) { var viewport = viewer.viewport; var expPosition = viewport.viewportToViewerElementCoordinates( new OpenSeadragon.Point( 0.2, 0.1 ) ).apply( Math.floor ); var actPosition = $( "#overlay" ).position(); equal( actPosition.left, expPosition.x, "X position mismatch " + contextMessage ); equal( actPosition.top, expPosition.y, "Y position mismatch " + contextMessage ); var expectedSize = viewport.deltaPixelsFromPoints( new OpenSeadragon.Point( 0.5, 0.1 ) ); equal( $( "#overlay" ).width(), expectedSize.x, "Width mismatch " + contextMessage ); equal( $( "#overlay" ).height(), expectedSize.y, "Height mismatch " + contextMessage ); expPosition = viewport.viewportToViewerElementCoordinates( new OpenSeadragon.Point( 0.5, 0.6 ) ).apply( Math.floor ); actPosition = $( "#fixed-overlay" ).position(); equal( actPosition.left, expPosition.x, "Fixed overlay X position mismatch " + contextMessage ); equal( actPosition.top, expPosition.y, "Fixed overlay Y position mismatch " + contextMessage ); equal( $( "#fixed-overlay" ).width(), 70, "Fixed overlay width mismatch " + contextMessage ); equal( $( "#fixed-overlay" ).height( ), 60, "Fixed overlay height mismatch " + contextMessage ); } waitForViewer( function() { checkOverlayPosition( "after opening using viewport coordinates" ); viewer.viewport.zoomBy( 1.1 ).panBy( new OpenSeadragon.Point( 0.1, 0.2 ) ); waitForViewer( function() { checkOverlayPosition( "after zoom and pan using viewport coordinates" ); viewer.viewport.goHome(); waitForViewer( function() { checkOverlayPosition( "after goHome using viewport coordinates" ); start(); } ); } ); } ); } ); asyncTest( 'Overlays placement', function() { var scalableOverlayLocation = new OpenSeadragon.Rect( 0.2, 0.1, 0.5, 0.1 ); var fixedOverlayLocation = new OpenSeadragon.Point( 0.5, 0.6 ); viewer = OpenSeadragon( { id: 'example-overlays', prefixUrl: '/build/openseadragon/images/', tileSources: '/test/data/testpattern.dzi', springStiffness: 100, // Faster animation = faster tests overlays: [ { x: scalableOverlayLocation.x, y: scalableOverlayLocation.y, width: scalableOverlayLocation.width, height: scalableOverlayLocation.height, id: "overlay", placement: "TOP_LEFT" }, { x: fixedOverlayLocation.x, y: fixedOverlayLocation.y, id: "fixed-overlay", placement: "TOP_LEFT" } ] } ); // Scalable overlays are always TOP_LEFT function checkScalableOverlayPosition( contextMessage ) { var viewport = viewer.viewport; var expPosition = viewport.viewportToViewerElementCoordinates( new OpenSeadragon.Point( 0.2, 0.1 ) ).apply( Math.floor ); var actPosition = $( "#overlay" ).position(); equal( actPosition.left, expPosition.x, "X position mismatch " + contextMessage ); equal( actPosition.top, expPosition.y, "Y position mismatch " + contextMessage ); } function checkFixedOverlayPosition( expectedOffset, contextMessage ) { var viewport = viewer.viewport; var expPosition = viewport.viewportToViewerElementCoordinates( new OpenSeadragon.Point( 0.5, 0.6 ) ) .apply( Math.floor ) .plus( expectedOffset ); var actPosition = $( "#fixed-overlay" ).position(); equal( actPosition.left, expPosition.x, "Fixed overlay X position mismatch " + contextMessage ); equal( actPosition.top, expPosition.y, "Fixed overlay Y position mismatch " + contextMessage ); } waitForViewer( function() { checkScalableOverlayPosition( "with TOP_LEFT placement." ); checkFixedOverlayPosition( new OpenSeadragon.Point( 0, 0 ), "with TOP_LEFT placement." ); viewer.updateOverlay( "overlay", scalableOverlayLocation, OpenSeadragon.OverlayPlacement.CENTER ); viewer.updateOverlay( "fixed-overlay", fixedOverlayLocation, OpenSeadragon.OverlayPlacement.CENTER ); setTimeout( function() { checkScalableOverlayPosition( "with CENTER placement." ); checkFixedOverlayPosition( new OpenSeadragon.Point( -35, -30 ), "with CENTER placement." ); viewer.updateOverlay( "overlay", scalableOverlayLocation, OpenSeadragon.OverlayPlacement.BOTTOM_RIGHT ); viewer.updateOverlay( "fixed-overlay", fixedOverlayLocation, OpenSeadragon.OverlayPlacement.BOTTOM_RIGHT ); setTimeout( function() { checkScalableOverlayPosition( "with BOTTOM_RIGHT placement." ); checkFixedOverlayPosition( new OpenSeadragon.Point( -70, -60 ), "with BOTTOM_RIGHT placement." ); start(); }, 100 ); }, 100 ); } ); } ); asyncTest( 'Overlays placement and resizing check', function() { var fixedOverlayLocation = new OpenSeadragon.Point( 0.5, 0.6 ); viewer = OpenSeadragon( { id: 'example-overlays', prefixUrl: '/build/openseadragon/images/', tileSources: '/test/data/testpattern.dzi', springStiffness: 100, // Faster animation = faster tests overlays: [ { x: fixedOverlayLocation.x, y: fixedOverlayLocation.y, id: "fixed-overlay", placement: "CENTER", checkResize: true } ] } ); function checkFixedOverlayPosition( expectedOffset, contextMessage ) { var viewport = viewer.viewport; var expPosition = viewport.viewportToViewerElementCoordinates( new OpenSeadragon.Point( 0.5, 0.6 ) ) .apply( Math.floor ) .plus( expectedOffset ); var actPosition = $( "#fixed-overlay" ).position(); equal( actPosition.left, expPosition.x, "Fixed overlay X position mismatch " + contextMessage ); equal( actPosition.top, expPosition.y, "Fixed overlay Y position mismatch " + contextMessage ); } waitForViewer( function() { checkFixedOverlayPosition( new OpenSeadragon.Point( -35, -30 ), "with overlay of size 70,60." ); $( "#fixed-overlay" ).width( 50 ); $( "#fixed-overlay" ).height( 40 ); // The resizing of the overlays is not detected by the viewer's loop. viewer.forceRedraw(); setTimeout( function() { checkFixedOverlayPosition( new OpenSeadragon.Point( -25, -20 ), "with overlay of size 50,40." ); // Restore original size $( "#fixed-overlay" ).width( 70 ); $( "#fixed-overlay" ).height( 60 ); start(); }, 100 ); } ); } ); asyncTest( 'Overlays placement and no resizing check', function() { var fixedOverlayLocation = new OpenSeadragon.Point( 0.5, 0.6 ); viewer = OpenSeadragon( { id: 'example-overlays', prefixUrl: '/build/openseadragon/images/', tileSources: '/test/data/testpattern.dzi', springStiffness: 100, // Faster animation = faster tests overlays: [ { x: fixedOverlayLocation.x, y: fixedOverlayLocation.y, id: "fixed-overlay", placement: "CENTER", checkResize: false } ] } ); function checkFixedOverlayPosition( expectedOffset, contextMessage ) { var viewport = viewer.viewport; var expPosition = viewport.viewportToViewerElementCoordinates( new OpenSeadragon.Point( 0.5, 0.6 ) ) .apply( Math.floor ) .plus( expectedOffset ); var actPosition = $( "#fixed-overlay" ).position(); equal( actPosition.left, expPosition.x, "Fixed overlay X position mismatch " + contextMessage ); equal( actPosition.top, expPosition.y, "Fixed overlay Y position mismatch " + contextMessage ); } waitForViewer( function() { checkFixedOverlayPosition( new OpenSeadragon.Point( -35, -30 ), "with overlay of size 70,60." ); $( "#fixed-overlay" ).width( 50 ); $( "#fixed-overlay" ).height( 40 ); // The resizing of the overlays is not detected by the viewer's loop. viewer.forceRedraw(); setTimeout( function() { checkFixedOverlayPosition( new OpenSeadragon.Point( -35, -30 ), "with overlay of size 50,40." ); // Restore original size $( "#fixed-overlay" ).width( 70 ); $( "#fixed-overlay" ).height( 60 ); start(); }, 100 ); } ); } ); // ---------- asyncTest('overlays appear immediately', function() { equal($('#immediate-overlay0').length, 0, 'overlay 0 does not exist'); equal($('#immediate-overlay1').length, 0, 'overlay 1 does not exist'); viewer = OpenSeadragon( { id: 'example-overlays', prefixUrl: '/build/openseadragon/images/', tileSources: '/test/data/testpattern.dzi', springStiffness: 100, // Faster animation = faster tests overlays: [ { x: 0, y: 0, id: "immediate-overlay0" } ] } ); viewer.addHandler('open', function() { equal($('#immediate-overlay0').length, 1, 'overlay 0 exists'); viewer.addOverlay( { x: 0, y: 0, id: "immediate-overlay1" } ); equal($('#immediate-overlay1').length, 1, 'overlay 1 exists'); start(); }); }); } )( );