| 1 |
wp.domReady(function () { |
| 2 |
var shadowMap = { |
| 3 |
none: 'none', |
| 4 |
sm: '0 2px 8px rgba(0,0,0,0.10)', |
| 5 |
md: '0 8px 32px rgba(0,0,0,0.15)', |
| 6 |
lg: '0 20px 60px rgba(0,0,0,0.22)' |
| 7 |
}; |
| 8 |
|
| 9 |
document.querySelectorAll('.bkbg-vertical-scroll-image-app').forEach(function (app) { |
| 10 |
var opts = {}; |
| 11 |
try { opts = JSON.parse(app.getAttribute('data-opts') || '{}'); } catch (e) {} |
| 12 |
|
| 13 |
if (!opts.imageUrl) { |
| 14 |
app.parentNode.removeChild(app); |
| 15 |
return; |
| 16 |
} |
| 17 |
|
| 18 |
var dir = opts.scrollDirection || 'vertical'; |
| 19 |
var trigger = opts.scrollTrigger || 'hover'; |
| 20 |
var dur = opts.scrollDuration || 4; |
| 21 |
var cHeight = opts.containerHeight || 420; |
| 22 |
var maxW = opts.maxWidth || 800; |
| 23 |
var radius = (opts.borderRadius !== undefined ? opts.borderRadius : 12) + 'px'; |
| 24 |
var shadow = shadowMap[opts.shadowSize] || shadowMap.md; |
| 25 |
var bgColor = opts.bgColor || '#f9fafb'; |
| 26 |
var borderCol = opts.borderColor || '#e5e7eb'; |
| 27 |
|
| 28 |
/* Outer section */ |
| 29 |
var wrap = document.createElement('div'); |
| 30 |
wrap.className = 'bkbg-vsi-wrap'; |
| 31 |
wrap.style.background = bgColor; |
| 32 |
wrap.style.paddingTop = (opts.paddingTop || 48) + 'px'; |
| 33 |
wrap.style.paddingBottom = (opts.paddingBottom || 48) + 'px'; |
| 34 |
|
| 35 |
var inner = document.createElement('div'); |
| 36 |
inner.className = 'bkbg-vsi-inner'; |
| 37 |
inner.style.maxWidth = maxW + 'px'; |
| 38 |
|
| 39 |
/* Container (clipping) */ |
| 40 |
var container = document.createElement('div'); |
| 41 |
container.className = 'bkbg-vsi-container' + (dir === 'horizontal' ? ' bkbg-vsi--horizontal' : ''); |
| 42 |
container.style.height = cHeight + 'px'; |
| 43 |
container.style.borderRadius = radius; |
| 44 |
container.style.border = '1px solid ' + borderCol; |
| 45 |
container.style.boxShadow = shadow; |
| 46 |
container.style.background = bgColor; |
| 47 |
|
| 48 |
/* Image */ |
| 49 |
var img = document.createElement('img'); |
| 50 |
img.className = 'bkbg-vsi-img'; |
| 51 |
img.src = opts.imageUrl; |
| 52 |
img.alt = opts.imageAlt || ''; |
| 53 |
img.setAttribute('loading', 'lazy'); |
| 54 |
img.setAttribute('decoding', 'async'); |
| 55 |
|
| 56 |
/* Label */ |
| 57 |
if (opts.showLabel && opts.label) { |
| 58 |
var lbl = document.createElement('div'); |
| 59 |
lbl.className = 'bkbg-vsi-label'; |
| 60 |
lbl.style.background = opts.labelBg || 'rgba(0,0,0,0.55)'; |
| 61 |
lbl.style.color = opts.labelColor || '#ffffff'; |
| 62 |
lbl.textContent = (dir === 'vertical' ? '↕ ' : '↔ ') + opts.label; |
| 63 |
container.appendChild(lbl); |
| 64 |
} |
| 65 |
|
| 66 |
container.prepend(img); // img before label in DOM order |
| 67 |
inner.appendChild(container); |
| 68 |
|
| 69 |
/* Caption */ |
| 70 |
if (opts.showCaption && opts.caption) { |
| 71 |
var cap = document.createElement('p'); |
| 72 |
cap.className = 'bkbg-vsi-caption'; |
| 73 |
cap.style.color = opts.captionColor || '#6b7280'; |
| 74 |
cap.innerHTML = opts.caption; |
| 75 |
inner.appendChild(cap); |
| 76 |
} |
| 77 |
|
| 78 |
wrap.appendChild(inner); |
| 79 |
app.parentNode.replaceChild(wrap, app); |
| 80 |
|
| 81 |
/* Scroll logic after image loads */ |
| 82 |
img.addEventListener('load', function () { |
| 83 |
var imgNatural = dir === 'vertical' ? img.naturalHeight : img.naturalWidth; |
| 84 |
var imgRendered = dir === 'vertical' ? img.offsetHeight : img.offsetWidth; |
| 85 |
var containerDim = cHeight; // For horizontal, need container width |
| 86 |
if (dir === 'horizontal') { |
| 87 |
containerDim = container.offsetWidth; |
| 88 |
} |
| 89 |
var maxTranslate = -(imgRendered - containerDim); |
| 90 |
if (maxTranslate >= 0) return; // Image smaller than container — nothing to scroll |
| 91 |
|
| 92 |
if (trigger === 'auto') { |
| 93 |
var axis = dir === 'vertical' ? 'v' : 'h'; |
| 94 |
img.style.setProperty('--bkbg-vsi-end', maxTranslate + 'px'); |
| 95 |
img.style.setProperty('--bkbg-vsi-dur', (dur * 2) + 's'); |
| 96 |
img.classList.add('bkbg-vsi--auto-' + axis); |
| 97 |
} else { |
| 98 |
/* Hover mode */ |
| 99 |
img.style.transition = 'transform ' + dur + 's ease'; |
| 100 |
container.addEventListener('mouseenter', function () { |
| 101 |
if (dir === 'vertical') { |
| 102 |
img.style.transform = 'translateY(' + maxTranslate + 'px)'; |
| 103 |
} else { |
| 104 |
img.style.transform = 'translateX(' + maxTranslate + 'px)'; |
| 105 |
} |
| 106 |
}); |
| 107 |
container.addEventListener('mouseleave', function () { |
| 108 |
img.style.transform = dir === 'vertical' ? 'translateY(0)' : 'translateX(0)'; |
| 109 |
}); |
| 110 |
} |
| 111 |
}); |
| 112 |
|
| 113 |
/* Handle cached images (already loaded) */ |
| 114 |
if (img.complete && img.naturalHeight > 0) { |
| 115 |
img.dispatchEvent(new Event('load')); |
| 116 |
} |
| 117 |
}); |
| 118 |
}); |
| 119 |
|