diff --git a/src/_h5ai/client/css/inc/preview-img.less b/src/_h5ai/client/css/inc/preview-img.less
index f104c786..312ce0ca 100644
--- a/src/_h5ai/client/css/inc/preview-img.less
+++ b/src/_h5ai/client/css/inc/preview-img.less
@@ -15,4 +15,13 @@
background-position: 0 0, 30px 30px;
box-shadow: 0 0 8px 2px rgba(0, 0, 0, 0.3);
+
+ &.loading {
+ opacity: 0.5;
+ margin-top: 32px;
+ width: 240px;
+ height: 240px;
+ border-radius: 1000px;
+ overflow: hidden;
+ }
}
diff --git a/src/_h5ai/client/js/inc/ext/preview-img.js b/src/_h5ai/client/js/inc/ext/preview-img.js
index 77761ec9..8ae5dda7 100644
--- a/src/_h5ai/client/js/inc/ext/preview-img.js
+++ b/src/_h5ai/client/js/inc/ext/preview-img.js
@@ -1,81 +1,128 @@
-modulejs.define('ext/preview-img', ['_', '$', 'core/settings', 'core/event', 'ext/preview'], function (_, $, allsettings, event, preview) {
+modulejs.define('ext/preview-img', ['_', '$', 'core/settings', 'core/event', 'core/server', 'ext/preview'], function (_, $, allsettings, event, server, preview) {
var settings = _.extend({
enabled: false,
+ size: null,
types: []
}, allsettings['preview-img']);
+ var templateLoading = '
';
+ var spinnerThreshold = 200;
+ var currentItems, currentIdx, currentItem;
- function preloadImg(src, callback) {
+ function requestSample(href, callback) {
- var $img = $('
')
- .one('load', function () {
+ if (!settings.size) {
+ callback(href);
+ return;
+ }
- callback($img);
- // setTimeout(function () { callback($img); }, 1000); // for testing
- })
- .attr('src', src);
+ server.request({
+ action: 'getThumbHref',
+ type: 'img',
+ href: href,
+ width: settings.size,
+ height: 0
+ }, function (json) {
+
+ callback(json && json.code === 0 ? json.absHref : null);
+ });
+ }
+
+ function showSpinner(item) {
+
+ var timeoutId;
+
+ function start() {
+
+ $('#pv-content')
+ .empty()
+ .append($(templateLoading).attr('src', item.thumbSquare))
+ .show();
+
+ onAdjustSize();
+
+ preview.setLabels([item.label]);
+ preview.showSpinner(true);
+ }
+
+ function stop() {
+
+ clearTimeout(timeoutId);
+ preview.showSpinner(false);
+ }
+
+ timeoutId = setTimeout(start, spinnerThreshold);
+ return stop;
+ }
+
+ function preloadImg(item, callback) {
+
+ var hide = showSpinner(item);
+
+ requestSample(item.absHref, function (src) {
+
+ $('
')
+ .one('load', function (ev) {
+
+ hide();
+ callback(item, ev.target);
+
+ // for testing
+ // setTimeout(function () { hide(); callback(item, ev.target); }, 1000);
+ })
+ .attr('src', src);
+ });
+ }
+
+ function onAdjustSize() {
+
+ var $content = $('#pv-content');
+ var $img = $('#pv-img-image');
+
+ if ($img.length === 0) {
+ return;
+ }
+
+ $img.css({
+ left: ($content.width() - $img.width()) * 0.5,
+ top: ($content.height() - $img.height()) * 0.5
+ });
+
+ var labels = [currentItem.label];
+ if (!settings.size) {
+ labels.push('' + $img[0].naturalWidth + 'x' + $img[0].naturalHeight);
+ labels.push('' + (100 * $img.width() / $img[0].naturalWidth).toFixed(0) + '%');
+ }
+ preview.setLabels(labels);
+ }
+
+ function onIdxChange(rel) {
+
+ currentIdx = (currentIdx + rel + currentItems.length) % currentItems.length;
+ currentItem = currentItems[currentIdx];
+
+ preview.setIndex(currentIdx + 1, currentItems.length);
+ preview.setRawLink(currentItem.absHref);
+
+ preloadImg(currentItem, function (item, preloaded_img) {
+
+ if (item !== currentItem) {
+ return;
+ }
+
+ $('#pv-content')
+ .empty()
+ .append($(preloaded_img).attr('id', 'pv-img-image'))
+ .show();
+ onAdjustSize();
+ });
}
function onEnter(items, idx) {
- var currentItems = items;
- var currentIdx = idx;
- var currentItem = items[idx];
-
- function onAdjustSize() {
-
- var $content = $('#pv-content');
- var $img = $('#pv-img-image');
-
- if ($img.length) {
-
- $img.css({
- 'left': '' + (($content.width()-$img.width())*0.5) + 'px',
- 'top': '' + (($content.height()-$img.height())*0.5) + 'px'
- });
-
- preview.setLabels([
- currentItem.label,
- '' + $img[0].naturalWidth + 'x' + $img[0].naturalHeight,
- '' + (100 * $img.width() / $img[0].naturalWidth).toFixed(0) + '%'
- ]);
- }
- }
-
- function onIdxChange(rel) {
-
- currentIdx = (currentIdx + rel + currentItems.length) % currentItems.length;
- currentItem = currentItems[currentIdx];
-
- var spinnerTimeout = setTimeout(function () { preview.showSpinner(true); }, 200);
-
- preloadImg(currentItem.absHref, function ($preloaded_img) {
-
- clearTimeout(spinnerTimeout);
- preview.showSpinner(false);
-
- $('#pv-content').fadeOut(100, function () {
-
- $('#pv-content').empty().append($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 () {
-
- 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);
- });
- });
- }
-
+ currentItems = items;
+ currentIdx = idx;
onIdxChange(0);
preview.setOnIndexChange(onIdxChange);
preview.setOnAdjustSize(onAdjustSize);
@@ -85,9 +132,9 @@ modulejs.define('ext/preview-img', ['_', '$', 'core/settings', 'core/event', 'ex
function initItem(item) {
if (item.$view && _.indexOf(settings.types, item.type) >= 0) {
- item.$view.find('a').on('click', function (event) {
+ item.$view.find('a').on('click', function (ev) {
- event.preventDefault();
+ ev.preventDefault();
var matchedEntries = _.compact(_.map($('#items .item'), function (item) {
diff --git a/src/_h5ai/conf/options.json b/src/_h5ai/conf/options.json
index e5745f13..7cf4ec09 100644
--- a/src/_h5ai/conf/options.json
+++ b/src/_h5ai/conf/options.json
@@ -202,9 +202,11 @@ Options
Show an image preview on click.
- types: array of strings
+ - size: number, sample size, or false for original size
*/
"preview-img": {
"enabled": true,
+ "size": false,
"types": ["img", "img-bmp", "img-gif", "img-ico", "img-jpg", "img-png", "img-raw"]
},
@@ -309,7 +311,7 @@ Options
"doc": ["x-pdf", "x-ps"],
"delay": 1,
"size": 240,
- "exif": true
+ "exif": false
},
/*
diff --git a/src/_h5ai/server/php/inc/class-thumb.php b/src/_h5ai/server/php/inc/class-thumb.php
index 880d0d90..68d95b58 100644
--- a/src/_h5ai/server/php/inc/class-thumb.php
+++ b/src/_h5ai/server/php/inc/class-thumb.php
@@ -63,7 +63,7 @@ class Thumb {
$et = false;
$opts = $this->app->get_options();
- if (HAS_PHP_EXIF && $opts["thumbnails"]["exif"] === true) {
+ if (HAS_PHP_EXIF && $opts["thumbnails"]["exif"] === true && $height != 0) {
$et = @exif_thumbnail($source_path);
}
if($et !== false) {
@@ -193,9 +193,23 @@ class Image {
return;
}
- $ratio = 1.0 * $width / $height;
$src_r = 1.0 * $this->width / $this->height;
+ if ($height == 0) {
+ if ($src_r >= 1) {
+ $height = 1.0 * $width / $src_r;
+ } else {
+ $height = $width;
+ $width = 1.0 * $height * $src_r;
+ }
+ if ($width > $this->width) {
+ $width = $this->width;
+ $height = $this->height;
+ }
+ }
+
+ $ratio = 1.0 * $width / $height;
+
if ($src_r <= $ratio) {
$src_w = $this->width;
$src_h = $src_w / $ratio;
@@ -206,6 +220,8 @@ class Image {
$src_x = 0.5 * ($this->width - $src_w);
}
+ $width = intval($width);
+ $height = intval($height);
$src_x = intval($src_x);
$src_w = intval($src_w);
$src_h = intval($src_h);