<div class="modal-trigger-area">
<button class="open-btn" onclick="openModal()">Open Draggable Window</button>
</div>
<div id="dragModal" class="modal-wrapper">
<div class="modal-window" id="windowBox">
<div class="modal-header" id="dragHandle">
<div class="title">
<span>New Project</span>
</div>
<button class="close-btn" onclick="closeModal()">×</button>
</div>
<div class="modal-body">
<h3>Drag me around!</h3>
<p>Grab the gray header bar to move this window. It stays exactly where you leave it.</p>
<div class="modal-footer">
<button class="action-btn" onclick="closeModal()">Close</button>
<button class="action-btn primary">Save Changes</button>
</div>
</div>
</div>
</div>.modal-trigger-area {
font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
padding: 50px;
text-align: center;
}
.open-btn {
padding: 12px 24px;
background: #1f2937;
color: white;
border: none;
border-radius: 8px;
font-weight: 600;
cursor: pointer;
transition: transform 0.2s;
}
.open-btn:active {
transform: scale(0.96);
}
/* Modal Overlay */
.modal-wrapper {
font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.4);
backdrop-filter: blur(4px);
z-index: 1000;
display: none;
opacity: 0;
transition: opacity 0.3s ease;
}
.modal-wrapper.show {
display: block;
opacity: 1;
}
/* Draggable Window */
.modal-window {
position: absolute;
top: 50%;
left: 50%;
/* Initial centering */
transform: translate(-50%, -50%);
width: 400px;
background: #ffffff;
border-radius: 12px;
box-shadow: 0 20px 50px rgba(0,0,0,0.15);
border: 1px solid #e5e7eb;
overflow: hidden;
}
.modal-header {
padding: 12px 16px;
background: #f3f4f6;
border-bottom: 1px solid #e5e7eb;
display: flex;
justify-content: space-between;
align-items: center;
cursor: grab;
user-select: none;
}
.modal-header:active {
cursor: grabbing;
background: #e5e7eb;
}
.title {
display: flex;
align-items: center;
gap: 8px;
font-weight: 600;
color: #374151;
}
.close-btn {
background: none;
border: none;
font-size: 1.5rem;
line-height: 1;
color: #9ca3af;
cursor: pointer;
padding: 0 4px;
}
.close-btn:hover {
color: #ef4444;
}
.modal-body {
padding: 24px;
}
.modal-body h3 {
margin: 0 0 10px 0;
color: #111827;
}
.modal-body p {
color: #6b7280;
line-height: 1.5;
margin-bottom: 24px;
}
.modal-footer {
display: flex;
justify-content: flex-end;
gap: 12px;
}
.action-btn {
padding: 8px 16px;
border-radius: 6px;
border: 1px solid #d1d5db;
background: white;
font-weight: 500;
cursor: pointer;
color: #374151;
}
.action-btn.primary {
background: #2563eb;
color: white;
border-color: #2563eb;
}const wrapper = document.getElementById("dragModal");
const modal = document.getElementById("windowBox");
const header = document.getElementById("dragHandle");
let isDragging = false;
let startX, startY, initialLeft, initialTop;
function openModal() {
wrapper.classList.add("show");
// Reset position to center whenever opened
modal.style.top = "50%";
modal.style.left = "50%";
modal.style.transform = "translate(-50%, -50%)";
}
function closeModal() {
wrapper.classList.remove("show");
}
header.addEventListener("mousedown", (e) => {
isDragging = true;
// Get the current computed position
const rect = modal.getBoundingClientRect();
// Calculate the offset from the mouse to the top-left corner
startX = e.clientX - rect.left;
startY = e.clientY - rect.top;
// Important: Switch from CSS centering to absolute pixel positioning
// This prevents the "jump" when removing the transform
modal.style.transform = "none";
modal.style.left = rect.left + "px";
modal.style.top = rect.top + "px";
});
document.addEventListener("mousemove", (e) => {
if (!isDragging) return;
e.preventDefault();
// Calculate new position
const x = e.clientX - startX;
const y = e.clientY - startY;
modal.style.left = `${x}px`;
modal.style.top = `${y}px`;
});
document.addEventListener("mouseup", () => {
isDragging = false;
});Nothing to show yetType HTML, CSS or JavaScript and your page appears here.
Click any element to find its code Esc
Check this code before you run it
It came from a shared link. It runs with fewer permissions, so it cannot open pop-ups, submit forms or start downloads.
0.00s / 0.00s
Nothing has animated yet. Hover, click or type in the preview and each CSS animation, transition or
element.animate() call shows up here as it plays.