1 2// ###### ######## ####### ###### ## ## ###### ###### 3// ## ## ## ## ## ## ## ## ## ## ## 4// ## ## ## ## ## ## ## ## ## 5// ## ###### ## ## ## ## ## ###### ## 6// ## ## ## ## ## ## ## ## ## 7// ## ## ## ## ## ## ## ## ## ## ## 8// ###### ## ####### ###### ####### ###### ###### 9 10function FocusFunction() { 11 12 let focusContext = this; 13 let observables = []; 14 15 /** 16 * 17 * @param target 18 * @return {*} 19 */ 20 function getObservable(target) { 21 22 for (let i=0; i < observables.length; i++) { 23 if (observables[i].target === target) { 24 return observables[i]; 25 } 26 } 27 } 28 29 let options = { 30 attributes: true, 31 attributeFilter: ['data-crop'] 32 }; 33 34 let resizeObserver = new ResizeObserver(function (entries, observer) { 35 for (let i=0; i < entries.length; i++) { 36 focusContext.handleEvent(getObservable(entries[i].target)); 37 } 38 }); 39 40 let intersectionObserver = new IntersectionObserver(function (entries, observer) { 41 42 for (let i=0; i < entries.length; i++) { 43 44 let observable = getObservable(entries[i].target); 45 46 if (entries[i].isIntersecting) { 47 if (!observable.viewport) { 48 resizeObserver.observe(entries[i].target); 49 observable.mutationObserver = new MutationObserver(function () { 50 focusContext.handleEvent(observable); 51 }); 52 observable.mutationObserver.observe(observable.img, options); 53 observable.viewport = true; 54 } 55 } else { 56 if (observable.viewport) { 57 resizeObserver.unobserve(entries[i].target); 58 observable.mutationObserver.disconnect(); 59 observable.viewport = false; 60 } 61 } 62 } 63 }, {}); 64 65 focusContext.observe = function (img) { 66 67 let item = { 'img': img, 'target': img.parentNode, 'viewport': false, 'mutationObserver': null }; 68 69 while ( 70 (item.target.tagName.toLowerCase() !== 'body') && 71 ((item.target.offsetWidth === 0) || (item.target.offsetHeight === 0))) { 72 item.target = item.target.parentNode; 73 } 74 if (item.target.tagName.toLowerCase() !== 'body') { 75 let properties = window.getComputedStyle(item.target); 76 if (!properties.getPropertyValue('position')) { 77 item.target.style.position = 'relative'; 78 } 79 80 img.style.position = 'absolute'; 81 img.style.maxWidth = 'none'; 82 observables.push(item); 83 intersectionObserver.observe(item.target); 84 } 85 }; 86 87 this.handleEvent = function (item) { 88 89 let img = item.img, 90 target = item.target, 91 92 width = target.offsetWidth, // frame width 93 height = target.offsetHeight, // frame height 94 focusX = .50, // center 95 focusY = .50; // center 96 97 // let focusJson = JSON.parse(img.getAttribute('data-focus-area')); 98 if (img.getAttribute('data-crop')){ 99 let focusJson = JSON.parse(img.getAttribute('data-crop')); 100 focusJson = focusJson.default.focusArea; 101 if (focusJson != null){ 102 // overwrite focus coordinates and calc to % 103 if (focusJson.x != null) { 104 // focusX = parseFloat(focusJson.x / img.naturalWidth * 100) / 100; 105 focusX = parseFloat(focusJson.x + (focusJson.width / 2)); 106 } 107 if (focusJson.y != null) { 108 // focusY = parseFloat(focusJson.y / img.naturalHeight * 100) / 100; 109 focusY = parseFloat(focusJson.y + (focusJson.height / 2)); 110 } 111 } 112 } 113 114 let scaled, 115 value; 116
117 if ( (img.naturalWidth / img.naturalHeight) >= (width / height) ) { 118 img.style.width = 'auto'; 119 img.style.height = '100%'; 120 img.style.top = '0'; 121 scaled = img.naturalWidth * (height / img.naturalHeight); 122 value = - Math.floor((scaled * focusX) - (width / 2)); 123 124 if (value > 0) { 125 value = 0; 126 } else if (value < width - scaled) { 127 value = Math.floor(width - scaled); 128 } 129 130 img.style.left = value + 'px'; 131 } else { 132 img.style.width = '100%'; 133 img.style.height = 'auto'; 134 img.style.left = '0'; 135 scaled = img.naturalHeight * (width / img.naturalWidth); 136 value = - Math.floor((scaled * focusY) - (height / 2)); 137 138 if (value > 0) { 139 value = 0; 140 } else if (value < (height - scaled)) { 141 value = Math.floor(height - scaled); 142 } 143 144 img.style.top = value + 'px'; 145 } 146 } 147} 148 149/** 150 * @param {NodeListOf<HTMLImageElement>} imgElementsToFocus 151 * 152 * @return void 153 */ 154export function callFocusFunction(imgElementsToFocus){ 155 156 if (imgElementsToFocus.length > 0) { 157 158 let focus = new FocusFunction(); 159 160 for (let i=0; i < imgElementsToFocus.length; i++) { 161 if (!imgElementsToFocus[i].complete || (imgElementsToFocus[i].naturalWidth === 0)) { 162 imgElementsToFocus[i].addEventListener("load", function (e) { focus.observe(this); }, false); 163 } else { 164 focus.observe(imgElementsToFocus[i]); 165 } 166 } 167 } 168}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.