Initial commit
[ghost-theme-work.git] / assets / js / main.js
1 /**
2 * Main JS file for Tawau
3 */
4
5 jQuery(document).ready(function($) {
6
7 var config = {
8 'share-selected-text': true,
9 'load-more': true,
10 'infinite-scroll': false,
11 'infinite-scroll-step': 3,
12 'disqus-shortname': 'hauntedthemes-demo',
13 'content-api-host': 'https://work.njae.me.uk',
14 'content-api-key': '',
15 };
16
17 var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0),
18 h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0),
19 checkMorph = false,
20 didScroll,
21 lastScrollTop = 0,
22 delta = 5;
23
24 var ghostAPI = new GhostContentAPI({
25 host: config['content-api-host'],
26 key: config['content-api-key'],
27 version: 'v2'
28 });
29
30 setGalleryRation();
31
32 // Execute on load
33 $(window).on('load', function(event) {
34
35 setGalleryRation();
36 setMorphHeight();
37
38 var currentPage = 1;
39 var pathname = window.location.pathname;
40 var $result = $('.post');
41 var step = 0;
42
43 // remove hash params from pathname
44 pathname = pathname.replace(/#(.*)$/g, '').replace('/\//g', '/');
45
46 if ($('body').hasClass('paged')) {
47 currentPage = parseInt(pathname.replace(/[^0-9]/gi, ''));
48 }
49
50 // Load more posts on click
51 if (config['load-more']) {
52
53 $('#load-posts').addClass('visible');
54
55 $('#load-posts').on('click', function(event) {
56 event.preventDefault();
57
58 if (currentPage == maxPages) {
59 $('#load-posts').addClass('hidden');
60 return;
61 };
62
63 var $this = $(this);
64
65 // next page
66 currentPage++;
67
68 if ($('body').hasClass('paged')) {
69 pathname = '/';
70 };
71
72 // Load more
73 var nextPage = pathname + 'page/' + currentPage + '/';
74
75 if ($this.hasClass('step')) {
76 setTimeout(function() {
77 $this.removeClass('step');
78 step = 0;
79 }, 1000);
80 };
81
82 $.get(nextPage, function (content) {
83 step++;
84 var post = $(content).find('.post').addClass('hidden');
85 $('#content.loop').append( post );
86 $.each(post, function(index, val) {
87 var $this = $(this);
88 var id = $(this).attr('data-id');
89 $('#content.loop').imagesLoaded( function() {
90 $this.removeClass('hidden');
91 });
92 });
93 });
94
95 });
96 };
97
98 if (config['infinite-scroll'] && config['load-more']) {
99 var checkTimer = 'on';
100 if ($('#load-posts').length > 0) {
101 $(window).on('scroll', function(event) {
102 var timer;
103 if (isScrolledIntoView('#load-posts') && checkTimer == 'on' && step < config['infinite-scroll-step']) {
104 $('#load-posts').click();
105 checkTimer = 'off';
106 timer = setTimeout(function() {
107 checkTimer = 'on';
108 if (step == config['infinite-scroll-step']) {
109 $('#load-posts').addClass('step');
110 };
111 }, 1000);
112 };
113 });
114 };
115 };
116
117 });
118
119 // Add classes and attributes for Fluidbox library
120 $('.post-content img').each(function(index, el) {
121 if (!$(this).parent().is("a") && !$(this).hasClass('error')) {
122 $( "<a href='" + $(this).attr('src') + "' class='zoom'></a>" ).insertAfter( $(this) );
123 $(this).appendTo($(this).next("a"));
124 };
125 });
126
127 $('.zoom').fluidbox();
128
129 var shareHeight = $('.content-inner .social-share').height();
130 $(window).on('scroll', function(event) {
131 $('.zoom').fluidbox('close');
132
133 var checkShare = 0;
134
135 $('.content-inner .kg-image-wide, .content-inner .kg-image-full').each(function(index, el) {
136 var scrollTop = $(window).scrollTop();
137 var elementOffset = $(this).offset().top;
138 var imgDistance = (elementOffset - scrollTop);
139 var imgHeight = $(this).height();
140 var shareDistance = shareHeight + 100;
141 if (imgDistance < shareDistance && (imgDistance + imgHeight) > 100) {
142 checkShare++;
143 };
144 });
145
146 if (checkShare > 0) {
147 $('.content-inner .social-share').addClass('fade');
148 }else{
149 $('.content-inner .social-share').removeClass('fade');
150 };
151
152 });
153
154 // Initialize shareSelectedText
155 if (config['share-selected-text']) {
156 shareSelectedText('.content-inner .post-content', {
157 sanitize: true,
158 buttons: [
159 'twitter',
160 ],
161 tooltipTimeout: 250
162 });
163 };
164
165 // Position social share buttons inside a single post
166 var checkIfSticky = 0;
167 if (w >= 992) {
168 stickIt();
169 checkIfSticky = 1;
170 };
171
172 // Initialize Disqus comments
173 if ($('#content').attr('data-id') && config['disqus-shortname'] != '') {
174
175 $('.comments').append('<div id="disqus_thread"></div>')
176
177 var url = [location.protocol, '//', location.host, location.pathname].join('');
178 var disqus_config = function () {
179 this.page.url = url;
180 this.page.identifier = $('#content').attr('data-id');
181 };
182
183 (function() {
184 var d = document, s = d.createElement('script');
185 s.src = '//'+ config['disqus-shortname'] +'.disqus.com/embed.js';
186 s.setAttribute('data-timestamp', +new Date());
187 (d.head || d.body).appendChild(s);
188 })();
189 };
190
191 // Search and Menu triggers
192 $('.search-trigger, .nav-trigger').on('click', function(event) {
193 event.preventDefault();
194
195 var className = event.currentTarget.className;
196
197 if ($('body').hasClass('scroll') && !$('body').hasClass('overflow-y')) {
198 return;
199 };
200
201 if ($('body, html').hasClass('end-search-trigger') && $(this).hasClass('nav-trigger')) {
202 $('body, html').removeClass('begin-search-trigger end-search-trigger').addClass('begin-nav-trigger end-nav-trigger');
203 return;
204 };
205
206 if ($('body, html').hasClass('end-nav-trigger') && $(this).hasClass('search-trigger')) {
207 $('body, html').removeClass('begin-nav-trigger end-nav-trigger').addClass('begin-search-trigger end-search-trigger');
208 return;
209 };
210
211 if (!$('body').hasClass('end')) {
212 if (!$('body').hasClass('begin')) {
213 morphStart(className);
214 };
215 }else{
216 morphReverse(className);
217 }
218 });
219
220 var ghostSearch = new GhostSearch({
221 host: config['content-api-host'],
222 key: config['content-api-key'],
223 input: '#search-field',
224 results: '#results',
225 template: function(result) {
226 let url = [location.protocol, '//', location.host].join('');
227 return '<li><a href="' + url + '/' + result.slug + '/">' + result.title + '</a></li>';
228 },
229 });
230
231 // Validate Subscribe input
232 $('.gh-signin').on('submit', function(event) {
233 var email = $('.gh-input').val();
234 if (!validateEmail(email)) {
235 $('.gh-input').addClass('error');
236 setTimeout(function() {
237 $('.gh-input').removeClass('error');
238 }, 500);
239 event.preventDefault();
240 };
241 });
242
243 // Animation for shareSelectedText
244 $('.tooltip').prependTo('.share-selected-text-inner');
245 $('.share-selected-text-btn').prependTo('.tooltip-content');
246
247 const config_tooltip = {
248 in: {
249 base: {
250 duration: 200,
251 easing: 'easeOutQuad',
252 rotate: [35,0],
253 opacity: {
254 value: 1,
255 easing: 'linear',
256 duration: 100
257 }
258 },
259 content: {
260 duration: 1000,
261 delay: 50,
262 easing: 'easeOutElastic',
263 translateX: [50,0],
264 rotate: [10, 0],
265 opacity: {
266 value: 1,
267 easing: 'linear',
268 duration: 100
269 }
270 },
271 trigger: {
272 translateX: [
273 {value: '-30%', duration: 130, easing: 'easeInQuad'},
274 {value: ['30%','0%'], duration: 900, easing: 'easeOutElastic'}
275 ],
276 opacity: [
277 {value: 0, duration: 130, easing: 'easeInQuad'},
278 {value: 1, duration: 130, easing: 'easeOutQuad'}
279 ],
280 color: [
281 {value: '#6fbb95', duration: 1, delay: 130, easing: 'easeOutQuad'}
282 ]
283 }
284 },
285 out: {
286 base: {
287 duration: 200,
288 delay: 100,
289 easing: 'easeInQuad',
290 rotate: -35,
291 opacity: 0
292 },
293 content: {
294 duration: 200,
295 easing: 'easeInQuad',
296 translateX: -30,
297 rotate: -10,
298 opacity: 0
299 },
300 trigger: {
301 translateX: [
302 {value: '-30%', duration: 200, easing: 'easeInQuad'},
303 {value: ['30%','0%'], duration: 200, easing: 'easeOutQuad'}
304 ],
305 opacity: [
306 {value: 0, duration: 200, easing: 'easeInQuad'},
307 {value: 1, duration: 200, easing: 'easeOutQuad'}
308 ],
309 color: [
310 {value: '#666', duration: 1, delay: 200, easing: 'easeOutQuad'}
311 ]
312 }
313 }
314 };
315
316 $('.tooltip').each(function(index, el) {
317 var $this = $(this);
318 var base = $(this).find('.tooltip-base')[0];
319 var content = $(this).find('.tooltip-content')[0];
320 $('.content-inner .post-content').bind('mouseup', function(e){
321 if (window.getSelection || document.selection) {
322 var sel = window.getSelection();
323 $this.mouseTimeout = setTimeout(function() {
324 $this.isShown = true;
325 animateTooltip('in', base, content);
326 }, 500);
327 }
328 });
329 $('body').bind('mousedown', function(e){
330 if (window.getSelection || document.selection) {
331 clearTimeout($this.mouseTimeout);
332 if( $this.isShown ) {
333 $this.isShown = false;
334 animateTooltip('out', base, content);
335 }
336 }
337 });
338 });
339
340 if (typeof Object.assign != 'function') {
341 Object.assign = function(target) {
342 'use strict';
343 if (target == null) {
344 throw new TypeError('Cannot convert undefined or null to object');
345 }
346
347 target = Object(target);
348 for (var index = 1; index < arguments.length; index++) {
349 var source = arguments[index];
350 if (source != null) {
351 for (var key in source) {
352 if (Object.prototype.hasOwnProperty.call(source, key)) {
353 target[key] = source[key];
354 }
355 }
356 }
357 }
358 return target;
359 };
360 }
361
362 // On scroll check if header should be visible or not
363 $(window).on('scroll', function(event) {
364 didScroll = true;
365 });
366
367 setInterval(function() {
368 if (didScroll && checkMorph == false) {
369 hasScrolled();
370 didScroll = false;
371 }
372 }, 250);
373
374 // Execute on resize
375 $(window).on('resize', function () {
376
377 w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
378
379 if (w < 960) {
380 $('.content-inner .post-content .social-share').trigger("sticky_kit:detach");
381 checkIfSticky = 0;
382 }else{
383 if (checkIfSticky == 0) {
384 stickIt();
385 checkIfSticky++;
386 }
387 };
388
389 setMorphHeight();
390
391 });
392
393 // Tawau's functions
394
395 // Check if element is into view when scrolling
396 function isScrolledIntoView(elem){
397 var docViewTop = $(window).scrollTop();
398 var docViewBottom = docViewTop + $(window).height();
399
400 var elemTop = $(elem).offset().top;
401 var elemBottom = elemTop + $(elem).height();
402
403 return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
404 }
405
406 // Get first number of words from a string
407 function getWords(str) {
408 return str.split(/\s+/).slice(0,44).join(" ");
409 }
410
411 // Morph effect start
412 function morphStart(c){
413 var morphing = anime({
414 targets: '#morphing .path',
415 d: [
416 { value: 'M 10,0 L 10,0 C 10,0 10,0 5,0 C 0,0 0,0 0,0 L 0,0 Z' },
417 { value: 'M 10,0 L 10,0 C 10,0 10,5 5,5 C 0,5 0,0 0,0 L 0,0 Z' },
418 { value: 'M10 0 L10 10 C10 10 10 10 5 10 C0 10 0 10 0 10 L0 0 '}
419 ],
420 easing: 'easeInOutQuint',
421 duration: 1000,
422 loop: false,
423 });
424
425 morphing.begin = function(){
426 $('body, html').addClass('overflow-y begin ' + 'begin-' + c);
427 }
428
429 morphing.complete = function(){
430 $('body, html').addClass('overflow-y end ' + 'end-' + c);
431 setTimeout(function() {
432 $('#search-field').focus();
433 }, 100);
434 }
435
436 }
437
438 // Morph effect reverse
439 function morphReverse(c){
440 var morphing = anime({
441 targets: '#morphing .path',
442 d: [
443 { value: 'M10 0 L10 10 C10 10 10 10 5 10 C0 10 0 10 0 10 L0 0' },
444 { value: 'M 10,0 L 10,0 C 10,0 10,5 5,5 C 0,5 0,0 0,0 L 0,0 Z' },
445 { value: 'M 10,0 L 10,0 C 10,0 10,0 5,0 C 0,0 0,0 0,0 L 0,0 Z '}
446 ],
447 easing: 'easeInOutQuint',
448 duration: 1000,
449 loop: false
450 });
451
452 morphing.begin = function(){
453 $('body, html').removeClass('overflow-y end ' + 'end-' + c);
454 checkMorph = true;
455 }
456
457 morphing.complete = function(){
458 $('body, html').removeClass('overflow-y begin ' + 'begin-' + c);
459 checkMorph = false;
460 }
461
462 }
463
464 // Validate email input
465 function validateEmail(email) {
466 var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
467 return re.test(email);
468 }
469
470 // Set morph height
471 function setMorphHeight(){
472 var headerContainerHeight = $('header .header-container').outerHeight();
473
474 $('#morphing').css({
475 top: headerContainerHeight + 'px',
476 height: 'calc(100vh - '+ headerContainerHeight +'px)'
477 });
478 }
479
480 // Animate tooltip for shareSelectedText
481 function animateTooltip(dir, base, content){
482 if ( config_tooltip[dir].base ) {
483 anime.remove(base);
484 var baseAnimOpts = {targets: base};
485 anime(Object.assign(baseAnimOpts, config_tooltip[dir].base));
486 }
487 if ( config_tooltip[dir].content ) {
488 anime.remove(content);
489 var contentAnimOpts = {targets: content};
490 anime(Object.assign(contentAnimOpts, config_tooltip[dir].content));
491 }
492 }
493
494 // Initialize stick_in_parent
495 function stickIt(){
496 $('.content-inner .post-content .social-share').stick_in_parent({
497 offset_top: 150
498 });
499 }
500
501 // Show/Hide menu on scroll
502 function hasScrolled() {
503 var st = $(this).scrollTop();
504
505 if(Math.abs(lastScrollTop - st) <= delta)
506 return;
507
508 if(st <= 0 || lastScrollTop <= 0){
509 console.log('do this');
510 $('body').removeClass('scroll');
511 }else if (st > lastScrollTop){
512 $('body').addClass('scroll');
513 } else {
514 if(st + $(window).height() < $(document).height()) {
515 $('body').removeClass('scroll');
516 }
517 }
518
519 lastScrollTop = st;
520 }
521
522 // Initialize Highlight.js
523 $('pre code').each(function(i, block) {
524 hljs.highlightBlock(block);
525 });
526
527 // Set the right proportion for images inside the gallery
528 function setGalleryRation(){
529 $('.kg-gallery-image img').each(function(index, el) {
530 var container = $(this).closest('.kg-gallery-image');
531 var width = $(this)[0].naturalWidth;
532 var height = $(this)[0].naturalHeight;
533 var ratio = width / height;
534 container.attr('style', 'flex: ' + ratio + ' 1 0%');
535 });
536 }
537
538 });