led-controller/src/static/light-component.js

144 lines
4.1 KiB
JavaScript

import { getWebSocket } from "./websocket.js";
export class LightComponent extends HTMLElement {
constructor() {
super();
// Create a shadow DOM for encapsulation
const shadow = this.attachShadow({ mode: "open" });
// Create the content for the component
const style = document.createElement("style");
style.textContent = `
:host {
display: block;
width: 100px;
height: 100px;
background-color: #4caf50;
color: white;
text-align: center;
line-height: 100px;
cursor: grab;
position: absolute;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
:host:active {
cursor: grabbing;
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3);
}
.color-picker {
position: absolute;
top: 0;
right: 0;
width: 50px;
height: 50px;
cursor: pointer;
}
`;
// Create the main content (draggable area)
const content = document.createElement("div");
content.textContent = this.textContent || "Light Me Up!";
content.style.position = "absolute";
content.style.top = "0";
content.style.left = "0";
content.style.width = "100%";
content.style.height = "100%";
content.style.display = "flex";
content.style.justifyContent = "center";
content.style.alignItems = "center";
// Create the color picker
const colorPicker = document.createElement("input");
colorPicker.type = "color";
colorPicker.classList.add("color-picker");
colorPicker.value = "#4caf50"; // Default color
colorPicker.addEventListener("input", () => {
this.style.backgroundColor = colorPicker.value;
this.dispatchEvent(
new CustomEvent("color-change", {
detail: { lightId: this.lightId, color: colorPicker.value },
}),
);
});
// Append the style, content, and color picker to the shadow DOM
shadow.appendChild(style);
shadow.appendChild(content);
shadow.appendChild(colorPicker);
// Add event listeners for drag-and-drop
content.addEventListener("mousedown", this.handleMouseDown.bind(this));
document.addEventListener("mousemove", this.handleMouseMove.bind(this));
document.addEventListener("mouseup", this.handleMouseUp.bind(this));
}
// Track the initial mouse position and component position
handleMouseDown(event) {
event.preventDefault();
// Get the initial mouse position relative to the component
this.initialMouseX = event.clientX;
this.initialMouseY = event.clientY;
// Get the initial position of the component
const rect = this.getBoundingClientRect();
this.initialComponentX = rect.left;
this.initialComponentY = rect.top;
// Add a class to indicate dragging
this.classList.add("dragging");
}
// Update the component's position as the mouse moves
handleMouseMove(event) {
if (!this.classList.contains("dragging")) return;
// Calculate the new position of the component
const newX = this.initialComponentX + (event.clientX - this.initialMouseX);
const newY = this.initialComponentY + (event.clientY - this.initialMouseY);
// Update the component's position
this.style.left = `${newX}px`;
this.style.top = `${newY}px`;
}
// Stop dragging when the mouse is released
handleMouseUp() {
// Check if the component is being dragged
if (!this.classList.contains("dragging")) {
return; // Do nothing if not dragging
}
// Remove the dragging class
this.classList.remove("dragging");
// Get the current position of the component
const rect = this.getBoundingClientRect();
const newX = rect.left;
const newY = rect.top;
// Dispatch an event to notify the parent about the updated position
this.dispatchEvent(
new CustomEvent("position-change", {
detail: { lightId: this.lightId, x: newX, y: newY },
}),
);
}
// Add a property to hold the lightId
set lightId(id) {
this._lightId = id;
}
get lightId() {
return this._lightId;
}
}
// Define the custom element
customElements.define("light-component", LightComponent);