| 1 |
/* Image Magnifier — frontend */ |
| 2 |
(function () { |
| 3 |
function init() { |
| 4 |
document.querySelectorAll('.bkmag-container[data-zoom]').forEach(function (container) { |
| 5 |
if (container._bkmagInit) return; |
| 6 |
container._bkmagInit = true; |
| 7 |
|
| 8 |
var img = container.querySelector('.bkmag-img'); |
| 9 |
if (!img) return; |
| 10 |
|
| 11 |
var zoom = parseInt(container.getAttribute('data-zoom'), 10) || 250; |
| 12 |
var lensSize = parseInt(container.getAttribute('data-lens-size'), 10) || 150; |
| 13 |
var lensShape = container.getAttribute('data-lens-shape') || 'circle'; |
| 14 |
var lensBorder = container.getAttribute('data-lens-border') || '#6c3fb5'; |
| 15 |
var lensBorderW = parseInt(container.getAttribute('data-lens-border-w'), 10) || 2; |
| 16 |
var lensShadow = container.getAttribute('data-lens-shadow') !== '0'; |
| 17 |
var effect = container.getAttribute('data-effect') || 'lens'; |
| 18 |
var previewW = parseInt(container.getAttribute('data-preview-w'), 10) || 300; |
| 19 |
var previewH = parseInt(container.getAttribute('data-preview-h'), 10) || 300; |
| 20 |
var previewBorder = container.getAttribute('data-preview-border') || '#e5e7eb'; |
| 21 |
var previewRadius = parseInt(container.getAttribute('data-preview-radius'), 10) || 8; |
| 22 |
|
| 23 |
var helpers; |
| 24 |
|
| 25 |
if (effect === 'lens') { |
| 26 |
var lens = document.createElement('div'); |
| 27 |
lens.className = 'bkmag-lens'; |
| 28 |
Object.assign(lens.style, { |
| 29 |
width: lensSize + 'px', |
| 30 |
height: lensSize + 'px', |
| 31 |
borderRadius: lensShape === 'circle' ? '50%' : previewRadius + 'px', |
| 32 |
border: lensBorderW + 'px solid ' + lensBorder, |
| 33 |
boxShadow: lensShadow ? '0 4px 20px rgba(0,0,0,0.3)' : 'none', |
| 34 |
backgroundImage: 'url(' + img.src + ')', |
| 35 |
}); |
| 36 |
container.appendChild(lens); |
| 37 |
|
| 38 |
container.addEventListener('mousemove', function (e) { |
| 39 |
var rect = img.getBoundingClientRect(); |
| 40 |
var containerRect = container.getBoundingClientRect(); |
| 41 |
var imgW = img.offsetWidth; |
| 42 |
var imgH = img.offsetHeight; |
| 43 |
var cx = e.clientX - rect.left; |
| 44 |
var cy = e.clientY - rect.top; |
| 45 |
|
| 46 |
var ratio = zoom / 100; |
| 47 |
var bgW = imgW * ratio; |
| 48 |
var bgH = imgH * ratio; |
| 49 |
var bgX = -(cx * ratio - lensSize / 2); |
| 50 |
var bgY = -(cy * ratio - lensSize / 2); |
| 51 |
|
| 52 |
lens.style.backgroundSize = bgW + 'px ' + bgH + 'px'; |
| 53 |
lens.style.backgroundPosition = bgX + 'px ' + bgY + 'px'; |
| 54 |
|
| 55 |
var lensX = cx - lensSize / 2; |
| 56 |
var lensY = cy - lensSize / 2; |
| 57 |
lens.style.left = lensX + 'px'; |
| 58 |
lens.style.top = lensY + 'px'; |
| 59 |
lens.style.display = 'block'; |
| 60 |
}); |
| 61 |
|
| 62 |
container.addEventListener('mouseleave', function () { |
| 63 |
lens.style.display = 'none'; |
| 64 |
}); |
| 65 |
|
| 66 |
} else { |
| 67 |
/* side preview box */ |
| 68 |
var preview = document.createElement('div'); |
| 69 |
preview.className = 'bkmag-preview'; |
| 70 |
Object.assign(preview.style, { |
| 71 |
width: previewW + 'px', |
| 72 |
height: previewH + 'px', |
| 73 |
border: '1px solid ' + previewBorder, |
| 74 |
borderRadius: previewRadius + 'px', |
| 75 |
backgroundImage: 'url(' + img.src + ')', |
| 76 |
boxShadow: '0 4px 24px rgba(0,0,0,0.12)', |
| 77 |
}); |
| 78 |
container.appendChild(preview); |
| 79 |
|
| 80 |
container.addEventListener('mousemove', function (e) { |
| 81 |
var rect = img.getBoundingClientRect(); |
| 82 |
var imgW = img.offsetWidth; |
| 83 |
var imgH = img.offsetHeight; |
| 84 |
var cx = e.clientX - rect.left; |
| 85 |
var cy = e.clientY - rect.top; |
| 86 |
|
| 87 |
var ratio = zoom / 100; |
| 88 |
var bgW = imgW * ratio; |
| 89 |
var bgH = imgH * ratio; |
| 90 |
var bgX = -(cx * ratio - previewW / 2); |
| 91 |
var bgY = -(cy * ratio - previewH / 2); |
| 92 |
|
| 93 |
preview.style.backgroundSize = bgW + 'px ' + bgH + 'px'; |
| 94 |
preview.style.backgroundPosition = bgX + 'px ' + bgY + 'px'; |
| 95 |
preview.style.display = 'block'; |
| 96 |
preview.style.top = Math.min(imgH - previewH, Math.max(0, cy - previewH / 2)) + 'px'; |
| 97 |
}); |
| 98 |
|
| 99 |
container.addEventListener('mouseleave', function () { |
| 100 |
preview.style.display = 'none'; |
| 101 |
}); |
| 102 |
} |
| 103 |
}); |
| 104 |
} |
| 105 |
|
| 106 |
if (document.readyState === 'loading') { |
| 107 |
document.addEventListener('DOMContentLoaded', init); |
| 108 |
} else { |
| 109 |
init(); |
| 110 |
} |
| 111 |
}()); |
| 112 |
|