Compare commits
12 commits
c1fea8064e
...
6098a1e62d
| Author | SHA1 | Date | |
|---|---|---|---|
| 6098a1e62d | |||
| 1ada62f6ec | |||
| 0996ace34f | |||
| e0cfcfac13 | |||
| 3c9c438b25 | |||
| e21b9d36b5 | |||
| ff5d4bd3eb | |||
| c77bcd8bdc | |||
| 6b644ca9f3 | |||
| 46988576a9 | |||
| afc733f4d4 | |||
| 07656b404f |
32 changed files with 860 additions and 145 deletions
18
.eleventy.js
18
.eleventy.js
|
|
@ -1,6 +1,14 @@
|
|||
module.exports = function (eleventyConfig) {
|
||||
// eleventyConfig.addPlugin(EleventyHtmlBasePlugin);
|
||||
|
||||
eleventyConfig.setLiquidOptions({
|
||||
// greedy: false,
|
||||
// trimOutputLeft: true,
|
||||
// trimOutputRight: true,
|
||||
// trimTagLeft: true,
|
||||
// trimTagRight : true,
|
||||
});
|
||||
|
||||
eleventyConfig.setNunjucksEnvironmentOptions({
|
||||
// throwOnUndefined: true,
|
||||
trimBlocks: true
|
||||
|
|
@ -32,6 +40,10 @@ module.exports = function (eleventyConfig) {
|
|||
|
||||
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"
|
||||
});
|
||||
// eleventyConfig.addPassthroughCopy({"node_modules/normalize.css/normalize.css": "vendor/normalize.css"});
|
||||
|
||||
eleventyConfig.addWatchTarget("./source/style/");
|
||||
|
|
@ -43,9 +55,7 @@ module.exports = function (eleventyConfig) {
|
|||
includes: "../templates",
|
||||
data: "../data"
|
||||
},
|
||||
markdownTemplateEngine: "njk",
|
||||
htmlTemplateEngine: "njk",
|
||||
templateFormats: ["html", "njk", "md"],
|
||||
templateFormats: ["html", "liquid", "njk", "md"]
|
||||
// pathPrefix: './demo/'
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
|||
7
package-lock.json
generated
7
package-lock.json
generated
|
|
@ -11,6 +11,7 @@
|
|||
"dependencies": {
|
||||
"@11ty/eleventy": "^2.0.1",
|
||||
"bootstrap-icons": "^1.13.1",
|
||||
"jquery": "^3.7.1",
|
||||
"sass": "^1.93.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
@ -1583,6 +1584,12 @@
|
|||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/jquery": {
|
||||
"version": "3.7.1",
|
||||
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
|
||||
"integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/js-stringify": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz",
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
"dependencies": {
|
||||
"@11ty/eleventy": "^2.0.1",
|
||||
"bootstrap-icons": "^1.13.1",
|
||||
"jquery": "^3.7.1",
|
||||
"sass": "^1.93.0"
|
||||
}
|
||||
}
|
||||
280
source/code/windows.js
Normal file
280
source/code/windows.js
Normal file
|
|
@ -0,0 +1,280 @@
|
|||
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) {
|
||||
this.element = element;
|
||||
this.placeholder = placeholder;
|
||||
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', this.barSize);
|
||||
}
|
||||
|
||||
onMouseDown(event) {
|
||||
if (event.button === 0) {
|
||||
this.isDragging = true;
|
||||
|
||||
this.showPlaceholder();
|
||||
|
||||
this.offsetX = this.placeholder.getBoundingClientRect().width / 2;
|
||||
this.offsetY = this.placeholder.getBoundingClientRect().height / 2;
|
||||
|
||||
let x = event.clientX - this.offsetX;
|
||||
let y = event.clientY - this.offsetY;
|
||||
|
||||
this.placeholder.style.left = `${x}px`;
|
||||
this.placeholder.style.top = `${y}px`;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
onMouseMove(event) {
|
||||
if (!this.isDragging) return;
|
||||
|
||||
let x = event.clientX - this.offsetX;
|
||||
let y = event.clientY - this.offsetY;
|
||||
|
||||
this.placeholder.style.left = `${x}px`;
|
||||
this.placeholder.style.top = `${y}px`;
|
||||
}
|
||||
|
||||
onMouseUp() {
|
||||
if (!this.isDragging) return;
|
||||
this.isDragging = false;
|
||||
|
||||
this.snapToEdges();
|
||||
this.hidePlaceholder();
|
||||
}
|
||||
|
||||
showPlaceholder() {
|
||||
this.element.style.display = 'none';
|
||||
this.placeholder.style.display = 'block';
|
||||
}
|
||||
|
||||
hidePlaceholder() {
|
||||
this.placeholder.style.display = 'none';
|
||||
this.element.style.display = '';
|
||||
}
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
const closestEdge = Object.keys(distances).reduce((a, b) => distances[a] < distances[b] ? a : b);
|
||||
|
||||
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 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -25,7 +25,7 @@ tags:
|
|||
<div class="demo__queries">
|
||||
<p class="query_phoneUp">Telefone und größer</p>
|
||||
<p class="query_phoneOnly">Nur Telefone</p>
|
||||
<p class="query_tabletPortaitOnly">Nur Schreibtafeln hochkant</p>
|
||||
<p class="query_tabletPortraitOnly">Nur Schreibtafeln hochkant</p>
|
||||
<p class="query_tabletPortraitUp">Schreibtafeln und größer</p>
|
||||
<p class="query_tabletLandscapeOnly">Schreibtafeln im Querformat</p>
|
||||
<p class="query_tabletLandscapeUp">Schreibtafeln quer und größer</p>
|
||||
|
|
|
|||
25
source/screens/demo/examples/game.liquid
Normal file
25
source/screens/demo/examples/game.liquid
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
title: Game - TFW
|
||||
tags:
|
||||
- demoExample
|
||||
- gameExample
|
||||
---
|
||||
{% assign bodyClass = "body_game" -%}
|
||||
{% layout "hippie/app.liquid" %}
|
||||
|
||||
{% block body %}
|
||||
<div class="sec_main_center">
|
||||
<nav role="doc-toc">
|
||||
<hgroup>
|
||||
<h1>{{ title }}</h1>
|
||||
<p>Additional name</p>
|
||||
</hgroup>
|
||||
<ul class="list_link">
|
||||
<li><a href="#new">Neues Spiel</a></li>
|
||||
<li><a href="#continue">Spiel fortsetzen</a></li>
|
||||
<li><a href="#options">Einstellungen</a></li>
|
||||
<li><a href="#quit">Spiel beenden</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
@ -49,7 +49,7 @@ tags:
|
|||
|
||||
{%- block script %}
|
||||
{{ super() }}
|
||||
<script src="{{ pageBase }}js/_intro.js"></script>
|
||||
<script src="{{ pageBase }}js/intro.js"></script>
|
||||
<script>
|
||||
//let intro = new Intro('Intro');
|
||||
//intro.init();
|
||||
|
|
|
|||
48
source/screens/demo/examples/ui/drag.liquid
Executable file
48
source/screens/demo/examples/ui/drag.liquid
Executable file
|
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
title: Drag
|
||||
tags:
|
||||
- ui
|
||||
---
|
||||
{% layout "hippie/app.liquid" %}
|
||||
|
||||
{% block body %}
|
||||
<header class="io pos_fix pin_top pin_right pin_left">
|
||||
<button data-action="add">Add</button>
|
||||
</header>
|
||||
<div id="space"></div>
|
||||
<div>
|
||||
<div id="test">
|
||||
<div class="body_frame">
|
||||
{% render 'hippie/partials/frame-header.liquid' %}
|
||||
<main></main>
|
||||
{% render 'hippie/partials/frame-mode.liquid' %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{%- block script %}
|
||||
<script src="{{ pageBase }}js/drag.js"></script>
|
||||
<script>
|
||||
// Get the space element
|
||||
const space = document.getElementById('space');
|
||||
const add = document.querySelector('[data-action=add]');
|
||||
const test = document.getElementById('test');
|
||||
|
||||
// Add event listener to the add space button
|
||||
add.addEventListener('click', () => {
|
||||
const newDiv = new NewDiv(100, 100, 100, 100, getRandomColor());
|
||||
newDiv.createDiv();
|
||||
newDiv.appendToFrame(space);
|
||||
});
|
||||
|
||||
// Create a new NewDiv instance
|
||||
const newDiv = new NewDiv(100, 100, 200, 200, '#000');
|
||||
newDiv.createDiv();
|
||||
newDiv.appendToFrame(space);
|
||||
|
||||
const explorer = new NewDiv(256, 128, 800, 600, '#fff', test);
|
||||
explorer.createDiv();
|
||||
explorer.appendToFrame(space);
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
---
|
||||
title: Drag
|
||||
tags:
|
||||
- ui
|
||||
---
|
||||
{% set pageId = page.fileSlug %}
|
||||
|
||||
{% extends "hippie/_app_frame.njk" %}
|
||||
|
||||
{% block body %}
|
||||
<header class="io pos_fix pin_top pin_right pin_left">
|
||||
<button data-action="add">Add</button>
|
||||
</header>
|
||||
<div id="space"></div>
|
||||
<div>
|
||||
<div id="test">
|
||||
<div class="body_frame">
|
||||
{{ io.frameHeader('title-bar') }}
|
||||
<main></main>
|
||||
{{ io.frameFooter('mode-bar') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{%- block script %}
|
||||
<script src="{{ pageBase }}js/_ui.js"></script>
|
||||
<script>
|
||||
// Get the space element
|
||||
const space = document.getElementById('space');
|
||||
const add = document.querySelector('[data-action=add]');
|
||||
const test = document.getElementById('test');
|
||||
|
||||
// Add event listener to the add space button
|
||||
add.addEventListener('click', () => {
|
||||
const newDiv = new NewDiv(100, 100, 100, 100, getRandomColor());
|
||||
newDiv.createDiv();
|
||||
newDiv.appendToFrame(space);
|
||||
});
|
||||
|
||||
// Create a new NewDiv instance
|
||||
const newDiv = new NewDiv(100, 100, 200, 200, '#000');
|
||||
newDiv.createDiv();
|
||||
newDiv.appendToFrame(space);
|
||||
|
||||
const explorer = new NewDiv(256, 128, 800, 600, '#fff', test);
|
||||
explorer.createDiv();
|
||||
explorer.appendToFrame(space);
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
@ -12,7 +12,7 @@ tags:
|
|||
<main class="io">
|
||||
<aside class="io">
|
||||
<nav>
|
||||
<div>location-pane</div>
|
||||
<span>location-pane</span>
|
||||
<ul class="vertical">
|
||||
<li>
|
||||
<a class="a_button" href="">
|
||||
|
|
@ -139,17 +139,7 @@ tags:
|
|||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<footer class="io">
|
||||
<nav>
|
||||
<span>## items</span>
|
||||
<span># selected (size)</span>
|
||||
<span># type(s)</span>
|
||||
<span># shared</span>
|
||||
</nav>
|
||||
<nav>
|
||||
<span>status-bar</span>
|
||||
</nav>
|
||||
</footer>
|
||||
{{ io.statusBar() }}
|
||||
</section>
|
||||
</main>
|
||||
{{ io.frameFooter('mode-bar') }}
|
||||
|
|
|
|||
56
source/screens/demo/examples/ui/form.liquid
Normal file
56
source/screens/demo/examples/ui/form.liquid
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
---
|
||||
title: Form
|
||||
tags:
|
||||
- ui
|
||||
---
|
||||
{% assign bodyClass = "body_frame" -%}
|
||||
{% layout "hippie/app.liquid" %}
|
||||
|
||||
{% block body %}
|
||||
{% render 'hippie/partials/frame-header.liquid' %}
|
||||
<header class="io">
|
||||
<h1>Formulare</h1>
|
||||
<button data-action="add">Hinzufügen</button>
|
||||
<button data-action="change">Ändern</button>
|
||||
<hr>
|
||||
</header>
|
||||
<form id="form" action="">
|
||||
<div id="grid">
|
||||
<div>a</div>
|
||||
<div>b</div>
|
||||
<div>c</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
{%- block script %}
|
||||
{{ block.super -}}
|
||||
<script>
|
||||
const add = document.querySelector('[data-action=add]');
|
||||
const change = document.querySelector('[data-action=change]');
|
||||
const grid = document.getElementById('grid');
|
||||
|
||||
add.addEventListener('click', (e) => {
|
||||
const item = document.createElement('div');
|
||||
|
||||
item.style.backgroundColor = '#f0f';
|
||||
item.textContent = 'c'
|
||||
|
||||
grid.appendChild(item);
|
||||
});
|
||||
|
||||
change.addEventListener('click', (e) => {
|
||||
changeLayout(grid);
|
||||
});
|
||||
|
||||
function changeLayout(grid) {
|
||||
const currentTemplate = grid.style.gridTemplateColumns;
|
||||
|
||||
if (currentTemplate === 'repeat(4, 1fr)') {
|
||||
grid.style.gridTemplateColumns = 'repeat(2, 1fr)';
|
||||
} else {
|
||||
grid.style.gridTemplateColumns = 'repeat(4, 1fr)';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
---
|
||||
title: Form
|
||||
tags:
|
||||
- ui
|
||||
---
|
||||
{% extends "hippie/_app_frame.njk" %}
|
||||
|
||||
{% block body %}
|
||||
{{ io.frameHeader('title-bar') }}
|
||||
<header class="io">
|
||||
<h1>Formulare</h1>
|
||||
<button data-action="add">Hinzufügen</button>
|
||||
<button data-action="change">Ändern</button>
|
||||
<hr>
|
||||
</header>
|
||||
<form id="form" action="">
|
||||
<div id="grid">
|
||||
<div>a</div>
|
||||
<div>b</div>
|
||||
<div>c</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
{%- block script %}
|
||||
{{ super() }}
|
||||
<script>
|
||||
const add = document.querySelector('[data-action=add]');
|
||||
const change = document.querySelector('[data-action=change]');
|
||||
const grid = document.getElementById('grid');
|
||||
|
||||
add.addEventListener('click', (e) => {
|
||||
const item = document.createElement('div');
|
||||
|
||||
item.style.backgroundColor = '#f0f';
|
||||
item.textContent = 'c'
|
||||
|
||||
grid.appendChild(item);
|
||||
});
|
||||
|
||||
change.addEventListener('click', (e) => {
|
||||
changeLayout(grid);
|
||||
});
|
||||
|
||||
function changeLayout(grid) {
|
||||
const currentTemplate = grid.style.gridTemplateColumns;
|
||||
|
||||
if (currentTemplate === 'repeat(4, 1fr)') {
|
||||
grid.style.gridTemplateColumns = 'repeat(2, 1fr)';
|
||||
} else {
|
||||
grid.style.gridTemplateColumns = 'repeat(4, 1fr)';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
77
source/screens/demo/examples/ui/gallery.liquid
Executable file
77
source/screens/demo/examples/ui/gallery.liquid
Executable file
|
|
@ -0,0 +1,77 @@
|
|||
---
|
||||
title: Gallery
|
||||
tags:
|
||||
- ui
|
||||
---
|
||||
{% assign bodyClass = "body_frame" -%}
|
||||
{% layout "hippie/app.liquid" %}
|
||||
|
||||
{% block body %}
|
||||
{% render 'hippie/partials/frame-header.liquid' %}
|
||||
<main class="io">
|
||||
<section>
|
||||
<header class="io">
|
||||
<nav>
|
||||
<div class="group">
|
||||
<input id="slider-size" value="5" min="1" max="10" step="1" type="range"/>
|
||||
<label class="right" for="slider-size">Größe</label>
|
||||
</div>
|
||||
<button title="details">
|
||||
<i class="bi bi-layout-sidebar-reverse"></i> Details
|
||||
</button>
|
||||
</nav>
|
||||
<nav></nav>
|
||||
</header>
|
||||
<div class="gallery">
|
||||
<div>A</div>
|
||||
<div>B</div>
|
||||
<div>C</div>
|
||||
</div>
|
||||
{% render 'hippie/partials/frame-status.liquid' %}
|
||||
</section>
|
||||
</main>
|
||||
{% render 'hippie/partials/frame-mode.liquid' %}
|
||||
{% endblock %}
|
||||
|
||||
{%- block script %}
|
||||
{{ block.super -}}
|
||||
<script>
|
||||
const sizeSlider = document.getElementById('slider-size');
|
||||
const galleryItems = document.querySelectorAll('#flex > div');
|
||||
|
||||
// Set the default size
|
||||
const defaultSize = 128; // In pixels
|
||||
const minSize = 16; // Minimum width in pixels
|
||||
const steps = 10;
|
||||
// Define specific sizes for each step (from 1 to 10)
|
||||
const sizes = [16, 32, 64, 96, 128, 256, 512, 1024, 2048]; // Sizes in pixels
|
||||
|
||||
|
||||
// Calculate width based on slider value
|
||||
function calculateWidth(value) {
|
||||
// Map 1-10 to a pixel width
|
||||
return Math.floor(minSize + (value - 1) * (defaultSize - minSize) / (steps - 1));
|
||||
}
|
||||
|
||||
// Set initial size
|
||||
galleryItems.forEach(item => {
|
||||
item.style.width = `${defaultSize}px`;
|
||||
item.style.width = `${sizes[5]}px`; // Initial width based on the default step (8 corresponds to index 7)
|
||||
});
|
||||
|
||||
sizeSlider.addEventListener('input', function () {
|
||||
// const newSize = calculateWidth(Number(sizeSlider.value));
|
||||
// galleryItems.forEach(item => {
|
||||
// item.style.width = `${newSize}px`;
|
||||
// });
|
||||
const selectedStep = Number(sizeSlider.value) - 1; // Adjust for zero-indexing
|
||||
const newSize = sizes[selectedStep]; // Get size from the array using slider value
|
||||
galleryItems.forEach(item => {
|
||||
item.style.width = `${newSize}px`;
|
||||
});
|
||||
});
|
||||
|
||||
// Initialize slider to default
|
||||
sizeSlider.value = 6; // Sets default to 128px width
|
||||
</script>
|
||||
{% endblock %}
|
||||
55
source/screens/demo/examples/ui/windows.liquid
Normal file
55
source/screens/demo/examples/ui/windows.liquid
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
---
|
||||
title: Windows
|
||||
tags:
|
||||
- ui
|
||||
---
|
||||
{% assign bodyClass = "body_frame" -%}
|
||||
{% layout "hippie/app.liquid" %}
|
||||
|
||||
{% block body %}
|
||||
<div id="task-bar">
|
||||
<nav>
|
||||
<button data-action="start"><i class="bi bi-microsoft"></i></button>
|
||||
</nav>
|
||||
<nav>
|
||||
<button><i class="bi bi-search"></i></button>
|
||||
<button><i class="bi bi-layers-half"></i></button>
|
||||
</nav>
|
||||
<nav class="big">
|
||||
<button><i class="bi bi-folder"></i></button>
|
||||
<button><i class="bi bi-terminal"></i></button>
|
||||
</nav>
|
||||
<div>
|
||||
<nav class="small">
|
||||
<button><i class="bi bi-chevron-up"></i></button>
|
||||
<button><i class="bi bi-steam"></i></button>
|
||||
<button><i class="bi bi-router"></i></button>
|
||||
<button><i class="bi bi-mic"></i></button>
|
||||
<button><i class="bi bi-volume-down"></i></button>
|
||||
</nav>
|
||||
<nav class="clock">
|
||||
<span>##:##<br>TT.MM.JJJJ</span>
|
||||
</nav>
|
||||
<nav>
|
||||
<button data-action="notification"><i class="bi bi-bell-fill"></i></button>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<div id="screen-space"></div>
|
||||
<div id="placeholder"></div>
|
||||
{% endblock %}
|
||||
|
||||
{%- block script %}
|
||||
<script src="{{ pageBase }}js/windows.js"></script>
|
||||
<script>
|
||||
// Get the space element
|
||||
const space = document.getElementById('screen-space');
|
||||
const start = document.querySelector('[data-action=start]');
|
||||
const draggableElement = document.getElementById('task-bar');
|
||||
const placeholderElement = document.getElementById('placeholder');
|
||||
|
||||
// const draggable = new Draggable(draggableElement);
|
||||
const dragMore = new DragAdv(draggableElement, placeholderElement);
|
||||
// const dragBest = new BestDrag(draggableElement, placeholderElement);
|
||||
</script>
|
||||
{% endblock %}
|
||||
18
source/screens/demo/pages/default.liquid
Normal file
18
source/screens/demo/pages/default.liquid
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
title: "Default"
|
||||
---
|
||||
{% assign pageBase = "../" -%}
|
||||
{% assign pageId = page.fileSlug -%}
|
||||
{% assign pageClass = "default" -%}
|
||||
{% assign bodyClass = "default" -%}
|
||||
{%- layout "hippie/default.liquid" %}
|
||||
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
|
||||
{% block script %}
|
||||
{{ block.super -}}
|
||||
<script>
|
||||
// Page script
|
||||
console.log("pageBase is: {{ pageBase }}");
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
---
|
||||
title: Default
|
||||
---
|
||||
{% set pageBase = "../" %}
|
||||
{% set pageId = page.fileSlug %}
|
||||
|
||||
{% extends "hippie/_default.njk" %}
|
||||
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
{{ super() }}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<!-- {{ page.fileSlug }}.page -->
|
||||
{% endblock %}
|
||||
|
||||
{% block script %}
|
||||
{{ super() }}
|
||||
{% endblock %}
|
||||
8
source/screens/demo/pages/hello.md
Normal file
8
source/screens/demo/pages/hello.md
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
title: "Hello World"
|
||||
layout: hippie/world.liquid
|
||||
---
|
||||
|
||||
# {{ title }}
|
||||
|
||||
This is a simple example for a *screen* written in Markdown, using Liquid *templates*.
|
||||
18
source/style/modules/ui/_gallery_module.scss
Normal file
18
source/style/modules/ui/_gallery_module.scss
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
@use "../../hippie-style/hippie";
|
||||
|
||||
.gallery {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: left;
|
||||
align-items: start;
|
||||
gap: 10px;
|
||||
background-color: hippie.$color_back_io;
|
||||
|
||||
& > div {
|
||||
background-color: hotpink;
|
||||
aspect-ratio: 2 / 3;
|
||||
width: 128px;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
}
|
||||
|
||||
3
source/style/modules/ui/_game_module.scss
Normal file
3
source/style/modules/ui/_game_module.scss
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
.body_game {
|
||||
background-color: hotpink;
|
||||
}
|
||||
91
source/style/modules/ui/_windows_module.scss
Normal file
91
source/style/modules/ui/_windows_module.scss
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
@use "sass:map";
|
||||
|
||||
@use "../../hippie-style/hippie";
|
||||
|
||||
$padding_half: calc(#{hippie.$space_half} - 3px) hippie.$space_half;
|
||||
|
||||
%flex-bar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-items: stretch;
|
||||
align-content: center;
|
||||
justify-content: flex-start;
|
||||
gap: hippie.$space_half hippie.$space_basic;
|
||||
}
|
||||
|
||||
#task-bar {
|
||||
@extend %flex-bar;
|
||||
z-index: map.get(hippie.$z-indexes, "content-top");
|
||||
position: fixed;
|
||||
//right: 0;
|
||||
//bottom: 0;
|
||||
//left: 0;
|
||||
border: 1px solid transparent;
|
||||
padding: hippie.$space_basic;
|
||||
background-color: rgba(0, 0, 0, .1);
|
||||
|
||||
nav,
|
||||
& > div {
|
||||
@extend %flex-bar;
|
||||
|
||||
&:last-child {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
@extend .button_io;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
nav.small {
|
||||
//font-size: .8em;
|
||||
|
||||
button {
|
||||
border: none;
|
||||
padding: $padding_half;
|
||||
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nav.big {
|
||||
font-size: 1.5em;
|
||||
|
||||
button {
|
||||
border: none;
|
||||
padding: 0;
|
||||
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.clock {
|
||||
text-align: end;
|
||||
|
||||
&,
|
||||
& > * {
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#screen-space {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#placeholder {
|
||||
display: none;
|
||||
z-index: map.get(hippie.$z-indexes, "content-top");
|
||||
position: fixed;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border: 2px dashed deeppink;
|
||||
background-color: hotpink;
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
@use "modules/ui/form_module";
|
||||
@use "modules/ui/game_module";
|
||||
@use "modules/ui/gallery_module";
|
||||
@use "modules/ui/windows_module";
|
||||
|
||||
$color_gui_back: hippie.$color_dark;
|
||||
$space_gui_half: hippie.$space_half;
|
||||
|
|
|
|||
40
source/templates/hippie/app.liquid
Normal file
40
source/templates/hippie/app.liquid
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
{% assign pageBase = "../../../" -%}
|
||||
{% assign pageId = page.fileSlug -%}
|
||||
{% assign pageClass = "html_ui" -%}
|
||||
{%- layout "hippie/default.liquid" %}
|
||||
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
|
||||
{% block links %}
|
||||
{{ block.super -}}
|
||||
<link href="/vendor/bootstrap-icons/font/bootstrap-icons.min.css" rel="stylesheet">
|
||||
<link href="{{ pageBase }}css/ui.css" media="all" rel="stylesheet"/>
|
||||
{% endblock %}
|
||||
|
||||
{% block script %}
|
||||
{{ block.super -}}
|
||||
<script src="/vendor/jquery.min.js"></script>
|
||||
<script src="{{ pageBase }}js/variables.js"></script>
|
||||
<script src="{{ pageBase }}js/app.js"></script>
|
||||
|
||||
<script>
|
||||
const frameHeader = document.querySelector('body > header.io');
|
||||
const closeActionElements = document.querySelectorAll('[data-action=close]');
|
||||
|
||||
if (frameHeader) {
|
||||
console.log('frame header found', frameHeader);
|
||||
|
||||
frameHeader.addEventListener('click', (e) => {
|
||||
if (e.target.dataset.action === 'close') {
|
||||
console.debug('close', e.target);
|
||||
|
||||
history.back();
|
||||
|
||||
if (closeActionElements.length > 1) {
|
||||
console.debug('other frames present', closeActionElements.length);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
37
source/templates/hippie/default.liquid
Normal file
37
source/templates/hippie/default.liquid
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
{% if pageId %}
|
||||
{%- capture idAttr %} id="{{ pageId }}"{% endcapture -%}
|
||||
{% endif -%}
|
||||
{% if pageClass %}
|
||||
{%- capture classAttr %} class="{{ pageClass }}"{% endcapture -%}
|
||||
{% endif -%}
|
||||
{% if bodyClass %}
|
||||
{%- capture bodyClassAttr %} class="{{ bodyClass }}"{% endcapture -%}
|
||||
{% endif -%}
|
||||
<html{{ idAttr }}{{ classAttr }} lang="de">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
{% block head %}
|
||||
<title>
|
||||
{{- hippie.titlePrefix -}}
|
||||
{% block title %}{% endblock -%}
|
||||
{{ hippie.titlePostfix -}}
|
||||
</title>
|
||||
{% block meta -%}
|
||||
{% render "hippie/partials/meta.liquid" %}
|
||||
{% endblock -%}
|
||||
{% block links -%}
|
||||
{% render "hippie/partials/links.liquid" %}
|
||||
{% endblock -%}
|
||||
{% endblock -%}
|
||||
</head>
|
||||
|
||||
<body{{ bodyClassAttr }}>
|
||||
{%- block body %}{% endblock -%}
|
||||
{% block script -%}
|
||||
<script>
|
||||
// Default script
|
||||
</script>
|
||||
{% endblock -%}
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -33,3 +33,17 @@
|
|||
</nav>
|
||||
</footer>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro statusBar(title) %}
|
||||
<footer class="io">
|
||||
<nav>
|
||||
<span>## items</span>
|
||||
<span># selected (size)</span>
|
||||
<span># type(s)</span>
|
||||
<span># shared</span>
|
||||
</nav>
|
||||
<nav>
|
||||
<span>{{ title | default('status-bar') }}</span>
|
||||
</nav>
|
||||
</footer>
|
||||
{% endmacro %}
|
||||
20
source/templates/hippie/partials/frame-header.liquid
Normal file
20
source/templates/hippie/partials/frame-header.liquid
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<header class="io">
|
||||
<nav>
|
||||
<button title="menu">
|
||||
<i class="bi bi-three-dots"></i>
|
||||
</button>
|
||||
<span>{{ title | default: 'title-bar' }}</span>
|
||||
</nav>
|
||||
<nav>
|
||||
<div class="spacer a"></div>
|
||||
<button title="minimize">
|
||||
<i class="bi bi-dash"></i>
|
||||
</button>
|
||||
<button title="maximize">
|
||||
<i class="bi bi-fullscreen"></i>
|
||||
</button>
|
||||
<button title="close" data-action="close">
|
||||
<i class="bi bi-x-square"></i>
|
||||
</button>
|
||||
</nav>
|
||||
</header>
|
||||
10
source/templates/hippie/partials/frame-mode.liquid
Normal file
10
source/templates/hippie/partials/frame-mode.liquid
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<footer class="io">
|
||||
<nav>
|
||||
<button>mode</button>
|
||||
<span>{{ title | default: 'mode-bar' }}</span>
|
||||
</nav>
|
||||
<nav>
|
||||
<div class="spacer a"></div>
|
||||
<button>action</button>
|
||||
</nav>
|
||||
</footer>
|
||||
11
source/templates/hippie/partials/frame-status.liquid
Normal file
11
source/templates/hippie/partials/frame-status.liquid
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<footer class="io">
|
||||
<nav>
|
||||
<span>## items</span>
|
||||
<span># selected (size)</span>
|
||||
<span># type(s)</span>
|
||||
<span># shared</span>
|
||||
</nav>
|
||||
<nav>
|
||||
<span>{{ title | default: 'status-bar' }}</span>
|
||||
</nav>
|
||||
</footer>
|
||||
3
source/templates/hippie/partials/links.liquid
Normal file
3
source/templates/hippie/partials/links.liquid
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{% comment %}<link rel="icon" href="/favicon.ico" type="image/vnd.microsoft.icon">{% endcomment %}
|
||||
<link rel="shortcut icon" type="image/x-icon" href="{{ pageBase }}favicon.ico">
|
||||
<link rel="shortcut icon" type="image/x-icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAAIBAQCbjUIABQQCAGdfKgDcxYUAiXpGABkWCgDXxnEApmxRAMGZawAIBwMArZ5PAKFydQBmIZIAoGJFAIx+QwBSSyIA1biBADlx0gBNn+0AgztQAMimcQAMCwQADAsFANS/dAB7P3EAeuH7ANb4/gBQPLwAp2pNAI6CQwCilEwAr3hdADyH5ADw/f8A////AHTU+AB6M2YA0LN4ABMRBwA/OhsAyKR2AGYvjQCf7PwA7fz/AENy2gCrclkAk4ZDAAYFAgDNtXEAjkhHAEul7QD8//8AlOn8AGk1hwDWvXsAGBYJAJaHSgCnbE4AVy6rAML0/gD7/v8AQ6vuAKx1YwCZjEQALCgTALyOZwB+NVoAZ8D0AL30/QBLULMA2sV+AB4bCwDFpm0Ak087AFArvgBv4PoAjOf7AIzm+wCN4/sAjuH7AI7h+gCP3fkAOI/sAKVvcwCfkUQAfnM6ANO2hAC3iGkAk150AI9OcACKRmkAhj9kAH84YQB9NWEAfTRgAH0zYAB6MWYAei9lAItFUADdy3wAKCQPAFtTJQB2bDIAhXk5AJKGPwCbjkQAq5xOALepWwDEtGcAzLlwAMyzcgDKrXIAx6NwALyNZgDWu4IApJZHAAcGAwANDAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB3eGhpamtsbW5vcHFycwt0dXZYWVpbXF1eX2BhYmNkZWZnAktMTU5PUFFRUlNUVVZXAABDREVGJSUlJSUlR0hJSgAAADs8PT4lJSUlP0BBQgAAAAAyMzQ1NiUlJTc4OToAAAAAACorLC0lJS4vMDEAAAAAAAAAISIjJCUmJygpAAAAAAAAABkaGxwdHh8gAAAAAAAAAAAAEhMUFRYXGAAAAAAAAAAAAAANDg8QEQAAAAAAAAAAAAAACAkKCwwAAAAAAAAAAAAAAAAFBgcAAAAAAAAAAAAAAAAAAgMEAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=">
|
||||
7
source/templates/hippie/partials/meta.liquid
Normal file
7
source/templates/hippie/partials/meta.liquid
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<meta name="robots" content="noindex">
|
||||
<meta name="generator" content="{{ eleventy.generator }}">
|
||||
<meta name="author" content="">
|
||||
<meta name="description" content="">
|
||||
<meta name="keywords" content="">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
11
source/templates/hippie/world.liquid
Normal file
11
source/templates/hippie/world.liquid
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>{{ title }}</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{{ content }}
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue