144 lines
4.1 KiB
JavaScript
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);
|