/* globals OpenSeadragon, SVG */ var ajax_url = ''; var strokeWidth = 2; var fontSize = 12; var zoomPadd = 40; $(function() { if (!$('#markers').length) { return; } // Create markers var markers = [ //{attr: { id: 'marker_circle', refX: 0, refY:0, viewBox: '-6 -6 12 12', markerUnits: 'strokeWidth' }, path: 'M 0, 0 m -5, 0 a 5,5 0 1,0 10,0 a 5,5 0 1,0 -10,0'}, //{attr: { id: 'marker_square', refX: 0, refY:0, viewBox: '-5 -5 10 10', markerUnits: 'strokeWidth' }, path: 'M 0,0 m -5,-5 L 5,-5 L 5,5 L -5,5 Z'}, {attr: { id: 'marker_arrow', refX: 5, refY:0, viewBox: '-5 -5 10 10', markerUnits: 'strokeWidth', orient: 'auto' }, path: 'M 5 5 L -5 0 L 5 -5 Z' }, {attr: { id: 'marker_stub', refX: 0, refY:0, viewBox: '-1 -5 2 10', markerUnits: 'strokeWidth' }, path: 'M 0,0 m -1,-5 L 1,-5 L 1,5 L -1,5 Z' } ]; var mrkrs = SVG('markers').size(0, 0); $.each(markers, function(k, m) { mrkrs.marker(5, 5, function(add) { add.path(m.path); }).attr(m.attr); }); // Show image $('#anatomy a, #examples a, #expression a').on('click', function() { $(this).closest('.menufix').find('.selected').removeClass('selected'); $(this).addClass('selected'); }); $(window).on('hashchange', function() { var $link = !window.location.hash? $('#examples a:first') : $('a[href="'+window.location.hash+'"]:first'); if ($link.length) { $link.trigger('click'); $.get(ajax_url+'&get_img='+$link.attr('id').replace('img_', ''), showImageWrapper, 'json'); } }).trigger('hashchange'); // Toggle channels $('body').on('click', '.channel_form button', function() { $(this).toggleClass('channel_inactive'); $.get(ajax_url+'&get_img='+$('#image_id').val()+'&channels='+getDictionaryChannels(), function(response) { var vwr = getViewer(); vwrOpen(vwr, response); }, 'json'); return false; }); // Annotation list actions $('.annot_div').on('click', 'a', annotationListAction); // Update text_div $('.text_div').on('updateText', updateText); // Click on annotation in image $('#img_div').on('click', 'g.annotation text', function() { var id = $(this).closest('g.annotation').attr('id'); $('div[name="#'+id+'"] a.label').trigger('click'); }); }); var current_image_type = ''; function showImageWrapper(response) { if (response.type === 'zarr') { $('#osdViewerWrapper').hide(); $('#codexViewerWrapper').show(); showImageZarr(response); } else { $('#osdViewerWrapper').show(); $('#codexViewerWrapper').hide(); showImage(response); } } function showImageZarr(response) { // Check if previous viwer exists & reset containers var imgDiv = $('#avivator_root').get(0); imgDiv.dataset.src = location.origin + '/' + response.url; imgDiv.channels = response.metadata.channels; $('#text_div').data('text_url', '').trigger('updateText'); if (response && response.controls) { $('#control_div').html(response.controls); } if (imgDiv.avivatorLoaded) { const event = new CustomEvent('changeImage', {detail: {url: imgDiv.dataset.src, channels: imgDiv.channels}}); imgDiv.dispatchEvent(event); } else { window.runAvivator(imgDiv.id, imgDiv.dataset.src, imgDiv.channels); imgDiv.avivatorLoaded = true; } $(imgDiv).data({ 'dictionary': response.dictionary, 'entry': response.entry }); } function showImage(response) { // Check if previous viwer exists & reset containers var vwr = getViewer(); if (vwr) { vwr.destroy(); vwr = null; } $('#img_div').html(''); $('#control_div').html(''); $('#text_div').data('text_url', '').trigger('updateText'); updateAnnotationList(vwr); if (response && response.controls) { $('#control_div').html(response.controls); } // Check if image is still in processing if (response && response.type == 'processing') { $('#img_div').html('Image still processing, please try again later.'); return; } else if (response && response.type == 'plain_image') { $('#img_div').html('<img src="'+response.url+'">'); return; } // Create openseadragon vwr = OpenSeadragon({ id: 'img_div', showHomeControl: false, showZoomControl: true, showFullPageControl: true, navigatorPosition: 'ABSOLUTE', navigatorTop: 35, navigatorLeft: 5, navigatorHeight: 120, navigatorWidth: 120, showNavigator: true, navigatorSizeRatio: 0.1, navigatorMaintainSizeRatio: true, maxZoomPixelRatio: 1, prefixUrl: "/images_static/", }); $('#img_div').data({'viewer':vwr, 'dictionary':response.dictionary, 'entry':response.entry}); if (response && response.type && response.url) { vwrOpen(vwr, response); // Add SVG overlay vwr.overlay = vwr.svgOverlay(); $(vwr.overlay.node()).parent().attr('id', 'SVGoverlay').addClass('SVGoverlay'); vwr.drawing = SVG.get('SVGoverlay'); vwr.gDrawing = vwr.drawing.select('g').first(); vwr.activeExample = null; // Zoom & Pan handler vwr.addHandler('animation', function(e) { var vwr = e.eventSource; var scale = vwr.gDrawing.transform().scaleX; var zoom = vwr.viewport.getZoom()/vwr.viewport.getMaxZoom(); // Show/hide depending on zoom vwr.gDrawing.select('g.annotation').each(function() { if (this.attr().zoom > zoom && !$('#ignore_zoom_dependent_display:checked').length) { this.hide(); } else { this.show(); } }); // Scale annot elements vwr.gDrawing.select('[stroke-width]').attr('stroke-width', strokeWidth/scale); // Scale and position text vwr.gDrawing.select('g.annotation text').each(function() { var tb = this.bbox(); var ta = this.attr(); var vpSize = getSeadragonPoint(vwr, tb.width, tb.height, true); var padX = 0.5*vpSize.y; var padY = 0.1*vpSize.y; var tx = ta.x; var bx = ta.x; var ty = ta.y + vpSize.y/1.5 + padY; var by = ta.y - padY; if (ta['text-anchor']=='start') { tx += padX/2; } else if (ta['text-anchor']=='end') { bx -= vpSize.x + padX; tx -= padX/2; } else if (ta['text-anchor']=='middle') { bx -= vpSize.x/2 + padX; } if (ta['type'] == 'arrow' || ta['type'] == 'section') { ty -= vpSize.y/2; by -= vpSize.y/2; } // text this.attr('transform', 'translate('+tx+', '+ty+') scale('+(1/scale)+')'); // background var txtBox = this.parent().select('.txtBox').first(); txtBox.attr({'x':bx, 'y':by, 'width':(vpSize.x+2*padX), 'height':(vpSize.y+2*padY)/*, 'rx':(0.2*vpSize.y), 'ry':(0.2*vpSize.y)*/}); }); }); // Use annotation list in full screen mode vwr.addHandler('pre-full-page', function(e) { if (e.fullPage) { var $div = $('<div></div>'); $('.seadragonMeta').each(function() { $(this).data('parent', $(this).parent()); $div.append($(this)); }); vwr.addControl($div[0], {anchor: OpenSeadragon.ControlAnchor.TOP_LEFT}); vwr.navigator.element.parentNode.style.width = ($('#annot_div').outerWidth()-4)+'px'; } }); vwr.addHandler('full-screen', function(e) { if (!e.fullScreen) { $('.seadragonMeta').each(function() { $(this).appendTo($(this).data('parent')); }); vwr.navigator.element.parentNode.style.width = '120px'; vwr.navigator.element.parentNode.style.width = '120px'; } vwr.raiseEvent('animation'); }); // Marking if vwr is in animation (used to wait with channel toggle until animation is finished) vwr.addHandler('animation-start', function(e) { vwr.inAnimation = true; }); vwr.addHandler('animation-finish', function(e) { vwr.inAnimation = false; }); // Go to saved zoom and pan on open (used when toggling channel in IF) vwr.addHandler('open', function(e) { if (vwr.zoom) { vwr.viewport.zoomTo(vwr.zoom, vwr.center, true); } if (vwr.center) { vwr.viewport.panTo(vwr.center, true); } }); // Add custom controls to seadragon var $div = $('<div></div>'); $('.seadragonControl').each(function() { $div.append($(this)); }); vwr.addControl($div[0], {anchor: OpenSeadragon.ControlAnchor.ABSOLUTE}); } $("div[title='Zoom in']").css({'cursor':'pointer'}); $("div[title='Zoom out']").css({'cursor':'pointer'}); $("div[title='Toggle full page']").css({'cursor':'pointer'}); if (response && response.annotations) { $.each(response.annotations.annotations, function(k, annotation) { vwr.gDrawing.svg(annotation); }); vwr.gDrawing.select('g.active').removeClass('active'); updateAnnotationList(vwr); vwr.raiseEvent('animation'); } } function goToAnnotation(vwr, annotation) { var ra, webPoint; var aa = annotation.attr(); vwr.viewport.panTo(new OpenSeadragon.Point(aa.x, aa.y), false); var zoom = aa.zoom*vwr.viewport.getMaxZoom(); if (aa.type=='rect') { ra = annotation.select('rect').first().attr(); webPoint = getSeadragonPoint(vwr, ra.width, ra.height, true, true); zoom = Math.min((vwr.viewport.containerSize.x-zoomPadd) / webPoint.x, (vwr.viewport.containerSize.y-zoomPadd) / webPoint.y); zoom = vwr.viewport.imageToViewportZoom(zoom); } else if (aa.type == 'circle') { ra = annotation.select('circle').first().attr(); webPoint = getSeadragonPoint(vwr, 2*ra.r, 0, true, true); zoom = Math.min((vwr.viewport.containerSize.x-zoomPadd) / webPoint.x, (vwr.viewport.containerSize.y-zoomPadd) / webPoint.x); zoom = vwr.viewport.imageToViewportZoom(zoom); } else if (aa.type == 'ellipse') { ra = annotation.select('ellipse').first().attr(); webPoint = getSeadragonPoint(vwr, 2*ra.rx, 2*ra.ry, true, true); zoom = Math.min((vwr.viewport.containerSize.x-zoomPadd) / webPoint.x, (vwr.viewport.containerSize.y-zoomPadd) / webPoint.y); zoom = vwr.viewport.imageToViewportZoom(zoom); } vwr.viewport.zoomTo(Math.min(zoom, vwr.viewport.getMaxZoom())); } function updateAnnotationList(vwr) { var $annot_div = $('#annot_div').html(''); if (vwr) { $(vwr.gDrawing.node).find('>g.example').each(function(k, example) { listAnnotation(vwr, $annot_div, $(example)); }); if (!vwr.activeExample) { setTimeout(function() { $annot_div.find('a[href="#goto"]:first').trigger('click'); }, 250); } } } function listAnnotation(vwr, $parent_div, $g) { var txt = $g.find('>text').html(); var id = $g.attr('id'); var eyeClass = ($g.hasClass('hidden') || $g.parents('.hidden').length || (!$g.hasClass('example') && $g.parent().hasClass('dic_hidden')))? 'fa-eye-slash' : 'fa-eye'; var $div = $('<div></div>').attr({'name':'#'+id}).addClass($g.hasClass('annotation')?'annotation':'example').appendTo($parent_div); if (vwr.activeExample && vwr.activeExample.attr('id') == id) { $div.addClass('active'); } $('<a></a>').attr({'href':'#toggle', 'class':'fa '+eyeClass, 'title':'Toggle display'}).appendTo($div)/*.trigger('click')*/; $('<a></a>').attr({'href':'#goto', 'class':'label'}).html(txt?txt:'<i>region</i>').appendTo($div); if ($g.hasClass('example')) { $parent_div = $div; } // List all sub examples and annotations $g.find('>g.annotation, >g.example').each(function(k, annotation) { listAnnotation(vwr, $parent_div, $(annotation)); }); } function annotationListAction() { var vwr = getViewer(); var annotation = vwr.gDrawing.select($(this).closest('div').attr('name')).first(); //activateExample(vwr); if ($(this).attr('href') == '#goto') { vwr.activeExample = vwr.gDrawing.select($(this).closest('div.example').attr('name')).first(); activateExample(vwr); goToAnnotation(vwr, annotation); var name = encodeURIComponent(vwr.activeExample.select('text').first().text()); var markdown_name = encodeURIComponent(getMarkdownName(vwr.activeExample.attr('id'))); var name2 = encodeURIComponent(annotation.select('text').first().text()); var markdown_name2 = (annotation.attr('id') == vwr.activeExample.attr('id'))? '' : encodeURIComponent(getMarkdownName(annotation.attr('id'))); $('#text_div').data('text_url', ajax_url+'&name='+name+'&markdown_name='+markdown_name+'&name2='+name2+'&markdown_name2='+markdown_name2).trigger('updateText'); updateAnnotationList(vwr); } else if ($(this).attr('href') == '#toggle') { annotation.toggleClass('hidden'); toggleAnnotation(annotation, annotation.hasClass("hidden")); updateAnnotationList(vwr); } else if ($(this).attr('href') == '#edit') { var txt = annotation.select('text').first(); var newTxt = prompt("Please enter annotation description", txt.text()); if (typeof newTxt == 'string') { txt.plain(newTxt); saveAnnotations(); vwr.raiseEvent('animation'); } } else if ($(this).attr('href') == '#markdown') { var win = window.open('markdown.php?markdown_name='+getMarkdownName($(this).closest('div').attr('name').replace('#', '')), 'editMarkdown', 'width=1000,height=700,resizable=1,scrollbars=1'); } /*else if ($(this).attr('href') == '#resize') { vwr.setMouseNavEnabled(false); var line = annotation.select('line').first(); line console.log(line); line.selectize().resize(); }*/ else if ($(this).attr('href') == '#moveUp') { annotation.backward(); saveAnnotations(); } else if ($(this).attr('href') == '#delete') { if (confirm('Delete annotation?')) { annotation.remove(); saveAnnotations(); } } return false; } function toggleAnnotation(annotation, hide) { annotation.select("g.annotation, g.example").each(function(k, elems) { var elem = elems[k]; if (hide) { elem.addClass("hidden"); } else { elem.removeClass("hidden"); } }); if (!hide) { annotation.parents("g.example, g.annotation").forEach(function (elem) { elem.removeClass("hidden"); }); } } function updateText() { var url; if (url = $(this).data('text_url')) { $(this).load(url); } else { $(this).html(''); } } function activateExample(vwr) { if (vwr.activeExample.hasClass('active')) { return; } vwr.gDrawing.select('g.example').removeClass('active').addClass('hidden'); $(vwr.activeExample.node).addClass('active').removeClass('hidden').removeClass('dic_hidden'); $(vwr.activeExample.node).parents('g.example').removeClass('hidden').addClass('dic_hidden'); $(vwr.activeExample.node).find('g.example').removeClass('hidden').removeClass('dic_hidden'); if ($(vwr.activeExample.node).attr('channels')) { var channels = $(vwr.activeExample.node).attr('channels').split('_'); $('.channel_form button').addClass('channel_inactive'); for (var i=0; i<channels.length; i++) { if (i < channels.length-1) { $('.channel_form button[name="'+channels[i]+'"]').removeClass('channel_inactive'); } else { $('.channel_form button[name="'+channels[i]+'"]').trigger('click'); } } } //$('#annot_div div.example').removeClass('active'); //$('#annot_div div.example[name="#'+vwr.activeExample.attr('id')+'"').addClass('active').find('>.fa-eye-slash').removeClass('fa-eye-slash').addClass('fa-eye'); } var thumbRequest = null; function setHomePosition() { var vwr = getViewer(); if (!vwr.activeExample) { alert('No active example, please create or select one.'); return false; } var center = vwr.viewport.getCenter(true); var viewportBounds = vwr.viewport.getBounds(true); var imagePoint1 = vwr.viewport.viewportToImageCoordinates(new OpenSeadragon.Point(viewportBounds.x, viewportBounds.y)); var imagePoint2 = vwr.viewport.viewportToImageCoordinates(new OpenSeadragon.Point(viewportBounds.x+viewportBounds.width, viewportBounds.y+viewportBounds.height)); var data = { 'zoom': vwr.viewport.getZoom()/vwr.viewport.getMaxZoom(), 'x': center.x, 'y': center.y, 'crop_x1': Math.round(imagePoint1.x), 'crop_y1': Math.round(imagePoint1.y), 'crop_x2': Math.round(imagePoint2.x), 'crop_y2': Math.round(imagePoint2.y), 'channels': getDictionaryChannels() }; vwr.activeExample.attr(data); /*data.crop_image_id = $('#image_id').val(); if (thumbRequest) thumbRequest.abort(); thumbRequest = $.ajax({ type: "POST", url: ajax_url, data: data, success: function(data) { console.log('thumb done'); vwr.activeExample.attr({'thumbnail':data}); saveAnnotations(); } });*/ saveAnnotations(); return false; } var saveRequest = null; function saveAnnotations() { var vwr = getViewer(); var data = {'save_image_id': $('#image_id').val(), 'image_name':$('.control_div input#image_name').val(), 'description':$('.control_div input#description').val(), 'data':{}}; if (vwr) { data.data.annotations = []; vwr.gDrawing.each(function() { data.data.annotations.push(this.svg()); }); } if (saveRequest) { saveRequest.abort(); } saveRequest = $.ajax({ type: "POST", url: ajax_url, data: data, dataType: 'json', success: function(data) { updateAnnotationList(vwr); $('#table_div tr.selected td.annotations').html(data.thumbnail_blob + $(vwr.gDrawing.node).find('g.annotation').length); } }); } function getViewer() { return $('#img_div').data('viewer'); } function vwrOpen(vwr, response) { // Wait for ongoning animation before switching images if (vwr.inAnimation) { setTimeout(function() { vwrOpen(vwr, response); }, 100); return; } vwr.center = vwr.viewport.getCenter(true); vwr.zoom = vwr.viewport.getZoom(); if (response.type == 'dzi') { vwr.open(response.url); } else { vwr.open({type:response.type, url:response.url}); } } function getMarkdownName(id) { return '/learn/dictionary/'+$('#img_div').data('dictionary')+'/'+$('#img_div').data('entry')+'/'+$('#image_id').val()+'/'+id; } function getDictionaryChannels() { var channels = []; $.each(['blue', 'red', 'green', 'yellow'], function(k, channel) { if ($('.channel_form').find('button[name='+channel+']:not(.channel_inactive)').length) { channels.push(channel); } }); return channels.join('_'); } function getSeadragonPoint(vwr, x, y, relativeZero, toImg) { var fromPoint = new OpenSeadragon.Point(x*1, y*1); var toPoint = toImg? vwr.viewport.viewportToImageCoordinates(fromPoint) : vwr.viewport.pointFromPixel(fromPoint); if (relativeZero) { var zeroPoint = getSeadragonPoint(vwr, 0, 0, false, toImg); toPoint.x -= zeroPoint.x; toPoint.y -= zeroPoint.y; } return toPoint; }