<div class="store-layout">
<div class="cart-header">
<h2>Shop</h2>
<div class="cart-icon" id="cart-icon">
<svg viewBox="0 0 24 24" width="28" height="28" fill="none" stroke="currentColor" stroke-width="2"><circle cx="9" cy="21" r="1"></circle><circle cx="20" cy="21" r="1"></circle><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path></svg>
<span class="cart-count" id="cart-count">0</span>
</div>
</div>
<div class="product-shelf">
<div class="product-item">
<img src="https://placehold.co/200x200/3b82f6/ffffff?text=Sneaker" alt="Shoe" class="draggable-img" id="shoe-img">
<h3>Air Runners</h3>
<p>$120.00</p>
<div class="drag-hint">Drag to cart</div>
</div>
</div>
</div>
*, *::before, *::after {
box-sizing: border-box;
}
body {
font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
margin: 0;
background: #f8fafc;
min-height: 100vh;
padding: 40px;
}
.store-layout {
max-width: 800px;
margin: 0 auto;
}
.cart-header {
display: flex;
justify-content: space-between;
align-items: center;
background: #ffffff;
padding: 20px 40px;
border-radius: 20px;
box-shadow: 0 10px 20px rgba(0,0,0,0.05);
margin-bottom: 60px;
}
.cart-header h2 {
margin: 0;
color: #0f172a;
}
.cart-icon {
position: relative;
background: #f1f5f9;
width: 60px;
height: 60px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
color: #0f172a;
transition: transform 0.2s, background 0.2s;
}
.cart-icon.bounce {
animation: cart-bounce 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
background: #dbeafe;
color: #3b82f6;
}
@keyframes cart-bounce {
0% { transform: scale(1); }
50% { transform: scale(1.2); }
100% { transform: scale(1); }
}
.cart-count {
position: absolute;
top: -5px;
right: -5px;
background: #ef4444;
color: #ffffff;
width: 24px;
height: 24px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
font-weight: 700;
font-size: 0.8rem;
box-shadow: 0 2px 5px rgba(239, 68, 68, 0.4);
}
.product-shelf {
display: flex;
justify-content: center;
}
.product-item {
background: #ffffff;
padding: 30px;
border-radius: 20px;
box-shadow: 0 20px 40px rgba(0,0,0,0.08);
text-align: center;
width: 260px;
}
.draggable-img {
width: 100%;
height: auto;
border-radius: 12px;
cursor: grab;
margin-bottom: 20px;
user-select: none;
/* Prevent native browser drag to avoid bugs */
-webkit-user-drag: none;
}
.draggable-img:active {
cursor: grabbing;
}
.product-item h3 {
margin: 0 0 10px 0;
color: #0f172a;
}
.product-item p {
color: #3b82f6;
font-weight: 700;
font-size: 1.25rem;
margin: 0 0 20px 0;
}
.drag-hint {
background: #f1f5f9;
color: #64748b;
padding: 8px 16px;
border-radius: 30px;
font-size: 0.9rem;
font-weight: 600;
display: inline-block;
}
/* The Ghost image safely generated by JS */
.ghost-item {
position: fixed;
pointer-events: none;
z-index: 9999;
opacity: 0.8;
border-radius: 12px;
box-shadow: 0 20px 40px rgba(0,0,0,0.3);
transition: none; /* Instant tracking */
}
const sourceImg = document.getElementById("shoe-img");
const cartIcon = document.getElementById("cart-icon");
const cartCount = document.getElementById("cart-count");
let isDragging = false;
let ghost = null;
let currentCount = 0;
function startDrag(e) {
isDragging = true;
sourceImg.style.opacity = "0.3";
/* Create exact visual clone flawlessly */
ghost = document.createElement("img");
ghost.src = sourceImg.src;
ghost.className = "ghost-item";
const rect = sourceImg.getBoundingClientRect();
ghost.style.width = rect.width + "px";
ghost.style.height = rect.height + "px";
document.body.appendChild(ghost);
moveGhost(e);
}
function moveGhost(e) {
if (!ghost) return;
const rect = ghost.getBoundingClientRect();
const x = e.clientX - (rect.width / 2);
const y = e.clientY - (rect.height / 2);
ghost.style.left = x + "px";
ghost.style.top = y + "px";
}
function endDrag(e) {
if (!isDragging) return;
isDragging = false;
sourceImg.style.opacity = "1";
if (ghost) {
const cartRect = cartIcon.getBoundingClientRect();
const dropX = e.clientX;
const dropY = e.clientY;
/* Check collision boundaries cleanly */
if (dropX > cartRect.left && dropX < cartRect.right && dropY > cartRect.top && dropY < cartRect.bottom) {
/* Trajectory animation directly into cart */
ghost.style.transition = "all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1)";
ghost.style.left = (cartRect.left + 15) + "px";
ghost.style.top = (cartRect.top + 15) + "px";
ghost.style.width = "30px";
ghost.style.height = "30px";
ghost.style.opacity = "0";
currentCount++;
setTimeout(function() {
cartCount.innerText = currentCount;
cartIcon.classList.add("bounce");
ghost.remove();
ghost = null;
setTimeout(function() {
cartIcon.classList.remove("bounce");
}, 400);
}, 400);
} else {
/* Drop failed, remove ghost safely */
ghost.remove();
ghost = null;
}
}
}
sourceImg.addEventListener("pointerdown", startDrag);
window.addEventListener("pointermove", function(e) {
if (isDragging) moveGhost(e);
});
window.addEventListener("pointerup", endDrag);
window.addEventListener("pointercancel", endDrag);