PageSourceSearch

https://openfixx.com/wp-content/themes/collax/assets/js/hover-reveal.js?ver=6.8.6

js openfixx.com collected 2026-09-24 09:07:22 UTC 118,899 bytes, 2,534 lines download raw bytes

1/**
2 * demo.js
3 * http://www.codrops.com
4 *
5 * Licensed under the MIT license.
6 * http://www.opensource.org/licenses/mit-license.php
7 * 
8 * Copyright 2018, Codrops
9 * http://www.codrops.com
10 */
11{
12    const mapNumber = (X,A,B,C,D) => (X-A)*(D-C)/(B-A)+C;
13    // from http://www.quirksmode.org/js/events_properties.html#position
14	const getMousePos = (e) => {
15        let posx = 0;
16        let posy = 0;
17		if (!e) e = window.event;
18		if (e.pageX || e.pageY) {
19            posx = e.pageX;
20			posy = e.pageY;
21		}
22		else if (e.clientX || e.clientY) 	{
23			posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
24			posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
25		}
26        return { x : posx, y : posy }
27    }
28    // Generate a random float.
29    const getRandomFloat = (min, max) => (Math.random() * (max - min) + min).toFixed(2);
30
31    /**
32     * One class per effect. 
33     * Lots of code is repeated, so that single effects can be easily used. 
34     */
35
36
37    // Effect 1
38    class HoverImgFx1 {
39        constructor(el) {
40            this.DOM = {el: el};
41            this.DOM.reveal = document.createElement('div');
42            this.DOM.reveal.className = 'tp-img-reveal-wrapper';
43            this.DOM.reveal.innerHTML = `<div class="tp-img-reveal-wrapper__inner">
44                <div class="tp-img-reveal-wrapper__img" style="background-image:url(${this.DOM.el.dataset.img ? this.DOM.el.dataset.img: ''})">
45                    <div class="tp-hover-wrapper"> 
46                        <h3 class="tp-hover-title">${this.DOM.el.dataset.title ? this.DOM.el.dataset.title: ''}</h3>
47                        <span class="tp-hover-subtitle">${this.DOM.el.dataset.subtitle ? this.DOM.el.dataset.subtitle: ''}</span>
48                        <p>${this.DOM.el.dataset.desc ? this.DOM.el.dataset.desc: ''}</p>
49                        <div class="tp-hover-meta">
50                            <span>
51                                <a href="${this.DOM.el.dataset.metaTagLink ? this.DOM.el.dataset.metaTagLink: '#'}">${this.DOM.el.dataset.metaTag ? this.DOM.el.dataset.metaTag: ''}</a>
52                            </span>
53                            <span>
54                                <a href="${this.DOM.el.dataset.metaTimeLink ? this.DOM.el.dataset.metaTimeLink: '#'}">${this.DOM.el.dataset.metaTime ? this.DOM.el.dataset.metaTime: ''}</a>
55                            </span>
56                            <span>
57                                <a href="${this.DOM.el.dataset.metaAuthorLink ? this.DOM.el.dataset.metaAuthorLink: '#'}">${this.DOM.el.dataset.metaAuthor ? this.DOM.el.dataset.metaAuthor: ''}</a>
58                            </span>
59                        </div>
60                    </div>
61                </div>
62            </div>`;
63            this.DOM.el.appendChild(this.DOM.reveal);
64            this.DOM.revealInner = this.DOM.reveal.querySelector('.tp-img-reveal-wrapper__inner');
65            this.DOM.revealInner.style.overflow = 'hidden';
66            this.DOM.revealImg = this.DOM.revealInner.querySelector('.tp-img-reveal-wrapper__img');
67
68            this.initEvents();
69        }
70        initEvents() {
71            this.positionElement = (ev) => {
72                const mousePos = getMousePos(ev);
73                const docScrolls = {
74                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
75                    top : document.body.scrollTop + document.documentElement.scrollTop
76                };
77                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
78                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
79            };
80            this.mouseenterFn = (ev) => {
81                this.positionElement(ev);
82                this.showImage();
83            };
84            this.mousemoveFn = ev => requestAnimationFrame(() => {
85                this.positionElement(ev);
86            });
87            this.mouseleaveFn = () => {
88                this.hideImage();
89            };
90            
91            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
92            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
93            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
94        }
95        showImage() {
96            TweenMax.killTweensOf(this.DOM.revealInner);
97            TweenMax.killTweensOf(this.DOM.revealImg);
98
99            this.tl = new TimelineMax({
100                onStart: () => {
101                    this.DOM.reveal.style.opacity = 1;
102                    TweenMax.set(this.DOM.el, {zIndex: 9});
103                }
104            })
105            .add('begin')
106            .add(new TweenMax(this.DOM.revealInner, 0.2, {
107                ease: Sine.easeOut,
108                startAt: {x: '-100%'},
109                x: '0%'
110            }), 'begin')
111            .add(new TweenMax(this.DOM.revealImg, 0.2, {
112                ease: Sine.easeOut,
113                startAt: {x: '100%'},
114                x: '0%'
115            }), 'begin');
116        }
117        hideImage() {
118            TweenMax.killTweensOf(this.DOM.revealInner);
119            TweenMax.killTweensOf(this.DOM.revealImg);
120
121            this.tl = new TimelineMax({
122                onStart: () => {
123                    TweenMax.set(this.DOM.el, {zIndex: 8});
124                },
125                onComplete: () => {
126                    TweenMax.set(this.DOM.el, {zIndex: ''});
127                    TweenMax.set(this.DOM.reveal, {opacity: 0});
128                }
129            })
130            .add('begin')
131            .add(new TweenMax(this.DOM.revealInner, 0.2, {
132                ease: Sine.easeOut,
133                x: '100%'
134            }), 'begin')
135            
136            .add(new TweenMax(this.DOM.revealImg, 0.2, {
137                ease: Sine.easeOut,
138                x: '-100%'
139            }), 'begin');
140        }
141    }
142
143
144
145    // Effect 2
146    class HoverImgFx2 {
147        constructor(el) {
148            this.DOM = {el: el};
149            this.DOM.reveal = document.createElement('div');
150            this.DOM.reveal.className = 'tp-img-reveal-wrapper';
151            this.DOM.reveal.innerHTML = `<div class="tp-img-reveal-wrapper__inner"><div class="tp-img-reveal-wrapper__img" style="background-image:url(${this.DOM.el.dataset.img})"><span class="tp-hover-subtitle">
151${this.DOM.el.dataset.subtitle ? this.DOM.el.dataset.subtitle: ''}</span> <h3 class="tp-hover-title">${this.DOM.el.dataset.title ? this.DOM.el.dataset.title: ''}</h3><p class="tp-hover-desc">${this.DOM.el.dataset.desc ? this.DOM.el.dataset.desc: ''}</p></div></div>`;
152            this.DOM.el.appendChild(this.DOM.reveal);
153            this.DOM.revealInner = this.DOM.reveal.querySelector('.tp-img-reveal-wrapper__inner');
154            this.DOM.revealInner.style.overflow = 'hidden';
155            this.DOM.revealImg = this.DOM.revealInner.querySelector('.tp-img-reveal-wrapper__img');
156
157            this.initEvents();
158        }
159        initEvents() {
160            this.positionElement = (ev) => {
161                const mousePos = getMousePos(ev);
162                const docScrolls = {
163                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
164                    top : document.body.scrollTop + document.documentElement.scrollTop
165                };
166                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
167                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
168            };
169            this.mouseenterFn = (ev) => {
170                this.positionElement(ev);
171                this.showImage();
172            };
173            this.mousemoveFn = ev => requestAnimationFrame(() => {
174                this.positionElement(ev);
175            });
176            this.mouseleaveFn = () => {
177                this.hideImage();
178            };
179            
180            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
181            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
182            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
183        }
184        showImage() {
185            TweenMax.killTweensOf(this.DOM.revealInner);
186            TweenMax.killTweensOf(this.DOM.revealImg);
187
188            this.tl = new TimelineMax({
189                onStart: () => {
190                    this.DOM.reveal.style.opacity = 1;
191                    TweenMax.set(this.DOM.el, {zIndex: 1000});
192                }
193            })
194            .add('begin')
195            .add(new TweenMax(this.DOM.revealInner, 0.4, {
196                ease: Quint.easeOut,
197                startAt: {x: '-100%', y: '-100%'},
198                x: '0%',
199                y: '0%'
200            }), 'begin')
201            .add(new TweenMax(this.DOM.revealImg, 0.4, {
202                ease: Quint.easeOut,
203                startAt: {x: '100%', y: '100%'},
204                x: '0%',
205                y: '0%'
206            }), 'begin');
207        }
208        hideImage() {
209            TweenMax.killTweensOf(this.DOM.revealInner);
210            TweenMax.killTweensOf(this.DOM.revealImg);
211
212            this.tl = new TimelineMax({
213                onStart: () => {
214                    TweenMax.set(this.DOM.el, {zIndex: 999});
215                },
216                onComplete: () => {
217                    TweenMax.set(this.DOM.el, {zIndex: ''});
218                    TweenMax.set(this.DOM.reveal, {opacity: 0});
219                }
220            })
221            .add('begin')
222            .add(new TweenMax(this.DOM.revealInner, 0.3, {
223                ease: Quint.easeOut,
224                x: '100%',
225                y: '100%'
226            }), 'begin')
227            
228            .add(new TweenMax(this.DOM.revealImg, 0.3, {
229                ease: Quint.easeOut,
230                x: '-100%',
231                y: '-100%'
232            }), 'begin');
233        }
234    }
235
236    // Effect 3
237    class HoverImgFx3 {
238        constructor(el) {
239            this.DOM = {el: el};
240            this.DOM.reveal = document.createElement('div');
241            this.DOM.reveal.className = 'tp-img-reveal-wrapper';
242            this.DOM.reveal.style.overflow = 'hidden';
243            this.DOM.reveal.innerHTML = `<div class="tp-img-reveal-wrapper__inner"><div class="tp-img-reveal-wrapper__img" style="background-image:url(${this.DOM.el.dataset.img})"><span class="tp-hover-subtitle">
243${this.DOM.el.dataset.subtitle ? this.DOM.el.dataset.subtitle: ''}</span> <h3 class="tp-hover-title">${this.DOM.el.dataset.title ? this.DOM.el.dataset.title: ''}</h3><p class="tp-hover-desc">${this.DOM.el.dataset.desc ? this.DOM.el.dataset.desc: ''}</p></div></div>`;
244            this.DOM.el.appendChild(this.DOM.reveal);
245            this.DOM.revealInner = this.DOM.reveal.querySelector('.tp-img-reveal-wrapper__inner');
246            this.DOM.revealInner.style.overflow = 'hidden';
247            this.DOM.revealImg = this.DOM.revealInner.querySelector('.tp-img-reveal-wrapper__img');
248            charming(this.DOM.el);
249            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
250            this.initEvents();
251        }
252        initEvents() {
253            this.positionElement = (ev) => {
254                const mousePos = getMousePos(ev);
255                const docScrolls = {
256                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
257                    top : document.body.scrollTop + document.documentElement.scrollTop
258                };
259                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
260                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
261            };
262            this.mouseenterFn = (ev) => {
263                this.positionElement(ev);
264                this.showImage();
265                this.animateLetters();
266            };
267            this.mousemoveFn = ev => requestAnimationFrame(() => {
268                this.positionElement(ev);
269            });
270            this.mouseleaveFn = () => {
271                this.hideImage();
272            };
273            
274            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
275            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
276            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
277        }
278        showImage() {
279            TweenMax.killTweensOf(this.DOM.revealInner);
280            TweenMax.killTweensOf(this.DOM.revealImg);
281
282            this.tl = new TimelineMax({
283                onStart: () => {
284                    this.DOM.reveal.style.opacity = 1;
285                    TweenMax.set(this.DOM.el, {zIndex: 1000});
286                }
287            })
288            .add('begin')
289            .set([this.DOM.revealInner, this.DOM.revealImg], {transformOrigin: '50% 100%'})
290            .add(new TweenMax(this.DOM.revealInner, 0.4, {
291                ease: Expo.easeOut,
292                startAt: {x: '50%', y: '120%', rotation: 50},
293                x: '0%',
294                y: '0%',
295                rotation: 0
296            }), 'begin')
297            .add(new TweenMax(this.DOM.revealImg, 0.4, {
298                ease: Expo.easeOut,
299                startAt: {x: '-50%', y: '-120%', rotation: -50},
300                x: '0%',
301                y: '0%',
302                rotation: 0
303            }), 'begin')
304            .add(new TweenMax(this.DOM.revealImg, 0.7, {
305                ease: Expo.easeOut,
306                startAt: {scale: 2},
307                scale: 1
308            }), 'begin');
309        }
310        hideImage() {
311            TweenMax.killTweensOf(this.DOM.revealInner);
312            TweenMax.killTweensOf(this.DOM.revealImg);
313
314            this.tl = new TimelineMax({
315                onStart: () => {
316                    TweenMax.set(this.DOM.el, {zIndex: 999});
317                },
318                onComplete: () => {
319                    TweenMax.set(this.DOM.el, {zIndex: ''});
320                    TweenMax.set(this.DOM.reveal, {opacity: 0});
321                }
322            })
323            .add('begin')
324            .add(new TweenMax(this.DOM.revealInner, 0.6, {
325                ease: Expo.easeOut,
326                y: '-120%',
327                rotation: -5
328            }), 'begin')
329            .add(new TweenMax(this.DOM.revealImg, 0.6, {
330                ease: Expo.easeOut,
331                y: '120%',
332                rotation: 5,
333                scale: 1.2
334            }), 'begin')
335        }
336        animateLetters() {
337            TweenMax.killTweensOf(this.DOM.letters);
338            TweenMax.set(this.DOM.letters, {opacity: 0});
339            TweenMax.staggerTo(this.DOM.letters, 0.2, {
340                ease: Expo.easeOut,
341                startAt: {x: '100%'},
342                x: '0%',
343                opacity: 1
344            }, 0.03);
345        }
346    }
347
348    // Effect 4
349    class HoverImgFx4 {
350        constructor(el) {
351            this.DOM = {el: el};
352            this.DOM.reveal = document.createElement('div');
353            this.DOM.reveal.className = 'tp-img-reveal-wrapper';
354            this.DOM.reveal.innerHTML = `<div class="tp-img-reveal-wrapper__inner"><div class="tp-img-reveal-wrapper__img" style="background-image:url(${this.DOM.el.dataset.img})"><span class="tp-hover-subtitle">
354${this.DOM.el.dataset.subtitle ? this.DOM.el.dataset.subtitle: ''}</span> <h3 class="tp-hover-title">${this.DOM.el.dataset.title ? this.DOM.el.dataset.title: ''}</h3><p class="tp-hover-desc">${this.DOM.el.dataset.desc ? this.DOM.el.dataset.desc: ''}</p></div></div>`;
355            this.DOM.el.appendChild(this.DOM.reveal);
356            this.DOM.revealInner = this.DOM.reveal.querySelector('.tp-img-reveal-wrapper__inner');
357            this.DOM.revealInner.style.overflow = 'hidden';
358            this.DOM.revealImg = this.DOM.revealInner.querySelector('.tp-img-reveal-wrapper__img');
359            charming(this.DOM.el);
360            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
361            this.initEvents();
362        }
363        initEvents() {
364            this.positionElement = (ev) => {
365                const mousePos = getMousePos(ev);
366                const docScrolls = {
367                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
368                    top : document.body.scrollTop + document.documentElement.scrollTop
369                };
370                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
371                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
372            };
373            this.mouseenterFn = (ev) => {
374                this.positionElement(ev);
375                this.showImage();
376                this.animateLetters();
377            };
378            this.mousemoveFn = ev => requestAnimationFrame(() => {
379                this.positionElement(ev);
380            });
381            this.mouseleaveFn = () => {
382                this.hideImage();
383            };
384            
385            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
386            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
387            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
388        }
389        showImage() {
390            TweenMax.killTweensOf(this.DOM.revealInner);
391            TweenMax.killTweensOf(this.DOM.revealImg);
392
393            this.tl = new TimelineMax({
394                onStart: () => {
395                    this.DOM.reveal.style.opacity = 1;
396                    TweenMax.set(this.DOM.el, {zIndex: 1000});
397                }
398            })
399            .add('begin')
400            .add(new TweenMax(this.DOM.revealInner, 0.8, {
401                ease: Expo.easeOut,
402                startAt: {opacity: 0, y: '50%', rotation: -15, scale:0},
403                y: '0%',
404                rotation: 0,
405                opacity: 1,
406                scale: 1
407            }), 'begin')
408            .add(new TweenMax(this.DOM.revealImg, 0.8, {
409                ease: Expo.easeOut,
410                startAt: {rotation: 15, scale: 2},
411                rotation: 0,
412                scale: 1
413            }), 'begin');
414        }
415        hideImage() {
416            TweenMax.killTweensOf(this.DOM.revealInner);
417            TweenMax.killTweensOf(this.DOM.revealImg);
418
419            this.tl = new TimelineMax({
420                onStart: () => {
421                    TweenMax.set(this.DOM.el, {zIndex: 999});
422                },
423                onComplete: () => {
424                    TweenMax.set(this.DOM.el, {zIndex: ''});
425                    TweenMax.set(this.DOM.reveal, {opacity: 0});
426                }
427            })
428            .add('begin')
429            .add(new TweenMax(this.DOM.revealInner, 0.15, {
430                ease: Sine.easeOut,
431                y: '-40%',
432                rotation: 10,
433                scale: 0.9,
434                opacity: 0
435            }), 'begin')
436            .add(new TweenMax(this.DOM.revealImg, 0.15, {
437                ease: Sine.easeOut,
438                rotation: -10,
439                scale: 1.5
440            }), 'begin')
441        }
442        animateLetters() {
443            TweenMax.killTweensOf(this.DOM.letters);
444            TweenMax.set(this.DOM.letters, {opacity: 0});
445            TweenMax.staggerTo(this.DOM.letters, 0.8, {
446                ease: Expo.easeOut,
447                startAt: {y: '50%'},
448                y: '0%',
449                opacity: 1
450            }, 0.03);
451        }
452    }
453
454    // Effect 5
455    class HoverImgFx5 {
456        constructor(el) {
457            this.DOM = {el: el};
458            
459            this.DOM.reveal = document.createElement('div');
460            this.DOM.reveal.className = 'tp-img-reveal-wrapper';
461            this.DOM.reveal.innerHTML = `<div class="tp-img-reveal-wrapper__deco"></div><div class="tp-img-reveal-wrapper__inner"><div class="tp-img-reveal-wrapper__img" style="background-image:url(${this.DOM.el.dataset.img})"><span class="tp-hover-subtitle">
461${this.DOM.el.dataset.subtitle ? this.DOM.el.dataset.subtitle: ''}</span> <h3 class="tp-hover-title">${this.DOM.el.dataset.title ? this.DOM.el.dataset.title: ''}</h3><p class="tp-hover-desc">${this.DOM.el.dataset.desc ? this.DOM.el.dataset.desc: ''}</p></div></div>`;
462            this.DOM.el.appendChild(this.DOM.reveal);
463            this.DOM.revealInner = this.DOM.reveal.querySelector('.tp-img-reveal-wrapper__inner');
464            this.DOM.revealInner.style.overflow = 'hidden';
465            this.DOM.revealDeco = this.DOM.reveal.querySelector('.tp-img-reveal-wrapper__deco');
466            this.DOM.revealImg = this.DOM.revealInner.querySelector('.tp-img-reveal-wrapper__img');
467            charming(this.DOM.el);
468            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
469            this.initEvents();
470        }
471        initEvents() {
472            this.positionElement = (ev) => {
473                const mousePos = getMousePos(ev);
474                const docScrolls = {
475                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
476                    top : document.body.scrollTop + document.documentElement.scrollTop
477                };
478                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
479                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
480            };
481            this.mouseenterFn = (ev) => {
482                this.positionElement(ev);
483                this.showImage();
484                this.animateLetters();
485            };
486            this.mousemoveFn = ev => requestAnimationFrame(() => {
487                this.positionElement(ev);
488            });
489            this.mouseleaveFn = () => {
490                this.hideImage();
491            };
492            
493            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
494            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
495            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
496        }
497        showImage() {
498            TweenMax.killTweensOf(this.DOM.revealInner);
499            TweenMax.killTweensOf(this.DOM.revealImg);
500            TweenMax.killTweensOf(this.DOM.revealDeco);
501
502            this.tl = new TimelineMax({
503                onStart: () => {
504                    this.DOM.reveal.style.opacity = 1;
505                    TweenMax.set(this.DOM.el, {zIndex: 1000});
506                }
507            })
508            .set(this.DOM.revealInner, {opacity: 0})
509            .add('begin')
510            .add(new TweenMax(this.DOM.revealDeco, 0.8, {
511                ease: Expo.easeOut,
512                startAt: {opacity: 0, scale: 0, rotation: 35},
513                opacity: 1,
514                scale: 1,
515                rotation: 0
516            }), 'begin')
517            .add(new TweenMax(this.DOM.revealInner, 0.8, {
518                ease: Expo.easeOut,
519                startAt: {scale: 0, rotation: 35},
520                rotation: 0,
521                scale: 1,
522                opacity: 1
523            }), 'begin+=0.15')
524            .add(new TweenMax(this.DOM.revealImg, 0.8, {
525                ease: Expo.easeOut,
526                startAt: {rotation: -35, scale: 2},
527                rotation: 0,
528                scale: 1
529            }), 'begin+=0.15')
530        }
531        hideImage() {
532            TweenMax.killTweensOf(this.DOM.revealInner);
533            TweenMax.killTweensOf(this.DOM.revealImg);
534            TweenMax.killTweensOf(this.DOM.revealDeco);
535
536            this.tl = new TimelineMax({
537                onStart: () => {
538                    TweenMax.set(this.DOM.el, {zIndex: 999});
539                },
540                onComplete: () => {
541                    TweenMax.set(this.DOM.el, {zIndex: ''});
542                    TweenMax.set(this.DOM.reveal, {opacity: 0});
543                }
544            })
545            .add('begin')
546            .add(new TweenMax([this.DOM.revealDeco, this.DOM.revealInner], 0.2, {
547                ease: Expo.easeOut,
548                opacity: 0,
549                scale: 0.9
550            }), 'begin')
551        }
552        animateLetters() {
553            TweenMax.killTweensOf(this.DOM.letters);
554            TweenMax.set(this.DOM.letters, {opacity: 0});
555            TweenMax.staggerTo(this.DOM.letters, 0.1, {
556                ease: Expo.easeOut,
557                startAt: {y: '50%'},
558                y: '0%',
559                opacity: 1
560            }, 0.06);
561        }
562    }
563
564    // Effect 6
565    class HoverImgFx6 {
566        constructor(el) {
567            this.DOM = {el: el};
568            
569            this.DOM.reveal = document.createElement('div');
570            this.DOM.reveal.className = 'tp-img-reveal-wrapper';
571            this.DOM.reveal.style.overflow = 'hidden';
572            this.DOM.reveal.innerHTML = `<div class="tp-img-reveal-wrapper__deco"></div><div class="tp-img-reveal-wrapper__inner"><div class="tp-img-reveal-wrapper__img" style="background-image:url(${this.DOM.el.dataset.img})"><span class="tp-hover-subtitle">
572${this.DOM.el.dataset.subtitle ? this.DOM.el.dataset.subtitle: ''}</span> <h3 class="tp-hover-title">${this.DOM.el.dataset.title ? this.DOM.el.dataset.title: ''}</h3><p class="tp-hover-desc">${this.DOM.el.dataset.desc ? this.DOM.el.dataset.desc: ''}</p></div></div>`;
573            this.DOM.el.appendChild(this.DOM.reveal);
574            this.DOM.revealInner = this.DOM.reveal.querySelector('.tp-img-reveal-wrapper__inner');
575            this.DOM.revealInner.style.overflow = 'hidden';
576            this.DOM.revealDeco = this.DOM.reveal.querySelector('.tp-img-reveal-wrapper__deco');
577            this.DOM.revealImg = this.DOM.revealInner.querySelector('.tp-img-reveal-wrapper__img');
578
579            this.initEvents();
580        }
581        initEvents() {
582            this.positionElement = (ev) => {
583                const mousePos = getMousePos(ev);
584                const docScrolls = {
585                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
586                    top : document.body.scrollTop + document.documentElement.scrollTop
587                };
588                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
589                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
590            };
591            this.mouseenterFn = (ev) => {
592                this.positionElement(ev);
593                this.showImage();
594            };
595            this.mousemoveFn = ev => requestAnimationFrame(() => {
596                this.positionElement(ev);
597            });
598            this.mouseleaveFn = () => {
599                this.hideImage();
600            };
601            
602            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
603            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
604            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
605        }
606        showImage() {
607            TweenMax.killTweensOf(this.DOM.reveal);
608            TweenMax.killTweensOf(this.DOM.revealInner);
609            TweenMax.killTweensOf(this.DOM.revealImg);
610            TweenMax.killTweensOf(this.DOM.revealDeco);
611
612            this.tl = new TimelineMax({
613                onStart: () => {
614                    this.DOM.reveal.style.opacity = 1;
615                    TweenMax.set(this.DOM.el, {zIndex: 1000});
616                }
617            })
618            .add('begin')
619            .set(this.DOM.revealInner, {x: '100%'})
620            .set(this.DOM.revealDeco, {transformOrigin: '100% 50%'})
621            .add(new TweenMax(this.DOM.revealDeco, 0.3, {
622                ease: Sine.easeInOut,
623                startAt: {scaleX: 0},
624                scaleX: 1
625            }), 'begin')
626            .set(this.DOM.revealDeco, {transformOrigin: '0% 50%'})
627            .add(new TweenMax(this.DOM.revealDeco, 0.6, {
628                ease: Expo.easeOut,
629                scaleX: 0
630            }), 'begin+=0.3')
631            .add(new TweenMax(this.DOM.revealInner, 0.6, {
632                ease: Expo.easeOut,
633                startAt: {x: '100%'},
634                x: '0%'
635            }), 'begin+=0.45')
636            .add(new TweenMax(this.DOM.revealImg, 0.6, {
637                ease: Expo.easeOut,
638                startAt: {x: '-100%'},
639                x: '0%'
640            }), 'begin+=0.45')
641            .add(new TweenMax(this.DOM.revealImg, 1.6, {
642                ease: Expo.easeOut,
643                startAt: {scale: 1.3},
644                scale: 1
645            }), 'begin+=0.45')
646            .add(new TweenMax(this.DOM.reveal, 0.8, {
647                ease: Quint.easeOut,
648                startAt: {x: '20%', rotation: 10},
649                x: '0%',
650                rotation: 0
651            }), 'begin');
652        }
653        hideImage() {
654            TweenMax.killTweensOf(this.DOM.reveal);
655            TweenMax.killTweensOf(this.DOM.revealInner);
656            TweenMax.killTweensOf(this.DOM.revealImg);
657            TweenMax.killTweensOf(this.DOM.revealDeco);
658
659            this.tl = new TimelineMax({
660                onStart: () => {
661                    TweenMax.set(this.DOM.el, {zIndex: 999});
662                },
663                onComplete: () => {
664                    TweenMax.set(this.DOM.el, {zIndex: ''});
665                    TweenMax.set(this.DOM.reveal, {opacity: 0});
666                }
667            })
668            .add('begin')
669            .add(new TweenMax(this.DOM.revealInner, 0.1, {
670                ease: Sine.easeOut,
671                x: '-100%'
672            }), 'begin')
673            .add(new TweenMax(this.DOM.revealImg, 0.1, {
674                ease: Sine.easeOut,
675                x: '100%'
676            }), 'begin')
677        }
678    }
679 
680    // Effect 7
681    class HoverImgFx7 {
682        constructor(el) {
683            this.DOM = {el: el};
684            this.DOM.reveal = document.createElement('div');
685            this.DOM.reveal.className = 'tp-img-reveal-wrapper';
686            this.DOM.reveal.innerHTML = `<div class="tp-img-reveal-wrapper__deco"></div><div class="tp-img-reveal-wrapper__inner"><div class="tp-img-reveal-wrapper__img" style="background-image:url(${this.DOM.el.dataset.img})"><span class="tp-hover-subtitle">
686${this.DOM.el.dataset.subtitle ? this.DOM.el.dataset.subtitle: ''}</span> <h3 class="tp-hover-title">${this.DOM.el.dataset.title ? this.DOM.el.dataset.title: ''}</h3><p class="tp-hover-desc">${this.DOM.el.dataset.desc ? this.DOM.el.dataset.desc: ''}</p></div></div>`;
687            this.DOM.el.appendChild(this.DOM.reveal);
688            this.DOM.revealInner = this.DOM.reveal.querySelector('.tp-img-reveal-wrapper__inner');
689            this.DOM.revealDeco = this.DOM.reveal.querySelector('.tp-img-reveal-wrapper__deco');
690            this.DOM.revealImg = this.DOM.revealInner.querySelector('.tp-img-reveal-wrapper__img');
691            charming(this.DOM.el);
692            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
693            this.initEvents();
694        }
695        initEvents() {
696            this.positionElement = (ev) => {
697                const mousePos = getMousePos(ev);
698                const docScrolls = {
699                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
700                    top : document.body.scrollTop + document.documentElement.scrollTop
701                };
702                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
703                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
704            };
705            this.mouseenterFn = (ev) => {
706                this.positionElement(ev);
707                this.showImage();
708                this.animateLetters();
709            };
710            this.mousemoveFn = ev => requestAnimationFrame(() => {
711                this.positionElement(ev);
712            });
713            this.mouseleaveFn = () => {
714                this.hideImage();
715            };
716            
717            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
718            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
719            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
720            window.addEventListener('resize', () => this.rect = this.DOM.reveal.getBoundingClientRect());
721        }
722        showImage() {
723            TweenMax.killTweensOf(this.DOM.reveal);
724            TweenMax.killTweensOf(this.DOM.revealInner);
725            TweenMax.killTweensOf(this.DOM.revealImg);
726            TweenMax.killTweensOf(this.DOM.revealDeco);
727
728            this.tl = new TimelineMax({
729                onStart: () => {
730                    this.DOM.reveal.style.opacity = 1;
731                    TweenMax.set(this.DOM.el, {zIndex: 1000});
732                }
733            })
734            .add('begin')
735            .set(this.DOM.revealInner, {opacity: 0})
736            .set(this.DOM.revealDeco, {transformOrigin: '-5% 50%'})
737            .add(new TweenMax(this.DOM.revealDeco, 0.2, {
738                ease: Quad.easeInOut,
739                startAt: {scaleX: 0},
740                scaleX: 1,
741                scaleY: 0.8
742            }), 'begin')
743            .set(this.DOM.revealDeco, {transformOrigin: '105% 50%'})
744            .add(new TweenMax(this.DOM.revealDeco, 0.3, {
745                ease: Sine.easeOut,
746                scaleX: 0,
747                scaleY: 1
748            }), 'begin+=0.2')
749            .add(new TweenMax(this.DOM.revealInner, 0.9, {
750                ease: Elastic.easeOut.config(1,0.6),
751                startAt: {scale: 0, opacity: 1, x: '0%'},
752                scale: 1,
753            }), 'begin+=0.4')
754            .add(new TweenMax(this.DOM.revealImg, 0.8, {
755                ease: Expo.easeOut,
756                rotation: -15,
757            }), 'begin')
758            .add(new TweenMax(this.DOM.reveal, 1.1, {
759                ease: Quint.easeOut,
760                startAt: {x: '-50%', y: '10%', rotation: -35},
761                x: '0%',
762                y: '0%',
763                rotation: 15
764            }), 'begin');
765        }
766        hideImage() {
767            TweenMax.killTweensOf(this.DOM.reveal);
768            TweenMax.killTweensOf(this.DOM.revealInner);
769            TweenMax.killTweensOf(this.DOM.revealImg);
770            TweenMax.killTweensOf(this.DOM.revealDeco);
771
772            this.tl = new TimelineMax({
773                onStart: () => {
774                    TweenMax.set(this.DOM.el, {zIndex: 999});
775                },
776                onComplete: () => {
777                    TweenMax.set(this.DOM.el, {zIndex: ''});
778                    TweenMax.set(this.DOM.reveal, {opacity: 0});
779                }
780            })
781            .add(new TweenMax(this.DOM.revealInner, 0.13, {
782                ease: Sine.easeOut,
783                scale: 0.8,
784                opacity: 0
785            }));
786        }
787        animateLetters() {
788            TweenMax.killTweensOf(this.DOM.letters);
789            TweenMax.set(this.DOM.letters, {opacity: 0});
790            TweenMax.staggerTo(this.DOM.letters, 0.8, {
791                ease: Elastic.easeOut.config(1,0.4),
792                startAt: {y: '50%'},
793                y: '0%',
794                opacity: 1
795            }, 0.02);
796        }
797    }
798
799    // Effect 8
800    class HoverImgFx8 {
801        constructor(el) {
802            this.DOM = {el: el};
803            
804            this.DOM.reveal = document.createElement('div');
805            this.DOM.reveal.className = 'tp-img-reveal-wrapper';
806            this.DOM.reveal.innerHTML = `<div class="tp-img-reveal-wrapper__deco"></div><div class="tp-img-reveal-wrapper__inner"><div class="tp-img-reveal-wrapper__img" style="background-image:url(${this.DOM.el.dataset.img})"><span class="tp-hover-subtitle">
806${this.DOM.el.dataset.subtitle ? this.DOM.el.dataset.subtitle: ''}</span> <h3 class="tp-hover-title">${this.DOM.el.dataset.title ? this.DOM.el.dataset.title: ''}</h3><p class="tp-hover-desc">${this.DOM.el.dataset.desc ? this.DOM.el.dataset.desc: ''}</p></div></div>`;
807            this.DOM.el.appendChild(this.DOM.reveal);
808            this.DOM.revealInner = this.DOM.reveal.querySelector('.tp-img-reveal-wrapper__inner');
809            this.DOM.revealInner.style.overflow = 'hidden';
810            this.DOM.revealDeco = this.DOM.reveal.querySelector('.tp-img-reveal-wrapper__deco');
811            this.DOM.revealImg = this.DOM.revealInner.querySelector('.tp-img-reveal-wrapper__img');
812            this.rect = this.DOM.reveal.getBoundingClientRect();
813            charming(this.DOM.el);
814            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
815            this.initEvents();
816        }
817        initEvents() {
818            this.positionElement = (ev) => {
819                const mousePos = getMousePos(ev);
820                const docScrolls = {
821                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
822                    top : document.body.scrollTop + document.documentElement.scrollTop
823                };
824                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
825                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
826            };
827            this.mouseenterFn = (ev) => {
828                this.positionElement(ev);
829                this.showImage();
830                this.animateLetters();
831            };
832            this.mousemoveFn = ev => requestAnimationFrame(() => {
833                this.positionElement(ev);
834            });
835            this.mouseleaveFn = () => {
836                this.hideImage();
837            };
838            
839            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
840            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
841            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
842        }
843        showImage() {
844            TweenMax.killTweensOf(this.DOM.revealInner);
845            TweenMax.killTweensOf(this.DOM.revealImg);
846            TweenMax.killTweensOf(this.DOM.revealDeco);
847
848            this.tl = new TimelineMax({
849                onStart: () => {
850                    this.DOM.reveal.style.opacity = 1;
851                    TweenMax.set(this.DOM.el, {zIndex: 1000});
852                }
853            })
854            .set(this.DOM.revealInner, {opacity: 0})
855            .add('begin')
856            .set(this.DOM.revealDeco, {transformOrigin: '50% 0%'})
857            .add(new TweenMax(this.DOM.revealDeco, 0.6, {
858                ease: Cubic.easeInOut,
859                startAt: {opacity: 0, x: '15%', y: '50%', scaleY: 3},
860                scaleY: 1,
861                opacity: 1,
862                y: '-15%'
863            }), 'begin')
864            .add(new TweenMax(this.DOM.revealInner, 0.8, {
865                ease: Expo.easeOut,
866                startAt: {y: '100%', rotation: 3},
867                opacity: 1,
868                rotation: 0,
869                y: '0%'
870            }), 'begin+=0.4')
871            .add(new TweenMax(this.DOM.revealImg, 1.3, {
872                ease: Expo.easeOut,
873                startAt: {scale: 1.4},
874                scale: 1
875            }), 'begin+=0.4')
876        }
877        hideImage() {
878            TweenMax.killTweensOf(this.DOM.revealInner);
879            TweenMax.killTweensOf(this.DOM.revealImg);
880            TweenMax.killTweensOf(this.DOM.revealDeco);
881
882            this.tl = new TimelineMax({
883                onStart: () => {
884                    TweenMax.set(this.DOM.el, {zIndex: 999});
885                },
886                onComplete: () => {
887                    TweenMax.set(this.DOM.el, {zIndex: ''});
888                    TweenMax.set(this.DOM.reveal, {opacity: 0});
889                }
890            })
891            .add('begin')
892            .add(new TweenMax([this.DOM.revealDeco, this.DOM.revealInner], 0.2, {
893                ease: Expo.easeOut,
894                opacity: 0
895            }), 'begin')
896        }
897        animateLetters() {
898            TweenMax.killTweensOf(this.DOM.letters);
899            TweenMax.set(this.DOM.letters, {opacity: 0});
900            TweenMax.staggerTo(this.DOM.letters, 0.1, {
901                ease: Elastic.easeOut.config(1,0.4),
902                startAt: {y: '50%'},
903                y: '0%',
904                opacity: 1
905            }, 0.08);
906        }
907    }
908
909    // Effect 9
910    class HoverImgFx9 {
911        constructor(el) {
912            this.DOM = {el: el};
913            
914            this.DOM.reveal = document.createElement('div');
915            this.DOM.reveal.className = 'tp-img-reveal-wrapper';
916            this.DOM.reveal.innerHTML = `<div class="tp-img-reveal-wrapper__deco"></div><div class="tp-img-reveal-wrapper__inner"><div class="tp-img-reveal-wrapper__img" style="background-image:url(${this.DOM.el.dataset.img})"><span class="tp-hover-subtitle">
916${this.DOM.el.dataset.subtitle ? this.DOM.el.dataset.subtitle: ''}</span> <h3 class="tp-hover-title">${this.DOM.el.dataset.title ? this.DOM.el.dataset.title: ''}</h3><p class="tp-hover-desc">${this.DOM.el.dataset.desc ? this.DOM.el.dataset.desc: ''}</p></div></div>`;
917            this.DOM.el.appendChild(this.DOM.reveal);
918            this.DOM.revealInner = this.DOM.reveal.querySelector('.tp-img-reveal-wrapper__inner');
919            this.DOM.revealInner.style.overflow = 'hidden';
920            this.DOM.revealDeco = this.DOM.reveal.querySelector('.tp-img-reveal-wrapper__deco');
921            this.DOM.revealImg = this.DOM.revealInner.querySelector('.tp-img-reveal-wrapper__img');
922            charming(this.DOM.el);
923            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
924            this.initEvents();
925        }
926        initEvents() {
927            this.positionElement = (ev) => {
928                const mousePos = getMousePos(ev);
929                const docScrolls = {
930                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
931                    top : document.body.scrollTop + document.documentElement.scrollTop
932                };
933                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
934                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
935            };
936            this.mouseenterFn = (ev) => {
937                this.positionElement(ev);
938                this.showImage();
939                this.animateLetters();
940            };
941            this.mousemoveFn = ev => requestAnimationFrame(() => {
942                this.positionElement(ev);
943            });
944            this.mouseleaveFn = () => {
945                this.hideImage();
946            };
947            
948            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
949            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
950            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
951        }
952        showImage() {
953            TweenMax.killTweensOf(this.DOM.revealInner);
954            TweenMax.killTweensOf(this.DOM.revealImg);
955            TweenMax.killTweensOf(this.DOM.revealDeco);
956
957            this.tl = new TimelineMax({
958                onStart: () => {
959                    this.DOM.reveal.style.opacity = 1;
960                    TweenMax.set(this.DOM.el, {zIndex: 1000});
961                }
962            })
963            .set([this.DOM.revealInner, this.DOM.revealImg, this.DOM.revealDeco], {transformOrigin: '120% 0%'})
964            .set(this.DOM.revealInner, {opacity: 0})
965            .add('begin')
966            .add(new TweenMax(this.DOM.revealDeco, 0.8, {
967                ease: Expo.easeOut,
968                startAt: {opacity: 0, rotation: -80, x: '15%', y: '60%'},
969                opacity: 1,
970                rotation: 0,
971                y: '-15%'
972            }), 'begin')
973            .add(new TweenMax(this.DOM.revealInner, 0.8, {
974                ease: Expo.easeOut,
975                startAt: {x: '50%', y: '150%', rotation: -25},
976                opacity: 1,
977                x: '0%',
978                y: '0%',
979                rotation: 0
980            }), 'begin+=0.25')
981
982            
983            .add(new TweenMax(this.DOM.revealImg, 0.8, {
984                ease: Expo.easeOut,
985                startAt: {y: '-150%', rotation: -25},
986                y: '0%',
987                rotation: 0
988            }), 'begin+=0.25');
989        }
990        hideImage() {
991            TweenMax.killTweensOf(this.DOM.revealInner);
992            TweenMax.killTweensOf(this.DOM.revealImg);
993            TweenMax.killTweensOf(this.DOM.revealDeco);
994
995            this.tl = new TimelineMax({
996                onStart: () => {
997                    TweenMax.set(this.DOM.el, {zIndex: 999});
998                },
999                onComplete: () => {
1000                    TweenMax.set(this.DOM.el, {zIndex: ''});
1001                    TweenMax.set(this.DOM.reveal, {opacity: 0});
1002                }
1003            })
1004            .add('begin')
1005            .add(new TweenMax([this.DOM.revealDeco, this.DOM.revealInner], 0.2, {
1006                ease: Expo.easeOut,
1007                opacity: 0
1008            }), 'begin')
1009        }
1010        animateLetters() {
1011            TweenMax.killTweensOf(this.DOM.letters);
1012            TweenMax.set(this.DOM.letters, {opacity: 0});
1013            TweenMax.staggerTo(this.DOM.letters, 0.1, {
1014                ease: Expo.easeOut,
1015                opacity: 1
1016            }, 0.08);
1017        }
1018    }
1019
1020    // Effect 10
1021    class HoverImgFx10 {
1022        constructor(el) {
1023            this.DOM = {el: el};
1024            
1025            this.DOM.reveal = document.createElement('div');
1026            this.DOM.reveal.className = 'tp-img-reveal-wrapper';
1027            this.DOM.reveal.innerHTML = `<div class="tp-img-reveal-wrapper__deco"></div><div class="tp-img-reveal-wrapper__inner"><div class="tp-img-reveal-wrapper__img" style="background-image:url(${this.DOM.el.dataset.img})"><span class="tp-hover-subtitle">
1027${this.DOM.el.dataset.subtitle ? this.DOM.el.dataset.subtitle: ''}</span> <h3 class="tp-hover-title">${this.DOM.el.dataset.title ? this.DOM.el.dataset.title: ''}</h3><p class="tp-hover-desc">${this.DOM.el.dataset.desc ? this.DOM.el.dataset.desc: ''}</p></div></div>`;
1028            this.DOM.el.appendChild(this.DOM.reveal);
1029            this.DOM.revealInner = this.DOM.reveal.querySelector('.tp-img-reveal-wrapper__inner');
1030            this.DOM.revealInner.style.overflow = 'hidden';
1031            this.DOM.revealDeco = this.DOM.reveal.querySelector('.tp-img-reveal-wrapper__deco');
1032            this.DOM.revealImg = this.DOM.revealInner.querySelector('.tp-img-reveal-wrapper__img');
1033            charming(this.DOM.el);
1034            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
1035            this.initEvents();
1036        }
1037        initEvents() {
1038            this.positionElement = (ev) => {
1039                const mousePos = getMousePos(ev);
1040                const docScrolls = {
1041                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
1042                    top : document.body.scrollTop + document.documentElement.scrollTop
1043                };
1044                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
1045                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
1046            };
1047            this.mouseenterFn = (ev) => {
1048                this.positionElement(ev);
1049                this.showImage();
1050                this.animateLetters();
1051            };
1052            this.mousemoveFn = ev => requestAnimationFrame(() => {
1053                this.positionElement(ev);
1054            });
1055            this.mouseleaveFn = () => {
1056                this.hideImage();
1057            };
1058            
1059            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
1060            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
1061            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
1062        }
1063        showImage() {
1064            TweenMax.killTweensOf(this.DOM.revealInner);
1065            TweenMax.killTweensOf(this.DOM.revealDeco);
1066
1067            this.tl = new TimelineMax({
1068                onStart: () => {
1069                    this.DOM.reveal.style.opacity = 1;
1070                    TweenMax.set(this.DOM.el, {zIndex: 1000});
1071                }
1072            })
1073            .set(this.DOM.revealInner, {opacity: 0})
1074            .add('begin')
1075            .add(new TweenMax(this.DOM.revealDeco, 0.5, {
1076                ease: Expo.easeOut,
1077                startAt: {scale: 0, opacity: 1, rotation: -10},
1078                scale: 1.6,
1079                rotation: 0
1080            }), 'begin')
1081            .add(new TweenMax(this.DOM.revealDeco, 0.3, {
1082                ease: Sine.easeOut,
1083                opacity: 0
1084            }), 'begin+=0.2')
1085            .add(new TweenMax(this.DOM.revealInner, 0.6, {
1086                ease: Expo.easeOut,
1087                startAt: {scale: 0, opacity: 0, rotation: 10},
1088                scale: 1,
1089                opacity: 1,
1090                rotation: 0
1091            }), 'begin+=0.2');
1092        }
1093        hideImage() {
1094            TweenMax.killTweensOf(this.DOM.revealInner);
1095            TweenMax.killTweensOf(this.DOM.revealDeco);
1096
1097            this.tl = new TimelineMax({
1098                onStart: () => {
1099                    TweenMax.set(this.DOM.el, {zIndex: 999});
1100                },
1101                onComplete: () => {
1102                    TweenMax.set(this.DOM.el, {zIndex: ''});
1103                    TweenMax.set(this.DOM.reveal, {opacity: 0});
1104                }
1105            })
1106            .add('begin')
1107            .add(new TweenMax([this.DOM.revealDeco, this.DOM.revealInner], 0.2, {
1108                ease: Expo.easeOut,
1109                opacity: 0,
1110                scale: 0.9
1111            }), 'begin')
1112        }
1113        animateLetters() {
1114            TweenMax.killTweensOf(this.DOM.letters);
1115            TweenMax.set(this.DOM.letters, {opacity: 0});
1116            TweenMax.staggerTo(this.DOM.letters, 0.1, {
1117                ease: Expo.easeOut,
1118                opacity: 1
1119            }, 0.04);
1120        }
1121    }
1122
1123    // Effect 11
1124    class HoverImgFx11 {
1125        constructor(el) {
1126            this.DOM = {el: el};
1127            
1128            this.DOM.reveal = document.createElement('div');
1129            this.DOM.reveal.className = 'tp-img-reveal-wrapper';
1130            this.DOM.reveal.style.overflow = 'hidden';
1131            this.DOM.reveal.innerHTML = `<div class="tp-img-reveal-wrapper__deco"></div><div class="tp-img-reveal-wrapper__inner"><div class="tp-img-reveal-wrapper__img" style="background-image:url(${this.DOM.el.dataset.img})"><span class="tp-hover-subtitle">
1131${this.DOM.el.dataset.subtitle ? this.DOM.el.dataset.subtitle: ''}</span> <h3 class="tp-hover-title">${this.DOM.el.dataset.title ? this.DOM.el.dataset.title: ''}</h3><p class="tp-hover-desc">${this.DOM.el.dataset.desc ? this.DOM.el.dataset.desc: ''}</p></div></div>`;
1132            this.DOM.el.appendChild(this.DOM.reveal);
1133            this.DOM.revealInner = this.DOM.reveal.querySelector('.tp-img-reveal-wrapper__inner');
1134            this.DOM.revealInner.style.overflow = 'hidden';
1135            this.DOM.revealDeco = this.DOM.reveal.querySelector('.tp-img-reveal-wrapper__deco');
1136            TweenMax.set(this.DOM.revealDeco, {
1137                width: '1%',
1138                height: '100%',
1139                background: 'white',
1140                left: '50%'
1141            });
1142            this.DOM.revealImg = this.DOM.revealInner.querySelector('.tp-img-reveal-wrapper__img');
1143            charming(this.DOM.el);
1144            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
1145            this.initEvents();
1146        }
1147        initEvents() {
1148            this.positionElement = (ev) => {
1149                const mousePos = getMousePos(ev);
1150                const docScrolls = {
1151                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
1152                    top : document.body.scrollTop + document.documentElement.scrollTop
1153                };
1154                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
1155                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
1156            };
1157            this.mouseenterFn = (ev) => {
1158                this.positionElement(ev);
1159                this.showImage();
1160                this.animateLetters();
1161            };
1162            this.mousemoveFn = ev => requestAnimationFrame(() => {
1163                this.positionElement(ev);
1164            });
1165            this.mouseleaveFn = () => {
1166                this.hideImage();
1167            };
1168            
1169            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
1170            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
1171            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
1172        }
1173        showImage() {
1174            TweenMax.killTweensOf(this.DOM.reveal);
1175            TweenMax.killTweensOf(this.DOM.revealInner);
1176            TweenMax.killTweensOf(this.DOM.revealImg);
1177            TweenMax.killTweensOf(this.DOM.revealDeco);
1178
1179            this.tl = new TimelineMax({
1180                onStart: () => {
1181                    this.DOM.reveal.style.opacity = 1;
1182                    TweenMax.set(this.DOM.el, {zIndex: 1000});
1183                }
1184            })
1185            .add('begin')
1186            .set(this.DOM.revealInner, {y: '100%'})
1187            .set(this.DOM.revealDeco, {transformOrigin: '50% 100%'})
1188            .add(new TweenMax(this.DOM.revealDeco, 0.3, {
1189                ease: Sine.easeInOut,
1190                startAt: {scaleY: 0, scaleX: 10},
1191                scaleY: 1,
1192                scaleX: 1
1193            }), 'begin')
1194            .set(this.DOM.revealDeco, {transformOrigin: '50% 0%'})
1195            .add(new TweenMax(this.DOM.revealDeco, 0.3, {
1196                ease: Expo.easeOut,
1197                scaleY: 0
1198            }), 'begin+=0.3')
1199            .add(new TweenMax(this.DOM.revealInner, 0.5, {
1200                ease: Expo.easeOut,
1201                startAt: {y: '100%'},
1202                y: '0%'
1203            }), 'begin+=0.4')
1204            .add(new TweenMax(this.DOM.revealImg, 0.5, {
1205                ease: Expo.easeOut,
1206                startAt: {y: '-100%'},
1207                y: '0%'
1208            }), 'begin+=0.4')
1209            .add(new TweenMax(this.DOM.revealImg, 0.5, {
1210                ease: Expo.easeOut,
1211                startAt: {y: '100%'},
1212                y: '0%'
1213            }), 'begin+=0.4')
1214            .add(new TweenMax(this.DOM.reveal, 1.1, {
1215                ease: Expo.easeOut,
1216                startAt: {y: '50%', rotation: 10},
1217                y: '0%',
1218                rotation: 0
1219            }), 'begin');
1220        }
1221        hideImage() {
1222            TweenMax.killTweensOf(this.DOM.reveal);
1223            TweenMax.killTweensOf(this.DOM.revealInner);
1224            TweenMax.killTweensOf(this.DOM.revealImg);
1225            TweenMax.killTweensOf(this.DOM.revealDeco);
1226
1227            this.tl = new TimelineMax({
1228                onStart: () => {
1229                    TweenMax.set(this.DOM.el, {zIndex: 999});
1230                },
1231                onComplete: () => {
1232                    TweenMax.set(this.DOM.el, {zIndex: ''});
1233                    TweenMax.set(this.DOM.reveal, {opacity: 0});
1234                }
1235            })
1236            .add('begin')
1237            .add(new TweenMax(this.DOM.revealInner, 0.1, {
1238                ease: Sine.easeOut,
1239                y: '-100%'
1240            }), 'begin')
1241            .add(new TweenMax(this.DOM.revealImg, 0.1, {
1242                ease: Sine.easeOut,
1243                y: '100%'
1244            }), 'begin')
1245        }
1246        animateLetters() {
1247            TweenMax.killTweensOf(this.DOM.letters);
1248            TweenMax.set(this.DOM.letters, {opacity: 0});
1249            TweenMax.staggerTo(this.DOM.letters, 0.1, {
1250                ease: Expo.easeOut,
1251                startAt: {y: '50%'},
1252                y: '0%',
1253                opacity: 1
1254            }, 0.06);
1255        }
1256    }
1257
1258    // Effect 12
1259    class HoverImgFx12 {
1260        constructor(el) {
1261            this.DOM = {el: el};
1262            this.DOM.reveal = document.createElement('div');
1263            this.DOM.reveal.className = 'tp-img-reveal-wrapper'; 
1264            this.totalDecos = 7;
1265            let inner = '';
1266            for (let i = 0; i <= this.totalDecos-1; ++i) {
1267                inner += '<div class="tp-img-reveal-wrapper__deco"></div>';
1268            }
1269            inner += `<div class="tp-img-reveal-wrapper__inner"><div class="tp-img-reveal-wrapper__img" style="background-image:url(${this.DOM.el.dataset.img})"><span class="tp-hover-subtitle">
1269${this.DOM.el.dataset.subtitle ? this.DOM.el.dataset.subtitle: ''}</span> <h3 class="tp-hover-title">${this.DOM.el.dataset.title ? this.DOM.el.dataset.title: ''}</h3><p class="tp-hover-desc">${this.DOM.el.dataset.desc ? this.DOM.el.dataset.desc: ''}</p></div></div>`
1270            this.DOM.reveal.innerHTML = inner;
1271            this.DOM.el.appendChild(this.DOM.reveal);
1272            this.DOM.revealDecos = [...this.DOM.reveal.querySelectorAll('.tp-img-reveal-wrapper__deco')];
1273            this.DOM.revealDecos.forEach((deco, pos) => {
1274                TweenMax.set(deco, {
1275                    width: pos === this.totalDecos-1 ? '100%' : `${getRandomFloat(40,100)}%`,
1276                    height: pos === this.totalDecos-1 ? '100%' : `${getRandomFloat(5,30)}%`,
1277                    x: pos === this.totalDecos-1 ? '0%' : `${getRandomFloat(-100,100)}%`,
1278                    y: pos === this.totalDecos-1 ? '0%' : `${getRandomFloat(-300,300)}%`,
1279                    scaleX: 0
1280                });
1281            });
1282            this.DOM.revealInner = this.DOM.reveal.querySelector('.tp-img-reveal-wrapper__inner');
1283            this.DOM.revealInner.style.overflow = 'hidden';
1284            this.DOM.revealImg = this.DOM.revealInner.querySelector('.tp-img-reveal-wrapper__img');
1285
1286            this.initEvents();
1287        }
1288        initEvents() {
1289            this.positionElement = (ev) => {
1290                const mousePos = getMousePos(ev);
1291                const docScrolls = {
1292                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
1293                    top : document.body.scrollTop + document.documentElement.scrollTop
1294                };
1295                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
1296                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
1297            };
1298            this.mouseenterFn = (ev) => {
1299                this.positionElement(ev);
1300                this.showImage();
1301            };
1302            this.mousemoveFn = ev => requestAnimationFrame(() => {
1303                this.positionElement(ev);
1304            });
1305            this.mouseleaveFn = () => {
1306                this.hideImage();
1307            };
1308            
1309            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
1310            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
1311            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
1312        }
1313        showImage() {
1314            TweenMax.killTweensOf(this.DOM.revealInner);
1315            TweenMax.killTweensOf(this.DOM.revealImg);
1316            TweenMax.killTweensOf(this.DOM.revealDecos);
1317
1318            this.tl = new TimelineMax({
1319                onStart: () => {
1320                    this.DOM.reveal.style.opacity = 1;
1321                    TweenMax.set(this.DOM.el, {zIndex: 1000});
1322                }
1323            })
1324            .add('begin')
1325            .set(this.DOM.revealInner, {x: '100%', opacity: 0})
1326            .set(this.DOM.revealDecos, {transformOrigin: '100% 50%'})
1327            .staggerTo(this.DOM.revealDecos, 0.3, {
1328                ease: Expo.easeInOut,
1329                scaleX: 1
1330            }, 0.06, 'begin')
1331            .staggerTo(this.DOM.revealDecos, getRandomFloat(0.3,0.6), {
1332                ease: Expo.easeOut,
1333                startAt: {transformOrigin: '0% 50%'},
1334                scaleX: 0,
1335                x: '-=5%'
1336            }, 0.04, 'begin+=0.3')
1337            .add(new TweenMax(this.DOM.revealInner, 0.6, {
1338                ease: Expo.easeOut,
1339                startAt: {x: '100%'},
1340                x: '0%',
1341                opacity: 1
1342            }), 'begin+=0.75')
1343            .add(new TweenMax(this.DOM.revealImg, 0.6, {
1344                ease: Expo.easeOut,
1345                startAt: {x: '-100%'},
1346                x: '0%'
1347            }), 'begin+=0.75');
1348        }
1349        hideImage() {
1350            TweenMax.killTweensOf(this.DOM.revealInner);
1351            TweenMax.killTweensOf(this.DOM.revealImg);
1352            TweenMax.killTweensOf(this.DOM.revealDecos);
1353
1354            this.tl = new TimelineMax({
1355                onStart: () => {
1356                    TweenMax.set(this.DOM.el, {zIndex: 999});
1357                },
1358                onComplete: () => {
1359                    TweenMax.set(this.DOM.el, {zIndex: ''});
1360                    TweenMax.set(this.DOM.reveal, {opacity: 0});
1361                }
1362            })
1363            .add('begin')
1364            .add(new TweenMax(this.DOM.revealInner, 0.1, {
1365                ease: Sine.easeOut,
1366                x: '-100%'
1367            }), 'begin')
1368            .add(new TweenMax(this.DOM.revealImg, 0.1, {
1369                ease: Sine.easeOut,
1370                x: '100%'
1371            }), 'begin')
1372        }
1373    }
1374
1375    // Effect 13
1376    class HoverImgFx13 {
1377        constructor(el) {
1378            this.DOM = {el: el};
1379            
1380            this.DOM.reveal = document.createElement('div');
1381            this.DOM.reveal.className = 'tp-img-reveal-wrapper';
1382            this.DOM.reveal.style.zIndex = -1;
1383            this.totalImages = 3;
1384            let inner = '';
1385            for (let i = 0; i <= this.totalImages-1; ++i) {
1386                inner += `<div class="tp-img-reveal-wrapper__img" style="position: absolute; background-image:url(${this.DOM.el.dataset.img})"><span class="tp-hover-subtitle">
1386${this.DOM.el.dataset.subtitle ? this.DOM.el.dataset.subtitle: ''}</span> <h3 class="tp-hover-title">${this.DOM.el.dataset.title ? this.DOM.el.dataset.title: ''}</h3><p class="tp-hover-desc">${this.DOM.el.dataset.desc ? this.DOM.el.dataset.desc: ''}</p></div>`;
1387            }
1388            this.DOM.reveal.innerHTML = inner;
1389            this.DOM.el.appendChild(this.DOM.reveal);
1390            this.DOM.revealImgs = [...this.DOM.reveal.querySelectorAll('.tp-img-reveal-wrapper__img')];
1391            charming(this.DOM.el);
1392            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
1393            this.initEvents();
1394        }
1395        position() {
1396            this.rect = this.DOM.el.getBoundingClientRect();
1397            this.DOM.reveal.style.top = `${this.rect.top - this.DOM.reveal.offsetHeight/2}px`;
1398            this.DOM.reveal.style.left = `${this.rect.left - this.DOM.reveal.offsetWidth/2}px`;
1399        }
1400        initEvents() {
1401            this.mouseenterFn = () => {
1402                this.showImage();
1403                this.animateLetters();
1404            };
1405            this.mouseleaveFn = () => {
1406                this.hideImage();
1407            };
1408            
1409            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
1410            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
1411        }
1412        showImage() {
1413            TweenMax.killTweensOf(this.DOM.revealImgs);
1414            this.position();
1415            
1416            this.tl = new TimelineMax({
1417                onStart: () => {
1418                    this.DOM.reveal.style.opacity = 1;
1419                }
1420            })
1421            .set([this.DOM.revealImgs], {opacity: 0})
1422
1423            for (let i = 0; i <= this.totalImages-1; ++i) {
1424                this.tl.add(new TweenMax(this.DOM.revealImgs[i], 0.7, {
1425                    ease: i === this.totalImages-1 ? Expo.easeOut : Quint.easeOut,
1426                    startAt: {x: '30%', y: '160%', rotation: i === this.totalImages-1 ? -30 : -10},
1427                    x: i === this.totalImages-1 ? '10%' : '-15%',
1428                    y: i === this.totalImages-1 ? '10%' : '-140%',
1429                    rotation: -10
1430                }), i*0.2);
1431                this.tl.add(new TweenMax(this.DOM.revealImgs[i], 0.5, {
1432                    ease: Quad.easeOut,
1433                    startAt: {opacity: 1},
1434                    opacity: i === this.totalImages-1 ? 1 : 0
1435                }), i*0.2);
1436            }
1437        }
1438        hideImage() {
1439            TweenMax.killTweensOf(this.DOM.revealImgs);
1440            this.tl = new TimelineMax({
1441                onComplete: () => {
1442                    TweenMax.set(this.DOM.reveal, {opacity: 0});
1443                }
1444            })
1445            .add(new TweenMax(this.DOM.revealImgs[this.totalImages-1], 0.15, {
1446                ease: Sine.easeOut,
1447                x: '-30%',
1448                y: '-240%',
1449                opacity: 0
1450            }))
1451        }
1452        animateLetters() {
1453            TweenMax.killTweensOf(this.DOM.letters);
1454            this.DOM.letters.forEach(letter => TweenMax.set(letter, {
1455                y: Math.round(Math.random()) === 0 ? '100%' : '0%',
1456                opacity: 0
1457            }));
1458            TweenMax.to(this.DOM.letters, 1, {
1459                ease: Expo.easeOut,
1460                y: '0%',
1461                opacity: 1
1462            });
1463        }
1464    }
1465
1466    // Effect 14
1467    class HoverImgFx14 {
1468        constructor(el) {
1469            this.DOM = {el: el};
1470            
1471            this.DOM.reveal = document.createElement('div');
1472            this.DOM.reveal.className = 'tp-img-reveal-wrapper';
1473            let inner = '';
1474            const imgsArr = this.DOM.el.dataset.img.split(',');
1475            for (let i = 0, len = imgsArr.length; i <= len-1; ++i ) {
1476                inner += `<div class="tp-img-reveal-wrapper__img" style="transform-origin:0% 0%;opacity:0;position:absolute;background-image:url(${imgsArr[i]})"><span class="tp-hover-subtitle">${this.DOM.el.dataset.subtitle ? this.DOM.el.dataset.subtitle: ''}</span> <h3 class="tp-hover-title">${this.DOM.el.dataset.title ? this.DOM.el.dataset.title: ''}</h3><p class="tp-hover-desc">${this.DOM.el.dataset.desc ? this.DOM.el.dataset.desc: ''}</p></div>`;
1477            }
1478            this.DOM.reveal.innerHTML = inner;
1479            this.DOM.el.appendChild(this.DOM.reveal);
1480            this.DOM.revealImgs = [...this.DOM.reveal.querySelectorAll('.tp-img-reveal-wrapper__img')];
1481            this.imgsTotal = this.DOM.revealImgs.length;
1482
1483            this.initEvents();
1484        }
1485        initEvents() {
1486            this.positionElement = (ev) => {
1487                const mousePos = getMousePos(ev);
1488                const docScrolls = {
1489                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
1490                    top : document.body.scrollTop + document.documentElement.scrollTop
1491                };
1492                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
1493                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
1494            };
1495            this.mouseenterFn = (ev) => {
1496                this.positionElement(ev);
1497                this.showImage();
1498            };
1499            this.mousemoveFn = ev => requestAnimationFrame(() => {
1500                this.positionElement(ev);
1501            });
1502            this.mouseleaveFn = () => {
1503                this.hideImage();
1504            };
1505            
1506            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
1507            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
1508            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
1509        }
1510        showImage() {
1511            this.DOM.reveal.style.opacity = 1;
1512            TweenMax.set(this.DOM.el, {zIndex: 1000});
1513            TweenMax.set(this.DOM.revealImgs, {opacity: 0});
1514
1515            const show = () => {
1516                TweenMax.killTweensOf(this.DOM.revealImgs[this.current]);
1517                TweenMax.set(this.DOM.revealImgs[this.current], {zIndex: 1000});
1518                TweenMax.to(this.DOM.revealImgs[this.current], 0.4, {
1519                    ease: Quint.easeOut,
1520                    startAt: {opacity: 0, scale: 0.5, rotation: -15, x: '0%', y: '-10%'},
1521                    opacity: 1,
1522                    y: '0%',
1523                    rotation: 0,
1524                    scale: 1
1525                });
1526            };
1527            this.current = 0;
1528            show();
1529            
1530            const loop = () => {
1531                this.imgtimeout = setTimeout(() => {
1532                    this.DOM.revealImgs[this.current].style.zIndex = '';
1533                    TweenMax.to(this.DOM.revealImgs[this.current], 0.8, {
1534                        ease: Expo.easeOut,
1535                        x: `${getRandomFloat(-10,10)}%`,
1536                        y: `${getRandomFloat(10,60)}%`,
1537                        rotation: getRandomFloat(5,15),
1538                        opacity: 0
1539                    });
1540                    this.current= this.current < this.imgsTotal-1 ? this.current+1 : 0;
1541                    show();
1542                    loop();
1543                }, 500);
1544            }
1545            loop();
1546        }
1547        hideImage() {
1548            clearTimeout(this.imgtimeout);
1549            this.DOM.revealImgs[this.current].style.zIndex = '';
1550            this.DOM.revealImgs[this.current].style.opacity = 0;
1551            this.current = 0;
1552            TweenMax.set(this.DOM.el, {zIndex: ''});
1553            TweenMax.set(this.DOM.reveal, {opacity: 0})
1554        }
1555    }
1556        
1557    // Effect 15
1558    class HoverImgFx15 {
1559        constructor(el) {
1560            this.DOM = {el: el};
1561            
1562            this.DOM.reveal = document.createElement('div');
1563            this.DOM.reveal.className = 'tp-img-reveal-wrapper';
1564            this.totalImages = 5;
1565            let inner = '';
1566            for (let i = 0; i <= this.totalImages-1; ++i) {
1567                inner += `<div class="tp-img-reveal-wrapper__img" style="position: absolute; background-image:url(${this.DOM.el.dataset.img})"><span class="tp-hover-subtitle">${this.DOM.el.dataset.subtitle ? this.DOM.el.dataset.subtitle: ''}</span> <h3 class="tp-hover-title">${this.DOM.el.dataset.title ? this.DOM.el.dataset.title: ''}</h3><p class="tp-hover-desc">${this.DOM.el.dataset.desc ? this.DOM.el.dataset.desc: ''}</p></div>`;
1568            }
1569            this.DOM.reveal.innerHTML = inner;
1570            this.DOM.el.appendChild(this.DOM.reveal);
1571            this.DOM.revealImgs = [...this.DOM.reveal.querySelectorAll('.tp-img-reveal-wrapper__img')];
1572            charming(this.DOM.el);
1573            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
1574            this.initEvents();
1575        }
1576        initEvents() {
1577            this.positionElement = (ev) => {
1578                const mousePos = getMousePos(ev);
1579                const docScrolls = {
1580                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
1581                    top : document.body.scrollTop + document.documentElement.scrollTop
1582                };
1583                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
1584                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
1585            };
1586            this.mouseenterFn = (ev) => {
1587                this.positionElement(ev);
1588                this.animateLetters();
1589                this.showImage();
1590            };
1591            this.mousemoveFn = ev => requestAnimationFrame(() => {
1592                this.positionElement(ev);
1593            });
1594            this.mouseleaveFn = () => {
1595                this.hideImage();
1596            };
1597            
1598            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
1599            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
1600            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
1601        }
1602        showImage() {
1603            TweenMax.killTweensOf(this.DOM.revealImgs);
1604            this.tl = new TimelineMax({
1605                onStart: () => {
1606                    this.DOM.reveal.style.opacity = 1;
1607                    TweenMax.set(this.DOM.el, {zIndex: 1000});
1608                }
1609            })
1610            .set(this.DOM.revealImgs, {opacity: 0});
1611
1612            for (let i = 0; i <= this.totalImages-1; ++i) {
1613                TweenMax.set(this.DOM.revealImgs[i], {
1614                    x: `${(this.totalImages-1-i)*5}%`, 
1615                    y: `${(this.totalImages-1-i)*10}%`
1616                });
1617                
1618                this.tl.add(new TweenMax(this.DOM.revealImgs[i], i === this.totalImages-1 ? 1.2 : 0.55, {
1619                    ease: i === this.totalImages-1 ? Quint.easeOut : Quad.easeOut,
1620                    startAt: i === this.totalImages-1 ? {opacity: 1, x: '5%', y: '10%'} : {opacity: 1},
1621                    opacity: i === this.totalImages-1 ? 1 : 0,
1622                    x: i === this.totalImages-1 ? '0%' : null,
1623                    y: i === this.totalImages-1 ? '0%' : null
1624                }), i*0.04);
1625            }
1626        }
1627        hideImage() {
1628            TweenMax.killTweensOf(this.DOM.revealImgs);
1629            this.tl = new TimelineMax({
1630                onStart: () => {
1631                    TweenMax.set(this.DOM.el, {zIndex: 999});
1632                },
1633                onComplete: () => {
1634                    TweenMax.set(this.DOM.el, {zIndex: ''});
1635                    TweenMax.set(this.DOM.reveal, {opacity: 0});
1636                }
1637            })
1638            .add(new TweenMax(this.DOM.revealImgs[this.totalImages-1], 0.15, {
1639                ease: Sine.easeOut,
1640                opacity: 0
1641            }))
1642        }
1643        animateLetters() {
1644            TweenMax.killTweensOf(this.DOM.letters);
1645            this.DOM.letters.forEach((letter) => {
1646                const opts = Math.round(Math.random()) === 0 ? {x: '100%', y: '100%', opacity: 0} : {opacity: 0};
1647                TweenMax.set(letter, opts);
1648            });
1649            TweenMax.to(this.DOM.letters, 1, {
1650                ease: Expo.easeOut,
1651                x: '0%',
1652                y: '0%',
1653                opacity: 1
1654            });
1655        }
1656    }
1657
1658    // Effect 16
1659    class HoverImgFx16 {
1660        constructor(el) {
1661            this.DOM = {el: el};
1662            
1663            this.DOM.reveal = document.createElement('div');
1664            this.DOM.reveal.className = 'tp-img-reveal-wrapper';
1665            this.totalImages = 10;
1666            let inner = '';
1667            for (let i = 0; i <= this.totalImages-1; ++i) {
1668                inner += `<div class="tp-img-reveal-wrapper__img" style="position: absolute; background-image:url(${this.DOM.el.dataset.img})"><span class="tp-hover-subtitle">${this.DOM.el.dataset.subtitle ? this.DOM.el.dataset.subtitle: ''}</span> <h3 class="tp-hover-title">${this.DOM.el.dataset.title ? this.DOM.el.dataset.title: ''}</h3><p class="tp-hover-desc">${this.DOM.el.dataset.desc ? this.DOM.el.dataset.desc: ''}</p></div>`;
1669            }
1670            this.DOM.reveal.innerHTML = inner;
1671            this.DOM.el.appendChild(this.DOM.reveal);
1672            this.DOM.revealImgs = [...this.DOM.reveal.querySelectorAll('.tp-img-reveal-wrapper__img')];
1673            this.rect = this.DOM.reveal.getBoundingClientRect();
1674            charming(this.DOM.el);
1675            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
1676            this.initEvents();
1677        }
1678        initEvents() {
1679            this.positionElement = (ev) => {
1680                const mousePos = getMousePos(ev);
1681                const docScrolls = {
1682                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
1683                    top : document.body.scrollTop + document.documentElement.scrollTop
1684                };
1685                this.DOM.reveal.style.top = `${mousePos.y-this.rect.height-20-docScrolls.top}px`;
1686                this.DOM.reveal.style.left = `${mousePos.x-this.rect.width-20-docScrolls.left}px`;
1687            };
1688            this.mouseenterFn = (ev) => {
1689                this.positionElement(ev);
1690                this.animateLetters();
1691                this.showImage();
1692            };
1693            this.mousemoveFn = ev => requestAnimationFrame(() => {
1694                this.positionElement(ev);
1695            });
1696            this.mouseleaveFn = () => {
1697                this.hideImage();
1698            };
1699            
1700            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
1701            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
1702            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
1703        }
1704        showImage() {
1705            TweenMax.killTweensOf(this.DOM.revealImgs);
1706            this.tl = new TimelineMax({
1707                onStart: () => {
1708                    this.DOM.reveal.style.opacity = 1;
1709                    TweenMax.set(this.DOM.el, {zIndex: 1000});
1710                }
1711            })
1712            .set(this.DOM.revealImgs, {opacity: 0, transformOrigin: '0% 0%'});
1713            
1714            for (let i = 0; i <= this.totalImages-1; ++i) {
1715                TweenMax.set(this.DOM.revealImgs[i], {
1716                    x: `${(this.totalImages-1-i)*getRandomFloat(-10,-5)}%`, 
1717                    y: `${(this.totalImages-1-i)*getRandomFloat(-15,-10)}%`,
1718                    rotation: `${getRandomFloat(-5,5)}deg`
1719                });
1720                
1721                this.tl.add(new TweenMax(this.DOM.revealImgs[i], i === this.totalImages-1 ? 0.3 : 0.3, {
1722                    ease: i === this.totalImages-1 ? Quint.easeOut : Sine.easeOut,
1723                    startAt: i === this.totalImages-1 ? {opacity: 1, x: '-5%', y: '-10%'} : {opacity: 1},
1724                    opacity: i === this.totalImages-1 ? 1 : 0,
1725                    x: i === this.totalImages-1 ? '0%' : null,
1726                    y: i === this.totalImages-1 ? '0%' : null,
1727                    rotation: 0
1728                }), i*0.02);
1729            }
1730        }
1731        hideImage() {
1732            TweenMax.killTweensOf(this.DOM.revealImgs);
1733            this.tl = new TimelineMax({
1734                onStart: () => {
1735                    TweenMax.set(this.DOM.el, {zIndex: 999});
1736                },
1737                onComplete: () => {
1738                    TweenMax.set(this.DOM.el, {zIndex: ''});
1739                    TweenMax.set(this.DOM.reveal, {opacity: 0});
1740                }
1741            })
1742            .add(new TweenMax(this.DOM.revealImgs[this.totalImages-1], 0.15, {
1743                ease: Sine.easeOut,
1744                opacity: 0
1745            }))
1746        }
1747        animateLetters() {
1748            TweenMax.killTweensOf(this.DOM.letters);
1749            this.DOM.letters.forEach((letter) => {
1750                const opts = Math.round(Math.random()) === 0 ? {x: '-100%', y: '-100%', opacity: 0} : {opacity: 0};
1751                TweenMax.set(letter, opts);
1752            });
1753            TweenMax.to(this.DOM.letters, 0.6, {
1754                ease: Expo.easeOut,
1755                x: '0%',
1756                y: '0%',
1757                opacity: 1
1758            });
1759        }
1760    }
1761
1762    // Effect 17
1763    class HoverImgFx17 {
1764        constructor(el) {
1765            this.DOM = {el: el};
1766            
1767            this.DOM.reveal = document.createElement('div');
1768            this.DOM.reveal.className = 'tp-img-reveal-wrapper';
1769            this.totalImages = 10;
1770            let inner = '';
1771            for (let i = 0; i <= this.totalImages-1; ++i) {
1772                inner += `<div class="tp-img-reveal-wrapper__img" style="position: absolute; background-image:url(${this.DOM.el.dataset.img})"><span class="tp-hover-subtitle">${this.DOM.el.dataset.subtitle ? this.DOM.el.dataset.subtitle: ''}</span> <h3 class="tp-hover-title">${this.DOM.el.dataset.title ? this.DOM.el.dataset.title: ''}</h3><p class="tp-hover-desc">${this.DOM.el.dataset.desc ? this.DOM.el.dataset.desc: ''}</p></div>`;
1773            }
1774            this.DOM.reveal.innerHTML = inner;
1775            this.DOM.el.appendChild(this.DOM.reveal);
1776            this.DOM.revealImgs = [...this.DOM.reveal.querySelectorAll('.tp-img-reveal-wrapper__img')];
1777            charming(this.DOM.el);
1778            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
1779            this.initEvents();
1780        }
1781        initEvents() {
1782            this.positionElement = (ev) => {
1783                const mousePos = getMousePos(ev);
1784                const docScrolls = {
1785                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
1786                    top : document.body.scrollTop + document.documentElement.scrollTop
1787                };
1788                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
1789                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
1790            };
1791            this.mouseenterFn = (ev) => {
1792                this.positionElement(ev);
1793                this.animateLetters();
1794                this.showImage();
1795            };
1796            this.mousemoveFn = ev => requestAnimationFrame(() => {
1797                this.positionElement(ev);
1798            });
1799            this.mouseleaveFn = () => {
1800                this.hideImage();
1801            };
1802            
1803            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
1804            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
1805            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
1806        }
1807        showImage() {
1808            TweenMax.killTweensOf(this.DOM.revealImgs);
1809            this.tl = new TimelineMax({
1810                onStart: () => {
1811                    this.DOM.reveal.style.opacity = 1;
1812                    TweenMax.set(this.DOM.el, {zIndex: 1000});
1813                }
1814            })
1815            .set(this.DOM.revealImgs, {opacity: 0, transformOrigin: '0% 100%'});
1816            
1817            for (let i = 0; i <= this.totalImages-1; ++i) {
1818                TweenMax.set(this.DOM.revealImgs[i], {
1819                    x: `${(this.totalImages-1-i)*15}%`, 
1820                    y: `${(this.totalImages-1-i)*-10}%`,
1821                    rotation: `${getRandomFloat(-7,7)}deg`,
1822                    scale: `${i === this.totalImages-1 ? 1 : getRandomFloat(0.2,1)}`,
1823                });
1824                
1825                this.tl.add(new TweenMax(this.DOM.revealImgs[i], i === this.totalImages-1 ? 0.8 : 0.55, {
1826                    ease: i === this.totalImages-1 ? Quint.easeOut : Quad.easeInOut,
1827                    startAt: i === this.totalImages-1 ? {opacity: 1, x: '5%', y: '-10%'} : {opacity: 1},
1828                    opacity: i === this.totalImages-1 ? 1 : 0,
1829                    x: i === this.totalImages-1 ? '0%' : null,
1830                    y: i === this.totalImages-1 ? '0%' : null,
1831                    //scale: 1
1832                }), i*0.06);
1833            }
1834        }
1835        hideImage() {
1836            TweenMax.killTweensOf(this.DOM.revealImgs);
1837            this.tl = new TimelineMax({
1838                onStart: () => {
1839                    TweenMax.set(this.DOM.el, {zIndex: 999});
1840                },
1841                onComplete: () => {
1842                    TweenMax.set(this.DOM.el, {zIndex: ''});
1843                    TweenMax.set(this.DOM.reveal, {opacity: 0});
1844                }
1845            })
1846            .add(new TweenMax(this.DOM.revealImgs[this.totalImages-1], 0.15, {
1847                ease: Sine.easeOut,
1848                opacity: 0
1849            }))
1850        }
1851        animateLetters() {
1852            TweenMax.killTweensOf(this.DOM.letters);
1853            this.DOM.letters.forEach((letter) => {
1854                const opts = Math.round(Math.random()) === 0 ? {x: '100%', y: '-100%', opacity: 0} : {opacity: 0};
1855                TweenMax.set(letter, opts);
1856            });
1857            TweenMax.to(this.DOM.letters, 1, {
1858                ease: Expo.easeOut,
1859                x: '0%',
1860                y: '0%',
1861                opacity: 1
1862            });
1863        }
1864    }
1865
1866    // Effect 18
1867    class HoverImgFx18 {
1868        constructor(el) {
1869            this.DOM = {el: el};
1870            
1871            this.DOM.reveal = document.createElement('div');
1872            this.DOM.reveal.className = 'tp-img-reveal-wrapper';
1873            this.totalImages = 10;
1874            let inner = '';
1875            for (let i = 0; i <= this.totalImages-1; ++i) {
1876                inner += `<div class="tp-img-reveal-wrapper__img" style="position: absolute; background-image:url(${this.DOM.el.dataset.img})"><span class="tp-hover-subtitle">${this.DOM.el.dataset.subtitle ? this.DOM.el.dataset.subtitle: ''}</span> <h3 class="tp-hover-title">${this.DOM.el.dataset.title ? this.DOM.el.dataset.title: ''}</h3><p class="tp-hover-desc">${this.DOM.el.dataset.desc ? this.DOM.el.dataset.desc: ''}</p></div>`;
1877            }
1878            this.DOM.reveal.innerHTML = inner;
1879            this.DOM.el.appendChild(this.DOM.reveal);
1880            this.DOM.revealImgs = [...this.DOM.reveal.querySelectorAll('.tp-img-reveal-wrapper__img')];
1881            this.rect = this.DOM.reveal.getBoundingClientRect();
1882            charming(this.DOM.el);
1883            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
1884            this.initEvents();
1885        }
1886        initEvents() {
1887            this.positionElement = (ev) => {
1888                const mousePos = getMousePos(ev);
1889                const docScrolls = {
1890                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
1891                    top : document.body.scrollTop + document.documentElement.scrollTop
1892                };
1893                this.DOM.reveal.style.top = `${mousePos.y-this.rect.height-20-docScrolls.top}px`;
1894                this.DOM.reveal.style.left = `${mousePos.x-this.rect.width-20-docScrolls.left}px`;
1895            };
1896            this.mouseenterFn = (ev) => {
1897                this.positionElement(ev);
1898                this.animateLetters();
1899                this.showImage();
1900            };
1901            this.mousemoveFn = ev => requestAnimationFrame(() => {
1902                this.positionElement(ev);
1903            });
1904            this.mouseleaveFn = () => {
1905                this.hideImage();
1906            };
1907            
1908            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
1909            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
1910            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
1911        }
1912        showImage() {
1913            TweenMax.killTweensOf(this.DOM.revealImgs);
1914            this.tl = new TimelineMax({
1915                onStart: () => {
1916                    this.DOM.reveal.style.opacity = 1;
1917                    TweenMax.set(this.DOM.el, {zIndex: 1000});
1918                }
1919            })
1920            .set(this.DOM.revealImgs, {opacity: 0});
1921
1922            for (let i = 0; i <= this.totalImages-1; ++i) {
1923                TweenMax.set(this.DOM.revealImgs[i], {
1924                    x: `${(this.totalImages-1-i)*-50}%`, 
1925                    y: `${(this.totalImages-1-i)*-getRandomFloat(-2,2)}%`,
1926                    rotation: `${i !== this.totalImages-1 ? getRandomFloat(-5,5) : 0}deg`
1927                });
1928                
1929                this.tl.add(new TweenMax(this.DOM.revealImgs[i], i === this.totalImages-1 ? 0.4 : 0.55, {
1930                    ease: i === this.totalImages-1 ? Back.easeOut : Quad.easeInOut,
1931                    startAt: i === this.totalImages-1 ? {opacity: 1, x: '-50%', y: '0%'} : {opacity: 1},
1932                    opacity: i === this.totalImages-1 ? 1 : 0,
1933                    x: i === this.totalImages-1 ? '0%' : null,
1934                    y: i === this.totalImages-1 ? '0%' : null,
1935                }), i*0.02);
1936            }
1937        }
1938        hideImage() {
1939            TweenMax.killTweensOf(this.DOM.revealImgs);
1940            this.tl = new TimelineMax({
1941                onStart: () => {
1942                    TweenMax.set(this.DOM.el, {zIndex: 999});
1943                },
1944                onComplete: () => {
1945                    TweenMax.set(this.DOM.el, {zIndex: ''});
1946                    TweenMax.set(this.DOM.reveal, {opacity: 0});
1947                }
1948            })
1949            .add(new TweenMax(this.DOM.revealImgs[this.totalImages-1], 0.15, {
1950                ease: Sine.easeOut,
1951                opacity: 0
1952            }))
1953        }
1954        animateLetters() {
1955            TweenMax.killTweensOf(this.DOM.letters);
1956            this.DOM.letters.forEach((letter) => {
1957                const opts = Math.round(Math.random()) === 0 ? {x: '-100%', opacity: 0} : {opacity: 0};
1958                TweenMax.set(letter, opts);
1959            });
1960            TweenMax.to(this.DOM.letters, 1, {
1961                ease: Expo.easeOut,
1962                x: '0%',
1963                opacity: 1
1964            });
1965        }
1966    }
1967
1968    // Effect 19
1969    class HoverImgFx19 {
1970        constructor(el) {
1971            this.DOM = {el: el};
1972            
1973            this.DOM.reveal = document.createElement('div');
1974            this.DOM.reveal.className = 'tp-img-reveal-wrapper';
1975            this.totalImages = 35;
1976            let inner = '';
1977            for (let i = 0; i <= this.totalImages-1; ++i) {
1978                inner += `<div class="tp-img-reveal-wrapper__img" style="position: absolute; background-image:url(${this.DOM.el.dataset.img})"><span class="tp-hover-subtitle">${this.DOM.el.dataset.subtitle ? this.DOM.el.dataset.subtitle: ''}</span> <h3 class="tp-hover-title">${this.DOM.el.dataset.title ? this.DOM.el.dataset.title: ''}</h3><p class="tp-hover-desc">${this.DOM.el.dataset.desc ? this.DOM.el.dataset.desc: ''}</p></div>`;
1979            }
1980            this.DOM.reveal.innerHTML = inner;
1981            this.DOM.el.appendChild(this.DOM.reveal);
1982            this.DOM.revealImgs = [...this.DOM.reveal.querySelectorAll('.tp-img-reveal-wrapper__img')];
1983            this.rect = this.DOM.reveal.getBoundingClientRect();
1984            charming(this.DOM.el);
1985            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
1986            this.initEvents();
1987        }
1988        initEvents() {
1989            this.positionElement = (ev) => {
1990                const mousePos = getMousePos(ev);
1991                const docScrolls = {
1992                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
1993                    top : document.body.scrollTop + document.documentElement.scrollTop
1994                };
1995                this.DOM.reveal.style.top = `${mousePos.y-this.rect.height-20-docScrolls.top}px`;
1996                this.DOM.reveal.style.left = `${mousePos.x-this.rect.width-20-docScrolls.left}px`;
1997            };
1998            this.mouseenterFn = (ev) => {
1999                this.positionElement(ev);
2000                this.animateLetters();
2001                this.showImage();
2002            };
2003            this.mousemoveFn = ev => requestAnimationFrame(() => {
2004                this.positionElement(ev);
2005            });
2006            this.mouseleaveFn = () => {
2007                this.hideImage();
2008            };
2009            
2010            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
2011            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
2012            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
2013        }
2014        showImage() {
2015            TweenMax.killTweensOf(this.DOM.revealImgs);
2016            this.tl = new TimelineMax({
2017                onStart: () => {
2018                    this.DOM.reveal.style.opacity = 1;
2019                    TweenMax.set(this.DOM.el, {zIndex: 1000});
2020                }
2021            })
2022            .set(this.DOM.revealImgs, {opacity: 0, transformOrigin: '100% 100%'});
2023
2024            for (let i = 0; i <= this.totalImages-1; ++i) {
2025                TweenMax.set(this.DOM.revealImgs[i], {
2026                    x: `${(this.totalImages-1-i)*-8}%`, 
2027                    y: `${(this.totalImages-1-i)*-5}%`,
2028                    rotation: `${i !== this.totalImages-1 ? -1+3*(this.totalImages-i-1) : 0}deg`,
2029                    scale: `${mapNumber(i,0,this.totalImages-1,0.1,1)}`
2030                });
2031                
2032                this.tl.add(new TweenMax(this.DOM.revealImgs[i], i === this.totalImages-1 ? 0.8 : 0.55, {
2033                    ease: i === this.totalImages-1 ? Back.easeOut : Quint.easeOut,
2034                    startAt: i === this.totalImages-1 ? {opacity: 1, x: '-5%', y: '-5%', rotation: -10} : {opacity: 1},
2035                    opacity: i === this.totalImages-1 ? 1 : 0,
2036                    x: i === this.totalImages-1 ? '0%' : null,
2037                    y: i === this.totalImages-1 ? '0%' : null,
2038                    rotation: i === this.totalImages-1 ? 0 : null
2039                }), i*0.01);
2040            }
2041        }
2042        hideImage() {
2043            TweenMax.killTweensOf(this.DOM.revealImgs);
2044            this.tl = new TimelineMax({
2045                onStart: () => {
2046                    TweenMax.set(this.DOM.el, {zIndex: 999});
2047                },
2048                onComplete: () => {
2049                    TweenMax.set(this.DOM.el, {zIndex: ''});
2050                    TweenMax.set(this.DOM.reveal, {opacity: 0});
2051                }
2052            })
2053            .add(new TweenMax(this.DOM.revealImgs[this.totalImages-1], 0.15, {
2054                ease: Sine.easeOut,
2055                opacity: 0
2056            }))
2057        }
2058        animateLetters() {
2059            TweenMax.killTweensOf(this.DOM.letters);
2060            this.DOM.letters.forEach((letter) => {
2061                const opts = Math.round(Math.random()) === 0 ? {x: '-200%', y: '-200%', opacity: 0} : {opacity: 0};
2062                TweenMax.set(letter, opts);
2063            });
2064            TweenMax.to(this.DOM.letters, 0.8, {
2065                ease: Expo.easeOut,
2066                x: '0%',
2067                y: '0%',
2068                opacity: 1
2069            });
2070        }
2071    }
2072
2073    // Effect 20
2074    class HoverImgFx20 {
2075        constructor(el) {
2076            this.DOM = {el: el};
2077            
2078            this.DOM.reveal = document.createElement('div');
2079            this.DOM.reveal.className = 'tp-img-reveal-wrapper';
2080            this.totalImages = 10;
2081            let inner = '';
2082            for (let i = 0; i <= this.totalImages-1; ++i) {
2083                inner += i === this.totalImages-1 ? `<div class="tp-img-reveal-wrapper__img" style="position: absolute; background-image:url(${this.DOM.el.dataset.img})"><span class="tp-hover-subtitle">${this.DOM.el.dataset.subtitle ? this.DOM.el.dataset.subtitle: ''}</span> <h3 class="tp-hover-title">${this.DOM.el.dataset.title ? this.DOM.el.dataset.title: ''}</h3><p class="tp-hover-desc">${this.DOM.el.dataset.desc ? this.DOM.el.dataset.desc: ''}</p></div>` :
2084                                                    `<div class="tp-img-reveal-wrapper__img" style="filter: hue-rotate(60deg) saturate(5); position: absolute; background-image:url(${this.DOM.el.dataset.img})"></div>`;
2085            }
2086            this.DOM.reveal.innerHTML = inner;
2087            this.DOM.el.appendChild(this.DOM.reveal);
2088            this.DOM.revealImgs = [...this.DOM.reveal.querySelectorAll('.tp-img-reveal-wrapper__img')];
2089            charming(this.DOM.el);
2090            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
2091            this.letterColor = getComputedStyle(this.DOM.el).color;
2092            this.initEvents();
2093        }
2094        initEvents() {
2095            this.positionElement = (ev) => {
2096                const mousePos = getMousePos(ev);
2097                const docScrolls = {
2098                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
2099                    top : document.body.scrollTop + document.documentElement.scrollTop
2100                };
2101                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
2102                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
2103            };
2104            this.mouseenterFn = (ev) => {
2105                this.positionElement(ev);
2106                this.showImage();
2107                this.animateLetters();
2108            };
2109            this.mousemoveFn = ev => requestAnimationFrame(() => {
2110                this.positionElement(ev);
2111            });
2112            this.mouseleaveFn = () => {
2113                this.hideImage();
2114            };
2115            
2116            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
2117            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
2118            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
2119        }
2120        showImage() {
2121            TweenMax.killTweensOf(this.DOM.revealImgs);
2122            this.tl = new TimelineMax({
2123                onStart: () => {
2124                    this.DOM.reveal.style.opacity = 1;
2125                    TweenMax.set(this.DOM.el, {zIndex: 1000});
2126                }
2127            })
2128            .set([this.DOM.revealImgs], {opacity: 0});
2129            for (let i = 0; i <= this.totalImages-1; ++i) {
2130                TweenMax.set(this.DOM.revealImgs[i], {
2131                    x: i === this.totalImages-1 ? '0%' : `${getRandomFloat(-5,5)}%`, 
2132                    y: i === this.totalImages-1 ? '0%' : `${getRandomFloat(-5,5)}%`
2133                });
2134                
2135                this.tl.add(new TweenMax(this.DOM.revealImgs[i], 0.25, {
2136                    ease: Quad.easeOut,
2137                    startAt: {opacity: 1},
2138                    opacity: i === this.totalImages-1 ? 1 : 0
2139                }), i*0.04);
2140            }
2141        }
2142        hideImage() {
2143            TweenMax.killTweensOf(this.DOM.revealImgs);
2144            this.tl = new TimelineMax({
2145                onStart: () => {
2146                    TweenMax.set(this.DOM.el, {zIndex: 999});
2147                },
2148                onComplete: () => {
2149                    TweenMax.set(this.DOM.el, {zIndex: ''});
2150                    TweenMax.set(this.DOM.reveal, {opacity: 0});
2151                }
2152            })
2153            .add(new TweenMax(this.DOM.revealImgs[this.totalImages-1], 0.15, {
2154                ease: Sine.easeOut,
2155                opacity: 0
2156            }))
2157        }
2158        animateLetters() {
2159            const setColor = letter => TweenMax.set(letter, {
2160                color: ['#fff', '#0ff', '#f0f'][parseInt(getRandomFloat(0,3))],
2161                opacity: Math.round(Math.random()) === 0 ? 1 : 0
2162            });
2163            this.DOM.letters.forEach((letter) => {
2164                TweenMax.to(letter, 0.1, {
2165                    ease: Expo.easeOut,
2166                    onStart: () => setColor(letter),
2167                    onRepeat: () => setColor(letter),
2168                    startAt: {x: `${getRandomFloat(-50,50)}%`, y: `${getRandomFloat(-50,50)}%`},
2169                    x: '0%',
2170                    y: '0%',
2171                    repeat: 3,
2172                    onComplete: () => TweenMax.set(letter, {color: this.letterColor, opacity: 1}),
2173                });
2174            });
2175        }
2176    }
2177
2178    // Effect 21
2179    class HoverImgFx21 {
2180        constructor(el) {
2181            this.DOM = {el: el};
2182            
2183            this.DOM.reveal = document.createElement('div');
2184            this.DOM.reveal.className = 'tp-img-reveal-wrapper';
2185            this.totalImages = 15;
2186            let inner = '';
2187            for (let i = 0; i <= this.totalImages-1; ++i) {
2188                inner += i === this.totalImages-1 ? `<div class="tp-img-reveal-wrapper__img" style="position: absolute; background-image:url(${this.DOM.el.dataset.img})"><span class="tp-hover-subtitle">${this.DOM.el.dataset.subtitle ? this.DOM.el.dataset.subtitle: ''}</span> <h3 class="tp-hover-title">${this.DOM.el.dataset.title ? this.DOM.el.dataset.title: ''}</h3><p class="tp-hover-desc">${this.DOM.el.dataset.desc ? this.DOM.el.dataset.desc: ''}</p></div>` :
2189                                                    `<div class="tp-img-reveal-wrapper__img" style="filter: hue-rotate(90deg) saturate(9); position: absolute; background-image:url(${this.DOM.el.dataset.img})"></div>`;
2190            }
2191            this.DOM.reveal.innerHTML = inner;
2192            this.DOM.el.appendChild(this.DOM.reveal);
2193            this.DOM.revealImgs = [...this.DOM.reveal.querySelectorAll('.tp-img-reveal-wrapper__img')];
2194            this.rect = this.DOM.reveal.getBoundingClientRect();
2195            charming(this.DOM.el);
2196            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
2197            this.letterColor = getComputedStyle(this.DOM.el).color;
2198            this.initEvents();
2199        }
2200        initEvents() {
2201            this.positionElement = (ev) => {
2202                const mousePos = getMousePos(ev);
2203                const docScrolls = {
2204                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
2205                    top : document.body.scrollTop + document.documentElement.scrollTop
2206                };
2207                this.DOM.reveal.style.top = `${mousePos.y-this.rect.height-20-docScrolls.top}px`;
2208                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
2209            };
2210            this.mouseenterFn = (ev) => {
2211                this.positionElement(ev);
2212                this.animateLetters();
2213                this.showImage();
2214            };
2215            this.mousemoveFn = ev => requestAnimationFrame(() => {
2216                this.positionElement(ev);
2217            });
2218            this.mouseleaveFn = () => {
2219                this.hideImage();
2220            };
2221            
2222            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
2223            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
2224            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
2225        }
2226        showImage() {
2227            TweenMax.killTweensOf(this.DOM.revealImgs);
2228            this.tl = new TimelineMax({
2229                onStart: () => {
2230                    this.DOM.reveal.style.opacity = 1;
2231                    TweenMax.set(this.DOM.el, {zIndex: 1000});
2232                }
2233            })
2234            .set(this.DOM.revealImgs, {opacity: 0});
2235
2236            for (let i = 0; i <= this.totalImages-1; ++i) {
2237                TweenMax.set(this.DOM.revealImgs[i], {
2238                    x: `${i !== this.totalImages-1 ? getRandomFloat(-45,45) : 0}%`, 
2239                    y: `${i !== this.totalImages-1 ? getRandomFloat(-45,45) : 0}%`,
2240                    rotation: `${i !== this.totalImages-1 ? getRandomFloat(-10,10) : 0}`,
2241                    scale: `${i !== this.totalImages-1 ? getRandomFloat(0.1,1.2) : 0.9}`
2242                });
2243                
2244                this.tl.add(new TweenMax(this.DOM.revealImgs[i], 0.5, {
2245                    ease: Quint.easeOut,
2246                    startAt: i === this.totalImages-1 ? {opacity: 1, x: '0%', y: '0%'} : {opacity: 1},
2247                    opacity: i === this.totalImages-1 ? 1 : 0,
2248                    x: i === this.totalImages-1 ? '0%' : null,
2249                    y: i === this.totalImages-1 ? '0%' : null,
2250                    scale: i === this.totalImages-1 ? 1 : null
2251                }), i*0.02);
2252            }
2253        }
2254        hideImage() {
2255            TweenMax.killTweensOf(this.DOM.revealImgs);
2256            this.tl = new TimelineMax({
2257                onStart: () => {
2258                    TweenMax.set(this.DOM.el, {zIndex: 999});
2259                },
2260                onComplete: () => {
2261                    TweenMax.set(this.DOM.el, {zIndex: ''});
2262                    TweenMax.set(this.DOM.reveal, {opacity: 0});
2263                }
2264            })
2265            .add(new TweenMax(this.DOM.revealImgs[this.totalImages-1], 0.15, {
2266                ease: Sine.easeOut,
2267                opacity: 0
2268            }))
2269        }
2270        animateLetters() {
2271            const setColor = letter => TweenMax.set(letter, {
2272                color: ['#fff', '#0ff', '#f0f'][parseInt(getRandomFloat(0,3))],
2273                opacity: Math.round(Math.random()) === 0 ? 1 : 0
2274            });
2275            this.DOM.letters.forEach((letter) => {
2276                TweenMax.to(letter, 0.1, {
2277                    ease: Expo.easeOut,
2278                    onStart: () => setColor(letter),
2279                    onRepeat: () => setColor(letter),
2280                    startAt: {x: `${getRandomFloat(-50,50)}%`, y: `${getRandomFloat(-50,50)}%`},
2281                    x: '0%',
2282                    y: '0%',
2283                    repeat: 3,
2284                    onComplete: () => TweenMax.set(letter, {color: this.letterColor, opacity: 1}),
2285                });
2286            });
2287        }
2288    }
2289	
2290    // Effect 22
2291    class HoverImgFx22 {
2292        constructor(el) {
2293            this.DOM = {el: el};
2294            this.DOM.reveal = document.createElement('div');
2295            this.DOM.reveal.className = 'tp-img-reveal-wrapper';
2296            this.DOM.reveal.innerHTML = `<div class="tp-img-reveal-wrapper__img" style="background-image:url(${this.DOM.el.dataset.img})"><span class="tp-hover-subtitle">${this.DOM.el.dataset.subtitle ? this.DOM.el.dataset.subtitle: ''}</span> <h3 class="tp-hover-title">${this.DOM.el.dataset.title ? this.DOM.el.dataset.title: ''}</h3><p class="tp-hover-desc">${this.DOM.el.dataset.desc ? this.DOM.el.dataset.desc: ''}</p></div>`;
2297            this.DOM.el.appendChild(this.DOM.reveal);
2298            this.DOM.revealImg = this.DOM.reveal.querySelector('.tp-img-reveal-wrapper__img');
2299
2300            this.initEvents();
2301        }
2302        initEvents() {
2303            this.positionElement = (ev) => {
2304                const mousePos = getMousePos(ev);
2305                const docScrolls = {
2306                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
2307                    top : document.body.scrollTop + document.documentElement.scrollTop
2308                };
2309                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
2310                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
2311            };
2312            this.mouseenterFn = (ev) => {
2313                this.positionElement(ev);
2314                this.showImage();
2315            };
2316            this.mousemoveFn = ev => requestAnimationFrame(() => {
2317                this.positionElement(ev);
2318            });
2319            this.mouseleaveFn = () => {
2320                this.hideImage();
2321            };
2322            
2323            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
2324            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
2325            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
2326        }
2327        showImage() {
2328            TweenMax.killTweensOf(this.DOM.revealImg);
2329
2330            this.tl = new TimelineMax({
2331                onStart: () => {
2332                    this.DOM.reveal.style.opacity = 1;
2333                    TweenMax.set(this.DOM.el, {zIndex: 1000});
2334                }
2335            })
2336            .add('begin')
2337            .set(this.DOM.revealImg, {transformOrigin: '95% 50%', x: '100%'})
2338            .add(new TweenMax(this.DOM.revealImg, 0.2, {
2339                ease: Sine.easeOut,
2340                startAt: {scaleX: 0.5, scaleY: 1},
2341                scaleX: 1.5,
2342                scaleY: 0.7
2343            }), 'begin')
2344            .add(new TweenMax(this.DOM.revealImg, 0.8, {
2345                ease: Expo.easeOut,
2346                startAt: {rotation: 10, y: '5%', opacity: 0},
2347                rotation: 0,
2348                y: '0%',
2349                opacity: 1
2350            }), 'begin')
2351            .set(this.DOM.revealImg, {transformOrigin: '0% 50%'})
2352            .add(new TweenMax(this.DOM.revealImg, 0.6, {
2353                ease: Expo.easeOut,
2354                scaleX: 1,
2355                scaleY: 1,
2356                opacity: 1
2357            }), 'begin+=0.2')
2358            .add(new TweenMax(this.DOM.revealImg, 0.6, {
2359                ease: Expo.easeOut,
2360                x: '0%'
2361            }), 'begin+=0.2')
2362        }
2363        hideImage() {
2364            TweenMax.killTweensOf(this.DOM.revealImg);
2365
2366            this.tl = new TimelineMax({
2367                onStart: () => {
2368                    TweenMax.set(this.DOM.el, {zIndex: 999});
2369                },
2370                onComplete: () => {
2371                    TweenMax.set(this.DOM.el, {zIndex: ''});
2372                    TweenMax.set(this.DOM.reveal, {opacity: 0});
2373                }
2374            })
2375            .add('begin')
2376            .add(new TweenMax(this.DOM.revealImg, 0.2, {
2377                ease: Sine.easeOut,
2378                opacity: 0,
2379                x: '-20%'
2380            }), 'begin');
2381        }
2382    }    
2383
2384    // Effect 23
2385    class HoverImgFx23 {
2386        constructor(el) {
2387            this.DOM = {el: el};
2388            
2389            this.DOM.reveal = document.createElement('div');
2390            this.DOM.reveal.className = 'tp-img-reveal-wrapper';
2391            this.totalImages = 15;
2392            let inner = '';
2393            for (let i = 0; i <= this.totalImages-1; ++i) {
2394                inner += `<div class="tp-img-reveal-wrapper__img" style="position: absolute; background-image:url(${this.DOM.el.dataset.img})"><span class="tp-hover-subtitle">
2394${this.DOM.el.dataset.subtitle ? this.DOM.el.dataset.subtitle: ''}</span> <h3 class="tp-hover-title">${this.DOM.el.dataset.title ? this.DOM.el.dataset.title: ''}</h3><p class="tp-hover-desc">${this.DOM.el.dataset.desc ? this.DOM.el.dataset.desc: ''}</p></div>`;
2395            }
2396            this.DOM.reveal.innerHTML = inner;
2397            this.DOM.el.appendChild(this.DOM.reveal);
2398            this.DOM.revealImgs = [...this.DOM.reveal.querySelectorAll('.tp-img-reveal-wrapper__img')];
2399            this.rect = this.DOM.reveal.getBoundingClientRect();
2400            charming(this.DOM.el);
2401            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
2402            this.initEvents();
2403        }
2404        initEvents() {
2405            this.positionElement = (ev) => {
2406                const mousePos = getMousePos(ev);
2407                const docScrolls = {
2408                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
2409                    top : document.body.scrollTop + document.documentElement.scrollTop
2410                };
2411                this.DOM.reveal.style.top = `${mousePos.y-this.rect.height-20-docScrolls.top}px`;
2412                this.DOM.reveal.style.left = `${mousePos.x-this.rect.width-20-docScrolls.left}px`;
2413            };
2414            this.mouseenterFn = (ev) => {
2415                this.positionElement(ev);
2416                this.animateLetters();
2417                this.showImage();
2418            };
2419            this.mousemoveFn = ev => requestAnimationFrame(() => {
2420                this.positionElement(ev);
2421            });
2422            this.mouseleaveFn = () => {
2423                this.hideImage();
2424            };
2425            
2426            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
2427            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
2428            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
2429        }
2430        showImage() {
2431            TweenMax.killTweensOf(this.DOM.revealImgs);
2432            this.tl = new TimelineMax({
2433                onStart: () => {
2434                    this.DOM.reveal.style.opacity = 1;
2435                    TweenMax.set(this.DOM.el, {zIndex: 1000});
2436                }
2437            })
2438            .set(this.DOM.revealImgs, {opacity: 0});
2439
2440            for (let i = 0; i <= this.totalImages-1; ++i) {
2441                TweenMax.set(this.DOM.revealImgs[i], {
2442                    x: `${i*getRandomFloat(-10,10)}%`, 
2443                    y: `${i*getRandomFloat(-15,15)}%`,
2444                    rotation: `${i !== this.totalImages-1 ? getRandomFloat(-7,7) : 0}deg`,
2445                    scale: `${getRandomFloat(0.1,0.5)}`
2446                });
2447                
2448                this.tl.add(new TweenMax(this.DOM.revealImgs[i], i === this.totalImages-1 ? 0.8 : 0.5, {
2449                    ease: i === this.totalImages-1 ? Expo.easeOut : Quint.easeOut,
2450                    startAt: i === this.totalImages-1 ? {opacity: 1, x: '0%', y: '-10%'} : {opacity: 1},
2451                    opacity: i === this.totalImages-1 ? 1 : 0,
2452                    x: i === this.totalImages-1 ? '0%' : null,
2453                    y: i === this.totalImages-1 ? '0%' : null,
2454                    scale: i === this.totalImages-1 ? 1 : 0.6
2455                }), i*0.04);
2456            }
2457        }
2458        hideImage() {
2459            TweenMax.killTweensOf(this.DOM.revealImgs);
2460            this.tl = new TimelineMax({
2461                onStart: () => {
2462                    TweenMax.set(this.DOM.el, {zIndex: 999});
2463                },
2464                onComplete: () => {
2465                    TweenMax.set(this.DOM.el, {zIndex: ''});
2466                    TweenMax.set(this.DOM.reveal, {opacity: 0});
2467                }
2468            })
2469            .add(new TweenMax(this.DOM.revealImgs[this.totalImages-1], 0.15, {
2470                ease: Sine.easeOut,
2471                opacity: 0
2472            }))
2473        }
2474        animateLetters() {
2475            TweenMax.killTweensOf(this.DOM.letters);
2476            this.DOM.letters.forEach((letter) => {
2477                const opts = Math.round(Math.random()) === 0 ? {scale: 0, opacity: 0} : {opacity: 0};
2478                TweenMax.set(letter, opts);
2479            });
2480            TweenMax.to(this.DOM.letters, 1, {
2481                ease: Expo.easeOut,
2482                scale: 1,
2483                opacity: 1
2484            });
2485        }
2486    }
2487    
2488    [...document.querySelectorAll('[data-fx="pt1"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="pt1"]')].forEac
2488h(link => new HoverPTCard1(link));
2489    [...document.querySelectorAll('[data-fx="1"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="1"]')].forEach(link => new HoverImgFx1(link));
2490    [...document.querySelectorAll('[data-fx="2"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="2"]')].forEach(link => new HoverImgFx2(link));
2491    [...document.querySelectorAll('[data-fx="3"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="3"]')].forEach(link => new HoverImgFx3(link));
2492    [...document.querySelectorAll('[data-fx="4"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="4"]')].forEach(link => new HoverImgFx4(link));
2493    [...document.querySelectorAll('[data-fx="5"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="5"]')].forEach(link => new HoverImgFx5(link));
2494    [...document.querySelectorAll('[data-fx="6"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="6"]')].forEach(link => new HoverImgFx6(link));
2495    [...document.querySelectorAll('[data-fx="7"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="7"]')].forEach(link => new HoverImgFx7(link));
2496    [...document.querySelectorAll('[data-fx="8"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="8"]')].forEach(link => new HoverImgFx8(link));
2497    [...document.querySelectorAll('[data-fx="9"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="9"]')].forEach(link => new HoverImgFx9(link));
2498    [...document.querySelectorAll('[data-fx="10"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="10"]')].forEach(link => new HoverImgFx10(link));
2499    [...document.querySelectorAll('[data-fx="11"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="11"]')].forEach(link => new HoverImgFx11(link));
2500    [...document.querySelectorAll('[data-fx="12"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="12"]')].forEach(link => new HoverImgFx12(link));
2501    [...document.querySelectorAll('[data-fx="13"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="13"]')].forEach(link => new HoverImgFx13(link));
2502    [...document.querySelectorAll('[data-fx="14"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="14"]')].forEach(link => new HoverImgFx14(link));
2503    [...document.querySelectorAll('[data-fx="15"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="15"]')].forEach(link => new HoverImgFx15(link));
2504    [...document.querySelectorAll('[data-fx="16"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="16"]')].forEach(link => new HoverImgFx16(link));
2505    [...document.querySelectorAll('[data-fx="17"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="17"]')].forEach(link => new HoverImgFx17(link));
2506    [...document.querySelectorAll('[data-fx="18"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="18"]')].forEach(link => new HoverImgFx18(link));
2507    [...document.querySelectorAll('[data-fx="19"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="19"]')].forEach(link => new HoverImgFx19(link));
2508    [...document.querySelectorAll('[data-fx="20"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="20"]')].forEach(link => new HoverImgFx20(link));
2509    [...document.querySelectorAll('[data-fx="21"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="21"]')].forEach(link => new HoverImgFx21(link));
2510    [...document.querySelectorAll('[data-fx="22"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="22"]')].forEach(link => new HoverImgFx22(link));
2511    [...document.querySelectorAll('[data-fx="23"] > .tp-img-reveal-item, .tp-img-reveal-item[data-fx="23"]')].forEach(link => new HoverImgFx23(link));
2512
2513    const contentel = document.querySelector('.content');
2514    [...document.querySelectorAll('.block__title, .block__link, .content__text-link')].forEach((el) => {
2515        const imgsArr = el.dataset.img.split(',');
2516        const imgsSubtitle = el.dataset.subtitle.split(',');
2517        const imgsTitle = el.dataset.title.split(',');
2518        const imgsDesc = el.dataset.desc.split(',');
2519        const metaDate = el.dataset.metaDate.split(',');
2520        const metaDateLink = el.dataset.metaDateLink.split(',');
2521        const metaAuthor = el.dataset.metaAuthor.split(',');
2522        const metaAuthorLink = el.dataset.metaAuthorLink.split(',');
2523        const metaTag = el.dataset.metaTag.split(',');
2524        const metaTagLink = el.dataset.metaTagLink.split(',');
2525        for (let i = 0, len = imgsArr.length; i <= len-1; ++i ) {
2526            const imgel = document.createElement('img');
2527            imgel.style.visibility = 'hidden';
2528            imgel.style.width = 0;
2529            imgel.src = imgsArr[i];
2530            imgel.className = 'preload';
2531            contentel.appendChild(imgel);
2532        }
2533    });
2534}

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.