diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..897a9ce8 Binary files /dev/null and b/.DS_Store differ diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..4d1a35a8 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "liveServer.settings.port": 5501, + "editor.acceptSuggestionOnEnter": "on" +} \ No newline at end of file diff --git a/src/css/main.css b/src/css/main.css index e69de29b..861fbabd 100644 --- a/src/css/main.css +++ b/src/css/main.css @@ -0,0 +1,286 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +.container { + background-color: #818181; + width: auto; + display: flex; + margin: 2rem; + display: grid; + grid-template-areas: "overflow"; +} + +.floor-container, +.lift-container { + background-color: rgb(255, 255, 133); + width: 100%; + display: flex; + flex-direction: column-reverse; + position: relative; + min-height: max-content; + grid-area: overflow; + overflow: hidden; /* Prevent scrolling */ +} + +.lift-container { + background-color: transparent; +} + +.floor-divider { + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: center; + padding: 0.5rem; + border: 2px solid #cdcdcd; + border-left: none; + border-right: none; +} + +.floor-divider > button { + padding: 5px 8px; + z-index: 2; +} + +.lift { + position: absolute; + bottom: 0; + left: 50%; + transform: translateX(-50%); + width: 60px; + height: 60px; + background-color: #715050; + border-radius: 8px; + transition: bottom 3s ease; + animation-duration: 2.5s; + animation-timing-function: ease; + animation-fill-mode: forwards; + display: flex; + margin: 2px; + /* overflow: hidden; */ +} + + +.left-door { + background-color: aqua; + width: 30px; + height: 60px; + border-top-left-radius: 8px; + border-bottom-left-radius: 8px; + border: 1px solid black; + +} + +.right-door { + background-color: aqua; + width: 30px; + height: 60px; + border-top-right-radius: 8px; + border-bottom-right-radius: 8px; + border: 1px solid black; +} + +.left-door-open { + background-color: red; + animation: left-animation 4s; +} + +.right-door-open { + background-color: red; + animation: right-animation 4s; +} + + +.left-door-close { + background-color: red; +} + +.right-door-close { + background-color: red; +} + +/* @keyframes right-animation { + from { + position: absolute; + right: 0; + } + to { + position: absolute; + right: -30px; + } +} + +@keyframes left-animation { + from { + position: absolute; + left: 0; + } + to { + position: absolute; + left: -30px; + } +} */ + +@keyframes right-animation { + 0%, 100% { + position: absolute; + right: 0; + } + 50% { + position: absolute; + right: -30px; + } + 75% { + position: absolute; + right: -30px; + } +} + +@keyframes left-animation { + 0%, 100% { + position: absolute; + left: 0; + } + 50% { + position: absolute; + left: -30px; + } + 75% { + position: absolute; + left: -30px; + } +} + + + + + + + + + + + + +/* .door-open{ + gap: 50px; + position: absolute; + bottom: 0; + left: 50%; + transform: translateX(-50%); + width: 60px; + height: 60px; + background-color: #715050; + border-radius: 8px; + animation-timing-function: ease; + animation-fill-mode: forwards; + display: flex; + margin: 2px; + transition: 2s ease; +} */ + +.input { + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; +} + +.input input { + padding: 10px; + border: 1px solid #ccc; + border-radius: 5px; + width: 200px; + font-size: 16px; +} + +.input button { + padding: 10px 20px; + background-color: #007bff; + color: #fff; + border: none; + border-radius: 5px; + font-size: 16px; + cursor: pointer; + transition: background-color 0.3s ease; +} + +.input button:hover { + background-color: #0056b3; +} + + +/* .door-close { + animation-name: doorClose; +} */ + +@media (max-width: 768px) { + .container { + margin: 1rem; + } + + .floor-divider { + padding: 0.3rem; + display: flex; + justify-content: start; + } + + .lift { + width: 40px; + height: 40px; + left: 10%; + } + + .container { + margin: 1rem; + } + + .floor-divider { + padding: 0.3rem; + } + + .floor-divider button { + font-size: 10px; + padding: 3px 6px; + } + .lift>span{ + background-color: aqua; + width: 20px; + height: 40px; + transition: 2s ease; +} + +@keyframes right-animation { + 0%, 100% { + position: absolute; + right: 0; + } + 50% { + position: absolute; + right: -20px; + } + 75% { + position: absolute; + right: -20px; + } +} + +@keyframes left-animation { + 0%, 100% { + position: absolute; + left: 0; + } + 50% { + position: absolute; + left: -20px; + } + 75% { + position: absolute; + left: -20px; + } +} + +} diff --git a/src/index.html b/src/index.html index e69de29b..2d1d65f9 100644 --- a/src/index.html +++ b/src/index.html @@ -0,0 +1,27 @@ + + + + + + + + Document + + + +
+ + + +
+ +
+
+
+
+
+
+ + + + \ No newline at end of file diff --git a/src/js/main.js b/src/js/main.js index e69de29b..7f28926d 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -0,0 +1,187 @@ +const state = { + noOfFloors: 0, + noOfLifts: 0, + heightOfEachFloor: 155, + leftMarginEachLift: 150, + requests: [], + lifts: [], +}; + +const floorContainer = document.querySelector(".floor-container"); +const liftContainer = document.querySelector(".lift-container"); + +const form = document.querySelector("form"); + +form.onsubmit = (e) => { + e.preventDefault(); + let formData = new FormData(e.target); + const floorInput = formData.get("floor_input"); + const liftInput = formData.get("lift_input"); + + if (!floorInput || !liftInput) { + alert("Both inputs must be filled."); + return; + } + + const numFloors = parseInt(floorInput); + const numLifts = parseInt(liftInput); + + if (isNaN(numFloors) || isNaN(numLifts)) { + alert("Inputs must be valid numbers."); + return; + } + + if (numFloors <= 0) { + alert("Value of floor cannot be negative or 0."); + return; + } + if (numLifts <= 0) { + alert("Value of lift cannot be negative or 0."); + return; + } + + const isDesktopDevice = window.innerWidth > 768; + const maxLifts = isDesktopDevice ? 8 : 6; + + if (numLifts <= maxLifts) { + state.noOfFloors = numFloors; + state.noOfLifts = numLifts; + initializeSimulation(); + form.style.display = "none"; + } else { + alert( + isDesktopDevice + ? "Desktop devices should have 8 lifts." + : "Mobile devices have a maximum of 6 lifts." + ); + } +}; + +function initializeSimulation() { + floorContainer.innerHTML = ""; + liftContainer.innerHTML = ""; + render(); +} + +function render() { + for (let index = 0; index < state.noOfFloors; index++) { + let floor = document.createElement("div"); + floor.classList.add("floor-divider"); + let floor_heading = document.createElement("h4"); + floor_heading.innerText = `Floor ${index + 1}`; + + + // Call button for going up + let floor_button_up = document.createElement("button"); + floor_button_up.innerText = `Up`; + floor_button_up.onclick = () => { + callLift(index + 1); + }; + + // Call button for going down + let floor_button_down = document.createElement("button"); + floor_button_down.innerText = `Down`; + floor_button_down.onclick = () => { + callLift(index + 1); + }; + + floor.append(floor_heading, floor_button_up, floor_button_down); + floor.style.height = `${state.heightOfEachFloor}px`; + floorContainer.append(floor); + } + + for (let index = 0; index < state.noOfLifts; index++) { + let lift = document.createElement("div"); + const liftLeftPosition = (index + 1) * 12; + lift.classList.add("lift"); + let lift_state = { id: index, state: "free", currentFloor: 1 }; + lift.classList.add(`lift-${lift_state.id}`); + state.lifts.push(lift_state); + + lift.setAttribute("data-id", lift_state.id); + lift.setAttribute("data-state", lift_state.state); + + lift.style.left = `${liftLeftPosition}%`; + + // Create the first span element + let span1 = document.createElement("span"); + span1.classList.add("left-door"); + // span1.innerText = "Span 1 Text"; // You can set the text as needed + lift.appendChild(span1); + + // Create the second span element + let span2 = document.createElement("span"); + span2.classList.add("right-door"); + + // span2.innerText = "Span 2 Text"; // You can set the text as needed + lift.appendChild(span2); + + liftContainer.append(lift); +} +} + +function callLift(floor, isGoingDown = false) { + const availableLift = state.lifts.find((lift) => lift.state === "free"); + + if (availableLift) { + // Mark the lift as occupied + availableLift.state = "occupied"; + const previousFloor = availableLift.currentFloor + availableLift.currentFloor = floor; // Set the current floor + + const liftElement = document.querySelector(`.lift-${availableLift.id}`); + const innerElement1 = liftElement.querySelector('.left-door'); + const innerElement2 = liftElement.querySelector('.right-door'); + + // Determine direction and target floor + const floorDifference = Math.abs(floor - previousFloor) + const targetFloorPosition = (floor - 1) * state.heightOfEachFloor+30; + const transitionDuration = isGoingDown + ? `${2 * floorDifference + 1}s` + : `${2 * floorDifference + 1}s`; + + // Move the lift to the target floor + liftElement.style.transitionDuration = transitionDuration; + liftElement.style.bottom = `${targetFloorPosition}px`; + console.log(transitionDuration, floor - 1, floor) + // Wait for the lift to reach the target floor + + const doorOpenTimeout = parseInt(transitionDuration) * 1000 + + setTimeout(() => { + liftElement.classList.add("door-open"); + innerElement1.classList.add("left-door-open") + innerElement2.classList.add("right-door-open") + }, doorOpenTimeout); + setTimeout(() => { + console.log(1, "dusra") + // liftElement.classList.remove("door-open"); + // innerElement1.classList.remove("left-door-open") + // innerElement2.classList.remove("right-door-open") + + innerElement1.classList.add("left-door-close") + innerElement2.classList.add("right-door-close") + +}, +doorOpenTimeout + 2500); + setTimeout(() => { + availableLift.state = "free"; + + // Check if there are pending requests + if (state.requests.length > 0) { + // Get the next requested floor from the queue + const nextRequest = state.requests.shift(); + // Call the lift to the next requested floor + callLift(nextRequest.floor, nextRequest.isGoingDown); + } + }, doorOpenTimeout + 3500); + innerElement1.classList.remove("left-door-open") + innerElement2.classList.remove("right-door-open") + } else { + // If all lifts are busy, add the request to the queue + state.requests.push({ floor, isGoingDown }); + } + console.log(state) +} + +initializeSimulation();