Update image preview.

This commit is contained in:
Lars Jung 2015-04-04 20:20:26 +02:00
parent 0022264a8e
commit 686405142b
4 changed files with 144 additions and 70 deletions

View File

@ -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;
}
}

View File

@ -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 = '<img id="pv-img-image" class="loading"/>';
var spinnerThreshold = 200;
var currentItems, currentIdx, currentItem;
function preloadImg(src, callback) {
function requestSample(href, callback) {
var $img = $('<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) {
$('<img/>')
.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) {

View File

@ -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
},
/*

View File

@ -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);