diff --git a/example/styles/main.scss b/example/styles/main.scss index 8abce27..751e67e 100644 --- a/example/styles/main.scss +++ b/example/styles/main.scss @@ -69,3 +69,7 @@ h1 { } } } + +.image-viewer-container { + height: 100vh; +} diff --git a/example/views/image-viewer.example.jade b/example/views/image-viewer.example.jade index 05f0440..81b1356 100644 --- a/example/views/image-viewer.example.jade +++ b/example/views/image-viewer.example.jade @@ -1,4 +1,5 @@ -modal.flex.column(show="true" background-click-close=true) - image-viewer-header.flex(handle="batman" title="My Very Important Project Images" download-allowed="true") +modal(show="true" background-click-close=true) + .image-viewer-container.flex.column + image-viewer-header.flex(handle="batman" title="My Very Important Project Images" download-allowed="true") - image-slide-viewer.flex.flex-grow(files="vm.files" starting-file="vm.startingFile" show-notifications="vm.showNotifications") \ No newline at end of file + image-slide-viewer.flex.flex-grow(files="vm.files" starting-file="vm.startingFile" show-notifications="vm.showNotifications") \ No newline at end of file diff --git a/src/scripts/controllers/image-viewer.controller.coffee b/src/scripts/controllers/image-viewer.controller.coffee index 73b199a..7702da6 100644 --- a/src/scripts/controllers/image-viewer.controller.coffee +++ b/src/scripts/controllers/image-viewer.controller.coffee @@ -1,97 +1,41 @@ 'use strict' -ImageViewerController = ($scope) -> +ImageViewerController = -> vm = this - vm.files = $scope.files - vm.showNotifications = $scope.showNotifications - startingFile = $scope.startingFile - vm.onFileChange = $scope.onFileChange - vm.imageZoomedIn = false - vm.prevFile = null - vm.nextFile = null - vm.showSmallImage = false - $scope.setAutoBg = false - - - updateFiles = -> - if vm.currentIndex + 1 < vm.files.length - vm.nextFile = true - else - vm.nextFile = null - - if vm.currentIndex - 1 >= 0 - vm.prevFile = true - else - vm.prevFile = null + vm.zoom = false + vm.prevFile = false + vm.nextFile = false + vm.largeImage = false activate = -> - vm.file = startingFile - - vm.currentIndex = vm.files.indexOf vm.file + update(vm.files.indexOf vm.startingFile) - vm.nextFile = vm.currentIndex + 1 < vm.files.length - - vm.prevFile = vm.currentIndex - 1 >= 0 + update = (fileIndex) -> + vm.file = vm.files[fileIndex] + vm.currentIndex = fileIndex + vm.nextFile = vm.currentIndex + 1 < vm.files.length + vm.prevFile = vm.currentIndex > 0 + vm.zoom = false vm.onFileChange({file: vm.file}) if vm.onFileChange - $scope.setAutoBg = true - - $scope.$watch 'showSmallImage', (newVal, OldVal) -> - vm.showSmallImage = newVal - vm.viewNext = -> - vm.file = vm.files[vm.currentIndex + 1] - - vm.currentIndex = vm.files.indexOf vm.file - - updateFiles() - - vm.imageZoomedIn = false - - vm.onFileChange({file: vm.file}) if vm.onFileChange - - $scope.setAutoBg = true - + update(vm.currentIndex + 1) vm.viewPrevious = -> - vm.file = vm.files[vm.currentIndex - 1] - - vm.currentIndex = vm.files.indexOf vm.file - - updateFiles() - - vm.imageZoomedIn = false - - vm.onFileChange({file: vm.file}) if vm.onFileChange - - $scope.setAutoBg = true - + update(vm.currentIndex - 1) vm.selectFile = (file) -> - vm.file = file - - vm.currentIndex = vm.files.indexOf vm.file - - updateFiles() - - vm.imageZoomedIn = false - - vm.onFileChange({file: vm.file}) if vm.onFileChange - - $scope.setAutoBg = true - + update(vm.files.indexOf file) vm.isCurrent = (file) -> (vm.files.indexOf file) == vm.currentIndex vm.toggleZoom = -> - vm.imageZoomedIn = !vm.imageZoomedIn + vm.zoom = !vm.zoom activate() vm -ImageViewerController.$inject = ['$scope'] - angular.module('appirio-tech-ng-ui-components').controller 'ImageViewerController', ImageViewerController \ No newline at end of file diff --git a/src/scripts/directives/image-viewer.directive.coffee b/src/scripts/directives/image-viewer.directive.coffee index 03cbcc5..52238c5 100644 --- a/src/scripts/directives/image-viewer.directive.coffee +++ b/src/scripts/directives/image-viewer.directive.coffee @@ -1,41 +1,31 @@ 'use strict' directive = ($window)-> - link = (scope, element, attrs) -> - checkHeights = -> - container = $('.img-container') - backgroundContainer = $('.bg-image')[0] - containerHeight = container.height() - containerWidth = container.width() - - image = container.find('img') - imageHeight = image.attr('height') - imageWidth = image.attr('width') - - if imageHeight > 0 && imageWidth > 0 - if imageHeight < containerHeight && imageWidth < containerWidth - scope.showSmallImage = true - scope.vm.imageZoomedIn = false - else - scope.showSmallImage = false - - scope.$watch 'setAutoBg', (newVal, oldVal) -> - if newVal - scope.setAutoBg = false - checkHeights() - - $($window).bind 'resize', -> - checkHeights() - scope.$digest() + link = (scope) -> + container = document.getElementsByClassName('image-container')[0] + image = document.getElementsByClassName('preview-image')[0] + + checkOverflow = -> + wide = image.naturalWidth > container.clientWidth + tall = image.naturalHeight > container.clientHeight + + scope.$apply "vm.largeImage = #{ wide || tall }" + + image.onload = -> + checkOverflow() + + $($window).bind 'resize', -> + checkOverflow() restrict: 'E' controller: 'ImageViewerController as vm' templateUrl: 'views/image-viewer.directive.html' link: link - scope: + scope: {} + bindToController: files : '=' startingFile : '=' - showNotifications : '=' + showNotifications : '&' onFileChange : '&' directive.$inject = ['$window'] diff --git a/src/styles/image-viewer.scss b/src/styles/image-viewer.scss index 88cb6a0..5cbdb76 100644 --- a/src/styles/image-viewer.scss +++ b/src/styles/image-viewer.scss @@ -1,123 +1,97 @@ @import "work/work-includes"; image-slide-viewer { - display: block; + position: absolute; + top: 0; + height: 100vh; + margin-top: 100px; + padding-bottom: 100px; + box-sizing: border-box; main { width : 100vw; - padding: 20px; - padding-top: 10px; - .content { - overflow: hidden; + .meta { text-align: center; - width: 100%; + margin-bottom: 20px; + } - .slideshow { - width: 100%; - .icon.arrow { - width: 33px; - height: 74px; - } + .content { + align-items: stretch; + min-height: 1px; - .preview { - overflow: hidden; - text-align: center; - padding: 20px 0; + .previous, .next { + flex-basis: 75px; - .previous, .next { - min-width: 50px; + .arrow-previous, .arrow-next { + margin: auto; - .arrow-previous, .arrow-next { - margin: auto - } + .icon.arrow { + width: 33px; + height: 74px + } + } + } - .arrow-next { - margin: auto - } + .image-container { + position: relative; + text-align: center; + + &.small, &.fit { + img { + position: absolute; + top: 50%; + left: 50%; + transform: translateY(-50%) translateX(-50%); + max-width: 100%; + max-height: 100%; } + } - .image { - width: 100%; - max-width: 1000px; - margin-right: 80px; - margin-left: 80px; - - .img-container { - width: 100%; - height: 100%; - max-height: 800px; - max-width: 1000px; - - &.zoomed { - - > .bg-image { - overflow: auto; - - img { - - &:hover { - cursor: zoom-out; - } - } - } - } - - &.small { - > .bg-image { - overflow: auto; - } - } - - .bg-image { - margin-top: 40px; - background-size: contain; - background-repeat: no-repeat; - background-position: center; - width: 100%; - - &:hover { - cursor: zoom-in; - } - - &.small { - &:hover { - cursor: inherit; - } - } - } - } + &.fit { + img { + cursor: zoom-in; } } - .thumbnails { + &.full { + overflow: scroll; text-align: center; - max-width: 100vw; - padding: 20px; - min-height: 100px; - overflow: auto; - white-space: nowrap; - - > * { - display: inline-block; - margin: 10px; - position: relative; - - &.elevated { - opacity: 0.4; - } - } - button { - img { - width : 60px; - height : 50px; - display: block; - } + img { + cursor: zoom-out; } } } } + + .thumbnails { + flex-basis: 110px; + flex-shrink: 0; + text-align: center; + width: 100vw; + padding: 25px; + overflow: auto; + white-space: nowrap; + + > * { + display: inline-block; + margin: 0 10px; + position: relative; + + &.elevated { + opacity: 0.4; + } + } + + button { + img { + width : 60px; + height : 50px; + display: block; + } + } + } } } diff --git a/src/views/image-viewer.directive.jade b/src/views/image-viewer.directive.jade index c1f3f05..171d35e 100644 --- a/src/views/image-viewer.directive.jade +++ b/src/views/image-viewer.directive.jade @@ -1,34 +1,24 @@ -main.flex.column.middle.light-bg - .content.flex.column.flex-grow +main.flex.column.light-bg + .meta p.file-name(ng-if="vm.file.name") {{ vm.file.name }} p.file-caption(ng-if="vm.file.caption") {{ vm.file.caption }} - .slideshow.flex.column.flex-grow - .preview.flex.center.flex-grow.flex-shrink - .previous.flex.flex-grow - a.arrow-previous(ng-class="{invisible: !vm.prevFile}" ng-click="vm.viewPrevious()") - button.clean.icon.arrow + .content.flex.flex-grow + .previous.flex + a.arrow-previous(ng-class="{invisible: !vm.prevFile}" ng-click="vm.viewPrevious()") + button.clean.icon.arrow - .image.flex.column.center - .img-container.flex.flex-grow(ng-class="{zoomed: vm.imageZoomedIn, small: showSmallImage}") + .image-container.flex-grow(ng-class="{ 'small' : !vm.largeImage, 'fit' : vm.largeImage && !vm.zoom, 'full elevated': vm.largeImage && vm.zoom }") + img.preview-image(ng-src="{{vm.file.url}}" ng-click="vm.toggleZoom()" ng-class="{ 'elevated': !vm.largeImage || (vm.largeImage && !vm.zoom) }") - .bg-image(ng-show="!vm.imageZoomedIn && !vm.showSmallImage" ng-click="vm.toggleZoom()" style="background-image: url({{vm.file.url}})") + .next.flex + a.arrow-next(ng-class="{invisible: !vm.nextFile}" ng-click="vm.viewNext()") + button.clean.icon.arrow.right - .bg-image.zoomed.elevated(ng-show="vm.imageZoomedIn && !vm.showSmallImage" ng-click="vm.toggleZoom()") - img(ng-src="{{vm.file.url}}") + ul.thumbnails + li.thumbnail(ng-repeat="file in vm.files" ng-class="{ elevated: !vm.isCurrent(file) }") + button.clean(ng-click="vm.selectFile(file)") + img(ng-src="{{ file.url }}") - .bg-image.zoomed.small.flex.center.middle(ng-show="!vm.imageZoomedIn && vm.showSmallImage") - img(ng-src="{{vm.file.url}}") - - - .next.flex.flex-grow - a.arrow-next(ng-class="{invisible: !vm.nextFile}" ng-click="vm.viewNext()") - button.clean.icon.arrow.right - - ul.thumbnails - li.thumbnail(ng-repeat="file in vm.files" ng-class="{ elevated: !vm.isCurrent(file) }") - button.clean(ng-click="vm.selectFile(file)") - img(ng-src="{{ file.url }}") - - .notification.absolute(ng-if="file.unreadMessages > 0 && vm.showNotifications") {{ file.unreadMessages }} \ No newline at end of file + .notification.absolute(ng-if="file.unreadMessages > 0 && vm.showNotifications") {{ file.unreadMessages }} \ No newline at end of file