← back to Interiordesignershowroom
public/js/hotspots.js
47 lines
// Shoppable room-setting hotspots. Tapping a dot opens its inline product card;
// the card flips above/below and clamps left/right so it never leaves the image.
// Outside-click and Esc close it. Keyboard: dots are real <button>s, Enter toggles.
(function () {
document.querySelectorAll('.room-scene-wrap.has-spots').forEach(function (wrap) {
var layer = wrap.querySelector('.hotspot-layer');
if (!layer) return;
var open = null;
function close() {
if (!open) return;
open.card.hidden = true;
open.btn.setAttribute('aria-expanded', 'false');
open = null;
}
function openCard(btn) {
close();
var card = wrap.querySelector('#' + btn.getAttribute('data-card'));
if (!card) return;
// vertical flip: if the dot is high in the image, drop the card below it
var topPct = parseFloat(card.style.top) || 50;
card.classList.toggle('below', topPct < 42);
// horizontal clamp: keep the card edge inside the figure
var leftPct = parseFloat(card.style.left) || 50;
card.classList.toggle('edge-left', leftPct < 22);
card.classList.toggle('edge-right', leftPct > 78);
card.hidden = false;
btn.setAttribute('aria-expanded', 'true');
open = { btn: btn, card: card };
}
layer.addEventListener('click', function (e) {
var btn = e.target.closest('.hotspot');
if (!btn) return;
e.preventDefault();
if (open && open.btn === btn) { close(); return; }
openCard(btn);
});
// clicks inside a card (e.g. the Shop link) shouldn't close it before navigating
wrap.addEventListener('click', function (e) {
if (!e.target.closest('.hotspot-card') && !e.target.closest('.hotspot')) close();
});
document.addEventListener('click', function (e) { if (!wrap.contains(e.target)) close(); });
document.addEventListener('keydown', function (e) { if (e.key === 'Escape') close(); });
});
})();