diff --git a/src/_h5ai/client/css/inc/preview-img.less b/src/_h5ai/client/css/inc/preview-img.less index 2ef51489..7ca5b28a 100644 --- a/src/_h5ai/client/css/inc/preview-img.less +++ b/src/_h5ai/client/css/inc/preview-img.less @@ -1,29 +1,11 @@ -#pv-img-overlay { - display: none; - position: fixed; - left: 0; - top: 0; - right: 0; - bottom: 0; - z-index: 100; - - background-color: rgba(0,0,0,0.5); - .transition(background-color 0.3s ease-in-out); - - text-align: center; -} - -#pv-img-content, #pv-spinner { - position: fixed; -} - @check-white: #f8f8f8; @check-black: #e8e8e8; #pv-img-image { + position: absolute; + max-width: 100%; max-height: 100%; - border: 1px solid #fff; background-color: @check-white; background-image: @@ -32,98 +14,3 @@ background-size: 60px 60px; background-position: 0 0, 30px 30px } - -#pv-img-overlay.fullscreen { - background-color: #111; - - #pv-img-image { - border: 0; - } -} - -#pv-img-close { - position: fixed; - left: 0; - top: 0; - width: 100%; - height: 100%; - cursor: pointer; -} - -#pv-img-prev { - position: fixed; - cursor: pointer; -} - -#pv-img-next { - position: fixed; - cursor: pointer; -} - -#pv-img-buttons, #pv-img-topbuttons { - list-style: none; - list-style-image: none; - margin: 0; - padding: 0; - - img { - position: relative; - top: -2px; - width: 16px; - height: 16px; - } - img + span, img + input { - margin-left: 6px; - } - input { - background-color: rgba(255,255,255,0.1); - border: none; - color: #ccc; - } - - .bar-label { - display: block; - color: #ccc; - height: 30px; - line-height: 30px; - padding: 0 10px; - opacity: 0.7; - .transition(all 0.2s ease-in-out); - } - - .bar-highlight { - background-color: rgba(255,255,255,0.1); - opacity: 1.0; - } - - @bar-sep-border: 1px solid rgba(255,255,255,0.08); - - .bar-button { - .bar-label; - cursor: pointer; - &:hover, &.hover { - .bar-highlight; - } - } - - .bar-left { - float: left; - border-right: @bar-sep-border; - } - - .bar-right { - float: right; - border-left: @bar-sep-border; - } -} - -#pv-img-bottombar { - position: fixed; - z-index: 5; - width: 100%; - height: 32px; - left: 0; - bottom: 0; - background-color: rgb(27,27,27); - border-top: 1px solid rgb(45,45,45); -} diff --git a/src/_h5ai/client/css/inc/preview.less b/src/_h5ai/client/css/inc/preview.less index 79789342..3ca1895f 100644 --- a/src/_h5ai/client/css/inc/preview.less +++ b/src/_h5ai/client/css/inc/preview.less @@ -18,12 +18,23 @@ background-color: #111; } -#pv-spinner { - position: fixed; +#pv-content { + position: absolute; + overflow: hidden; } -#pv-close { - position: fixed; +#pv-spinner { + position: absolute; + + img { + width: 100px; + height: 100px; + margin: -50px -50px; + } +} + +#pv-close-area { + position: absolute; left: 0; top: 0; width: 100%; @@ -31,14 +42,32 @@ cursor: pointer; } -#pv-prev { - position: fixed; +#pv-prev-area, #pv-next-area { + position: absolute; + top: 50%; cursor: pointer; + opacity: 0.5; + .transition(all 0.2s ease-in-out); + + img { + background-color: rgba(0,0,0,0.5); + border-radius: 8px; + width: 48px; + height: 48px; + margin: -24px 0; + } + + &:hover { + opacity: 1; + } } -#pv-next { - position: fixed; - cursor: pointer; +#pv-prev-area { + left: 8px; +} + +#pv-next-area { + right: 8px; } #pv-buttons { diff --git a/src/_h5ai/client/js/inc/ext/preview-img.js b/src/_h5ai/client/js/inc/ext/preview-img.js index bf693a9b..ead5a717 100644 --- a/src/_h5ai/client/js/inc/ext/preview-img.js +++ b/src/_h5ai/client/js/inc/ext/preview-img.js @@ -1,100 +1,11 @@ -modulejs.define('ext/preview-img', ['_', '$', 'core/settings', 'core/resource', 'core/store', 'core/event', 'core/location'], function (_, $, allsettings, resource, store, event, location) { +modulejs.define('ext/preview-img', ['_', '$', 'core/settings', 'core/store', 'core/event', 'ext/preview'], function (_, $, allsettings, store, event, preview) { var settings = _.extend({ enabled: false, types: ['bmp', 'gif', 'ico', 'image', 'jpg', 'png', 'tiff'] }, allsettings['preview-img']), - template = '
' + - '
' + - '' + - '
' + - '
' + - '' + - '
' + - '
' + - '
' + - '
' + - '
' + - '
    ' + - '
  • ' + - '
  • ' + - '
  • ' + - '
  • ' + - '
  • ' + - '
  • ' + - '
  • ' + - '
  • ' + - '
  • ' + - '
