Add slideshow for images

This commit is contained in:
Frederic Guillot 2016-12-11 18:37:40 -05:00
parent ffb3926178
commit a3d1ce47d3
9 changed files with 220 additions and 5 deletions

View File

@ -3,6 +3,8 @@ Version 1.0.36 (unreleased)
New features:
* Add slideshow for images
Improvements:
* Replace Chosen jQuery plugin by custom UI component

View File

@ -2,7 +2,16 @@
<div class="file-thumbnails">
<?php foreach ($images as $file): ?>
<div class="file-thumbnail">
<a href="<?= $this->url->href('FileViewerController', 'show', array('project_id' => $project['id'], 'file_id' => $file['id'])) ?>" class="popover"><img src="<?= $this->url->href('FileViewerController', 'thumbnail', array('file_id' => $file['id'], 'project_id' => $project['id'])) ?>" title="<?= $this->text->e($file['name']) ?>" alt="<?= $this->text->e($file['name']) ?>"></a>
<?= $this->app->component('image-slideshow', array(
'images' => $images,
'image' => $file,
'regex' => 'FILE_ID',
'url' => array(
'image' => $this->url->to('FileViewerController', 'image', array('file_id' => 'FILE_ID', 'project_id' => $project['id'])),
'thumbnail' => $this->url->to('FileViewerController', 'thumbnail', array('file_id' => 'FILE_ID', 'project_id' => $project['id'])),
)
)) ?>
<div class="file-thumbnail-content">
<div class="file-thumbnail-title">
<div class="dropdown">

View File

@ -2,7 +2,16 @@
<div class="file-thumbnails">
<?php foreach ($images as $file): ?>
<div class="file-thumbnail">
<a href="<?= $this->url->href('FileViewerController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?>" class="popover"><img src="<?= $this->url->href('FileViewerController', 'thumbnail', array('file_id' => $file['id'], 'project_id' => $task['project_id'], 'task_id' => $file['task_id'])) ?>" title="<?= $this->text->e($file['name']) ?>" alt="<?= $this->text->e($file['name']) ?>"></a>
<?= $this->app->component('image-slideshow', array(
'images' => $images,
'image' => $file,
'regex' => 'FILE_ID',
'url' => array(
'image' => $this->url->to('FileViewerController', 'image', array('file_id' => 'FILE_ID', 'project_id' => $task['project_id'], 'task_id' => $task['id'])),
'thumbnail' => $this->url->to('FileViewerController', 'thumbnail', array('file_id' => 'FILE_ID', 'project_id' => $task['project_id'], 'task_id' => $task['id'])),
)
)) ?>
<div class="file-thumbnail-content">
<div class="file-thumbnail-title">
<div class="dropdown">

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,153 @@
KB.component('image-slideshow', function (containerElement, options) {
var currentImage;
function onKeyDown(e) {
switch (e.keyCode) {
case 27:
destroySlide();
break;
case 39:
renderNextSlide();
break;
case 37:
renderPreviousSlide();
break;
}
}
function onOverlayClick(element) {
if (element.matches('.slideshow-next-icon')) {
renderNextSlide();
} else if (element.matches('.slideshow-previous-icon')) {
renderPreviousSlide();
} else {
destroySlide();
}
}
function onClick(element) {
var imageId = KB.dom(element).data('imageId');
var image = getImage(imageId);
renderSlide(image);
}
function renderNextSlide() {
destroySlide();
for (var i = 0; i < options.images.length; i++) {
if (options.images[i].id === currentImage.id) {
var index = i + 1;
if (index >= options.images.length) {
index = 0;
}
currentImage = options.images[index];
break;
}
}
renderSlide();
}
function renderPreviousSlide() {
destroySlide();
for (var i = 0; i < options.images.length; i++) {
if (options.images[i].id === currentImage.id) {
var index = i - 1;
if (index < 0) {
index = options.images.length - 1;
}
currentImage = options.images[index];
break;
}
}
renderSlide();
}
function renderSlide() {
var closeElement = KB.dom('div')
.attr('class', 'fa fa-window-close slideshow-icon slideshow-close-icon')
.build();
var previousElement = KB.dom('div')
.attr('class', 'fa fa-chevron-circle-left slideshow-icon slideshow-previous-icon')
.build();
var nextElement = KB.dom('div')
.attr('class', 'fa fa-chevron-circle-right slideshow-icon slideshow-next-icon')
.build();
var imageElement = KB.dom('img')
.attr('src', getUrl(currentImage, 'image'))
.attr('alt', currentImage.name)
.attr('title', currentImage.name)
.style('maxHeight', (window.innerHeight - 50) + 'px')
.build();
var captionElement = KB.dom('figcaption')
.text(currentImage.name)
.build();
var figureElement = KB.dom('figure')
.add(imageElement)
.add(captionElement)
.build();
var overlayElement = KB.dom('div')
.addClass('image-slideshow-overlay')
.add(closeElement)
.add(previousElement)
.add(nextElement)
.add(figureElement)
.click(onOverlayClick)
.build();
document.body.appendChild(overlayElement);
document.addEventListener('keydown', onKeyDown, false);
}
function destroySlide() {
var overlayElement = KB.find('.image-slideshow-overlay');
if (overlayElement !== null) {
document.removeEventListener('keydown', onKeyDown, false);
overlayElement.remove();
}
}
function getImage(imageId) {
for (var i = 0; i < options.images.length; i++) {
if (options.images[i].id === imageId) {
return options.images[i];
}
}
return null;
}
function getUrl(image, type) {
var regex = new RegExp(options.regex, 'g');
return options.url[type].replace(regex, image.id);
}
function buildThumbnailElement(image) {
return KB.dom('img')
.attr('src', getUrl(image, 'thumbnail'))
.attr('alt', image.name)
.attr('title', image.name)
.data('imageId', image.id)
.click(onClick)
.build();
}
this.render = function () {
currentImage = options.image;
containerElement.appendChild(buildThumbnailElement(currentImage));
};
});

View File

@ -0,0 +1,40 @@
.image-slideshow-overlay
position: fixed
top: 0
left: 0
width: 100%
height: 100%
background: rgba(0, 0, 0, 0.95)
overflow: auto
z-index: 100
img
display: block
margin: auto
figcaption
color: #fff
opacity: 0.7
position: absolute
bottom: 5px
right: 15px
.slideshow-icon
color: #fff
position: absolute
font-size: 2.5em
opacity: 0.6
&:hover
opacity: 0.9
cursor: pointer
.slideshow-previous-icon
left: 10px
top: 45%
.slideshow-next-icon
right: 10px
top: 45%
.slideshow-close-icon
right: 10px
top: 10px
font-size: 1.4em

View File

@ -15,6 +15,7 @@
box-shadow: 4px 2px 10px -6px rgba(0, 0, 0, 0.55)
margin-right: 15px
img
cursor: pointer
border-top-left-radius: 5px
border-top-right-radius: 5px
&:hover

View File

@ -52,3 +52,4 @@
@import activity_stream
@import gantt_chart
@import user_mentions
@import image_slideshow