diff --git a/.eleventy.js b/.eleventy.js index 00dded1..b5468e2 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -14,14 +14,14 @@ module.exports = function (eleventyConfig) { trimBlocks: true }); - eleventyConfig.addGlobalData("permalink", () => { + eleventyConfig.addGlobalData('permalink', () => { return (data) => `${data.page.filePathStem}.${data.page.outputFileExtension}`; }); let demoMode = false; let pageBase = demoMode ? './demo/' : './'; - eleventyConfig.addGlobalData("hippie", { + eleventyConfig.addGlobalData('hippie', { pageBase: pageBase, brand: 'hippie', titlePrefix: '', @@ -30,32 +30,32 @@ module.exports = function (eleventyConfig) { legacyMode: false }); - eleventyConfig.addPassthroughCopy({"source/art/images": "art"}); + eleventyConfig.addPassthroughCopy({'source/art/images': 'art'}); - eleventyConfig.addPassthroughCopy({"source/art/favicons/**/*.+(ico|png|svg)": "."}); + eleventyConfig.addPassthroughCopy({'source/art/favicons/**/*.+(ico|png|svg)': '.'}); - eleventyConfig.addPassthroughCopy({"source/code/**/*.js": "js"}); + eleventyConfig.addPassthroughCopy({'source/code/**/*.js': 'js'}); - eleventyConfig.addPassthroughCopy({"source/data/**/*.json": "json"}); + eleventyConfig.addPassthroughCopy({'source/data/**/*.json': 'json'}); - eleventyConfig.addPassthroughCopy("vendor"); - eleventyConfig.addPassthroughCopy({"node_modules/bootstrap-icons": "vendor/bootstrap-icons"}); + eleventyConfig.addPassthroughCopy('vendor'); + eleventyConfig.addPassthroughCopy({'node_modules/bootstrap-icons': 'vendor/bootstrap-icons'}); eleventyConfig.addPassthroughCopy({ - "node_modules/jquery/dist/jquery.min.js": "vendor", - "node_modules/jquery/dist/jquery.min.map": "vendor" + 'node_modules/jquery/dist/jquery.min.js': 'vendor/jquery.min.js', + 'node_modules/jquery/dist/jquery.min.map': 'vendor/jquery.min.map' }); // eleventyConfig.addPassthroughCopy({"node_modules/normalize.css/normalize.css": "vendor/normalize.css"}); - eleventyConfig.addWatchTarget("./source/style/"); + eleventyConfig.addWatchTarget('./source/style/'); return { dir: { - input: "source/screens", - output: "build", - includes: "../templates", - data: "../data" + input: 'source/screens', + output: 'build', + includes: '../templates', + data: '../data' }, - templateFormats: ["html", "liquid", "njk", "md"] + templateFormats: ['html', 'liquid', 'njk', 'md'] // pathPrefix: './demo/' }; }; diff --git a/.jshintrc b/.jshintrc index 7554aff..e11b79d 100644 --- a/.jshintrc +++ b/.jshintrc @@ -7,25 +7,25 @@ // Enforcing "bitwise" : true, // true: Prohibit bitwise operators (&, |, ^, etc.) "camelcase" : false, // true: Identifiers must be in camelCase - "curly" : true, // true: Require {} for every new block or scope + "curly" : false, // true: Require {} for every new block or scope "eqeqeq" : true, // true: Require triple equals (===) for comparison "forin" : true, // true: Require filtering for..in loops with obj.hasOwnProperty() "freeze" : true, // true: prohibits overwriting prototypes of native objects such as Array, Date etc. "immed" : false, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());` - "latedef" : false, // true: Require variables/functions to be defined before being used - "newcap" : false, // true: Require capitalization of all constructor functions e.g. `new F()` + "latedef" : true, // true: Require variables/functions to be defined before being used + "newcap" : true, // true: Require capitalization of all constructor functions e.g. `new F()` "noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee` "noempty" : true, // true: Prohibit use of empty blocks "nonbsp" : true, // true: Prohibit `non-breaking whitespace` characters. "nonew" : false, // true: Prohibit use of constructors for side-effects (without assignment) "plusplus" : false, // true: Prohibit use of `++` and `--` - "quotmark" : false, // Quotation mark consistency: + "quotmark" : true, // Quotation mark consistency: // false : do nothing (default) // true : ensure whatever is used is consistent // "single" : require single quotes // "double" : require double quotes "undef" : true, // true: Require all non-global variables to be declared (prevents global leaks) - "unused" : false, // Unused variables: + "unused" : true, // Unused variables: // true : all variables, last function parameter // "vars" : all variables only // "strict" : all variables, all function parameters @@ -42,7 +42,7 @@ "boss" : false, // true: Tolerate assignments where comparisons would be expected "debug" : false, // true: Allow debugger statements e.g. browser breakpoints. "eqnull" : false, // true: Tolerate use of `== null` - "esversion" : 6, // {int} Specify the ECMAScript version to which the code must adhere. + "esversion" : 9, // {int} Specify the ECMAScript version to which the code must adhere. "moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features) // (ex: `for each`, multiple try/catch, function expression…) "evil" : false, // true: Tolerate use of `eval` and `new Function()` diff --git a/source/code/app.js b/source/code/app.js deleted file mode 100644 index 8632638..0000000 --- a/source/code/app.js +++ /dev/null @@ -1,149 +0,0 @@ -//NEW - -function Clock(id) { - this.id = id; - - var that = this; - setInterval(function () { that.updateClock(); }, 1000); - this.updateClock(); -} - -Clock.prototype.updateClock = function () { - var date = new Date(); - var clock = document.getElementById(this.id); - //console.log(this); - clock.innerHTML = this.formatDigits(date.getHours()) + ":" + this.formatDigits(date.getMinutes()) + ":" + this.formatDigits(date.getSeconds()); -}; - -Clock.prototype.formatDigits = function (val) { - if (val < 10) val = "0" + val; - - return val; -} - -//OLD - -var floor = Math.floor; - -function ongoing() { - - var now = new Date(); - - var w = Math.floor(now.getDay()); - var D = new Array("Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"); - var DNumb = Math.floor(now.getDate()); - var MNumb = Math.floor(now.getMonth()); - var M = new Array("Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"); - var y = Math.floor(now.getYear()); - if (y < 999) y += 1900; - - var ms = Math.floor(now.getMilliseconds()); - var s = Math.floor(now.getSeconds()); - var m = Math.floor(now.getMinutes() + s / 60); - var h = Math.floor(now.getHours() + m / 60); - - var j2000 = new Date(); // Bezugspunkt ist der 1.1.2000 0:00 UT (entspricht JD 2451544,5) - j2000.setUTCFullYear(2000, 0, 1); - j2000.setUTCHours(0, 0, 0, 0); - - var utc = new Date(); - utc.setUTCFullYear(y, MNumb, DNumb); // Monate müssen im Wertebereich 0...11 übergeben werden - utc.setUTCHours(h, m, s, ms); - - var utc0 = new Date(); - utc0.setUTCFullYear(y, MNumb, DNumb); - utc0.setUTCHours(0, 0, 0, 0); - - var jd = 2451544.5 + (utc - j2000) / 86400000; // Zählung erfolgt in Millisekunden, 1 Tag = 86.400.000 ms - var jdUTC0 = 2451544.5 + (utc0 - j2000) / 86400000; - - var N = jd - 2451545.0; - var L = 280.460 + 0.9856474 * N; // mittlere ekliptikale Länge der Sonne - var g = 357.528 + 0.9856003 * N; // mittlere Anomalie - var el = L + 1.915 * Math.sin(g) + 0.020 * Math.sin(2 * g); - var e = 23.439 - 0.0000004 * N; - var rektaszension = Math.atan((Math.cos(e) * Math.sin(el)) / Math.cos(el)); - - var T = (jdUTC0 - 2451545.0) / 36525; - var stGMT = (((6 * 3600) + (41 * 60) + 50.54841) + (8640184.812866 * T) + (0.093104 * Math.pow(T, 2)) - (0.0000062 * Math.pow(T, 3))) / 3600; - - var stGMT2 = 6.697376 + 2400.05134 * T + 1.002738 * T; - var hWGMT = stGMT2 * 15; - var hW = hWGMT + 11.9566185772; - - var st = (stGMT + (now.getUTCHours() * 1.00273790935)) + (11.9566185772 / 15); // Sommerzeit muss noch berücksichtigt werden - var st24 = Math.abs(st - (Math.round(st / 24) * 24)); - var stH = Math.floor(st24); - var stM = Math.floor((st24 % 1) * 60); - var stS = zeroFill(Math.floor((((st24 % 1) * 60) % 1) * 60), 2); - - var travelWidth = document.body.clientWidth; - var travelHeight = document.body.clientHeight; - var sunPosX = 0; - var sunPosY = 0; - var moonPosX = 0; - var moonPosY = 0; - - var sun = $("#sun").css({ - "left": (s / 60) * travelWidth, - "top": (m / 60) * travelHeight - }); - - $("#day").text(D[w]); - $("#dayNumb").text(DNumb); - $("#month").text(M[MNumb]); - $("#year").text(y); - $("#time").text('' + zeroFill(h, 2) + ':' + zeroFill(m, 2) + ':' + zeroFill(s, 2)); - - $("#julian").text(jd.toFixed(6)); - //$("#star").text(stH + ':' + stM + ':' + stS); - $("#star").text(stH + ':' + stM); - $("#star1").text(stGMT); - $("#star2").text(stGMT2); - -} - -function zeroFill(number, width) { - width -= number.toString().length; - if (width > 0) { - return new Array(width + (/\./.test(number) ? 2 : 1)).join('0') + number; - } - return number + ""; // always return a string -} - -//Länge der Balken im Diagram berechnen -function barwidth(size, G, W) { - var s = size; - var g = G; - var w = W; - var p = (w / g) * 100; - var newW = s * (p / 100); - - return newW; -} -//String Element erweitern -String.prototype.transform = function () { - return parseFloat(this.replace(',', '.')); -} -//Array Element erweitern -Array.prototype.arrayAdd = function () { - return eval(this.join("+")); -} -//Speicherplatz in Prozent berechnen -function percentage(total, gigs, round) { - var totalSpace = total; - var singleSpace = gigs; - var z = round; - var p = singleSpace / (totalSpace / 100); - - return p; -} -//Speicherplatz in GB berechnen -function gigabytes(percent, total, round) { - var occupiedPercent = percent; - var singleSpace = total; - var z = round; - var g = (singleSpace / 100) * occupiedPercent; - - return g; -} diff --git a/source/code/hippie/app.js b/source/code/hippie/app.js new file mode 100644 index 0000000..4da28e0 --- /dev/null +++ b/source/code/hippie/app.js @@ -0,0 +1,533 @@ +// 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}
`; + } else { + return value; + } + }) + .join(''); + + return dateString; + case 0: + default: + return formatter.format(date); + } + } + + updateDate() { + const now = new Date(); + + this.element.innerHTML = this.formatDate(now); + } + + changeFormat(format, direction) { + this.options = format; + this.direction = direction; + + this.updateDate(); + } + + getTimeUntilNextMidnight() { + const now = new Date(); + const nextMidnight = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1); + + return nextMidnight - now; + } + + checkForDateChange() { + const timeUntilNextMidnight = this.getTimeUntilNextMidnight(); + + setTimeout(() => { + this.updateDate(); + this.checkForDateChange(); + }, timeUntilNextMidnight); + } +} + +// CONCEPTS + +// NOTE: Benutzt private Zuweisungen +class elementBinder { + #element; + + constructor(element) { + this.#setElement(element); + } + + #setElement(value) { + if (!value) { + throw new Error('No element found'); + } + this.#element = value; + this.#element.style.background = "hotpink"; + } + + get element() { + return this.#element; + } + + set element(value) { + this.#setElement(value); + } +} + +//OLD + +function Clock(id) { + 'use strict'; + + this.id = id; + const that = this; + + setInterval(function () { + that.updateClock(); + }, 1000); + this.updateClock(); +} + +Clock.prototype.updateClock = function () { + 'use strict'; + + const date = new Date(); + const clock = document.getElementById(this.id); + //console.log(this); + clock.innerHTML = this.formatDigits(date.getHours()) + ':' + this.formatDigits(date.getMinutes()) + ":" + this.formatDigits(date.getSeconds()); +}; + +Clock.prototype.formatDigits = function (val) { + 'use strict'; + + if (val < 10) val = '0' + val; + + return val; +}; + +var floor = Math.floor; + +function ongoing() { + + var now = new Date(); + + var w = Math.floor(now.getDay()); + var D = new Array("Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"); + var DNumb = Math.floor(now.getDate()); + var MNumb = Math.floor(now.getMonth()); + var M = new Array("Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"); + var y = Math.floor(now.getYear()); + if (y < 999) y += 1900; + + var ms = Math.floor(now.getMilliseconds()); + var s = Math.floor(now.getSeconds()); + var m = Math.floor(now.getMinutes() + s / 60); + var h = Math.floor(now.getHours() + m / 60); + + var j2000 = new Date(); // Bezugspunkt ist der 1.1.2000 0:00 UT (entspricht JD 2451544,5) + j2000.setUTCFullYear(2000, 0, 1); + j2000.setUTCHours(0, 0, 0, 0); + + var utc = new Date(); + utc.setUTCFullYear(y, MNumb, DNumb); // Monate müssen im Wertebereich 0...11 übergeben werden + utc.setUTCHours(h, m, s, ms); + + var utc0 = new Date(); + utc0.setUTCFullYear(y, MNumb, DNumb); + utc0.setUTCHours(0, 0, 0, 0); + + var jd = 2451544.5 + (utc - j2000) / 86400000; // Zählung erfolgt in Millisekunden, 1 Tag = 86.400.000 ms + var jdUTC0 = 2451544.5 + (utc0 - j2000) / 86400000; + + var N = jd - 2451545.0; + var L = 280.460 + 0.9856474 * N; // mittlere ekliptikale Länge der Sonne + var g = 357.528 + 0.9856003 * N; // mittlere Anomalie + var el = L + 1.915 * Math.sin(g) + 0.020 * Math.sin(2 * g); + var e = 23.439 - 0.0000004 * N; + var rektaszension = Math.atan((Math.cos(e) * Math.sin(el)) / Math.cos(el)); + + var T = (jdUTC0 - 2451545.0) / 36525; + var stGMT = (((6 * 3600) + (41 * 60) + 50.54841) + (8640184.812866 * T) + (0.093104 * Math.pow(T, 2)) - (0.0000062 * Math.pow(T, 3))) / 3600; + + var stGMT2 = 6.697376 + 2400.05134 * T + 1.002738 * T; + var hWGMT = stGMT2 * 15; + var hW = hWGMT + 11.9566185772; + + var st = (stGMT + (now.getUTCHours() * 1.00273790935)) + (11.9566185772 / 15); // Sommerzeit muss noch berücksichtigt werden + var st24 = Math.abs(st - (Math.round(st / 24) * 24)); + var stH = Math.floor(st24); + var stM = Math.floor((st24 % 1) * 60); + var stS = zeroFill(Math.floor((((st24 % 1) * 60) % 1) * 60), 2); + + var travelWidth = document.body.clientWidth; + var travelHeight = document.body.clientHeight; + var sunPosX = 0; + var sunPosY = 0; + var moonPosX = 0; + var moonPosY = 0; + + var sun = $("#sun").css({ + "left": (s / 60) * travelWidth, + "top": (m / 60) * travelHeight + }); + + $("#day").text(D[w]); + $("#dayNumb").text(DNumb); + $("#month").text(M[MNumb]); + $("#year").text(y); + $("#time").text('' + zeroFill(h, 2) + ':' + zeroFill(m, 2) + ':' + zeroFill(s, 2)); + + $("#julian").text(jd.toFixed(6)); + //$("#star").text(stH + ':' + stM + ':' + stS); + $("#star").text(stH + ':' + stM); + $("#star1").text(stGMT); + $("#star2").text(stGMT2); + +} + +function zeroFill(number, width) { + width -= number.toString().length; + if (width > 0) { + return new Array(width + (/\./.test(number) ? 2 : 1)).join('0') + number; + } + return number + ""; // always return a string +} + +//Länge der Balken im Diagram berechnen +function barwidth(size, G, W) { + var s = size; + var g = G; + var w = W; + var p = (w / g) * 100; + var newW = s * (p / 100); + + return newW; +} + +//String Element erweitern +String.prototype.transform = function () { + return parseFloat(this.replace(',', '.')); +} +//Array Element erweitern +Array.prototype.arrayAdd = function () { + return eval(this.join("+")); +} + +//Speicherplatz in Prozent berechnen +function percentage(total, gigs, round) { + var totalSpace = total; + var singleSpace = gigs; + var z = round; + var p = singleSpace / (totalSpace / 100); + + return p; +} + +//Speicherplatz in GB berechnen +function gigabytes(percent, total, round) { + var occupiedPercent = percent; + var singleSpace = total; + var z = round; + var g = (singleSpace / 100) * occupiedPercent; + + return g; +} + +function checkButtonAndTarget(event, element, button = 0) { + return ( + event.button === button && + event.target === element + ); +} \ No newline at end of file diff --git a/source/code/hippie/functions.js b/source/code/hippie/functions.js deleted file mode 100644 index ef2e3c7..0000000 --- a/source/code/hippie/functions.js +++ /dev/null @@ -1,228 +0,0 @@ -// 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(); diff --git a/source/code/hippie/global.js b/source/code/hippie/global.js deleted file mode 100644 index 0b05906..0000000 --- a/source/code/hippie/global.js +++ /dev/null @@ -1,3 +0,0 @@ -// Setup -// ----------------------------------------------------------------------------- -setup(); diff --git a/source/code/hippie/variables.js b/source/code/hippie/globals.js similarity index 92% rename from source/code/hippie/variables.js rename to source/code/hippie/globals.js index b5d8538..756af36 100644 --- a/source/code/hippie/variables.js +++ b/source/code/hippie/globals.js @@ -4,7 +4,7 @@ let hippie = { w: Math.max(document.documentElement.offsetWidth, document.documentElement.clientWidth, window.innerWidth, 0), vh: Math.max(document.documentElement.clientHeight, window.innerHeight, 0), dh: Math.max(document.documentElement.offsetHeight, document.documentElement.clientHeight, 0), - y: Math.min($(document).scrollTop(), document.documentElement.scrollTop) + y: document.documentElement.scrollTop // hippie.screen.y: document.documentElement.scrollTop }, body: { diff --git a/source/code/windows.js b/source/code/windows.js index f282729..6ca9f64 100644 --- a/source/code/windows.js +++ b/source/code/windows.js @@ -1,155 +1,47 @@ -class Draggable { - constructor(element) { - this.element = element; - this.offsetX = 0; - this.offsetY = 0; - this.isDragging = false; - this.barSize = ''; - - this.init(); - } - - init() { - this.element.addEventListener('mousedown', this.onMouseDown.bind(this)); - document.addEventListener('mousemove', this.onMouseMove.bind(this)); - document.addEventListener('mouseup', this.onMouseUp.bind(this)); - this.setPosition('bottom'); - } - - onMouseDown(event) { - this.isDragging = true; - this.offsetX = event.clientX - this.element.getBoundingClientRect().left; - this.offsetY = event.clientY - this.element.getBoundingClientRect().top; - - event.preventDefault(); - } - - onMouseMove(event) { - if (!this.isDragging) { - return; - } - - let x = event.clientX - this.offsetX; - let y = event.clientY - this.offsetY; - - // Update the position of the element - this.element.style.left = `${x}px`; - this.element.style.top = `${y}px`; - } - - onMouseUp() { - if (!this.isDragging) { - return; - } - this.isDragging = false; - - this.snapToEdges(); - } - - snapToEdges() { - const rect = this.element.getBoundingClientRect(); - const windowWidth = window.innerWidth; - const windowHeight = window.innerHeight; - - // Determine the closest edge - const distances = { - left: rect.left, - right: windowWidth - rect.right, - top: rect.top, - bottom: windowHeight - rect.bottom - }; - - const closestEdge = Object.keys(distances).reduce((a, b) => distances[a] < distances[b] ? a : b); - - /*switch (closestEdge) { - case 'left': - this.element.style.left = '0px'; - this.element.style.top = `${rect.top}px`; - break; - case 'right': - this.element.style.left = `${windowWidth - rect.width}px`; - this.element.style.top = `${rect.top}px`; - break; - case 'top': - this.element.style.top = '0px'; - this.element.style.left = `${rect.left}px`; - break; - case 'bottom': - this.element.style.top = `${windowHeight - rect.height}px`; - this.element.style.left = `${rect.left}px`; - break; - }*/ - this.setPosition(closestEdge, this.barSize); - } - - setPosition(side, barSize) { - switch (side) { - case 'left': - // this.element.style.top = `${rect.top}px`; // Optional: keep vertical position - this.element.style.top = '0px'; - this.element.style.right = ''; - this.element.style.bottom = '0px'; - this.element.style.left = '0px'; - this.element.style.width = barSize; - this.element.style.height = ''; - break; - case 'right': - // this.element.style.left = `${windowWidth - rect.width}px`; - // this.element.style.top = `${rect.top}px`; // Optional: keep vertical position - this.element.style.top = '0px'; - this.element.style.right = '0px'; - this.element.style.bottom = '0px'; - this.element.style.left = ''; - this.element.style.width = barSize; - this.element.style.height = ''; - break; - case 'top': - // this.element.style.top = '0px'; - // this.element.style.left = `${rect.left}px`; // Optional: keep horizontal position - this.element.style.top = '0px'; - this.element.style.right = '0px'; - this.element.style.bottom = ''; - this.element.style.left = '0px'; - this.element.style.width = ''; - this.element.style.height = barSize; - break; - case 'bottom': - // this.element.style.top = `${windowHeight - rect.height}px`; - // this.element.style.left = `${rect.left}px`; // Optional: keep horizontal position - this.element.style.top = ''; - this.element.style.right = '0px'; - this.element.style.bottom = '0px'; - this.element.style.left = '0px'; - this.element.style.width = ''; - this.element.style.height = barSize; - break; - } - } -} - -class DragAdv { - constructor(element, placeholder) { +class HippieTaskBar { + constructor(element, placeholder, options) { this.element = element; this.placeholder = placeholder; + this.date = null; this.offsetX = 0; this.offsetY = 0; this.isDragging = false; - this.barSize = ''; + this.barSize = '64px'; + // TODO: Erweitern auf allgemeine Möglichkeiten und dann aus JSON-Datei laden + this.options = options || { + direction: 0, + date: { + year: 'numeric', + month: '2-digit', + day: '2-digit' + } + }; this.init(); } + // TODO: Ereignisse besser delegieren init() { this.element.addEventListener('mousedown', this.onMouseDown.bind(this)); document.addEventListener('mousemove', this.onMouseMove.bind(this)); document.addEventListener('mouseup', this.onMouseUp.bind(this)); - this.setPosition('bottom', this.barSize); + + const dateElement = document.createElement('span'); + + dateElement.id = 'date'; + this.element.querySelector('.clock').appendChild(dateElement); + this.date = new DateDisplay(dateElement, this.options.date); + + this.setOptions('bottom'); } onMouseDown(event) { - if (event.button === 0) { + if (checkButtonAndTarget(event, this.element, 0)) { + console.debug('Drag mode enabled'); + this.isDragging = true; + // TODO: Platzhalter anpassen je nach Ziel this.showPlaceholder(); this.offsetX = this.placeholder.getBoundingClientRect().width / 2; @@ -166,21 +58,29 @@ class DragAdv { } onMouseMove(event) { - if (!this.isDragging) return; + if (this.isDragging) { + if (!this.isDragging) return; - let x = event.clientX - this.offsetX; - let y = event.clientY - this.offsetY; + let x = event.clientX - this.offsetX; + let y = event.clientY - this.offsetY; - this.placeholder.style.left = `${x}px`; - this.placeholder.style.top = `${y}px`; + console.debug('Position: ', x, y); + + this.placeholder.style.left = `${x}px`; + this.placeholder.style.top = `${y}px`; + } } onMouseUp() { - if (!this.isDragging) return; - this.isDragging = false; + if (event.target === this.placeholder) { + console.debug('Drag mode disabled'); - this.snapToEdges(); - this.hidePlaceholder(); + if (!this.isDragging) return; + this.isDragging = false; + + this.snapToEdges(); + this.hidePlaceholder(); + } } showPlaceholder() { @@ -193,88 +93,85 @@ class DragAdv { this.element.style.display = ''; } + // TODO: Prüfung auf Ziel auslagern und schon bei Mausbewegung verfügbar machen snapToEdges() { const rect = this.placeholder.getBoundingClientRect(); const windowWidth = window.innerWidth; const windowHeight = window.innerHeight; - const distances = { - left: rect.left, - right: windowWidth - rect.right, top: rect.top, - bottom: windowHeight - rect.bottom + right: windowWidth - rect.right, + bottom: windowHeight - rect.bottom, + left: rect.left }; - const closestEdge = Object.keys(distances).reduce((a, b) => distances[a] < distances[b] ? a : b); - this.setPosition(closestEdge, this.barSize); + this.setOptions(closestEdge); + this.date.changeFormat(this.options.date, this.options.direction); } - setPosition(side, barSize) { - switch (side) { - case 'left': - // this.element.style.top = `${rect.top}px`; // Optional: keep vertical position - this.element.style.top = '0px'; - this.element.style.right = ''; - this.element.style.bottom = '0px'; - this.element.style.left = '0px'; - this.element.style.width = barSize; - this.element.style.height = ''; - break; + setOptions(position) { + const attributes = { + top: { + className: 'top', + styles: { + top: '0', right: '0', bottom: '', left: '0', + width: '', height: this.barSize, + flexDirection: 'row' + } + }, + right: { + className: 'right', + styles: { + top: '0', right: '0', bottom: '0', left: '', + width: this.barSize, height: '', + flexDirection: 'column' + } + }, + bottom: { + className: 'bottom', + styles: { + top: '', right: '0', bottom: '0', left: '0', + width: '', height: this.barSize, + flexDirection: 'row' + } + }, + left: { + className: 'left', + styles: { + top: '0', + right: '', + bottom: '0', + left: '0', + width: this.barSize, + height: '', + flexDirection: 'column' + } + } + }; + + this.element.classList.remove(...Object.values(attributes).map(pos => pos.className)); + Object.keys(attributes[position].styles).forEach(key => { + this.element.style[key] = ''; + }); + + this.element.classList.add(attributes[position].className); + Object.entries(attributes[position].styles).forEach(([key, value]) => { + this.element.style[key] = value; + }); + + switch (position) { case 'right': - // this.element.style.left = `${windowWidth - rect.width}px`; - // this.element.style.top = `${rect.top}px`; // Optional: keep vertical position - this.element.style.top = '0px'; - this.element.style.right = '0px'; - this.element.style.bottom = '0px'; - this.element.style.left = ''; - this.element.style.width = barSize; - this.element.style.height = ''; + case 'left': + this.options.date = {year: '2-digit', month: '2-digit', day: '2-digit'}; + this.options.direction = 1; break; case 'top': - // this.element.style.top = '0px'; - // this.element.style.left = `${rect.left}px`; // Optional: keep horizontal position - this.element.style.top = '0px'; - this.element.style.right = '0px'; - this.element.style.bottom = ''; - this.element.style.left = '0px'; - this.element.style.width = ''; - this.element.style.height = barSize; - break; case 'bottom': - // this.element.style.top = `${windowHeight - rect.height}px`; - // this.element.style.left = `${rect.left}px`; // Optional: keep horizontal position - this.element.style.top = ''; - this.element.style.right = '0px'; - this.element.style.bottom = '0px'; - this.element.style.left = '0px'; - this.element.style.width = ''; - this.element.style.height = barSize; + default: + this.options.date = {year: 'numeric', month: '2-digit', day: '2-digit'}; + this.options.direction = 0; break; } } } - -class BestDrag { - #element; - - constructor(element) { - this.#setElement(element); - } - - #setElement(value) { - if (!value) { - throw new Error('No element found'); - } - this.#element = value; - this.#element.style.background = "hotpink"; - } - - get element() { - return this.#element; - } - - set element(value) { - this.#setElement(value); - } -} \ No newline at end of file diff --git a/source/data/new.json b/source/data/start.json similarity index 56% rename from source/data/new.json rename to source/data/start.json index 9d4a0a8..cc0da22 100644 --- a/source/data/new.json +++ b/source/data/start.json @@ -5,10 +5,10 @@ }, { "text": "Basics", - "href": "./demo/basics.html" + "href": "/demo/basics.html" }, { "text": "Drag", - "href": "./demo/examples/ui/drag.html" + "href": "/demo/examples/ui/drag.html" } ] \ No newline at end of file diff --git a/source/screens/demo/examples/ui/gallery.liquid b/source/screens/demo/examples/ui/gallery.liquid index f29cae5..c548374 100755 --- a/source/screens/demo/examples/ui/gallery.liquid +++ b/source/screens/demo/examples/ui/gallery.liquid @@ -37,7 +37,7 @@ tags: {{ block.super -}} -{% endblock %} \ No newline at end of file diff --git a/source/screens/demo/examples/ui/start.liquid b/source/screens/demo/examples/ui/start.liquid new file mode 100644 index 0000000..261cb16 --- /dev/null +++ b/source/screens/demo/examples/ui/start.liquid @@ -0,0 +1,45 @@ +--- +title: Start +tags: +- ui +--- +{% assign bodyClass = "body_new" -%} +{% layout "hippie/app.liquid" %} + +{% block body %} +{% render 'hippie/partials/header-status', hippie: hippie, links: start %} + +
+
1
+
2
+
3
+
4
+
+{% endblock %} + +{%- block script %} +{{ block.super -}} + +{% endblock %} \ No newline at end of file diff --git a/source/screens/demo/examples/ui/windows.liquid b/source/screens/demo/examples/ui/windows.liquid index daacb66..a0603e6 100644 --- a/source/screens/demo/examples/ui/windows.liquid +++ b/source/screens/demo/examples/ui/windows.liquid @@ -18,6 +18,8 @@ tags:
- +
+ ##:## +
+
@@ -40,6 +43,8 @@ tags: {% endblock %} {%- block script %} + + {% endblock %} \ No newline at end of file diff --git a/source/style/modules/ui/_windows_module.scss b/source/style/modules/ui/_windows_module.scss index c7a9846..d633b29 100644 --- a/source/style/modules/ui/_windows_module.scss +++ b/source/style/modules/ui/_windows_module.scss @@ -25,18 +25,54 @@ $padding_half: calc(#{hippie.$space_half} - 3px) hippie.$space_half; padding: hippie.$space_basic; background-color: rgba(0, 0, 0, .1); + &.top, + &.bottom { + nav, + & > div { + &:last-child { + margin-top: unset; + margin-left: auto; + } + } + + .clock { + text-align: end; + } + } + + &.right, + &.left { + nav, + & > div { + &:last-child { + margin-top: auto; + margin-left: unset; + } + } + + .clock { + text-align: center; + + & > span { + display: inline-block; + word-wrap: anywhere; + } + } + } + nav, & > div { @extend %flex-bar; - - &:last-child { - margin-left: auto; - } + flex-direction: inherit; } button { @extend .button_io; overflow: hidden; + + * { + pointer-events: none; + } } nav.small { @@ -66,8 +102,6 @@ $padding_half: calc(#{hippie.$space_half} - 3px) hippie.$space_half; } .clock { - text-align: end; - &, & > * { line-height: 1; diff --git a/source/templates/demo/_default.njk b/source/templates/demo/_default.njk index c8aeed3..e9b46de 100644 --- a/source/templates/demo/_default.njk +++ b/source/templates/demo/_default.njk @@ -15,5 +15,5 @@ {% block script %} {{ super() }} - + {% endblock %} \ No newline at end of file diff --git a/source/templates/hippie/_app.njk b/source/templates/hippie/_app.njk index 3dcc729..cf48706 100755 --- a/source/templates/hippie/_app.njk +++ b/source/templates/hippie/_app.njk @@ -22,8 +22,8 @@ {% block body %}{% endblock %} {% block script %} - - + + #} - - {# // TODO: Remove dependecy to jQuery; at least maek it optional #} - - - - + + + - +