提交 6a8023ac 编写于 作者: EvanOne(文一)'s avatar EvanOne(文一)

feat: Add enlarge the image when clicked without dependencies

上级 350fc82d
......@@ -142,8 +142,6 @@ sidebar:
position: right
# Sidebar offset from top menubar (Only px units are supported).
offsetTop: 20px
# Define the sidebar width, 260px ~ 360px is better (All CSS size units are supported).
width: 300px
# Horizon line.
horizon_line: true
......@@ -535,6 +533,13 @@ math:
# See: https://fancyapps.com/fancybox/3/
fancybox: false
# Whether to enlarge the image when clicked.
zoom_image:
enable: true
# The color of mask.
# Please use the quote to wrap value (All CSS size units are supported).
mask_color: "rgba(0,0,0,0.6)"
# If you are use "photos" attribute in the Front-matter,
# you can enable this to show images in waterfalls flow.
gallery_waterfall:
......
......@@ -35,6 +35,11 @@
gallery_waterfall = JSON.stringify(theme.gallery_waterfall);
}
var zoom_image = 'undefined';
if (theme.zoom_image.enable) {
zoom_image = JSON.stringify(theme.zoom_image);
}
var external_link = 'undefined';
if (theme.external_link.icon.enable) {
external_link = JSON.stringify({
......@@ -63,6 +68,7 @@ script.
back2top: !{ back2top },
reward: !{ theme.reward.enable },
fancybox: !{ theme.fancybox },
zoom_image: !{ zoom_image },
gallery_waterfall: !{ gallery_waterfall },
external_link: !{ external_link },
shortcuts: !{ shortcuts },
......
......@@ -80,7 +80,33 @@
content: ')'
// Gallery in post / page.
.post-g-img
if hexo-config('gallery_waterfall.enable')
width: convert(hexo-config('gallery_waterfall.col_width') || '220px')
margin-bottom: convert(hexo-config('gallery_waterfall.gap_y') || '10px')
.gallery-image
margin-bottom: convert(hexo-config('gallery_waterfall.gap_y') || '10px')
width: convert(hexo-config('gallery_waterfall.col_width') || '220px')
.zoom-image-mask
position: fixed
top: 0
left: 0
z-index: $z-index3
width: 100%
height: 100%
background-color: convert(hexo-config('zoom_image.mask_color') || '#fff')
opacity: 0
will-change: opacity
// Zoom in image without fancybox.
.zoom-image
cursor: zoom-in
&.hide
visibility: hidden
&.show
clearImgStyle()
position: absolute
z-index: $z-index3
margin: 0
box-sizing: content-box
cursor: zoom-out
will-change: transform
$(document).ready(function () {
CONFIG.shortcuts.switch_post && Stun.utils.registerSwitchPost();
CONFIG.reward && Stun.utils.registerShowReward();
CONFIG.fancybox && Stun.utils.wrapImageWithFancyBox();
CONFIG.back2top && Stun.utils.back2Top();
CONFIG.gallery_waterfall && Stun.utils.galleryWaterFall();
CONFIG.external_link && Stun.utils.addIconToExternalLink();
if (CONFIG.external_link) {
var EXTERNAL_LINK_CONTAINER = '.content, #footer';
Stun.utils.addIconToExternalLink(EXTERNAL_LINK_CONTAINER);
if (CONFIG.fancybox) {
Stun.utils.wrapImageWithFancyBox();
} else if (CONFIG.zoom_image) {
Stun.utils.registerClickToZoomImage();
}
});
......@@ -5,7 +5,7 @@ Stun.utils = Stun.$u = {
* Debounce
* @param {Object} func Callback function
* @param {Number} wait Waiting time
* @param {Number} immediate Time interval for immediate run
* @param {Boolean} immediate Run immediately
*/
debounce: function (func, wait, immediate) {
var timeout;
......@@ -13,42 +13,58 @@ Stun.utils = Stun.$u = {
return function () {
var context = this;
var args = arguments;
var later = function () {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
if (timeout) clearTimeout(timeout);
if (immediate) {
var callNow = !timeout;
timeout = setTimeout(function () {
timeout = null;
}, wait);
if (callNow) func.apply(context, args);
} else {
timeout = setTimeout(function () {
func.apply(context, args);
}, wait);
}
};
},
/**
* Throttle
* @param {Object} func Callback function
* @param {Number} wait Waiting time
* @param {Number} mustRun Time interval for must run
* @param {Object} options leading: Boolean, trailing: Boolean
*/
throttle: function (func, wait, mustRun) {
var timeout;
var startTime = new Date();
return function () {
var context = this;
var args = arguments;
var curTime = new Date();
clearTimeout(timeout);
throttle: function (func, wait, options) {
var timeout, context, args;
var previous = 0;
if (!options) options = {};
var later = function () {
previous = options.leading === false ? 0 : new Date().getTime();
timeout = null;
func.apply(context, args);
if (!timeout) context = args = null;
};
if (curTime - startTime >= mustRun) {
var throttled = function () {
var now = new Date().getTime();
if (!previous && options.leading === false) previous = now;
var remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
func.apply(context, args);
startTime = curTime;
} else {
timeout = setTimeout(func, wait);
if (!timeout) context = args = null;
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
};
return throttled;
},
/**
* Change the event code to keyCode.
......@@ -155,7 +171,7 @@ Stun.utils = Stun.$u = {
'" itemscope itemtype="http://schema.org/ImageObject" itemprop="url"></a>'
).parent('a');
if ($img.is('.post-gallery img')) {
if ($img.is('.gallery img')) {
$imgWrap.attr('data-fancybox', 'gallery');
} else {
$imgWrap.attr('data-fancybox', 'default');
......@@ -186,8 +202,8 @@ Stun.utils = Stun.$u = {
var colWidth = parseInt(gConfig.col_width);
var colGapX = parseInt(gConfig.gap_x);
$('.post-gallery').masonry({
itemSelector: '.post-g-img',
$('.gallery').masonry({
itemSelector: '.gallery-image',
columnWidth: colWidth,
percentPosition: true,
gutter: colGapX,
......@@ -213,12 +229,10 @@ Stun.utils = Stun.$u = {
}
});
},
/**
* Add a mark icon to the link with `target="_blank"` attribute.
* @param {String} wrapper Any Jquery wrapper.
*/
addIconToExternalLink: function (wrapper) {
if (!$(wrapper)[0]) return;
// Add a mark icon to the link with `target="_blank"` attribute.
addIconToExternalLink: function () {
var CONTAINER = '.content, #footer';
if (!$(CONTAINER)[0]) return;
var $icon = $(
'<i class="external-link fa fa-' +
......@@ -226,10 +240,10 @@ Stun.utils = Stun.$u = {
'"></i>'
);
// Insert icon after link.
// $icon.insertAfter($(wrapper).find('a[target="_blank"]'));
// $icon.insertAfter($(CONTAINER).find('a[target="_blank"]'));
// Insert icon inner link.
$(wrapper).find('a[target="_blank"]').append($icon);
$(CONTAINER).find('a[target="_blank"]').append($icon);
},
// Back the page to top.
back2Top: function () {
......@@ -285,7 +299,7 @@ Stun.utils = Stun.$u = {
$('.reward-button').on('click', function () {
var $container = $('.reward-qr-wrapper');
if ($container.css('display') === 'block') {
if ($container.is(':visible')) {
$container.css('display', 'none');
} else {
$container
......@@ -295,6 +309,79 @@ Stun.utils = Stun.$u = {
});
}
});
},
// Click to zoom in image, without fancybox.
registerClickToZoomImage: function () {
$('.content img').not(':hidden').each(function () {
$(this).addClass('zoom-image');
});
var $newImgMask = $('<div class="zoom-image-mask"></div>');
var $newImg = $('<img>');
var isZoom = false;
$(window).on('scroll', function () {
if (isZoom) {
isZoom = false;
setTimeout(closeZoom, 200);
}
});
$(document).on('click', function () {
closeZoom();
});
$('.zoom-image').on('click', function (ev) {
var e = ev || window.event;
e.stopPropagation();
isZoom = true;
var imgRect = this.getBoundingClientRect();
var imgW = $(this).width();
var imgH = $(this).height();
var imgOuterW = $(this).outerWidth();
var imgOuterH = $(this).outerHeight();
var winW = $(window).width();
var winH = $(window).height();
var scaleX = winW / imgW;
var scaleY = winH / imgH;
var scale = (scaleX < scaleY ? scaleX : scaleY) || 1;
var translateX = winW / 2 - (imgRect.x + imgOuterW / 2);
var translateY = winH / 2 - (imgRect.y + imgOuterH / 2);
$newImg.attr('class', this.className);
$newImg.attr('src', this.src);
$newImg.addClass('show');
$newImg.css({
left: $(this).offset().left + (imgOuterW - imgW) / 2,
top: $(this).offset().top + (imgOuterH - imgH) / 2,
width: imgW,
height: imgH
});
$(this).addClass('hide');
$('body').append($newImgMask).append($newImg);
$newImgMask.velocity({ opacity: 1 });
$newImg.velocity({
translateX: translateX,
translateY: translateY,
scale: scale
}, {
duration: 300,
easing: [0.2, 0, 0.2, 1]
});
});
function closeZoom () {
$newImg.velocity('reverse');
$newImgMask.velocity('reverse', {
complete: function () {
$('.zoom-image.show').remove();
$('.zoom-image-mask').remove();
$('.zoom-image').removeClass('hide');
}
});
}
}
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册