Spaces:
Running
Running
| <html> | |
| <head> | |
| <title>Whole Slide Image Annotation</title> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> | |
| <link rel="stylesheet" href="node_modules/@recogito/annotorious/dist/annotorious.min.css"> | |
| <link rel="stylesheet" href="node_modules/@recogito/annotorious-selector-pack/dist/annotorious-selector-pack.min.css"> | |
| <!-- Dependencies --> | |
| <script src="node_modules/openseadragon/build/openseadragon/openseadragon.min.js"></script> | |
| <script src="node_modules/@recogito/annotorious-openseadragon/dist/openseadragon-annotorious.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/@recogito/[email protected]/dist/annotorious-toolbar.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/@recogito/[email protected]/dist/annotorious-selector-pack.min.js"></script> | |
| </head> | |
| <body> | |
| <div style="padding: 0 0em; height: 100%; background: #303030"> | |
| <div class="sidebar-left" style="float: left; width: 10%;"> | |
| <h1 style="color: white; font-size: 16px; padding: 0 1.5em;">Whole Slide Image Annotation Demo</h1> | |
| <hr style="border: 2px solid white;"> | |
| <div id="annotations-container"> | |
| <h2 style="color: white; padding: 0 0.5em; font-size: 14px;">Annotations</h2> | |
| <hr style="border: 0.25px solid white;"> | |
| <div id="annotations-list"></div> | |
| </div> | |
| </div> | |
| <div id="wsi-canvas" style="float: left; width: 80%; height: 100%; background: white;"></div> | |
| <div id="annotation-toolbar"></div> | |
| <div class="sidebar-right" style="float: right; width: 10%;"> | |
| <h2 style="color: white; padding: 0 0.5em; font-size: 14px;">Info</h2> | |
| <hr style="border: 0.25px solid white;"> | |
| <div class="position" style="color: white; padding: 0 0.5em; font-size: 14px;"></div> | |
| <hr style="border: 0.25px solid white;"> | |
| <div class="zoom" style="color: white; padding: 0 0.5em; font-size: 14px;"></div> | |
| </div> | |
| <div id="annotation_list" style="display: none;"></div> | |
| </div> | |
| <link rel="stylesheet" href="annotorious.min.css"> | |
| <script type="text/javascript"> | |
| var viewer = OpenSeadragon({ | |
| id: "wsi-canvas", | |
| prefixUrl: "node_modules/openseadragon/build/openseadragon/images/", | |
| zoomPerScroll: 2, | |
| zoomPerClick: 1, | |
| showNavigator: true, | |
| showHomeControl: false, | |
| showFullPageControl: false, | |
| showZoomControl: false, | |
| minZoomLevel: 0.25, | |
| maxZoomLevel: 40, | |
| tileSources: { | |
| Image: { | |
| xmlns: "http://schemas.microsoft.com/deepzoom/2008", | |
| Url: "A05_files/", | |
| Format: "jpeg", | |
| Overlap: "0", | |
| TileSize: "256", | |
| Size: { | |
| Height: 42625, | |
| Width: 51553 | |
| } | |
| }, | |
| overlays: [], | |
| }, | |
| }); | |
| viewer.innerTracker.keyHandler = null; | |
| var anno = OpenSeadragon.Annotorious(viewer); | |
| Annotorious.SelectorPack(anno); | |
| const toolbar = new Annotorious.Toolbar(anno, document.getElementById('annotation-toolbar')); | |
| viewer.addControl(document.getElementById("annotation-toolbar"), {anchor: OpenSeadragon.ControlAnchor.TOP_LEFT}); | |
| document.getElementById('annotation-toolbar').addEventListener('click', function(event) { | |
| event.preventDefault(); | |
| }); | |
| // Listen for annotation creation event | |
| anno.on('createAnnotation', function(annotation) { | |
| // Create a new div element for the annotation | |
| var annotationItem = document.createElement('div'); | |
| annotationItem.className = 'annotation-item'; | |
| annotationItem.style.color = 'white'; | |
| annotationItem.style.padding = '10px'; | |
| annotationItem.style.border = '1px solid white'; | |
| annotationItem.style.marginTop = '10px'; | |
| annotationItem.style.cursor = 'pointer'; | |
| annotationItem.style.fontSize = '12px'; // Set font size in pixels | |
| annotationItem.dataset.annotationId = annotation.id; | |
| // Add annotation details to the item | |
| annotationItem.innerHTML = ` | |
| ${annotation.body[0].value} | |
| `; | |
| // Add click event to make the annotation active | |
| annotationItem.addEventListener('click', function() { | |
| anno.selectAnnotation(annotation.id); | |
| }); | |
| // Append the annotation item to the annotations list in the sidebar | |
| document.getElementById('annotations-list').appendChild(annotationItem); | |
| }); | |
| // Listen for annotation deletion event | |
| anno.on('deleteAnnotation', function(annotation) { | |
| // Find the corresponding annotation item in the sidebar | |
| var annotationItems = document.querySelectorAll('.annotation-item'); | |
| annotationItems.forEach(function(item) { | |
| if (item.dataset.annotationId === annotation.id) { | |
| item.remove(); | |
| } | |
| }); | |
| }); | |
| // Disable panning when polygon tool is active | |
| anno.on('startSelection', function(event) { | |
| if (event.tool === 'polygon') { | |
| viewer.setMouseNavEnabled(false); | |
| } | |
| }); | |
| // Re-enable panning when polygon tool is deactivated | |
| anno.on('cancelSelection', function(event) { | |
| if (event.tool === 'polygon') { | |
| viewer.setMouseNavEnabled(true); | |
| } | |
| }); | |
| anno.on('createAnnotation', function(event) { | |
| if (event.tool === 'polygon') { | |
| viewer.setMouseNavEnabled(true); | |
| } | |
| }); | |
| // Add a listener to the viewer to update the position and zoom info | |
| var positionEl = document.querySelectorAll('.sidebar-right .position')[0]; | |
| var zoomEl = document.querySelectorAll('.sidebar-right .zoom')[0]; | |
| // Default values | |
| positionEl.innerHTML = 'Web:<br> (NA) <br><br>Viewport:<br> (NA) <br><br>Image:<br> (NA)'; | |
| zoomEl.innerHTML = 'Zoom:<br> NA <br><br>Image Zoom:<br> NA'; | |
| var updateZoom = function() { | |
| var zoom = viewer.viewport.getZoom(true); | |
| var imageZoom = viewer.viewport.viewportToImageZoom(zoom); | |
| zoomEl.innerHTML = 'Zoom:<br>' + (Math.round(zoom * 100) / 100) + | |
| '<br><br>Image Zoom:<br>' + (Math.round(imageZoom * 100) / 100); | |
| } | |
| viewer.addHandler('open', function() { | |
| var tracker = new OpenSeadragon.MouseTracker({ | |
| element: viewer.container, | |
| moveHandler: function(event) { | |
| var webPoint = event.position; | |
| var viewportPoint = viewer.viewport.pointFromPixel(webPoint); | |
| var imagePoint = viewer.viewport.viewportToImageCoordinates(viewportPoint); | |
| var zoom = viewer.viewport.getZoom(true); | |
| var imageZoom = viewer.viewport.viewportToImageZoom(zoom); | |
| positionEl.innerHTML = 'Web:<br>' + webPoint.toString() + | |
| '<br><br>Viewport:<br>' + viewportPoint.toString() + | |
| '<br><br>Image:<br>' + imagePoint.toString(); | |
| updateZoom(); | |
| } | |
| }); | |
| tracker.setTracking(true); | |
| viewer.addHandler('animation', updateZoom); | |
| }); | |
| </script> | |
| </body> | |
| </html> |