feat: Add and rename screens
- Add windows screen - Add windows.js - Different variants of classes for drag and edge snap behaviour - Rename js files to better distinguish usage
This commit is contained in:
parent
3c9c438b25
commit
e0cfcfac13
8 changed files with 351 additions and 2 deletions
282
source/code/windows.js
Normal file
282
source/code/windows.js
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
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);
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
onMouseDown(event) {
|
||||
this.isDragging = true;
|
||||
// this.offsetX = event.clientX - this.element.getBoundingClientRect().left;
|
||||
// this.offsetY = event.clientY - this.element.getBoundingClientRect().top;
|
||||
this.offsetX = 0;
|
||||
this.offsetY = 0;
|
||||
this.element.style.display = 'none';
|
||||
|
||||
this.showPlaceholder();
|
||||
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`;
|
||||
// this.element.style.display = 'none';
|
||||
|
||||
// Update placeholder position
|
||||
this.placeholder.style.left = `${x}px`;
|
||||
this.placeholder.style.top = `${y}px`;
|
||||
// this.placeholder.style.display = 'block';
|
||||
}
|
||||
|
||||
onMouseUp() {
|
||||
if (!this.isDragging) return;
|
||||
this.isDragging = false;
|
||||
|
||||
this.element.style.display = 'block';
|
||||
|
||||
this.snapToEdges();
|
||||
this.hidePlaceholder();
|
||||
}
|
||||
|
||||
showPlaceholder() {
|
||||
this.placeholder.style.display = 'block';
|
||||
}
|
||||
|
||||
hidePlaceholder() {
|
||||
this.placeholder.style.display = 'none';
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
console.log(rect);
|
||||
console.log(closestEdge);
|
||||
this.setPosition(closestEdge, this.barSize);
|
||||
/*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;
|
||||
}*/
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ tags:
|
|||
{% endblock %}
|
||||
|
||||
{%- block script %}
|
||||
<script src="{{ pageBase }}js/_ui.js"></script>
|
||||
<script src="{{ pageBase }}js/drag.js"></script>
|
||||
<script>
|
||||
// Get the space element
|
||||
const space = document.getElementById('space');
|
||||
|
|
|
|||
30
source/screens/demo/examples/ui/windows.liquid
Normal file
30
source/screens/demo/examples/ui/windows.liquid
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
title: Windows
|
||||
tags:
|
||||
- ui
|
||||
---
|
||||
{% assign bodyClass = "body_frame" -%}
|
||||
{% layout "hippie/app.liquid" %}
|
||||
|
||||
{% block body %}
|
||||
<nav id="task-bar">
|
||||
<button data-action="start">Start</button>
|
||||
</nav>
|
||||
<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 %}
|
||||
36
source/style/modules/ui/_windows_module.scss
Normal file
36
source/style/modules/ui/_windows_module.scss
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
@use "sass:map";
|
||||
|
||||
@use "../../hippie-style/hippie";
|
||||
|
||||
#task-bar {
|
||||
@extend %flex-inline;
|
||||
z-index: map.get(hippie.$z-indexes, "content-top");
|
||||
align-items: stretch;
|
||||
position: fixed;
|
||||
//right: 0;
|
||||
//bottom: 0;
|
||||
//left: 0;
|
||||
border: 1px solid transparent;
|
||||
padding: hippie.$space_basic;
|
||||
background-color: rgba(0, 0, 0, .1);
|
||||
|
||||
button {
|
||||
@extend .button_io;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
#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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue