PageSourceSearch

https://hotelastoriaplaya.com/assets/blocks/block-customizer/block-customizer.js?v=72.0

js hotelastoriaplaya.com collected 2026-10-08 21:06:41 UTC 22,048 bytes, 627 lines download raw bytes

1class BlockCustomizer {
2    constructor(block) {
3        frontendSetLazyContent(block.get(0));
4        setVideoBackground(block);
5
6        if (block.find('.block-scroll-effect-fixed').each((index, element) => {
7            new BlockCustomizerItemsFixed($(element));
8        }));
9
10        if (block.find('.block-scroll-effect-parallax').each((index, element) => {
11            new BlockCustomizerItemsParallax(index, $(element));
12        }));
13
14        if (block.find('.block-scroll-effect-scale').each((index, element) => {
15            new BlockCustomizerItemsScale(index, $(element));
16        }));
17
18        if (block.find('.block-scroll-effect-scale-inv').each((index, element) => {
19            new BlockCustomizerItemsScaleInv(index, $(element));
20        }));
21
22        if (block.find('.block-mousemove-effect-opposite').each((index, element) => {
23            new BlockCustomizerItemsMouseMoveOpposite($(element));
24        }));
25
26        if (block.find('.block-mousemove-effect-follow').each((index, element) => {
27            new BlockCustomizerItemsMouseMoveFollow($(element));
28        }));
29
30        if (block.find('[data-width-option="screen-adaptive"]').each((index, element) => {
31            new BlockCustomizerItemsFullWidth($(element));
32        }));
33
34        if (block.find('[data-height-option="content-adaptive"]').each((index, element) => {
35            new BlockCustomizerItemsAutoHeight($(element));
36        }));
37
38        new BlockCustomizerContainerHeight(block);
39        BlockCustomizerItemsBackgroundClip.addBlock(block);
40    }
41}
42
43// No usamos esta clase porque se ha desactivado el ancho máximo para el .container
44class BlockCustomizerCssVars {
45    constructor(block) {
46        const wrapper = $('#wrapper');
47
48        // Solo aplicable a proyectos con un ancho grande y relativo
49        if (!wrapper.hasClass('size-lg') && !wrapper.hasClass('size-xl'))
50            return;
51
52        this.block = block;
53        this.varBlockCustomizerItemSizeFixed = '--block-customizer-item-size-fixed';
54        this.cssBlockCustomizerItemSizeFixed = getComputedStyle(document.documentElement).getPropertyValue(this.var).trim();
55
56        this.updateVars();
57
58        $(window).on('resize', e => {
59            this.updateVars();
60        });
61    }
62
63    updateVars() {
64        const container = this.block.find('.container');
65        const maxContainerWidth = 1920;
66
67        if (container.outerWidth() >= maxContainerWidth) {
68            document.documentElement.style.setProperty(this.varBlockCustomizerItemSizeFixed, '7.44px');
69        } else {
70            document.documentElement.style.setProperty(this.varBlockCustomizerItemSizeFixed, this.cssBlockCustomizerItemSizeFixed);
71        }
72    }
73}
74
75class BlockCustomizerItemsFixed {
76    constructor(element) {
77
78        this.element = element;
79        this.parent = element.parents('.block.block-customizer');
80        this.builderTopBarHeight = (_APP.builder ? $('#builder-header').outerHeight() : 0);
81
82        this.element.attr('data-offset-top', this.element.offset().top);
83
84        $(window).on('scroll', e => {
85            this._updatePosition();
86        });
87
88        $(window).on('load', e => {
89            this._updatePosition();
90            this._updateElementOffsetTop();
91        });
92
93        $(window).on('resize', e => {
94            this._updatePosition();
95            this._updateElementOffsetTop();
96        });
97
98        const obsResize = new ResizeObserver(entries => {
99            this._updatePosition();
100            this._updateElementOffsetTop();
101        });
102
103        obsResize.observe(document.body);
104    }
105
106    _getTransformScaleValue(element) {
107        let matrix = element.css('transform');
108        let scale = 1; // Valor por defecto si no hay transformación
109
110        if (matrix !== 'none') {
111            let v = matrix.split('(')[1].split(')')[0].split(',');
112            // Math.hypot(v[0], v[1]) extrae la escala real combinada
113            scale = Math.hypot(v[0], v[1]);
114        }
115
116        return scale;
117    }
118
119    // Obtenemos el left del elemento respecto a su contenedor
120    _getRealCssLeft(element) {
121        return parseInt(element.css('left'));
122    }
123
124    _updatePosition() {
125        const builderHeaderBarHeight = (_APP.builder ? $('#builder-header').height() : 0);
126        const scrollY = window.scrollY;
127        const parentOffsetTop = this.parent.offset().top;
128        const elementTop = parseInt(this.element.attr('data-offset-top')) - parseInt(this.parent.offset().top);
129        const parentEnd = (this.parent.offset().top + this.parent.outerHeight()) - scrollY;
130        const scrollYLimit = parentEnd - (this.element.outerHeight() + elementTop * 2);
131        const elementBorderWidth = parseInt(this.element.css('border-width'));
132        let width;
133        let height;
134
135        // Debido a un problema que al cambiar de position absolute a fixed, si el tamaño se adapta al contenido,
136        // el tamaño del elemento puede cambiar, por lo que tenemos que guardar el tamaño antes de pasar a position fixed
137        // Además, lo guardamos en un atributo para poder usarlo luego
138        // Al cambiar de position absolute a fixed, a veces aparecen problemas
139        // - Si el tamaño se adapta al contenido
140        // - Si hay animaciones en el proyecto, el offset.left no funciona correctamente
141        if (this.element.css('position') == 'absolute') {
142
143            // El ancho lo guardamos cuando el ancho deba adaptarse al contenido y ... 
144            // cuando esté configurado en el diseño, esto es porque en el móvil da problemas y da un salto (ya que son unidades relativas)
145            if (this.element.attr('data-width-option') == 'content-adaptive' || this.element.attr('data-width-option') == 'none')
146                this.element.attr('data-content-inner-width', this.element.find('.content').innerWidth() + elementBorderWidth + 1);
147
148            // Solo guardamos el alto cuando el alto deba adaptarse al contenido
149            if (this.element.attr('data-height-option') == 'content-adaptive')
150                this.element.attr('data-content-inner-height', this.element.find('.content').innerHeight() + elementBorderWidth + 1);
151
152            // Guardamos el left para su posterior uso
153            this.element.attr('data-offset-left', this._getRealCssLeft(this.element) + this.element.parents('.block-customizer-grid').offset().left);
154        }
155
156        // El scroll está dentro del bloque, lo fijamos
157        if (scrollY >= parentOffsetTop - builderHeaderBarHeight && scrollYLimit >= 0) {
158            this.element.css({
159                position: 'fixed',
160                top: elementTop + builderHeaderBarHeight,
161                left: parseInt(this.element.attr('data-offset-left')),
162                bottom: '',
163            });
164
165            // Si el atributo tiene el tamaño del contenido lo establecemos como important
166            if (width = this.element.attr('data-content-inner-width'))
167                this.element.get(0).style.setProperty('width', width + 'px', 'important');
168
169            if (height = this.element.attr('data-content-inner-height'))
170                this.element.get(0).style.setProperty('height', height + 'px', 'important');
171
172        }
173        // El scroll no ha llegado al bloque, desactivamos estilos
174        else if (scrollY <= parentOffsetTop) {
175            this.element.css({
176                position: '',
177                top: '',
178                left: '',
179                bottom: '',
180                width: '',
181                height: '',
182            });
183        }
184        // El scroll está en el límite, fijamos el elemento al final del bloque
185        else if (scrollYLimit < 0) {
186            this.element.css({
187                position: 'absolute',
188                top: 'unset',
189                left: '',
190                bottom: elementTop - builderHeaderBarHeight,
191                width: '',
192                height: '',
193            });
194        }
195
196        BlockCustomizerItemsAutoHeight.forceUpdateHeight(this.element);
197        BlockCustomizerItemsFullWidth.forceUpdateWidth(this.element);
198    }
199
200    _updateElementOffsetTop() {
201        const position = this.element.css('position');
202        const top = this.element.css('top');
203        const left = this.element.css('left');
204        const bottom = this.element.css('bottom');
205
206        this.element.css({
207            position: '',
208            top: '',
209            left: '',
210            bottom: '',
211        });
212
213        this.element.attr('data-offset-top', this.element.offset().top);
214
215        this.element.css({
216            position: position,
217            top: top,
218            left: left,
219            bottom: bottom,
220        });
221    }
222}
223
224class BlockCustomizerItemsParallax {
225    constructor(index, element) {
226        this.element = $(element);
227        this.parent = this.element.parent();
228        this.step = 0.3;
229        this.margin = -150; // Margen de seguridad
230
231        // Guardamos la posición inicial de diseño (CSS)
232        this.initialElementTop = parseInt(this.element.css('top')) || 0;
233
234        setTimeout(() => this._init(), 350);
235    }
236
237    _init() {
238        $(window).on('scroll.parallax', () => this._onScroll())
239            .trigger('scroll.parallax');
240    }
241
242    _onScroll() {
243        const windowHeight = $(window).height();
244        const scrollTop = $(window).scrollTop();
245
246        const parentOffsetTop = this.parent.offset().top;
247        const parentHeight = this.parent.outerHeight();
248
249        // Punto de activación: cuando el borde superior del padre entra por abajo
250        const startPoint = parentOffsetTop - windowHeight - this.margin + this.initialElementTop;
251        // Punto de finalización: cuando el borde inferior sale por arriba
252        const endPoint = parentOffsetTop + parentHeight;
253
254        if (scrollTop <= startPoint) {
255            // Antes de entrar en la zona: mantenemos el top inicial
256            this._animate(this.initialElementTop);
257            return;
258        }
259
260        if (scrollTop >= endPoint) {
261            // Después de la zona: clamp al valor máximo calculado en endPoint
262            const relativeScrollMax = endPoint - startPoint;
263            this._animate(this.initialElementTop + (relativeScrollMax * this.step));
264            return;
265        }
266
267        // Dentro de la zona: el desplazamiento 0 es justo en startPoint
268        const relativeScroll = scrollTop - startPoint;
269
270        this._animate(this.initialElementTop + (relativeScroll * this.step));
271    }
272
273    _animate(top) {
274        anime({
275            targets: this.element.get(0),
276            top: top,
277            duration: 10,
278            easing: 'linear'
279        });
280    }
281}
282
283class BlockCustomizerItemsParallax__NO {
284    constructor(index, element) {
285        this.element = $(element);
286        this.parent = this.element.parent();
287        this.step = 0.2 + (index * 0.15);
288        this.margin = 20;
289
290        // Guardamos la posición inicial de diseño (CSS)
291        this.initialTop = parseInt(this.element.css('top')) || 0;
292
293        setTimeout(() => this._init(), 1100);
294    }
295
296    _init() {
297        $(window).on('scroll.parallax', () => this._onScroll())
298            .trigger('scroll.parallax');
299    }
300
301    _onScroll() {
302        const windowHeight = $(window).height();
303        const elementHeight = this.element.outerHeight();
304        const elementTop = parseInt(this.element.css('top'));
305        const scrollTop = $(window).scrollTop();
306
307        // Posición del padre respecto al documento
308        const parentOffsetTop = this.parent.offset().top;
309        const parentHeight = this.parent.outerHeight();
310
311        // Punto de activación: cuando el borde superior del padre entra por abajo
312        const startPoint = parentOffsetTop - windowHeight - this.margin + elementTop;
313        // Punto de finalización: cuando el borde inferior sale por arriba
314        const endPoint = parentOffsetTop + parentHeight - elementHeight * 2;
315
316        if (scrollTop > startPoint && scrollTop < endPoint) {
317            // Calculamos cuánto ha avanzado el scroll dentro de la "zona del padre"
318            // El desplazamiento 0 será justo cuando el padre empieza a asomar
319            const relativeScroll = scrollTop - parentOffsetTop;
320
321            const offset = Math.max(scrollTop - parentOffsetTop + this.initialTop, 0) * 1.3;
322
323            this.element.css('transform', 'translateY(' + offset + 'px)');
324
325            //this._animate(this.initialTop + offset);
326
327            console.log('Animando..', this.initialTop, offset)
328        }
329    }
330
331    _animate(top) {
332        anime({
333            targets: this.element.get(0),
334            top: top,
335            duration: 10,
336            easing: 'linear' // Para parallax es mejor linear o un ease muy suave
337        });
338    }
339}
340
341class BlockCustomizerItemsScale {
342    constructor(index, element) {
343
344        if (element.find('.block-background-image-parallax').length) {
345            element.find('.block-background-image-parallax').addClass('with-scale-effect');
346        }
347
348        $(window).on('scroll', e => {
349            const blockOffsetTop = element.parents('.block-customizer').offset().top;
350            const blockHeight = element.parents('.block-customizer').outerHeight();
351            const scrollTop = $(window).scrollTop();
352            const windowHeight = $(window).height();
353            const maxValue = 125;
354            const start = blockOffsetTop;
355            const end = blockOffsetTop + blockHeight;
356            const total = (end - start) / 100;
357            const current = ((scrollTop + windowHeight) - blockOffsetTop) / 100;
358            let value = 0;
359
360            if (scrollTop + windowHeight > blockOffsetTop && scrollTop + windowHeight <= blockOffsetTop + blockHeight) {
361                value = (maxValue * current) / total;
362
363                element.css('transform', 'scale(' + (value / 100) + ')');
364            }
365        }).scroll();
366    }
367}
368
369class BlockCustomizerItemsScaleInv {
370    constructor(index, element) {
371
372        if (element.find('.block-background-image-parallax').length) {
373            element.find('.block-background-image-parallax').addClass('with-scale-effect');
374        }
375
376        $(window).on('scroll', e => {
377            const blockOffsetTop = element.parents('.block-customizer').offset().top;
378            const blockHeight = element.parents('.block-customizer').outerHeight();
379            const scrollTop = $(window).scrollTop();
380            const windowHeight = $(window).height();
381            const maxValue = 400;
382            const start = blockOffsetTop;
383            const end = blockOffsetTop + blockHeight * 1.3;
384            const total = (end - start) / 100;
385            let current = ((scrollTop + windowHeight) - blockOffsetTop) / 100;
386            let value = 0;
387
388            if (scrollTop + windowHeight > blockOffsetTop && scrollTop + windowHeight <= blockOffsetTop + blockHeight) {
389                let scale = 1;
390                current = (total - current);
391                value = (maxValue * current) / total;
392
393                scale = (value / 100);
394
395                if (scale < 1)
396                    scale = 1;
397
398                element.css('transform', 'scale(' + scale + ')');
399            }
400        }).scroll();
401    }
402}
403
404class BlockCustomizerContainerHeight {
405    constructor(block) {
406        this.block = block;
407
408        this.setGridHeightAuto();
409
410        $(window).on('resize', e => {
411            this.setGridHeightAuto();
412        });
413    }
414
415    setGridHeightAuto() {
416        // Estos valores se encuentran en block-customizer-backend.css y deben coincidir
417        const fakeDesktopContainerWidthLG = 1302;
418        const fakeDesktopContainerWidthXL = 1502;
419        const fakeMobileContainerWidth = 402;
420
421        const wrapper = $('#wrapper');
422        const grid = this.block.find('.block-customizer-grid');
423        let gridHeight = parseInt(grid.css('height'));
424        const wrapperWidth = wrapper.outerWidth() - ($('body').hasClass('builder') ? 50 : 0);
425        let fakeContainerWidth = 0;
426        let newHeight = 0;
427
428        // Solo aplicable a proyectos con un ancho grande y relativo
429        if (!wrapper.hasClass('size-lg') && !wrapper.hasClass('size-xl'))
430            return;
431
432        if (!grid.attr('data-height'))
433            grid.attr('data-height', gridHeight);
434        else
435            gridHeight = parseInt(grid.attr('data-height'));
436
437        if (isSmallScreen()) {
438            fakeContainerWidth = fakeMobileContainerWidth;
439        } else {
440            fakeContainerWidth = (wrapper.hasClass('size-lg') ? fakeDesktopContainerWidthLG : fakeDesktopContainerWidthXL);
441        }
442
443        newHeight = ((wrapperWidth * gridHeight) / fakeContainerWidth);
444
445        // NOTA: desactivamos este código porque está estirando la altura del grid hasta mostrar todos los items
446        // Esto es un problema puesto que hay veces que se quiere dejar parcialmente fuera del grid un elemento
447        // Buscamos el bloque que está más abajo del todo para establecer la nueva altura del grid
448        /*
449        this.block.find('.block-customizer-item').each((index, element) => {
450            element = $(element);
451
452            let value = parseInt(element.css('top')) + element.outerHeight();
453
454            if (value > newHeight)
455                newHeight = value + 15;
456        });
457        */
458
459        // Configuramos la nueva altura del grid
460        if (newHeight > 0)
461            grid.css('height', newHeight);
462    }
463}
464
465class BlockCustomizerItemsBackgroundClip {
466
467    static addBlock(block) {
468        block.find('.block-customizer-item[data-bg-clip="true"]').each((index, element) => {
469            BlockCustomizerItemsBackgroundClip.addItemStyles($(element));
470        });
471    }
472
473    static addItemStyles(item) {
474
475        if (item.attr('data-bg-clip') != 'true') {
476            return false;
477        }
478
479        const bgImage = item.find('.block-background-image img');
480        const src = (bgImage.attr('src') != undefined ? bgImage.attr('src') : bgImage.attr('data-src'));
481
482        if (src == undefined) {
483            item.find('.content').css({
484                'background-color': item.css('background-color'),
485            });
486        }
487        else {
488            item.find('.content').css({
489                'background-image': 'url(' + src + ')',
490            });
491        }
492
493        item.css('background-color', 'transparent');
494    }
495}
496
497class BlockCustomizerItemsMouseMoveOpposite {
498    constructor(element) {
499
500        element = element.get(0);
501
502        document.addEventListener('mousemove', (e) => {
503            const { clientX, clientY } = e;
504            const { innerWidth, innerHeight } = window;
505
506            const offsetX = (clientX - innerWidth / 2) * -0.05;
507            const offsetY = (clientY - innerHeight / 2) * -0.05;
508
509            anime({
510                targets: element,
511                translateX: offsetX,
512                translateY: offsetY,
513                duration: 500,
514                easing: 'easeOutQuad'
515            });
516        });
517    }
518}
519
520class BlockCustomizerItemsMouseMoveFollow {
521    constructor(element) {
522
523        element = element.get(0);
524
525        document.addEventListener('mousemove', (e) => {
526            const { clientX, clientY } = e;
527            const { innerWidth, innerHeight } = window;
528
529            const offsetX = (clientX - innerWidth / 2) * 0.1;
530            const offsetY = (clientY - innerHeight / 2) * 0.1;
531
532            anime({
533                targets: element,
534                translateX: offsetX,
535                translateY: offsetY,
536                duration: 500,
537                easing: 'easeOutQuad'
538            });
539        });
540    }
541}
542
543class BlockCustomizerItemsFullWidth {
544    constructor(element) {
545        if (element.attr('data-width-option') != 'screen-adaptive')
546            return;
547
548        this.element = element;
549
550        function isInViewport(element) {
551            const rect = element.getBoundingClientRect();
552            return (
553                rect.top >= 0 &&
554                rect.left >= 0 &&
555                rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
556                rect.right <= (window.innerWidth || document.documentElement.clientWidth)
557            );
558        }
559
560        $(window).resize(e => {
561            this._updateLeft();
562        });
563
564        this._updateLeft();
565
566        if (isInViewport(this.element.get(0))) {
567            setTimeout(() => {
568                this._updateLeft();
569            }, 300);
570        }
571    }
572
573    _updateLeft() {
574        BlockCustomizerItemsFullWidth.forceUpdateWidth(this.element);
575    }
576
577    static forceUpdateWidth(element) {
578        if (element.attr('data-width-option') != 'screen-adaptive')
579            return;
580
581        const parent = element.parents('.block.block-customizer');
582        const container = parent.find('.container');
583        const builderMenuWidth = (_APP.builder ? $('#builder-menu').outerWidth() : 0);
584        let left = 0;
585
586        if (element.offset().left == 0) {
587            left = builderMenuWidth;
588        } else {
589            left = builderMenuWidth - parseInt(container.css('padding-left')) + container.offset().left * -1;
590        }
591
592        element.get(0).style.setProperty('left', parseInt(left) + 'px', 'important');
593    }
594}
595
596class BlockCustomizerItemsAutoHeight {
597    constructor(element) {
598        if (element.attr('data-height-option') != 'content-adaptive')
599            return;
600
601        this.element = element;
602
603        $(window).resize(e => {
604            this._updateHeight();
605        });
606
607        this._updateHeight();
608    }
609
610    _updateHeight() {
611        BlockCustomizerItemsAutoHeight.forceUpdateHeight(this.element);
612    }
613
614    static forceUpdateHeight(element) {
615        if (element.attr('data-height-option') != 'content-adaptive')
616            return;
617
618        const item = element.parents('.block-customizer-item');
619        element.get(0).style.setProperty('height', parseInt(element.find('.content').outerHeight() + parseInt(item.css('padding-top')) + parseInt(item.css('padding-bottom'))) + 'px', 'important');
620    }
621}
622
623$(document).on('ready', e => {
624    $('.block-customizer').each((index, element) => {
625        new BlockCustomizer($(element));
626    });
627});

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.