' + - '
' + - '
', - - storekey = 'preview-img.isFullscreen', - - currentEntries = [], - currentIdx = 0, - isFullscreen = store.get(storekey) || false, - - adjustSize = function () { - - var rect = $(window).fracs('viewport'), - $container = $('#pv-img-content'), - $spinner = $('#pv-spinner'), - $spinnerimg = $spinner.find('img').width(100).height(100), - $img = $('#pv-img-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-img-overlay').fracs('rect')); - - $('#pv-img-prev').css({ - left: rect.left, - top: rect.top, - width: rect.width / 2, - height: rect.height - }); - $('#pv-img-next').css({ - left: rect.left + rect.width / 2, - top: rect.top, - width: rect.width / 2, - height: rect.height - }); - - $('#pv-img-bar-percent').text('' + (100 * $img.width() / $img[0].naturalWidth).toFixed(0) + '%'); - if (isFullscreen) { - $('#pv-img-overlay').addClass('fullscreen'); - $('#pv-img-bar-fullscreen').find('img').attr('src', resource.image('preview/no-fullscreen')); - $('#pv-img-bottombar').fadeOut(400); - } else { - $('#pv-img-overlay').removeClass('fullscreen'); - $('#pv-img-bar-fullscreen').find('img').attr('src', resource.image('preview/fullscreen')); - $('#pv-img-bottombar').fadeIn(200); - } - }, - preloadImg = function (src, callback) { var $img = $('') @@ -106,94 +17,69 @@ modulejs.define('ext/preview-img', ['_', '$', 'core/settings', 'core/resource', .attr('src', src); }, - onIndexChange = function (idx) { - - currentIdx = (idx + currentEntries.length) % currentEntries.length; - - var $container = $('#pv-img-content'), - $img = $('#pv-img-image'), - src = currentEntries[currentIdx].absHref, - spinnerTimeout = setTimeout(function () { $('#pv-spinner').show(); }, 200); - - preloadImg(src, function ($preloaded_img) { - - clearTimeout(spinnerTimeout); - $('#pv-spinner').hide(); - - $('#pv-img-image').fadeOut(100, function () { - - $('#pv-img-image').replaceWith($preloaded_img.hide()); - $preloaded_img.attr('id', 'pv-img-image').fadeIn(200); - - // small timeout, so $preloaded_img is visible and therefore $preloaded_img.width is available - setTimeout(function () { - - adjustSize(); - $('#pv-img-bar-label').text(currentEntries[currentIdx].label); - $('#pv-img-bar-size').text('' + $preloaded_img[0].naturalWidth + 'x' + $preloaded_img[0].naturalHeight); - $('#pv-img-bar-idx').text('' + (currentIdx + 1) + ' / ' + currentEntries.length); - $('#pv-img-bar-original').find('a').attr('href', currentEntries[currentIdx].absHref); - }, 10); - }); - }); - }, - onEnter = function (items, idx) { - $(window).on('keydown', onKeydown); - $('#pv-img-image').hide(); - $('#pv-img-overlay').stop(true, true).fadeIn(200); + var currentItems = items, + currentIdx = idx, + currentItem = items[idx], - currentEntries = items; - adjustSize(); - onIndexChange(idx); - }, + onAdjustSize = function () { - onNext = function () { + var $content = $('#pv-content'), + $img = $('#pv-img-image'); - onIndexChange(currentIdx + 1); - }, + if ($img.length) { - onPrevious = function () { + $img.css({ + 'left': '' + (($content.width()-$img.width())*0.5) + 'px', + 'top': '' + (($content.height()-$img.height())*0.5) + 'px' + }); - onIndexChange(currentIdx - 1); - }, + preview.setLabels([ + currentItem.label, + '' + $img[0].naturalWidth + 'x' + $img[0].naturalHeight, + '' + (100 * $img.width() / $img[0].naturalWidth).toFixed(0) + '%' + ]); + } + }, - onExit = function () { + onIdxChange = function (rel) { - $(window).off('keydown', onKeydown); - $('#pv-img-overlay').stop(true, true).fadeOut(200); - }, + currentIdx = (currentIdx + rel + currentItems.length) % currentItems.length; + currentItem = currentItems[currentIdx]; - onFullscreen = function () { + var spinnerTimeout = setTimeout(function () { preview.showSpinner(true); }, 200); - isFullscreen = !isFullscreen; - store.put(storekey, isFullscreen); + preloadImg(currentItem.absHref, function ($preloaded_img) { - adjustSize(); - }, + clearTimeout(spinnerTimeout); + preview.showSpinner(false); - onKeydown = function (event) { + $('#pv-content').fadeOut(100, function () { - var key = event.which; + $('#pv-content').empty().append($preloaded_img.attr('id', 'pv-img-image')).fadeIn(200); - 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(); - } + // small timeout, so $preloaded_img is visible and therefore $preloaded_img.width is available + setTimeout(function () { + + onAdjustSize(); + + preview.setIndex(currentIdx + 1, currentItems.length); + preview.setLabels([ + currentItem.label, + '' + $preloaded_img[0].naturalWidth + 'x' + $preloaded_img[0].naturalHeight, + '' + (100 * $preloaded_img.width() / $preloaded_img[0].naturalWidth).toFixed(0) + '%' + ]); + preview.setRawLink(currentItem.absHref); + }, 10); + }); + }); + }; + + onIdxChange(0); + preview.setOnIndexChange(onIdxChange); + preview.setOnAdjustSize(onAdjustSize); + preview.enter(); }, initItem = function (item) { @@ -230,59 +116,8 @@ modulejs.define('ext/preview-img', ['_', '$', 'core/settings', 'core/resource', return; } - $(template).appendTo('body'); - $('#pv-img-bar-prev, #pv-img-prev').on('click', onPrevious); - $('#pv-img-bar-next, #pv-img-next').on('click', onNext); - $('#pv-img-bar-close, #pv-img-close').on('click', onExit); - $('#pv-img-bar-fullscreen').on('click', onFullscreen); - - $('#pv-img-prev') - .on('mouseenter', function () { - $('#pv-img-bar-prev').addClass('hover'); - }) - .on('mouseleave', function () { - $('#pv-img-bar-prev').removeClass('hover'); - }); - - $('#pv-img-next') - .on('mouseenter', function () { - $('#pv-img-bar-next').addClass('hover'); - }) - .on('mouseleave', function () { - $('#pv-img-bar-next').removeClass('hover'); - }); - - $('#pv-img-close') - .on('mouseenter', function () { - $('#pv-img-bar-close').addClass('hover'); - }) - .on('mouseleave', function () { - $('#pv-img-bar-close').removeClass('hover'); - }); - - $('#pv-img-overlay') - .on('keydown', onKeydown) - .on('mousemove', function (event) { - - if (isFullscreen) { - var rect = $('#pv-img-overlay').fracs('rect'); - - if (rect.bottom - event.pageY < 64) { - $('#pv-img-bottombar').fadeIn(200); - } else { - $('#pv-img-bottombar').fadeOut(400); - } - } - }) - .on('click mousedown mousemove keydown keypress', function (event) { - - event.stopImmediatePropagation(); - }); - event.sub('location.changed', onLocationChanged); event.sub('location.refreshed', onLocationRefreshed); - - $(window).on('resize load', adjustSize); }; init(); diff --git a/src/_h5ai/client/js/inc/ext/preview.js b/src/_h5ai/client/js/inc/ext/preview.js index bcfef0ca..7e2e4016 100644 --- a/src/_h5ai/client/js/inc/ext/preview.js +++ b/src/_h5ai/client/js/inc/ext/preview.js @@ -6,19 +6,15 @@ modulejs.define('ext/preview', ['_', '$', 'core/settings', 'core/resource', 'cor }, allsettings['preview']), template = '
' + - '
' + - '' + - '
' + - '
' + - '' + - '
' + - '
' + - '
' + - '
' + + '
' + + '
' + + '
' + + '
' + + '
' + '
' + '
    ' + '
  • ' + - '
  • ' + + '
  • ' + '
  • ' + '
  • ' + '
  • ' + @@ -38,69 +34,49 @@ modulejs.define('ext/preview', ['_', '$', 'core/settings', 'core/resource', 'cor 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({ + $container.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' + $spinner.css({ + left: rect.width * 0.5, + top: rect.height * 0.5 }); - 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); + } + + if (_.isFunction(onAdjustSize)) { + onAdjustSize(1); } }, - onEnter = function (items, idx) { + onEnter = function () { $(window).on('keydown', onKeydown); - $('#pv-image').hide(); + $('#pv-content').empty(); $('#pv-overlay').stop(true, true).fadeIn(200); - currentEntries = items; adjustSize(); }, + onExit = function () { + + $(window).off('keydown', onKeydown); + $('#pv-overlay').stop(true, true).fadeOut(200); + }, + onNext = function () { if (_.isFunction(onIndexChange)) { @@ -115,10 +91,19 @@ modulejs.define('ext/preview', ['_', '$', 'core/settings', 'core/resource', 'cor } }, - onExit = function () { + fsTimer = null, + onMouseMove = function () { - $(window).off('keydown', onKeydown); - $('#pv-overlay').stop(true, true).fadeOut(200); + clearTimeout(fsTimer); + $('#pv-bottombar, #pv-prev-area, #pv-next-area').fadeIn(200); + + if (isFullscreen) { + + fsTimer = setTimeout(function () { + + $('#pv-bottombar, #pv-prev-area, #pv-next-area').fadeOut(400); + }, 2000); + } }, onFullscreen = function () { @@ -126,6 +111,7 @@ modulejs.define('ext/preview', ['_', '$', 'core/settings', 'core/resource', 'cor isFullscreen = !isFullscreen; store.put(storekey, isFullscreen); + onMouseMove(); adjustSize(); }, @@ -152,12 +138,31 @@ modulejs.define('ext/preview', ['_', '$', 'core/settings', 'core/resource', 'cor } }, + enter = function () { + + onEnter(); + }, + + exit = function () { + + onExit(); + }, + setIndex = function (idx, total) { if (_.isNumber(idx)) { - $('#pv-bar-idx').show().text('' + idx + (_.isNumber(total) ? '/' + total : '')); + $('#pv-bar-idx').text('' + idx + (_.isNumber(total) ? '/' + total : '')).show(); } else { - $('#pv-bar-idx').hide(); + $('#pv-bar-idx').text('').hide(); + } + }, + + setRawLink = function (href) { + + if (href) { + $('#pv-bar-raw').find('a').attr('href', href).end().show(); + } else { + $('#pv-bar-raw').find('a').attr('href', '#').end().hide(); } }, @@ -179,6 +184,25 @@ modulejs.define('ext/preview', ['_', '$', 'core/settings', 'core/resource', 'cor onIndexChange = fn; }, + onAdjustSize = null, + setOnAdjustSize = function (fn) { + + onAdjustSize = fn; + }, + + showSpinner = function (show, millis) { + + if (!_.isNumber(millis)) { + millis = 400; + } + + if (show) { + $('#pv-spinner').stop(true, true).fadeIn(millis); + } else { + $('#pv-spinner').stop(true, true).fadeOut(millis); + } + }, + init = function () { if (!settings.enabled) { @@ -186,12 +210,14 @@ modulejs.define('ext/preview', ['_', '$', 'core/settings', 'core/resource', 'cor } $(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-spinner').hide(); + $('#pv-bar-prev, #pv-prev-area').on('click', onPrevious); + $('#pv-bar-next, #pv-next-area').on('click', onNext); + $('#pv-bar-close, #pv-close-area').on('click', onExit); $('#pv-bar-fullscreen').on('click', onFullscreen); - $('#pv-prev') + $('#pv-prev-area') .on('mouseenter', function () { $('#pv-bar-prev').addClass('hover'); }) @@ -199,7 +225,7 @@ modulejs.define('ext/preview', ['_', '$', 'core/settings', 'core/resource', 'cor $('#pv-bar-prev').removeClass('hover'); }); - $('#pv-next') + $('#pv-next-area') .on('mouseenter', function () { $('#pv-bar-next').addClass('hover'); }) @@ -207,7 +233,7 @@ modulejs.define('ext/preview', ['_', '$', 'core/settings', 'core/resource', 'cor $('#pv-bar-next').removeClass('hover'); }); - $('#pv-close') + $('#pv-close-area') .on('mouseenter', function () { $('#pv-bar-close').addClass('hover'); }) @@ -215,20 +241,10 @@ modulejs.define('ext/preview', ['_', '$', 'core/settings', 'core/resource', 'cor $('#pv-bar-close').removeClass('hover'); }); + var fsTimer = null; $('#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('mousemove', onMouseMove) .on('click mousedown mousemove keydown keypress', function (event) { event.stopImmediatePropagation(); @@ -240,8 +256,13 @@ modulejs.define('ext/preview', ['_', '$', 'core/settings', 'core/resource', 'cor init(); return { + enter: enter, + exit: exit, setIndex: setIndex, + setRawLink: setRawLink, setLabels: setLabels, - setOnIndexChange: setOnIndexChange + setOnIndexChange: setOnIndexChange, + setOnAdjustSize: setOnAdjustSize, + showSpinner: showSpinner }; });