PageSourceSearch

https://www.stadt-roth.de/fileadmin/templates/js/parts/hw_focus.js

js stadt-roth.de collected 2026-10-02 05:33:06 UTC 5,801 bytes, 169 lines download raw bytes

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        // attributeFilter: ['data-focus-area']
33    };
34
35    let resizeObserver = new ResizeObserver(function (entries, observer) {
36        for (let i=0; i < entries.length; i++) {
37            focusContext.handleEvent(getObservable(entries[i].target));
38        }
39    });
40
41    let intersectionObserver = new IntersectionObserver(function (entries, observer) {
42
43        for (let i=0; i < entries.length; i++) {
44
45            let observable = getObservable(entries[i].target);
46
47            if (entries[i].isIntersecting) {
48                if (!observable.viewport) {
49                    resizeObserver.observe(entries[i].target);
50                    observable.mutationObserver = new MutationObserver(function () {
51                        focusContext.handleEvent(observable);
52                    });
53                    observable.mutationObserver.observe(observable.img, options);
54                    observable.viewport = true;
55                }
56            } else {
57                if (observable.viewport) {
58                    resizeObserver.unobserve(entries[i].target);
59                    observable.mutationObserver.disconnect();
60                    observable.viewport = false;
61                }
62            }
63        }
64    }, {});
65
66    focusContext.observe = function (img) {
67
68        let item = { 'img': img, 'target': img.parentNode, 'viewport': false, 'mutationObserver': null };
69
70        while (
71            (item.target.tagName.toLowerCase() !== 'body') &&
72            ((item.target.offsetWidth === 0) || (item.target.offsetHeight === 0))) {
73            item.target = item.target.parentNode;
74        }
75        if (item.target.tagName.toLowerCase() !== 'body') {
76            let properties = window.getComputedStyle(item.target);
77            if (!properties.getPropertyValue('position')) {
78                item.target.style.position = 'relative';
79            }
80
81            img.style.position = 'absolute';
82            img.style.maxWidth = 'none';
83            observables.push(item);
84            intersectionObserver.observe(item.target);
85        }
86    };
87
88    this.handleEvent = function (item) {
89
90        let img = item.img,
91            target = item.target,
92
93            width = target.offsetWidth, // frame width
94            height = target.offsetHeight, // frame height
95            focusX = .50, // center
96            focusY = .50; // center
97
98        // let focusJson = JSON.parse(img.getAttribute('data-focus-area'));
99        if (img.getAttribute('data-crop')){
100            let focusJson = JSON.parse(img.getAttribute('data-crop'));
101            focusJson = focusJson.default.focusArea;
102            if (focusJson != null){
103                // overwrite focus coordinates and calc to %
104                if (focusJson.x != null) {
105                    // focusX = parseFloat(focusJson.x / img.naturalWidth * 100) / 100;
106                    focusX = parseFloat(focusJson.x + (focusJson.width / 2));
107                }
108                if (focusJson.y != null) {
109                    // focusY = parseFloat(focusJson.y / img.naturalHeight * 100) / 100;
110                    focusY = parseFloat(focusJson.y + (focusJson.height / 2));
111                }
112            }
113        }
114
115        let scaled,
116            value;
117
118        if ( (img.naturalWidth / img.naturalHeight) >= (width / height) ) {
119            img.style.width = 'auto';
120            img.style.height = '100%';
121            img.style.top = '0';
122            scaled = img.naturalWidth * (height / img.naturalHeight);
123            value = - Math.floor((scaled * focusX) - (width / 2));
124
125            if (value > 0) {
126                value = 0;
127            } else if (value < width - scaled) {
128                value = Math.floor(width - scaled);
129            }
130
131            img.style.left = value + 'px';
132        } else {
133            img.style.width = '100%';
134            img.style.height = 'auto';
135            img.style.left = '0';
136            scaled = img.naturalHeight * (width / img.naturalWidth);
137            value = - Math.floor((scaled * focusY) - (height / 2));
138
139            if (value > 0) {
140                value = 0;
141            } else if (value < (height - scaled)) {
142                value = Math.floor(height - scaled);
143            }
144
145            img.style.top = value + 'px';
146        }
147    }
148}
149
150/**
151 * @param {NodeListOf<HTMLImageElement>} imgElementsToFocus
152 *
153 * @return void
154 */
155export function callFocusFunction(imgElementsToFocus){
156
157    if (imgElementsToFocus.length > 0) {
158
159        let focus = new FocusFunction();
160
161        for (let i=0; i < imgElementsToFocus.length; i++) {
162            if (!imgElementsToFocus[i].complete || (imgElementsToFocus[i].naturalWidth === 0)) {
163                imgElementsToFocus[i].addEventListener("load", function (e) { focus.observe(this); }, false);
164            } else {
165                focus.observe(imgElementsToFocus[i]);
166            }
167        }
168    }
169}

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.