add modal interaction with code
This commit is contained in:
parent
1ec5a8d088
commit
cd6a3a56b0
@ -4,6 +4,13 @@ import { Miscellaneous } from "./engine/config";
|
||||
export const App = () => {
|
||||
return (
|
||||
<div className="main">
|
||||
<div id="modal" className="modal">
|
||||
<div className="modal-content">
|
||||
<span className="close">×</span>
|
||||
<p>Some text in the Modal..</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="header">
|
||||
<div className="nav">
|
||||
<h1>the abstraction engine</h1>
|
||||
|
67
src/css/modal.css
Normal file
67
src/css/modal.css
Normal file
@ -0,0 +1,67 @@
|
||||
/* The Modal (background) */
|
||||
.modal {
|
||||
display: none; /* Hidden by default */
|
||||
position: fixed; /* Stay in place */
|
||||
z-index: 1; /* Sit on top */
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%; /* Full width */
|
||||
height: 100%; /* Full height */
|
||||
justify-content: center; /* Center horizontally */
|
||||
align-items: center; /* Center vertically */
|
||||
background-color: rgba(0, 0, 0, 0.4); /* Black w/ opacity */
|
||||
overflow: auto; /* Enable scroll if needed */
|
||||
animation: fadeIn 0.25s; /* Fade in the background */
|
||||
}
|
||||
|
||||
/* Modal Content */
|
||||
.modal-content {
|
||||
display: flex;
|
||||
background-color: #282828; /* Gruvbox background */
|
||||
color: #ebdbb2; /* Gruvbox foreground */
|
||||
margin: auto;
|
||||
padding: 20px;
|
||||
border: 1px solid #928374; /* Gruvbox grey */
|
||||
width: 40%; /* Adjust as needed */
|
||||
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
|
||||
animation: scaleUp 0.25s; /* Scale animation */
|
||||
border-radius: 8px; /* Rounded corners */
|
||||
justify-content: center; /* Center horizontally */
|
||||
}
|
||||
|
||||
/* Animations */
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeOut {
|
||||
from {
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes scaleUp {
|
||||
from {
|
||||
transform: scale(0.5);
|
||||
}
|
||||
to {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes scaleDown {
|
||||
from {
|
||||
transform: scale(1);
|
||||
}
|
||||
to {
|
||||
transform: scale(0.5);
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
@import url("./theme.css");
|
||||
@import url("./tf.css");
|
||||
@import url("./modal.css");
|
||||
|
||||
@font-face {
|
||||
font-family: "scientifica";
|
||||
|
@ -39,9 +39,9 @@ export class TheAbstractionEngine {
|
||||
const player = new Player();
|
||||
this.game.addEntity(player);
|
||||
|
||||
const box = new FunctionBox({ x: 3, y: 1 });
|
||||
const box = new FunctionBox({ x: 3, y: 1 }, "λ x . (x)");
|
||||
this.game.addEntity(box);
|
||||
const box2 = new FunctionBox({ x: 4, y: 1 });
|
||||
const box2 = new FunctionBox({ x: 4, y: 1 }, "λ x . (x)");
|
||||
this.game.addEntity(box2);
|
||||
}
|
||||
|
||||
|
@ -54,4 +54,6 @@ export namespace Miscellaneous {
|
||||
|
||||
export const GRID_CELL_WIDTH = Math.floor(WIDTH / GRID_COLUMNS);
|
||||
export const GRID_CELL_HEIGHT = Math.floor(HEIGHT / GRID_ROWS);
|
||||
|
||||
export const MODAL_ID = "modal";
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
Sprite,
|
||||
} from "../components";
|
||||
import { Coord2D } from "../interfaces";
|
||||
import { openModal, closeModal } from "../utils";
|
||||
|
||||
export class FunctionBox extends Entity {
|
||||
private static spriteSpec: SpriteSpec = SPRITE_SPECS.get(
|
||||
@ -52,15 +53,23 @@ export class FunctionBox extends Entity {
|
||||
|
||||
this.hooks.set(ComponentNames.Highlight, {
|
||||
add: () => {
|
||||
this.addComponent(new Interactable(() => this.viewInsides()));
|
||||
let modalOpen = false;
|
||||
const interaction = () => {
|
||||
if (modalOpen) {
|
||||
modalOpen = false;
|
||||
closeModal();
|
||||
return;
|
||||
}
|
||||
modalOpen = true;
|
||||
openModal(this.code);
|
||||
};
|
||||
|
||||
this.addComponent(new Interactable(interaction));
|
||||
},
|
||||
remove: () => {
|
||||
closeModal();
|
||||
this.removeComponent(ComponentNames.Interactable);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public viewInsides() {
|
||||
console.log("I am a function box!");
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +52,9 @@ export class Input extends System {
|
||||
}
|
||||
|
||||
interactable.interact();
|
||||
KeyConstants.ActionKeys.get(Action.INTERACT)!.forEach((key) =>
|
||||
this.keyReleased(key),
|
||||
);
|
||||
}
|
||||
|
||||
public handleMovement(entity: Entity) {
|
||||
|
@ -1,3 +1,4 @@
|
||||
export * from "./clamp";
|
||||
export * from "./dotProduct";
|
||||
export * from "./rotateVector";
|
||||
export * from "./modal";
|
||||
|
38
src/engine/utils/modal.ts
Normal file
38
src/engine/utils/modal.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import { Miscellaneous } from "../config";
|
||||
|
||||
let modalOpen = false;
|
||||
|
||||
export const openModal = (content: string, id = Miscellaneous.MODAL_ID) => {
|
||||
const modal = document.getElementById(id);
|
||||
if (modal && !modalOpen) {
|
||||
modal.style.display = "flex";
|
||||
modal.style.animation = "fadeIn 0.25s";
|
||||
|
||||
modal.innerHTML = `<div class="modal-content">${content}</div>`;
|
||||
const modalContent = document.querySelector<HTMLElement>(".modal-content");
|
||||
if (modalContent) {
|
||||
modalContent.style.animation = "scaleUp 0.25s";
|
||||
}
|
||||
|
||||
modalOpen = true;
|
||||
}
|
||||
};
|
||||
|
||||
export const closeModal = (id = Miscellaneous.MODAL_ID) => {
|
||||
const modal = document.getElementById(id);
|
||||
if (modal && modalOpen) {
|
||||
modal.style.animation = "fadeOut 0.25s";
|
||||
|
||||
const modalContent = document.querySelector<HTMLElement>(".modal-content");
|
||||
if (modalContent) {
|
||||
modalContent.style.animation = "scaleDown 0.25s";
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
modal.innerHTML = "";
|
||||
modal.style.display = "none";
|
||||
|
||||
modalOpen = false;
|
||||
}, 250);
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue
Block a user