UNPKG

iobroker.roborock

Version:
256 lines (230 loc) 5.28 kB
<!doctype html> <html> <head> <title>Roborock Map</title> <script type="importmap"> { "imports": { "d3": "https://esm.sh/d3@7.9.0" } } </script> <script src="/socket.io/socket.io.js"></script> <script type="module" src="./app.js"></script> <style> /* Main Layout */ body { display: flex; align-items: center; background-color: #000000; margin: 0; overflow: hidden; /* Prevents scrollbars from D3 zoom */ font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; } #mapSvgContainer { /* SVG Container */ width: 450px; height: 450px; border: 2px solid #4f4f4f; box-shadow: 0px 0px 10px #333; border-radius: 15px; overflow: hidden; /* Important for Pan/Zoom constraints */ position: relative; background-color: #1a1a1a; } #mapSvg { width: 100%; height: 100%; display: block; cursor: grab; } #mapSvg:active { cursor: grabbing; } /* --- Interactive SVG Elements --- */ .zone-rect { fill: rgba(255, 255, 255, 0.5); stroke: white; stroke-width: 1.5; /* vector-effect: non-scaling-stroke; Keeps stroke width constant */ cursor: move; } .zone-handle { fill: red; cursor: nwse-resize; } .obstacle-marker { fill: rgba(0, 150, 255, 0.7); stroke: white; stroke-width: 0.5; vector-effect: non-scaling-stroke; cursor: pointer; transition: r 0.1s ease-in-out; } .obstacle-marker:hover { fill: rgba(0, 200, 255, 0.9); } .go-to-pin { cursor: crosshair; } /* --- Popup Styling --- */ #popup { display: none; position: absolute; background-color: white; border-radius: 5px; padding: 5px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5); pointer-events: none; transform: translate(-50%, -100%); margin-top: -15px; z-index: 10; } #popup-image { display: block; width: 100px; height: 100px; border: 1px solid black; cursor: pointer; pointer-events: auto; } #triangle { display: none; position: absolute; bottom: -10px; left: 50%; transform: translateX(-50%); width: 0; height: 0; border-style: solid; border-width: 10px 10px 0 10px; border-color: white transparent transparent transparent; z-index: 10; } #largePhoto { top: 50%; left: 50%; transform: translate(-50%, -50%); display: none; position: fixed; z-index: 1000; border: 2px solid white; box-shadow: 0 0 15px rgba(0, 0, 0, 0.7); } #largePhoto-image { display: block; max-width: 80vw; max-height: 80vh; width: auto; height: auto; } #largePhoto-bbox { display: none; position: absolute; border: 3px solid #ff3b30; box-shadow: 0 0 8px rgba(255, 59, 48, 0.8); pointer-events: none; z-index: 1001; } /* --- General Styling --- */ #addButton, #deleteButton { display: inline-block; width: 100px; } #addButton { margin-right: 0px; } #deleteButton { margin-left: 0px; } #startButton, #stopButton, #pauseButton { display: inline-block; width: 100px; } #startButton, #pauseButton { margin-right: 0px; } #stopButton { margin-left: 0px; } button, select { margin: 10px 20px; padding: 10px 20px; border-radius: 10px; background-color: #2d9cdb; color: #f0f0f0; cursor: pointer; transition: background-color 0.2s ease-in-out; font-size: 16px; font-weight: bold; border: 1px solid #4f4f4f; width: 200px; } button:hover, select:hover { background-color: #47a9dc; } button:disabled { color: gray; background-color: lightgray; cursor: not-allowed; } .hovered-option { background-color: #47a9dc !important; } </style> </head> <body> <div id="mapSvgContainer"> <svg id="mapSvg" width="450" height="450"></svg> </div> <div id="popup"> <img id="popup-image" src="" alt="Obstacle Preview" /> <div id="triangle"></div> </div> <div id="largePhoto"> <img id="largePhoto-image" src="" alt="Obstacle Detail" /> <div id="largePhoto-bbox"></div> </div> <div style="display: flex; flex-direction: column; align-items: center"> <div style="margin-left: auto"> <select id="robotSelect"></select> </div> <div style="margin-left: auto"> <select id="cleanCount"> <option value="1">1 Time</option> <option value="2">2 Times</option> <option value="3">3 Times</option> </select> </div> <div style="display: flex" id="zoneButtons"> <button id="addButton">+ Zone</button> <button disabled id="deleteButton">- Zone</button> </div> <div style="display: flex" id="robotButtons"> <button id="pauseButton" style="display: none">Pause</button> <button id="startButton">Start</button> <button id="stopButton">Stop</button> </div> <button id="dockButton">Dock</button> <button id="goToButton">GoTo Point</button> <button id="resetZoomButton">Reset zoom</button> </div> </body> </html>