From 686405142be421284e6978159646fff7d2eabb4c Mon Sep 17 00:00:00 2001 From: Lars Jung Date: Sat, 4 Apr 2015 20:20:26 +0200 Subject: [PATCH] Update image preview. --- src/_h5ai/client/css/inc/preview-img.less | 9 + src/_h5ai/client/js/inc/ext/preview-img.js | 181 +++++++++++++-------- src/_h5ai/conf/options.json | 4 +- src/_h5ai/server/php/inc/class-thumb.php | 20 ++- 4 files changed, 144 insertions(+), 70 deletions(-) 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);