diff --git a/src/_h5ai/client/js/inc/ext/preview.js b/src/_h5ai/client/js/inc/ext/preview.js new file mode 100644 index 00000000..bcfef0ca --- /dev/null +++ b/src/_h5ai/client/js/inc/ext/preview.js @@ -0,0 +1,247 @@ + +modulejs.define('ext/preview', ['_', '$', 'core/settings', 'core/resource', 'core/store', 'core/event', 'core/location'], function (_, $, allsettings, resource, store, event, location) { + + var settings = _.extend({ + enabled: true + }, allsettings['preview']), + + template = '
' + + '
' + + '' + + '
' + + '
' + + '' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
    ' + + '
  • ' + + '
  • ' + + '
  • ' + + '
  • ' + + '
  • ' + + '
  • ' + + '
' + + '
' + + '
', + + storekey = 'preview.isFullscreen', + + currentEntries = [], + currentIdx = 0, + isFullscreen = store.get(storekey) || false, + + adjustSize = function () { + + var rect = $(window).fracs('viewport'), + $container = $('#pv-content'), + $spinner = $('#pv-spinner'), + $spinnerimg = $spinner.find('img').width(100).height(100), + $img = $('#pv-image'), + margin = isFullscreen ? 0 : 20, + barheight = isFullscreen ? 0 : 31; + + $container.add($spinner).css({ + width: rect.width - 2 * margin, + height: rect.height - 2 * margin - barheight, + left: margin, + top: margin + }); + + var lr = ($container.width() - $img.width()) / 2, + tb = ($container.height() - $img.height()) / 2; + + $img.css({ + margin: '' + tb + 'px ' + lr + 'px' + }); + $spinnerimg.css({ + margin: '' + (($spinner.height() - $spinnerimg.height()) / 2) + 'px ' + (($spinner.width() - $spinnerimg.height()) / 2) + 'px' + }); + + rect = $img.fracs('rect'); + if (!rect) { + return; + } + rect = rect.relativeTo($('#pv-overlay').fracs('rect')); + + $('#pv-prev').css({ + left: rect.left, + top: rect.top, + width: rect.width / 2, + height: rect.height + }); + $('#pv-next').css({ + left: rect.left + rect.width / 2, + top: rect.top, + width: rect.width / 2, + height: rect.height + }); + + $('#pv-bar-percent').text('' + (100 * $img.width() / $img[0].naturalWidth).toFixed(0) + '%'); + if (isFullscreen) { + $('#pv-overlay').addClass('fullscreen'); + $('#pv-bar-fullscreen').find('img').attr('src', resource.image('preview/no-fullscreen')); + $('#pv-bottombar').fadeOut(400); + } else { + $('#pv-overlay').removeClass('fullscreen'); + $('#pv-bar-fullscreen').find('img').attr('src', resource.image('preview/fullscreen')); + $('#pv-bottombar').fadeIn(200); + } + }, + + onEnter = function (items, idx) { + + $(window).on('keydown', onKeydown); + $('#pv-image').hide(); + $('#pv-overlay').stop(true, true).fadeIn(200); + + currentEntries = items; + adjustSize(); + }, + + onNext = function () { + + if (_.isFunction(onIndexChange)) { + onIndexChange(1); + } + }, + + onPrevious = function () { + + if (_.isFunction(onIndexChange)) { + onIndexChange(-1); + } + }, + + onExit = function () { + + $(window).off('keydown', onKeydown); + $('#pv-overlay').stop(true, true).fadeOut(200); + }, + + onFullscreen = function () { + + isFullscreen = !isFullscreen; + store.put(storekey, isFullscreen); + + adjustSize(); + }, + + onKeydown = function (event) { + + var key = event.which; + + if (key === 27) { // esc + event.preventDefault(); + event.stopImmediatePropagation(); + onExit(); + } else if (key === 8 || key === 37 || key === 40) { // backspace, left, down + event.preventDefault(); + event.stopImmediatePropagation(); + onPrevious(); + } else if (key === 13 || key === 32 || key === 38 || key === 39) { // enter, space, up, right + event.preventDefault(); + event.stopImmediatePropagation(); + onNext(); + } else if (key === 70) { // f + event.preventDefault(); + event.stopImmediatePropagation(); + onFullscreen(); + } + }, + + setIndex = function (idx, total) { + + if (_.isNumber(idx)) { + $('#pv-bar-idx').show().text('' + idx + (_.isNumber(total) ? '/' + total : '')); + } else { + $('#pv-bar-idx').hide(); + } + }, + + setLabels = function (labels) { + + $('#pv-buttons .bar-left').remove(); + _.each(labels, function (label) { + + $('
  • ') + .addClass('bar-left bar-label') + .text(label) + .appendTo('#pv-buttons'); + }); + }, + + onIndexChange = null, + setOnIndexChange = function (fn) { + + onIndexChange = fn; + }, + + init = function () { + + if (!settings.enabled) { + return; + } + + $(template).appendTo('body'); + $('#pv-bar-prev, #pv-prev').on('click', onPrevious); + $('#pv-bar-next, #pv-next').on('click', onNext); + $('#pv-bar-close, #pv-close').on('click', onExit); + $('#pv-bar-fullscreen').on('click', onFullscreen); + + $('#pv-prev') + .on('mouseenter', function () { + $('#pv-bar-prev').addClass('hover'); + }) + .on('mouseleave', function () { + $('#pv-bar-prev').removeClass('hover'); + }); + + $('#pv-next') + .on('mouseenter', function () { + $('#pv-bar-next').addClass('hover'); + }) + .on('mouseleave', function () { + $('#pv-bar-next').removeClass('hover'); + }); + + $('#pv-close') + .on('mouseenter', function () { + $('#pv-bar-close').addClass('hover'); + }) + .on('mouseleave', function () { + $('#pv-bar-close').removeClass('hover'); + }); + + $('#pv-overlay') + .on('keydown', onKeydown) + .on('mousemove', function (event) { + + if (isFullscreen) { + var rect = $('#pv-overlay').fracs('rect'); + + if (rect.bottom - event.pageY < 64) { + $('#pv-bottombar').fadeIn(200); + } else { + $('#pv-bottombar').fadeOut(400); + } + } + }) + .on('click mousedown mousemove keydown keypress', function (event) { + + event.stopImmediatePropagation(); + }); + + $(window).on('resize load', adjustSize); + }; + + init(); + + return { + setIndex: setIndex, + setLabels: setLabels, + setOnIndexChange: setOnIndexChange + }; +});