first commits
This commit is contained in:
2306
public/js/bootstrap.js
vendored
Normal file
2306
public/js/bootstrap.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7
public/js/bootstrap.min.js
vendored
Normal file
7
public/js/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/js/eac.min.json
Normal file
1
public/js/eac.min.json
Normal file
File diff suppressed because one or more lines are too long
87
public/js/fitvids.js
Normal file
87
public/js/fitvids.js
Normal file
@@ -0,0 +1,87 @@
|
||||
/*jshint browser:true */
|
||||
/*!
|
||||
* FitVids 1.1
|
||||
*
|
||||
* Copyright 2013, Chris Coyier - http://css-tricks.com + Dave Rupert - http://daverupert.com
|
||||
* Credit to Thierry Koblentz - http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/
|
||||
* Released under the WTFPL license - http://sam.zoy.org/wtfpl/
|
||||
*
|
||||
*/
|
||||
|
||||
;(function( $ ){
|
||||
|
||||
'use strict';
|
||||
|
||||
$.fn.fitVids = function( options ) {
|
||||
var settings = {
|
||||
customSelector: null,
|
||||
ignore: null
|
||||
};
|
||||
|
||||
if(!document.getElementById('fit-vids-style')) {
|
||||
// appendStyles: https://github.com/toddmotto/fluidvids/blob/master/dist/fluidvids.js
|
||||
var head = document.head || document.getElementsByTagName('head')[0];
|
||||
var css = '.fluid-width-video-wrapper{width:100%;position:relative;padding:0;}.fluid-width-video-wrapper iframe,.fluid-width-video-wrapper object,.fluid-width-video-wrapper embed {position:absolute;top:0;left:0;width:100%;height:100%;}';
|
||||
var div = document.createElement("div");
|
||||
div.innerHTML = '<p>x</p><style id="fit-vids-style">' + css + '</style>';
|
||||
head.appendChild(div.childNodes[1]);
|
||||
}
|
||||
|
||||
if ( options ) {
|
||||
$.extend( settings, options );
|
||||
}
|
||||
|
||||
return this.each(function(){
|
||||
var selectors = [
|
||||
'iframe[src*="player.vimeo.com"]',
|
||||
'iframe[src*="youtube.com"]',
|
||||
'iframe[src*="youtube-nocookie.com"]',
|
||||
'iframe[src*="kickstarter.com"][src*="video.html"]',
|
||||
'object',
|
||||
'embed'
|
||||
];
|
||||
|
||||
if (settings.customSelector) {
|
||||
selectors.push(settings.customSelector);
|
||||
}
|
||||
|
||||
var ignoreList = '.fitvidsignore';
|
||||
|
||||
if(settings.ignore) {
|
||||
ignoreList = ignoreList + ', ' + settings.ignore;
|
||||
}
|
||||
|
||||
var $allVideos = $(this).find(selectors.join(','));
|
||||
$allVideos = $allVideos.not('object object'); // SwfObj conflict patch
|
||||
$allVideos = $allVideos.not(ignoreList); // Disable FitVids on this video.
|
||||
|
||||
$allVideos.each(function(){
|
||||
var $this = $(this);
|
||||
if($this.parents(ignoreList).length > 0) {
|
||||
return; // Disable FitVids on this video.
|
||||
}
|
||||
if (this.tagName.toLowerCase() === 'embed' && $this.parent('object').length || $this.parent('.fluid-width-video-wrapper').length) { return; }
|
||||
if ((!$this.css('height') && !$this.css('width')) && (isNaN($this.attr('height')) || isNaN($this.attr('width'))))
|
||||
{
|
||||
$this.attr('height', 9);
|
||||
$this.attr('width', 16);
|
||||
}
|
||||
var height = ( this.tagName.toLowerCase() === 'object' || ($this.attr('height') && !isNaN(parseInt($this.attr('height'), 10))) ) ? parseInt($this.attr('height'), 10) : $this.height(),
|
||||
width = !isNaN(parseInt($this.attr('width'), 10)) ? parseInt($this.attr('width'), 10) : $this.width(),
|
||||
aspectRatio = height / width;
|
||||
if(!$this.attr('name')){
|
||||
var videoName = 'fitvid' + $.fn.fitVids._count;
|
||||
$this.attr('name', videoName);
|
||||
$.fn.fitVids._count++;
|
||||
}
|
||||
$this.wrap('<div class="fluid-width-video-wrapper"></div>').parent('.fluid-width-video-wrapper').css('padding-top', (aspectRatio * 100)+'%');
|
||||
$this.removeAttr('height').removeAttr('width');
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Internal counter for unique video names.
|
||||
$.fn.fitVids._count = 0;
|
||||
|
||||
// Works with either jQuery or Zepto
|
||||
})( window.jQuery || window.Zepto );
|
||||
75
public/js/hux-blog.js
Normal file
75
public/js/hux-blog.js
Normal file
@@ -0,0 +1,75 @@
|
||||
/*!
|
||||
* Clean Blog v1.0.0 (http://startbootstrap.com)
|
||||
* Copyright 2015 Start Bootstrap
|
||||
* Licensed under Apache 2.0 (https://github.com/IronSummitMedia/startbootstrap/blob/gh-pages/LICENSE)
|
||||
*/
|
||||
|
||||
// Tooltip Init
|
||||
$(function() {
|
||||
$("[data-toggle='tooltip']").tooltip();
|
||||
});
|
||||
|
||||
|
||||
// make all images responsive
|
||||
/*
|
||||
* Unuse by Hux
|
||||
* actually only Portfolio-Pages can't use it and only post-img need it.
|
||||
* so I modify the _layout/post and CSS to make post-img responsive!
|
||||
*/
|
||||
// $(function() {
|
||||
// $("img").addClass("img-responsive");
|
||||
// });
|
||||
|
||||
// responsive tables
|
||||
$(document).ready(function() {
|
||||
$("table").wrap("<div class='table-responsive'></div>");
|
||||
$("table").addClass("table");
|
||||
});
|
||||
|
||||
// responsive embed videos
|
||||
$(document).ready(function () {
|
||||
$('iframe[src*="youtube.com"]').wrap('<div class="embed-responsive embed-responsive-16by9"></div>');
|
||||
$('iframe[src*="youtube.com"]').addClass('embed-responsive-item');
|
||||
$('iframe[src*="vimeo.com"]').wrap('<div class="embed-responsive embed-responsive-16by9"></div>');
|
||||
$('iframe[src*="vimeo.com"]').addClass('embed-responsive-item');
|
||||
});
|
||||
|
||||
// Navigation Scripts to Show Header on Scroll-Up
|
||||
jQuery(document).ready(function($) {
|
||||
var MQL = 1170;
|
||||
|
||||
//primary navigation slide-in effect
|
||||
if ($(window).width() > MQL) {
|
||||
var headerHeight = $('.navbar-custom').height(),
|
||||
bannerHeight = $('.intro-header .container').height();
|
||||
$(window).on('scroll', {
|
||||
previousTop: 0
|
||||
},
|
||||
function() {
|
||||
var currentTop = $(window).scrollTop(),
|
||||
$catalog = $('.side-catalog');
|
||||
//check if user is scrolling up
|
||||
if (currentTop < this.previousTop) {
|
||||
//if scrolling up...
|
||||
if (currentTop > 0 && $('.navbar-custom').hasClass('is-fixed')) {
|
||||
$('.navbar-custom').addClass('is-visible');
|
||||
} else {
|
||||
$('.navbar-custom').removeClass('is-visible is-fixed');
|
||||
}
|
||||
} else {
|
||||
//if scrolling down...
|
||||
$('.navbar-custom').removeClass('is-visible');
|
||||
if (currentTop > headerHeight && !$('.navbar-custom').hasClass('is-fixed')) $('.navbar-custom').addClass('is-fixed');
|
||||
}
|
||||
this.previousTop = currentTop;
|
||||
|
||||
//adjust the appearance of side-catalog
|
||||
$catalog.show()
|
||||
if (currentTop > (bannerHeight + 41)) {
|
||||
$catalog.addClass('fixed')
|
||||
} else {
|
||||
$catalog.removeClass('fixed')
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
6
public/js/hux-blog.min.js
vendored
Normal file
6
public/js/hux-blog.min.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Clean Blog v1.0.0 (http://startbootstrap.com)
|
||||
* Copyright 2015 Start Bootstrap
|
||||
* Licensed under Apache 2.0 (https://github.com/IronSummitMedia/startbootstrap/blob/gh-pages/LICENSE)
|
||||
*/
|
||||
$(function(){$("[data-toggle='tooltip']").tooltip()}),$(document).ready(function(){$("table").wrap("<div class='table-responsive'></div>"),$("table").addClass("table")}),$(document).ready(function(){$('iframe[src*="youtube.com"]').wrap('<div class="embed-responsive embed-responsive-16by9"></div>'),$('iframe[src*="youtube.com"]').addClass("embed-responsive-item"),$('iframe[src*="vimeo.com"]').wrap('<div class="embed-responsive embed-responsive-16by9"></div>'),$('iframe[src*="vimeo.com"]').addClass("embed-responsive-item")}),jQuery(document).ready(function(s){if(s(window).width()>1170){var e=s(".navbar-custom").height(),i=s(".intro-header .container").height();s(window).on("scroll",{previousTop:0},function(){var a=s(window).scrollTop(),o=s(".side-catalog");a<this.previousTop?a>0&&s(".navbar-custom").hasClass("is-fixed")?s(".navbar-custom").addClass("is-visible"):s(".navbar-custom").removeClass("is-visible is-fixed"):(s(".navbar-custom").removeClass("is-visible"),a>e&&!s(".navbar-custom").hasClass("is-fixed")&&s(".navbar-custom").addClass("is-fixed")),this.previousTop=a,o.show(),a>i+41?o.addClass("fixed"):o.removeClass("fixed")})}});
|
||||
178
public/js/iDisqus.js
Normal file
178
public/js/iDisqus.js
Normal file
File diff suppressed because one or more lines are too long
12
public/js/iDisqus.min.js
vendored
Normal file
12
public/js/iDisqus.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/js/iDisqus.min.js.map
Normal file
1
public/js/iDisqus.min.js.map
Normal file
File diff suppressed because one or more lines are too long
9205
public/js/jquery.js
vendored
Normal file
9205
public/js/jquery.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4
public/js/jquery.min.js
vendored
Normal file
4
public/js/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
224
public/js/jquery.nav.js
Normal file
224
public/js/jquery.nav.js
Normal file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* jQuery One Page Nav Plugin
|
||||
* http://github.com/davist11/jQuery-One-Page-Nav
|
||||
*
|
||||
* Copyright (c) 2010 Trevor Davis (http://trevordavis.net)
|
||||
* Dual licensed under the MIT and GPL licenses.
|
||||
* Uses the same license as jQuery, see:
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* @version 3.0.0
|
||||
*
|
||||
* Example usage:
|
||||
* $('#nav').onePageNav({
|
||||
* currentClass: 'current',
|
||||
* changeHash: false,
|
||||
* scrollSpeed: 750
|
||||
* });
|
||||
*/
|
||||
|
||||
;(function($, window, document, undefined){
|
||||
|
||||
// our plugin constructor
|
||||
var OnePageNav = function(elem, options){
|
||||
this.elem = elem;
|
||||
this.$elem = $(elem);
|
||||
this.options = options;
|
||||
this.metadata = this.$elem.data('plugin-options');
|
||||
this.$win = $(window);
|
||||
this.sections = {};
|
||||
this.didScroll = false;
|
||||
this.$doc = $(document);
|
||||
this.docHeight = this.$doc.height();
|
||||
};
|
||||
|
||||
// the plugin prototype
|
||||
OnePageNav.prototype = {
|
||||
defaults: {
|
||||
navItems: 'a',
|
||||
currentClass: 'current',
|
||||
changeHash: false,
|
||||
easing: 'swing',
|
||||
filter: '',
|
||||
scrollSpeed: 750,
|
||||
scrollThreshold: 0.5,
|
||||
begin: false,
|
||||
end: false,
|
||||
scrollChange: false,
|
||||
padding: 0
|
||||
},
|
||||
|
||||
init: function() {
|
||||
// Introduce defaults that can be extended either
|
||||
// globally or using an object literal.
|
||||
this.config = $.extend({}, this.defaults, this.options, this.metadata);
|
||||
|
||||
this.$nav = this.$elem.find(this.config.navItems);
|
||||
|
||||
//Filter any links out of the nav
|
||||
if(this.config.filter !== '') {
|
||||
this.$nav = this.$nav.filter(this.config.filter);
|
||||
}
|
||||
|
||||
//Handle clicks on the nav
|
||||
this.$nav.on('click.onePageNav', $.proxy(this.handleClick, this));
|
||||
|
||||
//Get the section positions
|
||||
this.getPositions();
|
||||
|
||||
//Handle scroll changes
|
||||
this.bindInterval();
|
||||
|
||||
//Update the positions on resize too
|
||||
this.$win.on('resize.onePageNav', $.proxy(this.getPositions, this));
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
adjustNav: function(self, $parent) {
|
||||
self.$elem.find('.' + self.config.currentClass).removeClass(self.config.currentClass);
|
||||
$parent.addClass(self.config.currentClass);
|
||||
},
|
||||
|
||||
bindInterval: function() {
|
||||
var self = this;
|
||||
var docHeight;
|
||||
|
||||
self.$win.on('scroll.onePageNav', function() {
|
||||
self.didScroll = true;
|
||||
});
|
||||
|
||||
self.t = setInterval(function() {
|
||||
docHeight = self.$doc.height();
|
||||
|
||||
//If it was scrolled
|
||||
if(self.didScroll) {
|
||||
self.didScroll = false;
|
||||
self.scrollChange();
|
||||
}
|
||||
|
||||
//If the document height changes
|
||||
if(docHeight !== self.docHeight) {
|
||||
self.docHeight = docHeight;
|
||||
self.getPositions();
|
||||
}
|
||||
}, 250);
|
||||
},
|
||||
|
||||
getHash: function($link) {
|
||||
return $link.attr('href').split('#')[1];
|
||||
},
|
||||
|
||||
getPositions: function() {
|
||||
var self = this;
|
||||
var linkHref;
|
||||
var topPos;
|
||||
var $target;
|
||||
|
||||
self.$nav.each(function() {
|
||||
linkHref = self.getHash($(this));
|
||||
$target = $('#' + linkHref);
|
||||
|
||||
if($target.length) {
|
||||
topPos = $target.offset().top;
|
||||
self.sections[linkHref] = Math.round(topPos);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
getSection: function(windowPos) {
|
||||
var returnValue = null;
|
||||
var windowHeight = Math.round(this.$win.height() * this.config.scrollThreshold);
|
||||
|
||||
for(var section in this.sections) {
|
||||
if((this.sections[section] - windowHeight) < windowPos) {
|
||||
returnValue = section;
|
||||
}
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
},
|
||||
|
||||
handleClick: function(e) {
|
||||
var self = this;
|
||||
var $link = $(e.currentTarget);
|
||||
var $parent = $link.parent();
|
||||
var newLoc = '#' + self.getHash($link);
|
||||
|
||||
if(!$parent.hasClass(self.config.currentClass)) {
|
||||
//Start callback
|
||||
if(self.config.begin) {
|
||||
self.config.begin();
|
||||
}
|
||||
|
||||
//Change the highlighted nav item
|
||||
self.adjustNav(self, $parent);
|
||||
|
||||
//Removing the auto-adjust on scroll
|
||||
self.unbindInterval();
|
||||
|
||||
//Scroll to the correct position
|
||||
self.scrollTo(newLoc, function() {
|
||||
//Do we need to change the hash?
|
||||
if(self.config.changeHash) {
|
||||
window.location.hash = newLoc;
|
||||
}
|
||||
|
||||
//Add the auto-adjust on scroll back in
|
||||
self.bindInterval();
|
||||
|
||||
//End callback
|
||||
if(self.config.end) {
|
||||
self.config.end();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
},
|
||||
|
||||
scrollChange: function() {
|
||||
var windowTop = this.$win.scrollTop();
|
||||
var position = this.getSection(windowTop);
|
||||
var $parent;
|
||||
|
||||
//If the position is set
|
||||
if(position !== null) {
|
||||
$parent = this.$elem.find('a[href$="#' + position + '"]').parent();
|
||||
|
||||
//If it's not already the current section
|
||||
if(!$parent.hasClass(this.config.currentClass)) {
|
||||
//Change the highlighted nav item
|
||||
this.adjustNav(this, $parent);
|
||||
|
||||
//If there is a scrollChange callback
|
||||
if(this.config.scrollChange) {
|
||||
this.config.scrollChange($parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
scrollTo: function(target, callback) {
|
||||
var offset = $(target).offset().top - this.config.padding;
|
||||
|
||||
$('html, body').animate({
|
||||
scrollTop: offset
|
||||
}, this.config.scrollSpeed, this.config.easing, callback);
|
||||
},
|
||||
|
||||
unbindInterval: function() {
|
||||
clearInterval(this.t);
|
||||
this.$win.unbind('scroll.onePageNav');
|
||||
}
|
||||
};
|
||||
|
||||
OnePageNav.defaults = OnePageNav.prototype.defaults;
|
||||
|
||||
$.fn.onePageNav = function(options) {
|
||||
return this.each(function() {
|
||||
new OnePageNav(this, options).init();
|
||||
});
|
||||
};
|
||||
|
||||
})( jQuery, window , document );
|
||||
81
public/js/jquery.tagcloud.js
Executable file
81
public/js/jquery.tagcloud.js
Executable file
@@ -0,0 +1,81 @@
|
||||
(function($) {
|
||||
|
||||
$.fn.tagcloud = function(options) {
|
||||
var opts = $.extend({}, $.fn.tagcloud.defaults, options);
|
||||
tagWeights = this.map(function(){
|
||||
return $(this).attr("rel");
|
||||
});
|
||||
tagWeights = jQuery.makeArray(tagWeights).sort(compareWeights);
|
||||
lowest = tagWeights[0];
|
||||
highest = tagWeights.pop();
|
||||
range = highest - lowest;
|
||||
if(range === 0) {range = 1;}
|
||||
// Sizes
|
||||
if (opts.size) {
|
||||
fontIncr = (opts.size.end - opts.size.start)/range;
|
||||
}
|
||||
// Colors
|
||||
if (opts.color) {
|
||||
colorIncr = colorIncrement (opts.color, range);
|
||||
}
|
||||
return this.each(function() {
|
||||
weighting = $(this).attr("rel") - lowest;
|
||||
if (opts.size) {
|
||||
$(this).css({"font-size": opts.size.start + (weighting * fontIncr) + opts.size.unit});
|
||||
}
|
||||
if (opts.color) {
|
||||
// change color to background-color
|
||||
$(this).css({"backgroundColor": tagColor(opts.color, colorIncr, weighting)});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.tagcloud.defaults = {
|
||||
size: {start: 14, end: 18, unit: "pt"}
|
||||
};
|
||||
|
||||
// Converts hex to an RGB array
|
||||
function toRGB (code) {
|
||||
if (code.length == 4) {
|
||||
code = jQuery.map(/\w+/.exec(code), function(el) {return el + el; }).join("");
|
||||
}
|
||||
hex = /(\w{2})(\w{2})(\w{2})/.exec(code);
|
||||
return [parseInt(hex[1], 16), parseInt(hex[2], 16), parseInt(hex[3], 16)];
|
||||
}
|
||||
|
||||
// Converts an RGB array to hex
|
||||
function toHex (ary) {
|
||||
return "#" + jQuery.map(ary, function(i) {
|
||||
hex = i.toString(16);
|
||||
hex = (hex.length == 1) ? "0" + hex : hex;
|
||||
return hex;
|
||||
}).join("");
|
||||
}
|
||||
|
||||
function colorIncrement (color, range) {
|
||||
return jQuery.map(toRGB(color.end), function(n, i) {
|
||||
return (n - toRGB(color.start)[i])/range;
|
||||
});
|
||||
}
|
||||
|
||||
function tagColor (color, increment, weighting) {
|
||||
rgb = jQuery.map(toRGB(color.start), function(n, i) {
|
||||
ref = Math.round(n + (increment[i] * weighting));
|
||||
if (ref > 255) {
|
||||
ref = 255;
|
||||
} else {
|
||||
if (ref < 0) {
|
||||
ref = 0;
|
||||
}
|
||||
}
|
||||
return ref;
|
||||
});
|
||||
return toHex(rgb);
|
||||
}
|
||||
|
||||
function compareWeights(a, b)
|
||||
{
|
||||
return a - b;
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
2
public/js/jquerymigrate.js
vendored
Normal file
2
public/js/jquerymigrate.js
vendored
Normal file
File diff suppressed because one or more lines are too long
12
public/js/kity.min.js
vendored
Normal file
12
public/js/kity.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
10
public/js/kityminder.core.min.js
vendored
Normal file
10
public/js/kityminder.core.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
3
public/js/lazysizes.min.js
vendored
Normal file
3
public/js/lazysizes.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
80
public/js/load-photoswipe.js
Normal file
80
public/js/load-photoswipe.js
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
Put this file in /static/js/load-photoswipe.js
|
||||
Documentation and licence at https://github.com/liwenyip/hugo-easy-gallery/
|
||||
*/
|
||||
|
||||
/* Show an alert if this js file has been loaded twice */
|
||||
if (window.loadphotoswipejs) {
|
||||
window.alert("You've loaded load-photoswipe.js twice. See https://github.com/liwenyip/hugo-easy-gallery/issues/6")
|
||||
}
|
||||
var loadphotoswipejs = 1
|
||||
|
||||
/* TODO: Make the share function work */
|
||||
$( document ).ready(function() {
|
||||
/*
|
||||
Initialise Photoswipe
|
||||
*/
|
||||
var items = []; // array of slide objects that will be passed to PhotoSwipe()
|
||||
// for every figure element on the page:
|
||||
$('figure').each( function() {
|
||||
if ($(this).attr('class') == 'no-photoswipe') return true; // ignore any figures where class="no-photoswipe"
|
||||
// get properties from child a/img/figcaption elements,
|
||||
var $figure = $(this),
|
||||
$a = $figure.find('a'),
|
||||
$img = $figure.find('img'),
|
||||
$src = $a.attr('href'),
|
||||
$title = $img.attr('alt'),
|
||||
$msrc = $img.attr('src');
|
||||
// if data-size on <a> tag is set, read it and create an item
|
||||
if ($a.data('size')) {
|
||||
var $size = $a.data('size').split('x');
|
||||
var item = {
|
||||
src : $src,
|
||||
w : $size[0],
|
||||
h : $size[1],
|
||||
title : $title,
|
||||
msrc : $msrc
|
||||
};
|
||||
console.log("Using pre-defined dimensions for " + $src);
|
||||
// if not, set temp default size then load the image to check actual size
|
||||
} else {
|
||||
var item = {
|
||||
src : $src,
|
||||
w : 800, // temp default size
|
||||
h : 600, // temp default size
|
||||
title : $title,
|
||||
msrc : $msrc
|
||||
};
|
||||
console.log("Using default dimensions for " + $src);
|
||||
// load the image to check its dimensions
|
||||
// update the item as soon as w and h are known (check every 30ms)
|
||||
var img = new Image();
|
||||
img.src = $src;
|
||||
var wait = setInterval(function() {
|
||||
var w = img.naturalWidth,
|
||||
h = img.naturalHeight;
|
||||
if (w && h) {
|
||||
clearInterval(wait);
|
||||
item.w = w;
|
||||
item.h = h;
|
||||
console.log("Got actual dimensions for " + img.src);
|
||||
}
|
||||
}, 30);
|
||||
}
|
||||
// Save the index of this image then add it to the array
|
||||
var index = items.length;
|
||||
items.push(item);
|
||||
// Event handler for click on a figure
|
||||
$figure.on('click', function(event) {
|
||||
event.preventDefault(); // prevent the normal behaviour i.e. load the <a> hyperlink
|
||||
// Get the PSWP element and initialise it with the desired options
|
||||
var $pswp = $('.pswp')[0];
|
||||
var options = {
|
||||
index: index,
|
||||
bgOpacity: 0.8,
|
||||
showHideOpacity: true
|
||||
}
|
||||
new PhotoSwipe($pswp, PhotoSwipeUI_Default, items, options).init();
|
||||
});
|
||||
});
|
||||
});
|
||||
50
public/js/mindmap.js
Normal file
50
public/js/mindmap.js
Normal file
@@ -0,0 +1,50 @@
|
||||
$(document).ready(function() {
|
||||
$('.mindmap').each(function() {
|
||||
MM_FUNCS.drawMindMap(this);
|
||||
});
|
||||
});
|
||||
|
||||
var MM_FUNCS = {
|
||||
// 将 li 节点转换为 JSON 数据
|
||||
li2jsonData: function(liNode) {
|
||||
var liData;
|
||||
var aNode = liNode.children("a:first");
|
||||
if (aNode.length !== 0) {
|
||||
liData = {
|
||||
"data": {
|
||||
"text": aNode.text(),
|
||||
"hyperlink": aNode.attr("href")
|
||||
}
|
||||
};
|
||||
} else {
|
||||
liData = {
|
||||
"data": {
|
||||
"text": liNode[0].childNodes[0].nodeValue.trim()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
liNode.find("> ul > li").each(function() {
|
||||
if (!liData.hasOwnProperty("children")) {
|
||||
liData.children = [];
|
||||
}
|
||||
liData.children.push(MM_FUNCS.li2jsonData($(this)));
|
||||
});
|
||||
|
||||
return liData;
|
||||
},
|
||||
// 绘制脑图
|
||||
drawMindMap: function(ulParent) {
|
||||
var ulElement = $(ulParent).find(">ul:first");
|
||||
var mmData = {"root": {}};
|
||||
var minder = new kityminder.Minder({
|
||||
renderTo: ulParent
|
||||
});
|
||||
|
||||
mmData.root = MM_FUNCS.li2jsonData(ulElement.children("li:first"));
|
||||
minder.importData('json', JSON.stringify(mmData));
|
||||
minder.disable();
|
||||
minder.execCommand('hand');
|
||||
$(ulElement).hide();
|
||||
}
|
||||
};
|
||||
1
public/js/mindmap.min.js
vendored
Normal file
1
public/js/mindmap.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
$(document).ready(function(){$(".mindmap").each(function(){MM_FUNCS.drawMindMap(this)})});var MM_FUNCS={li2jsonData:function(c){var a;var b=c.children("a:first");if(b.length!==0){a={"data":{"text":b.text(),"hyperlink":b.attr("href")}}}else{a={"data":{"text":c[0].childNodes[0].nodeValue.trim()}}}c.find("> ul > li").each(function(){if(!a.hasOwnProperty("children")){a.children=[]}a.children.push(MM_FUNCS.li2jsonData($(this)))});return a},drawMindMap:function(a){var d=$(a).find(">ul:first");var c={"root":{}};var b=new kityminder.Minder({renderTo:a});c.root=MM_FUNCS.li2jsonData(d.children("li:first"));b.importData("json",JSON.stringify(c));b.disable();b.execCommand("hand");$(d).hide()}};
|
||||
1
public/js/production.min.js
vendored
Normal file
1
public/js/production.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
59
public/js/reward.js
Normal file
59
public/js/reward.js
Normal file
@@ -0,0 +1,59 @@
|
||||
function ZanShang(){
|
||||
this.popbg = $('.zs-modal-bg');
|
||||
this.popcon = $('.zs-modal-box');
|
||||
this.closeBtn = $('.zs-modal-box .close');
|
||||
this.zsbtn = $('.zs-modal-btns .btn');
|
||||
this.zsPay = $('.zs-modal-pay');
|
||||
this.zsBtns = $('.zs-modal-btns');
|
||||
this.zsFooter = $('.zs-modal-footer');
|
||||
var that = this;
|
||||
$('.show-zs').on('click',function(){
|
||||
//点击赞赏按钮出现弹窗
|
||||
that._show();
|
||||
that._init();
|
||||
})
|
||||
}
|
||||
ZanShang.prototype._hide = function(){
|
||||
this.popbg.hide();
|
||||
this.popcon.hide();
|
||||
}
|
||||
ZanShang.prototype._show = function(){
|
||||
this.popbg.show();
|
||||
this.popcon.show();
|
||||
this.zsBtns.show();
|
||||
this.zsFooter.show();
|
||||
this.zsPay.hide();
|
||||
}
|
||||
ZanShang.prototype._init = function(){
|
||||
var that = this;
|
||||
this.closeBtn.on('click',function(){
|
||||
that._hide();
|
||||
})
|
||||
this.popbg.on('click',function(){
|
||||
that._hide();
|
||||
})
|
||||
this.zsbtn.each(function(el){
|
||||
$(this).on('click',function(){
|
||||
var num = $(this).attr('data-num'); //按钮的对应的数字
|
||||
var type = $('.zs-type:radio:checked').val();//付款方式
|
||||
//根据不同付款方式和选择对应的按钮的数字来生成对应的二维码图片,你可以自定义这个图片的路径,默认放在/img/reward目录中
|
||||
//假如你需要加一个远程路径,比如我的就是
|
||||
//http://zhaohuabing.com/img/reward/'+type+'-'+num+'.png';
|
||||
var src = '/img/reward/'+type+'-'+num+'.png';
|
||||
var text = $(this).html();
|
||||
var payType=$('#pay-type'), payImage = $('#pay-image'),payText = $('#pay-text');
|
||||
if(type=='alipay'){
|
||||
payType.html('支付宝');
|
||||
}else{
|
||||
payType.html('微信');
|
||||
}
|
||||
payImage.attr('src',src);
|
||||
payText.html(text);
|
||||
that.zsPay.show();
|
||||
that.zsBtns.hide();
|
||||
that.zsFooter.hide();
|
||||
|
||||
})
|
||||
})
|
||||
}
|
||||
var zs = new ZanShang();
|
||||
265
public/js/theme-toggle.js
Normal file
265
public/js/theme-toggle.js
Normal file
@@ -0,0 +1,265 @@
|
||||
/**
|
||||
* Theme Toggle Manager for Hugo CleanWhite Theme
|
||||
* Manages dark/light mode switching with system preference detection and localStorage persistence
|
||||
*/
|
||||
|
||||
const ThemeManager = (function() {
|
||||
'use strict';
|
||||
|
||||
const STORAGE_KEY = 'cleanwhite-theme';
|
||||
const THEMES = {
|
||||
LIGHT: 'light',
|
||||
DARK: 'dark'
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the current theme from localStorage or system preference
|
||||
*/
|
||||
function getStoredTheme() {
|
||||
try {
|
||||
const stored = localStorage.getItem(STORAGE_KEY);
|
||||
if (stored === THEMES.LIGHT || stored === THEMES.DARK) {
|
||||
return stored;
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Unable to access localStorage:', e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get system preference for dark mode
|
||||
*/
|
||||
function getSystemPreference() {
|
||||
// Check if user wants auto theme based on sunrise/sunset
|
||||
const useAutoTheme = document.documentElement.getAttribute('data-auto-theme') === 'true';
|
||||
|
||||
if (useAutoTheme) {
|
||||
return getSunriseSunsetTheme();
|
||||
}
|
||||
|
||||
// Fall back to system preference
|
||||
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
return THEMES.DARK;
|
||||
}
|
||||
return THEMES.LIGHT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate sunrise/sunset times and determine appropriate theme
|
||||
*/
|
||||
function getSunriseSunsetTheme() {
|
||||
const now = new Date();
|
||||
const hours = now.getHours();
|
||||
const minutes = now.getMinutes();
|
||||
const currentTime = hours + minutes / 60;
|
||||
|
||||
// Simple algorithm for sunrise/sunset based on day of year
|
||||
// Approximate values (can be improved with precise calculation)
|
||||
const dayOfYear = Math.floor((now - new Date(now.getFullYear(), 0, 0)) / (1000 * 60 * 60 * 24));
|
||||
|
||||
// Approximate sunrise/sunset times for mid-latitude locations
|
||||
// Sunrise ranges from ~6:30 to ~7:30 (varies by season)
|
||||
// Sunset ranges from ~16:30 to ~19:30 (varies by season)
|
||||
const baseSunrise = 6.5; // 6:30 AM
|
||||
const baseSunset = 18.5; // 6:30 PM
|
||||
|
||||
// Seasonal adjustment (±1 hour)
|
||||
const seasonalOffset = Math.sin((dayOfYear - 80) / 365 * 2 * Math.PI) * 1;
|
||||
|
||||
const sunriseTime = baseSunrise + seasonalOffset;
|
||||
const sunsetTime = baseSunset + seasonalOffset;
|
||||
|
||||
// Dark mode before sunrise or after sunset
|
||||
if (currentTime < sunriseTime || currentTime > sunsetTime) {
|
||||
return THEMES.DARK;
|
||||
}
|
||||
return THEMES.LIGHT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply theme to document
|
||||
*/
|
||||
function applyTheme(theme) {
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
|
||||
// Update toggle icon if it exists
|
||||
updateToggleIcon(theme);
|
||||
|
||||
// Update Giscus theme if it exists
|
||||
updateGiscusTheme(theme);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Giscus theme dynamically
|
||||
*/
|
||||
function updateGiscusTheme(theme) {
|
||||
const iframe = document.querySelector('iframe[src*="giscus.app"]');
|
||||
if (!iframe) return;
|
||||
|
||||
try {
|
||||
// Send postMessage to Giscus iframe to update theme
|
||||
iframe.contentWindow.postMessage({
|
||||
giscus: {
|
||||
setConfig: {
|
||||
theme: theme
|
||||
}
|
||||
}
|
||||
}, 'https://giscus.app');
|
||||
} catch (e) {
|
||||
// If iframe isn't ready yet, retry after a short delay
|
||||
console.warn('Failed to update Giscus theme, retrying...', e);
|
||||
setTimeout(function() {
|
||||
updateGiscusTheme(theme);
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the toggle button icon
|
||||
*/
|
||||
function updateToggleIcon(theme) {
|
||||
const toggleBtn = document.getElementById('theme-toggle');
|
||||
if (!toggleBtn) return;
|
||||
|
||||
const moonIcon = toggleBtn.querySelector('.fa-moon');
|
||||
const sunIcon = toggleBtn.querySelector('.fa-sun');
|
||||
|
||||
// Handle new method (both icons present, show/hide)
|
||||
if (moonIcon && sunIcon) {
|
||||
if (theme === THEMES.DARK) {
|
||||
moonIcon.style.display = 'none';
|
||||
sunIcon.style.display = 'inline';
|
||||
toggleBtn.setAttribute('title', 'Switch to light mode');
|
||||
} else {
|
||||
moonIcon.style.display = 'inline';
|
||||
sunIcon.style.display = 'none';
|
||||
toggleBtn.setAttribute('title', 'Switch to dark mode');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle old method (single icon, swap classes)
|
||||
const icon = toggleBtn.querySelector('i');
|
||||
if (!icon) return;
|
||||
|
||||
// Remove both classes
|
||||
icon.classList.remove('fa-moon', 'fa-sun');
|
||||
|
||||
// Add appropriate class
|
||||
if (theme === THEMES.DARK) {
|
||||
icon.classList.add('fa-sun');
|
||||
toggleBtn.setAttribute('title', 'Switch to light mode');
|
||||
} else {
|
||||
icon.classList.add('fa-moon');
|
||||
toggleBtn.setAttribute('title', 'Switch to dark mode');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set theme and save to localStorage
|
||||
*/
|
||||
function setTheme(theme) {
|
||||
// Add theme-switching class to disable transitions
|
||||
document.body.classList.add('theme-switching');
|
||||
|
||||
// Apply the theme
|
||||
applyTheme(theme);
|
||||
|
||||
// Save to localStorage
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY, theme);
|
||||
} catch (e) {
|
||||
console.warn('Unable to save theme preference:', e);
|
||||
}
|
||||
|
||||
// Remove theme-switching class after a brief delay
|
||||
setTimeout(() => {
|
||||
document.body.classList.remove('theme-switching');
|
||||
}, 50);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle between light and dark themes
|
||||
*/
|
||||
function toggle() {
|
||||
const currentTheme = document.documentElement.getAttribute('data-theme') || THEMES.LIGHT;
|
||||
const newTheme = currentTheme === THEMES.DARK ? THEMES.LIGHT : THEMES.DARK;
|
||||
setTheme(newTheme);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize theme on page load
|
||||
*/
|
||||
function init() {
|
||||
// Get stored theme or system preference
|
||||
const storedTheme = getStoredTheme();
|
||||
const theme = storedTheme || getSystemPreference();
|
||||
|
||||
// Apply theme immediately
|
||||
applyTheme(theme);
|
||||
|
||||
// Set up toggle button
|
||||
const toggleBtn = document.getElementById('theme-toggle');
|
||||
if (toggleBtn) {
|
||||
toggleBtn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
toggle();
|
||||
});
|
||||
}
|
||||
|
||||
// Check if auto-theme (sunrise/sunset) is enabled
|
||||
const useAutoTheme = document.documentElement.getAttribute('data-auto-theme') === 'true';
|
||||
|
||||
if (useAutoTheme && !storedTheme) {
|
||||
// Update theme every minute based on sunrise/sunset
|
||||
setInterval(function() {
|
||||
const newTheme = getSunriseSunsetTheme();
|
||||
const currentTheme = document.documentElement.getAttribute('data-theme');
|
||||
if (newTheme !== currentTheme) {
|
||||
applyTheme(newTheme);
|
||||
}
|
||||
}, 60000); // Check every minute
|
||||
}
|
||||
|
||||
// Watch for system preference changes (only if user hasn't set a manual preference)
|
||||
if (!storedTheme && !useAutoTheme && window.matchMedia) {
|
||||
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
if (mediaQuery.addEventListener) {
|
||||
mediaQuery.addEventListener('change', function(e) {
|
||||
const newTheme = e.matches ? THEMES.DARK : THEMES.LIGHT;
|
||||
applyTheme(newTheme);
|
||||
});
|
||||
} else if (mediaQuery.addListener) {
|
||||
// Fallback for older browsers
|
||||
mediaQuery.addListener(function(e) {
|
||||
const newTheme = e.matches ? THEMES.DARK : THEMES.LIGHT;
|
||||
applyTheme(newTheme);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Public API
|
||||
return {
|
||||
init: init,
|
||||
setTheme: setTheme,
|
||||
getTheme: function() {
|
||||
return document.documentElement.getAttribute('data-theme') || THEMES.LIGHT;
|
||||
},
|
||||
toggle: toggle,
|
||||
THEMES: THEMES
|
||||
};
|
||||
})();
|
||||
|
||||
// Initialize when DOM is ready
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', ThemeManager.init);
|
||||
} else {
|
||||
ThemeManager.init();
|
||||
}
|
||||
|
||||
// Export for use in other scripts if needed
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = ThemeManager;
|
||||
}
|
||||
Reference in New Issue
Block a user