summaryrefslogtreecommitdiff
path: root/assets
diff options
context:
space:
mode:
Diffstat (limited to 'assets')
-rw-r--r--assets/sass/main.scss24
-rw-r--r--assets/zoomjs/zoom.css41
-rwxr-xr-xassets/zoomjs/zoom.js285
3 files changed, 350 insertions, 0 deletions
diff --git a/assets/sass/main.scss b/assets/sass/main.scss
index 9eff6c8..3f986db 100644
--- a/assets/sass/main.scss
+++ b/assets/sass/main.scss
@@ -303,6 +303,30 @@ samp {
left: -0.75em;
}
}
+
+ figure {
+ margin: .5rem;
+ text-align: center;
+
+ .image-caption:not(:empty) {
+ min-width: 20%;
+ max-width: 80%;
+ display: inline-block;
+ font-style: italic;
+ padding: .5rem;
+ margin: 0 auto;
+ font-size: 13px;
+ color: $brand-gray;
+ }
+
+ img {
+ display: block;
+ width: 100%;
+ height: auto;
+ margin: 0 auto;
+ overflow: hidden;
+ }
+ }
}
// Navigation
diff --git a/assets/zoomjs/zoom.css b/assets/zoomjs/zoom.css
new file mode 100644
index 0000000..679bccc
--- /dev/null
+++ b/assets/zoomjs/zoom.css
@@ -0,0 +1,41 @@
+img[data-action="zoom"] {
+ cursor: pointer;
+ cursor: -webkit-zoom-in;
+ cursor: -moz-zoom-in;
+}
+.zoom-img,
+.zoom-img-wrap {
+ position: relative;
+ z-index: 666;
+ -webkit-transition: all 300ms;
+ -o-transition: all 300ms;
+ transition: all 300ms;
+}
+img.zoom-img {
+ cursor: pointer;
+ cursor: -webkit-zoom-out;
+ cursor: -moz-zoom-out;
+}
+.zoom-overlay {
+ z-index: 420;
+ background: #fff;
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ pointer-events: none;
+ filter: "alpha(opacity=0)";
+ opacity: 0;
+ -webkit-transition: opacity 300ms;
+ -o-transition: opacity 300ms;
+ transition: opacity 300ms;
+}
+.zoom-overlay-open .zoom-overlay {
+ filter: "alpha(opacity=100)";
+ opacity: 1;
+}
+.zoom-overlay-open,
+.zoom-overlay-transitioning {
+ cursor: default;
+}
diff --git a/assets/zoomjs/zoom.js b/assets/zoomjs/zoom.js
new file mode 100755
index 0000000..25d76d6
--- /dev/null
+++ b/assets/zoomjs/zoom.js
@@ -0,0 +1,285 @@
+/**
+ * zoom.js - It's the best way to zoom an image
+ * @version v0.0.2
+ * @link https://github.com/fat/zoom.js
+ * @license MIT
+ */
+
++function ($) { "use strict";
+
+ /**
+ * The zoom service
+ */
+ function ZoomService () {
+ this._activeZoom =
+ this._initialScrollPosition =
+ this._initialTouchPosition =
+ this._touchMoveListener = null
+
+ this._$document = $(document)
+ this._$window = $(window)
+ this._$body = $(document.body)
+
+ this._boundClick = $.proxy(this._clickHandler, this)
+ }
+
+ ZoomService.prototype.listen = function () {
+ this._$body.on('click', '[data-action="zoom"]', $.proxy(this._zoom, this))
+ }
+
+ ZoomService.prototype._zoom = function (e) {
+ var target = e.target
+
+ if (!target || target.tagName != 'IMG') return
+
+ if (this._$body.hasClass('zoom-overlay-open')) return
+
+ if (e.metaKey || e.ctrlKey) {
+ return window.open((e.target.getAttribute('data-original') || e.target.src), '_blank')
+ }
+
+ if (target.width >= ($(window).width() - Zoom.OFFSET)) return
+
+ this._activeZoomClose(true)
+
+ this._activeZoom = new Zoom(target)
+ this._activeZoom.zoomImage()
+
+ // todo(fat): probably worth throttling this
+ this._$window.on('scroll.zoom', $.proxy(this._scrollHandler, this))
+
+ this._$document.on('keyup.zoom', $.proxy(this._keyHandler, this))
+ this._$document.on('touchstart.zoom', $.proxy(this._touchStart, this))
+
+ // we use a capturing phase here to prevent unintended js events
+ // sadly no useCapture in jquery api (http://bugs.jquery.com/ticket/14953)
+ if (document.addEventListener) {
+ document.addEventListener('click', this._boundClick, true)
+ } else {
+ document.attachEvent('onclick', this._boundClick, true)
+ }
+
+ if ('bubbles' in e) {
+ if (e.bubbles) e.stopPropagation()
+ } else {
+ // Internet Explorer before version 9
+ e.cancelBubble = true
+ }
+ }
+
+ ZoomService.prototype._activeZoomClose = function (forceDispose) {
+ if (!this._activeZoom) return
+
+ if (forceDispose) {
+ this._activeZoom.dispose()
+ } else {
+ this._activeZoom.close()
+ }
+
+ this._$window.off('.zoom')
+ this._$document.off('.zoom')
+
+ document.removeEventListener('click', this._boundClick, true)
+
+ this._activeZoom = null
+ }
+
+ ZoomService.prototype._scrollHandler = function (e) {
+ if (this._initialScrollPosition === null) this._initialScrollPosition = $(window).scrollTop()
+ var deltaY = this._initialScrollPosition - $(window).scrollTop()
+ if (Math.abs(deltaY) >= 40) this._activeZoomClose()
+ }
+
+ ZoomService.prototype._keyHandler = function (e) {
+ if (e.keyCode == 27) this._activeZoomClose()
+ }
+
+ ZoomService.prototype._clickHandler = function (e) {
+ if (e.preventDefault) e.preventDefault()
+ else event.returnValue = false
+
+ if ('bubbles' in e) {
+ if (e.bubbles) e.stopPropagation()
+ } else {
+ // Internet Explorer before version 9
+ e.cancelBubble = true
+ }
+
+ this._activeZoomClose()
+ }
+
+ ZoomService.prototype._touchStart = function (e) {
+ this._initialTouchPosition = e.touches[0].pageY
+ $(e.target).on('touchmove.zoom', $.proxy(this._touchMove, this))
+ }
+
+ ZoomService.prototype._touchMove = function (e) {
+ if (Math.abs(e.touches[0].pageY - this._initialTouchPosition) > 10) {
+ this._activeZoomClose()
+ $(e.target).off('touchmove.zoom')
+ }
+ }
+
+
+ /**
+ * The zoom object
+ */
+ function Zoom (img) {
+ this._fullHeight =
+ this._fullWidth =
+ this._overlay =
+ this._targetImageWrap = null
+
+ this._targetImage = img
+
+ this._$body = $(document.body)
+ }
+
+ Zoom.OFFSET = 80
+ Zoom._MAX_WIDTH = 2560
+ Zoom._MAX_HEIGHT = 4096
+
+ Zoom.prototype.zoomImage = function () {
+ var img = document.createElement('img')
+ img.onload = $.proxy(function () {
+ this._fullHeight = Number(img.height)
+ this._fullWidth = Number(img.width)
+ this._zoomOriginal()
+ }, this)
+ img.src = this._targetImage.src
+ }
+
+ Zoom.prototype._zoomOriginal = function () {
+ this._targetImageWrap = document.createElement('div')
+ this._targetImageWrap.className = 'zoom-img-wrap'
+
+ this._targetImage.parentNode.insertBefore(this._targetImageWrap, this._targetImage)
+ this._targetImageWrap.appendChild(this._targetImage)
+
+ $(this._targetImage)
+ .addClass('zoom-img')
+ .attr('data-action', 'zoom-out')
+
+ this._overlay = document.createElement('div')
+ this._overlay.className = 'zoom-overlay'
+
+ document.body.appendChild(this._overlay)
+
+ this._calculateZoom()
+ this._triggerAnimation()
+ }
+
+ Zoom.prototype._calculateZoom = function () {
+ this._targetImage.offsetWidth // repaint before animating
+
+ var originalFullImageWidth = this._fullWidth
+ var originalFullImageHeight = this._fullHeight
+
+ var scrollTop = $(window).scrollTop()
+
+ var maxScaleFactor = originalFullImageWidth / this._targetImage.width
+
+ var viewportHeight = ($(window).height() - Zoom.OFFSET)
+ var viewportWidth = ($(window).width() - Zoom.OFFSET)
+
+ var imageAspectRatio = originalFullImageWidth / originalFullImageHeight
+ var viewportAspectRatio = viewportWidth / viewportHeight
+
+ if (originalFullImageWidth < viewportWidth && originalFullImageHeight < viewportHeight) {
+ this._imgScaleFactor = maxScaleFactor
+
+ } else if (imageAspectRatio < viewportAspectRatio) {
+ this._imgScaleFactor = (viewportHeight / originalFullImageHeight) * maxScaleFactor
+
+ } else {
+ this._imgScaleFactor = (viewportWidth / originalFullImageWidth) * maxScaleFactor
+ }
+ }
+
+ Zoom.prototype._triggerAnimation = function () {
+ this._targetImage.offsetWidth // repaint before animating
+
+ var imageOffset = $(this._targetImage).offset()
+ var scrollTop = $(window).scrollTop()
+
+ var viewportY = scrollTop + ($(window).height() / 2)
+ var viewportX = ($(window).width() / 2)
+
+ var imageCenterY = imageOffset.top + (this._targetImage.height / 2)
+ var imageCenterX = imageOffset.left + (this._targetImage.width / 2)
+
+ this._translateY = viewportY - imageCenterY
+ this._translateX = viewportX - imageCenterX
+
+ var targetTransform = 'scale(' + this._imgScaleFactor + ')'
+ var imageWrapTransform = 'translate(' + this._translateX + 'px, ' + this._translateY + 'px)'
+
+ if ($.support.transition) {
+ imageWrapTransform += ' translateZ(0)'
+ }
+
+ $(this._targetImage)
+ .css({
+ '-webkit-transform': targetTransform,
+ '-ms-transform': targetTransform,
+ 'transform': targetTransform
+ })
+
+ $(this._targetImageWrap)
+ .css({
+ '-webkit-transform': imageWrapTransform,
+ '-ms-transform': imageWrapTransform,
+ 'transform': imageWrapTransform
+ })
+
+ this._$body.addClass('zoom-overlay-open')
+ }
+
+ Zoom.prototype.close = function () {
+ this._$body
+ .removeClass('zoom-overlay-open')
+ .addClass('zoom-overlay-transitioning')
+
+ // we use setStyle here so that the correct vender prefix for transform is used
+ $(this._targetImage)
+ .css({
+ '-webkit-transform': '',
+ '-ms-transform': '',
+ 'transform': ''
+ })
+
+ $(this._targetImageWrap)
+ .css({
+ '-webkit-transform': '',
+ '-ms-transform': '',
+ 'transform': ''
+ })
+
+ if (!$.support.transition) {
+ return this.dispose()
+ }
+
+ $(this._targetImage)
+ .one($.support.transition.end, $.proxy(this.dispose, this))
+ .emulateTransitionEnd(300)
+ }
+
+ Zoom.prototype.dispose = function () {
+ if (this._targetImageWrap && this._targetImageWrap.parentNode) {
+ $(this._targetImage)
+ .removeClass('zoom-img')
+ .attr('data-action', 'zoom')
+
+ this._targetImageWrap.parentNode.replaceChild(this._targetImage, this._targetImageWrap)
+ this._overlay.parentNode.removeChild(this._overlay)
+
+ this._$body.removeClass('zoom-overlay-transitioning')
+ }
+ }
+
+ // wait for dom ready (incase script included before body)
+ $(function () {
+ new ZoomService().listen()
+ })
+
+}(jQuery)