// TODO: Inhalte angleichen nach Zusammenfassung von app.js und function.js. // Bennung und Beschreibungen verbessern. // This is called everytime function setup() { 'use strict'; console.group('Document information'); console.info('\n', hippie.brand, '\n\n'); console.info('HTML:', hippie.screen, '\nBODY:', hippie.body); console.groupEnd(); if (debugOn) { console.group('Debug information'); console.dir(hippie); console.groupEnd(); } } // MODULE Scroll navigation // Using constructor function function HippieScroll($tp, $dn) { 'use strict'; // this.$tp = $tp; // Define initial situation let initLeft = false; const initY = hippie.screen.vh; $tp.addClass('di_none'); // Check scroll position and toggle element this.check = function () { hippie.screen.y = Math.min($(document).scrollTop(), document.documentElement.scrollTop); if (hippie.screen.y > initY) { if (!initLeft) { $tp.removeClass('di_none'); console.info('Initial viewport left'); } initLeft = true; } else { if (initLeft) { $tp.addClass('di_none'); console.info('Initial viewport entered'); } initLeft = false; } }; // Add events to navigation elements $tp.click(function (event) { event.preventDefault(); $('html, body').stop().animate({ scrollTop: 0 }, basicEase); // console.log('Scrolled to top'); }); $dn.click(function (event) { event.preventDefault(); var pos = Math.max(hippie.screen.dh, hippie.body.h) - hippie.screen.vh; $('html').scrollTop(pos); // document.documentElement.scrollTop = pos; console.info('Scrolled down to', pos); }); } function HippieFade(toggleElement, initState) { 'use strict'; const fragment = document.createDocumentFragment(); const overlay = document.createElement('div'); overlay.id = 'mouse-overlay'; if (initState) { overlay.classList.add('active'); } toggleElement.addEventListener('click', function () { overlay.classList.toggle('active'); }); fragment.appendChild(overlay); document.body.style.position = 'relative'; document.body.prepend(fragment); } // MODULE Meta elements function HippieMeta($ma, $pp) { 'use strict'; let metaOn = false; $ma.click(function () { var $wrap, $pop; // if (metaOn !== true) { if (!metaOn) { metaOn = true; $pp.each(function () { // if ($(this).css('position') === 'static') { // $(this).addClass('js_changed_pos'); // $(this).css('position', 'relative'); // } // $pop = $(this).next('.exp_pop').detach(); // $wrap = $(this).wrap('').parent().prepend('').prepend(''); // $wrap.after($pop); $('
').addClass('exp_overlay').css({ position: 'absolute', width: '100%', height: '100%', top: 0, left: 0 }).appendTo($(this).addClass('exp_wrap')); // Displays explanation popup following the mouse $(this).on({ mouseenter: function () { // if ($(this).attr('emmet')) { // // } $(this).next('.exp_pop').show(); }, mouseleave: function () { $(this).next('.exp_pop').hide(); }, mousemove: function (event) { $(this).next('.exp_pop').css({ 'top': event.pageY - $(this).next('.exp_pop').outerHeight() - 4, 'left': event.pageX + 8 // 'left': event.pageX - $(this).offset().left + 8 }); } }); }); } else { $pp.each(function () { $(this).off('mouseenter mouseleave mousemove'); $(this).removeClass('exp_wrap').find('.exp_overlay').remove(); // $wrap = $(this).parent('.exp_wrap'); // $pop = $wrap.next('.exp_pop').detach(); // $wrap.find('.exp_marker_pop').remove(); // $(this).unwrap('.exp_wrap'); // $(this).after($pop); // if ($(this).hasClass('js_changed_pos')) { // $(this).css('position', ''); // if ($(this).attr('style') === '') { // $(this).removeAttr('style'); // } // $(this).removeClass('js_changed_pos'); // } }); metaOn = false; } console.log('Explanation mode', metaOn); }); } // Sets the href attribute to mailto: with given information function composeMail(tag, name, prov, suffix, text, topic) { let trigger = tag.indexOf("."); let mailString = name + '@' + prov + '.' + suffix; let textString = mailString.replace(/@/g, "(at)"); let descString = "Nachricht an " + mailString; if (!text) { text = mailString; } else if (text === "at") { text = textString; } else if (text === "to") { text = descString; } if (topic) { topic = "?subject=" + topic; } else { topic = ""; } if (trigger === -1) { const el = document.getElementById(tag); const elContent = el.innerHTML; el.innerHTML = elContent + text; el.setAttribute("href", "mailto:" + mailString + topic); } else { const els = document.getElementsByClassName(tag.slice(1)); for (let el of els) { const elContent = el.innerHTML; el.innerHTML = elContent + text; el.setAttribute("href", "mailto:" + mailString + topic); } } } // get document coordinates of the element // function getCoords (elem) { // let box = elem.getBoundingClientRect(); // // return { // top: box.top + pageYOffset, // left: box.left + pageXOffset // }; // } // https://stackoverflow.com/a/488073/1444149 // function Utils () {} // // Utils.prototype = { // constructor: Utils, // isElementInView: function (element, fullyInView) { // var pageTop = $(window).scrollTop(); // var pageBottom = pageTop + $(window).height(); // var elementTop = $(element).offset().top; // var elementBottom = elementTop + $(element).height(); // // if (fullyInView === true) { // return ((pageTop < elementTop) && (pageBottom > elementBottom)); // } else { // return ((elementTop <= pageBottom) && (elementBottom >= pageTop)); // } // } // }; // // var Utils = new Utils(); class TimeDisplay { constructor(element, options, interval) { this.element = element; this.options = options || {hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false}; this.interval = interval || 1000; this.isPaused = false; this.locale = navigator.language || 'en-US'; this.updateTime(); console.group('Time information'); console.info('\nOptions:', this.options, '\n\n'); console.info('Interval:', this.interval); console.groupEnd(); } formatTime(time) { return time.toLocaleTimeString(this.locale, this.options); } // TODO: Zeit nur im Sekundentakt aktualisieren wenn Sekunden angezeigt werden async updateTime() { while (true) { if (!this.isPaused) { const now = new Date(); this.element.textContent = this.formatTime(now); } await new Promise(resolve => setTimeout(resolve, this.interval)); } } pause() { this.isPaused = true; } resume() { this.isPaused = false; } } class DateDisplay { constructor(element, options, direction) { this.element = element; this.options = options || {year: 'numeric', month: 'long', day: 'numeric'}; this.direction = direction || 0; this.updateDate(); this.checkForDateChange(); console.group('Date information'); console.info('\nOptions:', this.options, '\n\n'); console.info('Remaining minutes:', Math.floor(this.getTimeUntilNextMidnight() / 3600)); console.groupEnd(); } formatDate(date) { const formatter = new Intl.DateTimeFormat(navigator.language, this.options); switch (this.direction) { case 1: const dateString = formatter .formatToParts(date) .map(({type, value}) => { // if (type === 'day' || type === 'month') { if (type === 'literal') { return `${value}