<div id="shop">
<header>
<p>Stamppot-Shop</p>
<div>
<svg id="cart" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 446.853 446.853">
<path d="M444.274,93.36c-2.558-3.666-6.674-5.932-11.145-6.123L155.942,75.289c-7.953-0.348-14.599,5.792-14.939,13.708 c-0.338,7.913,5.792,14.599,13.707,14.939l258.421,11.14L362.32,273.61H136.205L95.354,51.179 c-0.898-4.875-4.245-8.942-8.861-10.753L19.586,14.141c-7.374-2.887-15.695,0.735-18.591,8.1c-2.891,7.369,0.73,15.695,8.1,18.591 l59.491,23.371l41.572,226.335c1.253,6.804,7.183,11.746,14.104,11.746h6.896l-15.747,43.74c-1.318,3.664-0.775,7.733,1.468,10.916 c2.24,3.184,5.883,5.078,9.772,5.078h11.045c-6.844,7.617-11.045,17.646-11.045,28.675c0,23.718,19.299,43.012,43.012,43.012 s43.012-19.294,43.012-43.012c0-11.028-4.201-21.058-11.044-28.675h93.777c-6.847,7.617-11.047,17.646-11.047,28.675 c0,23.718,19.294,43.012,43.012,43.012c23.719,0,43.012-19.294,43.012-43.012c0-11.028-4.2-21.058-11.042-28.675h13.432 c6.6,0,11.948-5.349,11.948-11.947c0-6.6-5.349-11.948-11.948-11.948H143.651l12.902-35.843h216.221 c6.235,0,11.752-4.028,13.651-9.96l59.739-186.387C447.536,101.679,446.832,97.028,444.274,93.36z M169.664,409.814 c-10.543,0-19.117-8.573-19.117-19.116s8.574-19.117,19.117-19.117s19.116,8.574,19.116,19.117S180.207,409.814,169.664,409.814z M327.373,409.814c-10.543,0-19.116-8.573-19.116-19.116s8.573-19.117,19.116-19.117s19.116,8.574,19.116,19.117 S337.916,409.814,327.373,409.814z"/>
</svg>
<span id="cartCounter"></span>
</div>
</header>
<section class="products">
<article>
<img src="https://www.limburgsmaaktnaarmeer.be/site/data/images/product/thumb_gele-aardappel_15271573345b0692561ca48.png" alt="logo">
<p>Aardappel</p>
<p>€0,69</p>
</article>
<article>
<img src="https://cdn.pixabay.com/photo/2018/02/28/22/42/kale-3189314_960_720.png" />
<p>Boerenkool</p>
<p>€4,20</p>
</article>
<article>
<img src="https://www.unox.nl/sk-eu/content/dam/brands/unox/netherlands/1587677-8712100647864.png.rendition.767.767.png" />
<p>Rookworst</p>
<p>€4,20</p>
</article>
<article>
<img src="https://www.groentehal.nl/app/uploads/2020/06/2-635938271922064256.png"/>
<p>Jus</p>
<p>€4,20</p>
</article>
</section>
</div>
/* *** Init *** */
*{
box-sizing: border-box;
font-family: sans-serif
}
body {
background-color: #173F5F
}
#shop {
position: absolute;
top: 50%;
left: 50%;
width: 400px;
height: 400px;
transform: translate(-50%, -50%);
border-radius: 10px;
background-color: #F6D55C;
display: flex;
flex-direction: column;
box-shadow: 0 0 5px #333;
}
/* *** Header *** */
#shop > header {
width: 100%;
height: 3rem;
display: flex;
padding: 0 1rem;
justify-content: space-between;
}
#shop header div {
display: flex;
justify-content: center;
align-items: flex-end;
}
#shop svg {
width: 1.5rem;
height: 100%;
}
#shop svg > path {
/* stroke-dasharray: 3237; */
stroke-dashoffset: 3237;
fill: none;
stroke: black;
stroke-width: 15px;
}
#shop svg:hover > path {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: dash .5s linear alternate infinite;
}
@keyframes dash {
from {
stroke-dashoffset: 1000;
}
to {
stroke-dashoffset: 0;
}
}
/* *** Products *** */
.products {
width: 100%;
height: 100%;
padding: .5rem 1rem 0 1rem;
}
.products > article {
user-select: none;
position: relative;
width: 100%;
background-color: white;
display: flex;
justify-content: space-between;
padding: 0 .5rem;
margin-bottom: .5rem;
border-radius: 10px;
align-items: center;
cursor: pointer;
}
.products img {
width: 3rem;
height: 3rem;
}
.productClone {
position: absolute;
left: 5px;
top: 5px;
transition: transform 1s, opacity .3s ease-out 0.6s;
pointer-event: none;
}
@media(prefers-reduced-motion) {
.productClone {
transition: none;
}
}
const products = document.querySelectorAll(".products > article");
const productImgs = document.querySelectorAll(".products > article > img");
const cart = document.querySelector("#cart")
const cartCounter = document.querySelector("#cartCounter")
let cartPos = cart.getBoundingClientRect()
let cartItems = 0
window.addEventListener("resize", () => {
cartPos = cart.getBoundingClientRect()
})
products.forEach((product, i) => {
product.addEventListener("click", () => {
// initiate timer "[TIMERNAME]"
console.time(`responseTime`)
cartItems++
cartCounter.innerHTML = cartItems
// get and set img
const productImg = productImgs[i].cloneNode()
productImg.classList.add("productClone")
product.appendChild(productImg)
// create animation
productImg.style.transform = calculateDifference(productImg)
productImg.style.opacity = 0
requestAnimationFrame(() => {
// stop timer "[TIMERNAME]"
console.timeEnd("responseTime")
})
// remove el
// kan beter met requestTimeFrame()
setTimeout(() => {
productImg.remove()
}, 1100)
})
})
const calculateDifference = (img) => {
// For an even better performance, you can create an Array filled with all img-getboundingClientRect() info
const imgPos = img.getBoundingClientRect()
const deltaX = cartPos.left - imgPos.left
const deltaY = cartPos.top - imgPos.top
return `translate3d(${deltaX}px, ${deltaY}px, 0)`
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.