Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /********************************************************************
- * ADVANCED HUD TEMPLATE
- * - Dragging
- * - Resize handles (SE, E, S)
- * - Tabs
- * - Snap-to-grid
- * - Snap-to-screen-edge
- * - Close + Minimize
- ********************************************************************/
- class HUD {
- constructor({
- title = "HUD",
- width = 260,
- height = 180,
- startX = 100,
- startY = 100,
- snapGrid = 20,
- snapEdge = 15,
- tabs = {}
- } = {}) {
- this.snapGrid = snapGrid;
- this.snapEdge = snapEdge;
- this.tabs = tabs;
- // HUD Container
- this.hud = document.createElement("div");
- Object.assign(this.hud.style, {
- position: "absolute",
- left: startX + "px",
- top: startY + "px",
- width: width + "px",
- height: height + "px",
- background: "lightgray",
- border: "1px solid black",
- borderRadius: "8px",
- zIndex: 9999,
- display: "flex",
- flexDirection: "column",
- overflow: "hidden",
- fontFamily: "Roboto Mono, monospace"
- });
- /**************** HEADER ****************/
- this.header = document.createElement("div");
- Object.assign(this.header.style, {
- height: "28px",
- background: "gray",
- color: "white",
- display: "flex",
- alignItems: "center",
- justifyContent: "space-between",
- padding: "0 6px",
- cursor: "grab",
- userSelect: "none"
- });
- this.header.textContent = title;
- // Header buttons
- this.btnArea = document.createElement("div");
- this.minBtn = this.#makeHeaderButton("-");
- this.closeBtn = this.#makeHeaderButton("X");
- this.btnArea.appendChild(this.minBtn);
- this.btnArea.appendChild(this.closeBtn);
- this.header.appendChild(this.btnArea);
- this.hud.appendChild(this.header);
- /**************** TABS ****************/
- this.tabBar = document.createElement("div");
- Object.assign(this.tabBar.style, {
- display: "flex",
- background: "#d0d0d0",
- height: "24px",
- borderBottom: "1px solid #aaa"
- });
- this.hud.appendChild(this.tabBar);
- this.tabContents = {};
- Object.keys(tabs).forEach((name, index) => {
- const tabBtn = document.createElement("div");
- Object.assign(tabBtn.style, {
- flex: "1",
- textAlign: "center",
- paddingTop: "4px",
- fontSize: "12px",
- cursor: "pointer",
- background: index === 0 ? "#fff" : "#c7c7c7"
- });
- tabBtn.textContent = name;
- tabBtn.onclick = () => this.#switchTab(name);
- this.tabBar.appendChild(tabBtn);
- const tabContent = document.createElement("div");
- tabContent.innerHTML = tabs[name];
- Object.assign(tabContent.style, {
- flex: "1",
- overflow: "auto",
- padding: "10px",
- display: index === 0 ? "block" : "none"
- });
- this.tabContents[name] = tabContent;
- this.hud.appendChild(tabContent);
- });
- /**************** RESIZE HANDLES ****************/
- this.#addResizeHandle("se", "8px", "8px", "se-resize");
- this.#addResizeHandle("e", "0", "8px", "e-resize", true);
- this.#addResizeHandle("s", "8px", "0", "s-resize", false, true);
- // Append HUD to page
- document.body.appendChild(this.hud);
- // Setup interactions
- this.#enableDragging();
- this.#setupClose();
- this.#setupMinimize();
- }
- /**************** UTILITIES ****************/
- #makeHeaderButton(label) {
- const b = document.createElement("span");
- Object.assign(b.style, {
- cursor: "pointer",
- fontWeight: "bold",
- fontSize: "16px",
- padding: "0 6px"
- });
- b.textContent = label;
- return b;
- }
- /**************** TABS ****************/
- #switchTab(name) {
- const allNames = Object.keys(this.tabContents);
- allNames.forEach((tab, i) => {
- // show/hide content
- this.tabContents[tab].style.display = (tab === name) ? "block" : "none";
- // highlight tab
- this.tabBar.children[i].style.background =
- (tab === name) ? "#fff" : "#c7c7c7";
- });
- }
- /**************** DRAGGING ****************/
- #enableDragging() {
- let isDragging = false;
- let offsetX = 0, offsetY = 0;
- this.header.addEventListener("mousedown", (e) => {
- if (e.target === this.minBtn || e.target === this.closeBtn) return;
- isDragging = true;
- offsetX = e.clientX - this.hud.offsetLeft;
- offsetY = e.clientY - this.hud.offsetTop;
- this.header.style.cursor = "grabbing";
- });
- document.addEventListener("mousemove", (e) => {
- if (!isDragging) return;
- let x = e.clientX - offsetX;
- let y = e.clientY - offsetY;
- // Snap to grid
- x = Math.round(x / this.snapGrid) * this.snapGrid;
- y = Math.round(y / this.snapGrid) * this.snapGrid;
- // Snap to edges
- if (Math.abs(x) < this.snapEdge) x = 0;
- if (Math.abs(y) < this.snapEdge) y = 0;
- const maxX = window.innerWidth - this.hud.offsetWidth;
- const maxY = window.innerHeight - this.hud.offsetHeight;
- if (Math.abs(x - maxX) < this.snapEdge) x = maxX;
- if (Math.abs(y - maxY) < this.snapEdge) y = maxY;
- this.hud.style.left = x + "px";
- this.hud.style.top = y + "px";
- });
- document.addEventListener("mouseup", () => {
- isDragging = false;
- this.header.style.cursor = "grab";
- });
- }
- /**************** CLOSE BUTTON ****************/
- #setupClose() {
- this.closeBtn.onclick = () => {
- this.hud.remove();
- };
- }
- /**************** MINIMIZE BUTTON ****************/
- #setupMinimize() {
- this.minBtn.onclick = () => {
- const collapsed = this.tabBar.style.display === "none";
- this.tabBar.style.display = collapsed ? "flex" : "none";
- Object.values(this.tabContents).forEach(
- c => c.style.display = collapsed ? "block" : "none"
- );
- this.minBtn.textContent = collapsed ? "-" : "+";
- this.hud.style.height = collapsed ? "180px" : "28px";
- };
- }
- /**************** RESIZING ****************/
- #addResizeHandle(pos, right, bottom, cursor, verticalOnly = false, horizontalOnly = false) {
- const handle = document.createElement("div");
- Object.assign(handle.style, {
- position: "absolute",
- width: verticalOnly ? "6px" : "12px",
- height: horizontalOnly ? "6px" : "12px",
- right,
- bottom,
- cursor,
- zIndex: 10000,
- background: "transparent"
- });
- this.hud.appendChild(handle);
- let resizing = false;
- handle.addEventListener("mousedown", () => resizing = true);
- document.addEventListener("mousemove", (e) => {
- if (!resizing) return;
- if (!horizontalOnly) {
- const newW = e.clientX - this.hud.offsetLeft;
- if (newW > 120) this.hud.style.width = newW + "px";
- }
- if (!verticalOnly) {
- const newH = e.clientY - this.hud.offsetTop;
- if (newH > 60) this.hud.style.height = newH + "px";
- }
- });
- document.addEventListener("mouseup", () => resizing = false);
- }
- }
- /********************************************************************
- * CREATE YOUR HUD (no more spawn button)
- ********************************************************************/
- const myHUD = new HUD({
- title: "Super HUD",
- width: 260,
- height: 200,
- startX: 100,
- startY: 100,
- snapGrid: 20,
- snapEdge: 15,
- tabs: {
- "Main": `
- <p>Welcome to the new advanced HUD!</p>
- `,
- "Settings": `<p>Future settings go here.</p>`,
- "About": `<p>Hello</p>`
- }
- });
Advertisement
Add Comment
Please, Sign In to add comment