Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URLs added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                main
  .message Please try with a pointing device to see the hover effects.
  .frame
    h1.frame__title Image Reveal Hover Effects
    .frame__links
      a(href='https://tympanus.net/codrops/?p=36588') Article
    a.github(href='https://github.com/codrops/ImageRevealHover/') GitHub
  .content
    .block(data-fx='1')
      a.block__title(data-img='https://dl.dropbox.com/s/e8t9h4z1n67m3l6/1.jpg?dl=0') Effect 1
      a.block__link(data-img='https://dl.dropbox.com/s/sdlts324os0comb/2.jpg?dl=0') chloride
      a.block__link(data-img='https://dl.dropbox.com/s/4ndf4l1wvwxc92c/3.jpg?dl=0') magnesium
      a.block__link(data-img='https://dl.dropbox.com/s/a8p3meuom0c5eij/4.jpg?dl=0') zinc
      a.block__link(data-img='https://dl.dropbox.com/s/n1m19i0jt952w3b/5.jpg?dl=0') iodine
    .block(data-fx='2')
      a.block__title(data-img='https://dl.dropbox.com/s/psiwenpcaomfs11/6.jpg?dl=0') Effect 2
      a.block__link(data-img='https://dl.dropbox.com/s/sez2b1c144g0guw/7.jpg?dl=0') Asli
      a.block__link(data-img='https://dl.dropbox.com/s/gaf06q9dbwfz1gd/8.jpg?dl=0') D24
      a.block__link(data-img='https://dl.dropbox.com/s/nycy0vcjez4uyx3/9.jpg?dl=0') Jantung
      a.block__link(data-img='https://dl.dropbox.com/s/vfl1sjsftn2z1c2/10.jpg?dl=0') Tracka
    .block(data-fx='3')
      a.block__title(data-img='https://dl.dropbox.com/s/c06hgxqhr4kigu4/11.jpg?dl=0') Effect 3
      a.block__link(data-img='https://dl.dropbox.com/s/mo9anxu3j8t4544/12.jpg?dl=0') mimas
      a.block__link(data-img='https://dl.dropbox.com/s/q027bxq4css8oxg/13.jpg?dl=0') phobos
      a.block__link(data-img='https://dl.dropbox.com/s/a6zvt6om2ftnbqe/14.jpg?dl=0') lapetus
      a.block__link(data-img='https://dl.dropbox.com/s/p00smzy2g7y1zke/15.jpg?dl=0') titania
    .block(data-fx='4')
      a.block__title(data-img='https://dl.dropbox.com/s/umkoiq8fl8heyhx/16.jpg?dl=0') Effect 4
      a.block__link(data-img='https://dl.dropbox.com/s/kkue8fomfirhxc1/17.jpg?dl=0') Capitate
      a.block__link(data-img='https://dl.dropbox.com/s/0duj75lgr9ek9rx/18.jpg?dl=0') Triquetral
      a.block__link(data-img='https://dl.dropbox.com/s/g38na8nxtacenzd/19.jpg?dl=0') scaphoid
      a.block__link(data-img='https://dl.dropbox.com/s/8iqw06dl5gxh5yw/20.jpg?dl=0') Hamate
    .block(data-fx='5')
      a.block__title(data-img='https://dl.dropbox.com/s/8fp0rkpbcjr0prn/21.jpg?dl=0') Effect 5
      a.block__link(data-img='https://dl.dropbox.com/s/zipvm0b8960y4pt/22.jpg?dl=0') stratus
      a.block__link(data-img='https://dl.dropbox.com/s/el4mlkh21syskfo/23.jpg?dl=0') cirrus
      a.block__link(data-img='https://dl.dropbox.com/s/37adrhtexo428p6/24.jpg?dl=0') nimbus
      a.block__link(data-img='https://dl.dropbox.com/s/k7rwbg406gcx9xn/25.jpg?dl=0') cumulus
    .block(data-fx='6')
      a.block__title(data-img='https://dl.dropbox.com/s/7fpc7z0q4zzmut6/26.jpg?dl=0') Effect 6
      a.block__link(data-img='https://dl.dropbox.com/s/h7s03e57me8apz1/27.jpg?dl=0') king's quest
      a.block__link(data-img='https://dl.dropbox.com/s/gji5s2bdftmlqwh/28.jpg?dl=0') asteroids
      a.block__link(data-img='https://dl.dropbox.com/s/oah7qxlut3deemc/29.jpg?dl=0') centipede
      a.block__link(data-img='https://dl.dropbox.com/s/5i0bydzvxut3ryy/30.jpg?dl=0') defender
    .block(data-fx='7')
      a.block__title(data-img='https://dl.dropbox.com/s/uk3mob7yn9p7poo/31.jpg?dl=0') Effect 7
      a.block__link(data-img='https://dl.dropbox.com/s/rr3vw9fnrpzi7w8/32.jpg?dl=0') Jerry
      a.block__link(data-img='https://dl.dropbox.com/s/nspn50d8sesxmo7/33.jpg?dl=0') Michael
      a.block__link(data-img='https://dl.dropbox.com/s/sjmnkkclbsr78vz/34.jpg?dl=0') Jason
      a.block__link(data-img='https://dl.dropbox.com/s/xkuoufu04pdtbwl/35.jpg?dl=0') Julia
    .block(data-fx='8')
      a.block__title(data-img='https://dl.dropbox.com/s/b4m0qq2vdjzl5e7/36.jpg?dl=0') Effect 8
      a.block__link(data-img='https://dl.dropbox.com/s/a6zvt6om2ftnbqe/14.jpg?dl=0') Mistral
      a.block__link(data-img='https://dl.dropbox.com/s/cgteodx18533y54/38.jpg?dl=0') Sirocco
      a.block__link(data-img='https://dl.dropbox.com/s/g7edi3h7xv66uh9/39.jpg?dl=0') Khamseen
      a.block__link(data-img='https://dl.dropbox.com/s/6jz1k3vttoev8b3/40.jpg?dl=0') Brickfielder
    .block(data-fx='9')
      a.block__title(data-img='https://dl.dropbox.com/s/qh6h5kw2kl5xpgo/41.jpg?dl=0') Effect 9
      a.block__link(data-img='https://dl.dropbox.com/s/savbvtp03bq96xe/42.jpg?dl=0') Quechan
      a.block__link(data-img='https://dl.dropbox.com/s/e8t9h4z1n67m3l6/1.jpg?dl=0') Chemehuevi
      a.block__link(data-img='https://dl.dropbox.com/s/sdlts324os0comb/2.jpg?dl=0') Meskwaki
      a.block__link(data-img='https://dl.dropbox.com/s/4ndf4l1wvwxc92c/3.jpg?dl=0') Ponca
    .block(data-fx='10')
      a.block__title(data-img='https://dl.dropbox.com/s/a8p3meuom0c5eij/4.jpg?dl=0') Effect 10
      a.block__link(data-img='https://dl.dropbox.com/s/n1m19i0jt952w3b/5.jpg?dl=0') Dugbe
      a.block__link(data-img='https://dl.dropbox.com/s/psiwenpcaomfs11/6.jpg?dl=0') Lordsdale
      a.block__link(data-img='https://dl.dropbox.com/s/sez2b1c144g0guw/7.jpg?dl=0') Sindbis
      a.block__link(data-img='https://dl.dropbox.com/s/gaf06q9dbwfz1gd/8.jpg?dl=0') Cowpox
    .block(data-fx='11')
      a.block__title(data-img='https://dl.dropbox.com/s/nycy0vcjez4uyx3/9.jpg?dl=0') Effect 11
      a.block__link(data-img='https://dl.dropbox.com/s/vfl1sjsftn2z1c2/10.jpg?dl=0') Celuk
      a.block__link(data-img='https://dl.dropbox.com/s/c06hgxqhr4kigu4/11.jpg?dl=0') Batuan
      a.block__link(data-img='https://dl.dropbox.com/s/mo9anxu3j8t4544/12.jpg?dl=0') Trunyan
      a.block__link(data-img='https://dl.dropbox.com/s/q027bxq4css8oxg/13.jpg?dl=0') Mas
    .block(data-fx='12')
      a.block__title(data-img='https://dl.dropbox.com/s/a6zvt6om2ftnbqe/14.jpg?dl=0') Effect 12
      a.block__link(data-img='https://dl.dropbox.com/s/p00smzy2g7y1zke/15.jpg?dl=0') bahuk
      a.block__link(data-img='https://dl.dropbox.com/s/umkoiq8fl8heyhx/16.jpg?dl=0') godiva
      a.block__link(data-img='https://dl.dropbox.com/s/kkue8fomfirhxc1/17.jpg?dl=0') lepanto
      a.block__link(data-img='https://dl.dropbox.com/s/0duj75lgr9ek9rx/18.jpg?dl=0') pierrot
    .block(data-fx='13')
      a.block__title(data-img='https://dl.dropbox.com/s/g38na8nxtacenzd/19.jpg?dl=0') Effect 13
      a.block__link(data-img='https://dl.dropbox.com/s/8iqw06dl5gxh5yw/20.jpg?dl=0') Howard
      a.block__link(data-img='https://dl.dropbox.com/s/8fp0rkpbcjr0prn/21.jpg?dl=0') Penny
      a.block__link(data-img='https://dl.dropbox.com/s/zipvm0b8960y4pt/22.jpg?dl=0') Leonard
      a.block__link(data-img='https://dl.dropbox.com/s/el4mlkh21syskfo/23.jpg?dl=0') Raj
    .block(data-fx='14')
      a.block__title(data-img='https://dl.dropbox.com/s/psiwenpcaomfs11/6.jpg?dl=0,https://dl.dropbox.com/s/nycy0vcjez4uyx3/9.jpg?dl=0,https://dl.dropbox.com/s/gaf06q9dbwfz1gd/8.jpg?dl=0') Effect 14
      a.block__link(data-img='https://dl.dropbox.com/s/n1m19i0jt952w3b/5.jpg?dl=0,https://dl.dropbox.com/s/a8p3meuom0c5eij/4.jpg?dl=0,https://dl.dropbox.com/s/c06hgxqhr4kigu4/11.jpg?dl=0') Khufu
      a.block__link(data-img='https://dl.dropbox.com/s/mo9anxu3j8t4544/12.jpg?dl=0,https://dl.dropbox.com/s/q027bxq4css8oxg/13.jpg?dl=0,https://dl.dropbox.com/s/a6zvt6om2ftnbqe/14.jpg?dl=0') Hatshepsut
      a.block__link(data-img='https://dl.dropbox.com/s/kkue8fomfirhxc1/17.jpg?dl=0,https://dl.dropbox.com/s/umkoiq8fl8heyhx/16.jpg?dl=0,https://dl.dropbox.com/s/p00smzy2g7y1zke/15.jpg?dl=0') Tutankhamun
      a.block__link(data-img='https://dl.dropbox.com/s/g38na8nxtacenzd/19.jpg?dl=0,https://dl.dropbox.com/s/8iqw06dl5gxh5yw/20.jpg?dl=0,https://dl.dropbox.com/s/e8t9h4z1n67m3l6/1.jpg?dl=0') Djoser
    .block(data-fx='15')
      a.block__title(data-img='https://dl.dropbox.com/s/37adrhtexo428p6/24.jpg?dl=0') Effect 15
      a.block__link(data-img='https://dl.dropbox.com/s/k7rwbg406gcx9xn/25.jpg?dl=0') Nyman
      a.block__link(data-img='https://dl.dropbox.com/s/7fpc7z0q4zzmut6/26.jpg?dl=0') Einaudi
      a.block__link(data-img='https://dl.dropbox.com/s/h7s03e57me8apz1/27.jpg?dl=0') Glass
      a.block__link(data-img='https://dl.dropbox.com/s/gji5s2bdftmlqwh/28.jpg?dl=0') Paterlini
    .block(data-fx='16')
      a.block__title(data-img='https://dl.dropbox.com/s/oah7qxlut3deemc/29.jpg?dl=0') Effect 16
      a.block__link(data-img='https://dl.dropbox.com/s/5i0bydzvxut3ryy/30.jpg?dl=0') Shankill
      a.block__link(data-img='https://dl.dropbox.com/s/uk3mob7yn9p7poo/31.jpg?dl=0') Lombard
      a.block__link(data-img='https://dl.dropbox.com/s/rr3vw9fnrpzi7w8/32.jpg?dl=0') Downing
      a.block__link(data-img='https://dl.dropbox.com/s/nspn50d8sesxmo7/33.jpg?dl=0') Khao San
    .block(data-fx='17')
      a.block__title(data-img='https://dl.dropbox.com/s/sjmnkkclbsr78vz/34.jpg?dl=0') Effect 17
      a.block__link(data-img='https://dl.dropbox.com/s/xkuoufu04pdtbwl/35.jpg?dl=0') Chabrier
      a.block__link(data-img='https://dl.dropbox.com/s/b4m0qq2vdjzl5e7/36.jpg?dl=0') Bax
      a.block__link(data-img='https://dl.dropbox.com/s/1mhyepvwl6mka2p/37.jpg?dl=0') Mompou
      a.block__link(data-img='https://dl.dropbox.com/s/cgteodx18533y54/38.jpg?dl=0') Sibelius
    .block(data-fx='18')
      a.block__title(data-img='https://dl.dropbox.com/s/g7edi3h7xv66uh9/39.jpg?dl=0') Effect 18
      a.block__link(data-img='https://dl.dropbox.com/s/6jz1k3vttoev8b3/40.jpg?dl=0') Argelia
      a.block__link(data-img='https://dl.dropbox.com/s/qh6h5kw2kl5xpgo/41.jpg?dl=0') Guamal
      a.block__link(data-img='https://dl.dropbox.com/s/savbvtp03bq96xe/42.jpg?dl=0') Montecristo
      a.block__link(data-img='https://dl.dropbox.com/s/e8t9h4z1n67m3l6/1.jpg?dl=0') Guatavita
    .block(data-fx='19')
      a.block__title(data-img='https://dl.dropbox.com/s/vfl1sjsftn2z1c2/10.jpg?dl=0') Effect 19
      a.block__link(data-img='https://dl.dropbox.com/s/p00smzy2g7y1zke/15.jpg?dl=0') Buretsu
      a.block__link(data-img='https://dl.dropbox.com/s/8iqw06dl5gxh5yw/20.jpg?dl=0') Genmei
      a.block__link(data-img='https://dl.dropbox.com/s/k7rwbg406gcx9xn/25.jpg?dl=0') Murakami
      a.block__link(data-img='https://dl.dropbox.com/s/5i0bydzvxut3ryy/30.jpg?dl=0') Juntoku
    .block(data-fx='20')
      a.block__title(data-img='https://dl.dropbox.com/s/sdlts324os0comb/2.jpg?dl=0') Effect 20
      a.block__link(data-img='https://dl.dropbox.com/s/psiwenpcaomfs11/6.jpg?dl=0') Akira
      a.block__link(data-img='https://dl.dropbox.com/s/0duj75lgr9ek9rx/18.jpg?dl=0') Dex
      a.block__link(data-img='https://dl.dropbox.com/s/mo9anxu3j8t4544/12.jpg?dl=0') Slave Zero
      a.block__link(data-img='https://dl.dropbox.com/s/37adrhtexo428p6/24.jpg?dl=0') Ruiner
    .block(data-fx='21')
      a.block__title(data-img='https://dl.dropbox.com/s/kkue8fomfirhxc1/17.jpg?dl=0') Effect 21
      a.block__link(data-img='https://dl.dropbox.com/s/7fpc7z0q4zzmut6/26.jpg?dl=0') Intellivision
      a.block__link(data-img='https://dl.dropbox.com/s/a8p3meuom0c5eij/4.jpg?dl=0') Saturn
      a.block__link(data-img='https://dl.dropbox.com/s/gaf06q9dbwfz1gd/8.jpg?dl=0') Odyssey
      a.block__link(data-img='https://dl.dropbox.com/s/g38na8nxtacenzd/19.jpg?dl=0') GameCube
    .block(data-fx='22')
      a.block__title(data-img='https://dl.dropbox.com/s/a6zvt6om2ftnbqe/14.jpg?dl=0') Effect 22
      a.block__link(data-img='https://dl.dropbox.com/s/4ndf4l1wvwxc92c/3.jpg?dl=0') Flores
      a.block__link(data-img='https://dl.dropbox.com/s/oah7qxlut3deemc/29.jpg?dl=0') Komodo
      a.block__link(data-img='https://dl.dropbox.com/s/1mhyepvwl6mka2p/37.jpg?dl=0') Nias
      a.block__link(data-img='https://dl.dropbox.com/s/6jz1k3vttoev8b3/40.jpg?dl=0') Buru
    .block(data-fx='23')
      a.block__title(data-img='https://dl.dropbox.com/s/c06hgxqhr4kigu4/11.jpg?dl=0') Effect 23
      a.block__link(data-img='https://dl.dropbox.com/s/8fp0rkpbcjr0prn/21.jpg?dl=0') Edinburgh
      a.block__link(data-img='https://dl.dropbox.com/s/gji5s2bdftmlqwh/28.jpg?dl=0') Sydney
      a.block__link(data-img='https://dl.dropbox.com/s/nycy0vcjez4uyx3/9.jpg?dl=0') Hong Kong
      a.block__link(data-img='https://dl.dropbox.com/s/q027bxq4css8oxg/13.jpg?dl=0') Berlin
    .content__text
      | All you have to learn here is how to have 
      a.content__text-link(data-img='https://dl.dropbox.com/s/savbvtp03bq96xe/42.jpg?dl=0' data-fx='1') fun
      | . It's almost like something out of a 
      a.content__text-link(data-img='https://dl.dropbox.com/s/6jz1k3vttoev8b3/40.jpg?dl=0' data-fx='2') fairytale
      |  book. Almost everything is going to happen for you automatically - you don't have to spend any time 
      a.content__text-link(data-img='https://dl.dropbox.com/s/cgteodx18533y54/38.jpg?dl=0' data-fx='3') working
      |  or worrying. Take your 
      a.content__text-link(data-img='https://dl.dropbox.com/s/b4m0qq2vdjzl5e7/36.jpg?dl=0' data-fx='4') time
      | . Speed will come later. A thin paint will stick to a 
      a.content__text-link(data-img='https://dl.dropbox.com/s/sjmnkkclbsr78vz/34.jpg?dl=0' data-fx='5') thick
      |  paint. There comes a nice little 
      a.content__text-link(data-img='https://dl.dropbox.com/s/rr3vw9fnrpzi7w8/32.jpg?dl=0' data-fx='6') fluffer
      | .
      | 					You can create the 
      a.content__text-link(data-img='https://dl.dropbox.com/s/5i0bydzvxut3ryy/30.jpg?dl=0' data-fx='7') world
      |  you want to see and be a part of. You have that 
      a.content__text-link(data-img='https://dl.dropbox.com/s/gji5s2bdftmlqwh/28.jpg?dl=0' data-fx='8') power
      | . Don't forget to tell these special 
      a.content__text-link(data-img='https://dl.dropbox.com/s/7fpc7z0q4zzmut6/26.jpg?dl=0' data-fx='9') people
      |  in your life just how special they are to 
      a.content__text-link(data-img='https://dl.dropbox.com/s/37adrhtexo428p6/24.jpg?dl=0' data-fx='10') you
      | . Let's build an almighty 
      a.content__text-link(data-img='https://dl.dropbox.com/s/zipvm0b8960y4pt/22.jpg?dl=0' data-fx='11') mountain
      | . Isn't that fantastic that you can create an almighty 
      a.content__text-link(data-img='https://dl.dropbox.com/s/n1m19i0jt952w3b/5.jpg?dl=0' data-fx='12') tree
      |  that fast? The only 
      a.content__text-link(data-img='https://dl.dropbox.com/s/8iqw06dl5gxh5yw/20.jpg?dl=0' data-fx='13') prerequisite
      |  is that it makes you happy. If it makes you happy then it's good.
      | 					This is your 
      a.content__text-link(data-img='https://dl.dropbox.com/s/0duj75lgr9ek9rx/18.jpg?dl=0,https://dl.dropbox.com/s/umkoiq8fl8heyhx/16.jpg?dl=0,https://dl.dropbox.com/s/a6zvt6om2ftnbqe/14.jpg?dl=0' data-fx='14') creation
      |  - and it's just as unique and 
      a.content__text-link(data-img='https://dl.dropbox.com/s/mo9anxu3j8t4544/12.jpg?dl=0' data-fx='15') special
      |  as you are. Decide where your 
      a.content__text-link(data-img='https://dl.dropbox.com/s/4ndf4l1wvwxc92c/3.jpg?dl=0' data-fx='16') cloud
      |  lives. Maybe he lives right in 
      a.content__text-link(data-img='https://dl.dropbox.com/s/sdlts324os0comb/2.jpg?dl=0' data-fx='17') here
      | . You have to make those little 
      a.content__text-link(data-img='https://dl.dropbox.com/s/e8t9h4z1n67m3l6/1.jpg?dl=0' data-fx='18') noises
      |  or it won't 
      a.content__text-link(data-img='https://dl.dropbox.com/s/qh6h5kw2kl5xpgo/41.jpg?dl=0' data-fx='19') work
      | . Just go 
      a.content__text-link(data-img='https://dl.dropbox.com/s/nspn50d8sesxmo7/33.jpg?dl=0' data-fx='20') out
      |  and talk to a tree. Make 
      a.content__text-link(data-img='https://dl.dropbox.com/s/g7edi3h7xv66uh9/39.jpg?dl=0' data-fx='21') friends
      |  with it. This is 
      a.content__text-link(data-img='https://dl.dropbox.com/s/1mhyepvwl6mka2p/37.jpg?dl=0' data-fx='22') truly
      |  an almighty 
      a.content__text-link(data-img='https://dl.dropbox.com/s/xkuoufu04pdtbwl/35.jpg?dl=0' data-fx='23') mountain
      | .

              
            
!

CSS

              
                /**
 * demo.js
 * http://www.codrops.com
 *
 * Licensed under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 * 
 * Copyright 2018, Codrops
 * http://www.codrops.com
 */
//https://github.com/codrops/ImageRevealHover/
//https://tympanus.net/codrops/2018/11/27/image-reveal-hover-effects/

.tp-dfwv {
  position: fixed !important;
}

article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block;}audio,canvas,video{display:inline-block;}audio:not([controls]){display:none;height:0;}[hidden]{display:none;}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;}body{margin:0;}a:focus{outline:thin dotted;}a:active,a:hover{outline:0;}h1{font-size:2em;margin:0.67em 0;}abbr[title]{border-bottom:1px dotted;}b,strong{font-weight:bold;}dfn{font-style:italic;}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0;}mark{background:#ff0;color:#000;}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em;}pre{white-space:pre-wrap;}q{quotes:"\201C" "\201D" "\2018" "\2019";}small{font-size:80%;}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sup{top:-0.5em;}sub{bottom:-0.25em;}img{border:0;}svg:not(:root){overflow:hidden;}figure{margin:0;}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em;}legend{border:0;padding:0;}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;}button,input{line-height:normal;}button,select{text-transform:none;}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}button[disabled],html input[disabled]{cursor:default;}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}textarea{overflow:auto;vertical-align:top;}table{border-collapse:collapse;border-spacing:0;}
*,
*::after,
*::before {
	box-sizing: border-box;
}

:root {
	font-size: 16px;
}

body {
	--color-text: #fff;
	--color-bg: #181a1e;
	--color-link: #fff;
	--color-link-hover: #ffcbd6;
	--color-blocklink: #515151;
	--color-blocklink-hover: #fff;
	--color-blocktitle: #fff;
	--color-blocktitle-hover: #ff4081;
	--color-text: #767676;
	font-family: titling-gothic-fb, sans-serif;
	min-height: 100vh;
	color: #57585c;
	color: var(--color-text);
	background-color: #fff;
	background-color: var(--color-bg);
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

/* Page Loader */
.js .loading::before {
	content: '';
	position: fixed;
	z-index: 100000;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background: var(--color-bg);
}

.js .loading::after {
	content: '';
	position: fixed;
	z-index: 100000;
	top: 50%;
	left: 50%;
	width: 60px;
	height: 60px;
	margin: -30px 0 0 -30px;
	pointer-events: none;
	border-radius: 50%;
	opacity: 0.4;
	background: var(--color-link);
	animation: loaderAnim 0.7s linear infinite alternate forwards;
}

@keyframes loaderAnim {
	to {
		opacity: 1;
		transform: scale3d(0.5,0.5,1);
	}
}


a {
	text-decoration: none;
	color: var(--color-link);
	outline: none;
}

a:hover,
a:focus {
	color: var(--color-link-hover);
}

button:focus,
a:focus {
	outline: none;
}

main {
	position: relative;
	width: 100%;
}

.message {
	background: #e47073;
	color: #fff;
	padding: 1rem;
}

.frame {
	padding: 3rem 5vw;
	text-align: center;
	font-size: 0.8rem;
}

.frame__title {
	font-size: inherit;
	margin: 0 0 1rem;
	font-weight: normal;
}

.frame__links {
	display: inline;
}

.frame__links a {
	text-transform: lowercase;
}

.frame__links a:not(:last-child) {
	margin-right: 1rem;
}

.github {
	text-transform: lowercase;
	margin-left: 1rem;
}

.block {
	text-transform: lowercase;
	padding: 0 4rem 20vh;
	display: flex;
	flex-direction: column;
	align-items: center;
}

.block__title {
	position: relative;
	font-size: 1rem;
	margin: 0 0 1.5rem 0;
	padding: 0.5rem 0;
	cursor: pointer;
	font-family: titling-gothic-fb-wide, sans-serif;
	font-weight: 700;
	color: var(--color-blocktitle);
}

.block__title:hover {
	color: var(--color-blocktitle-hover);
}

.block__link {
	position: relative;
	cursor: pointer;
	padding: 0.5rem;
	color: var(--color-blocklink);
}

.block__link:hover {
	color: var(--color-blocklink-hover);
}

.block__title span,
.block__link span,
.content__text-link span {
	display: inline-block;
	white-space: pre;
}

.content__text {
	padding: 0 5vw 25vh;
	line-height: 2;
	color: var(--color-text);
}

.content__text-link {
	position: relative;
	font-weight: bold;
	cursor: pointer;
}

.content__text-link:first-of-type,
.content__text-link:nth-of-type(11),
.content__text-link:nth-of-type(21) {
	color: #f7e300;
}

.content__text-link:nth-of-type(2),
.content__text-link:nth-of-type(12),
.content__text-link:nth-of-type(22) {
	color: #002df7;
}

.content__text-link:nth-of-type(3),
.content__text-link:nth-of-type(13),
.content__text-link:nth-of-type(23) {
	color: #e51679;
}

.content__text-link:nth-of-type(4),
.content__text-link:nth-of-type(14) {
	color: #fff;
}

.content__text-link:nth-of-type(5),
.content__text-link:nth-of-type(15) {
	color: #00f73d;
}

.content__text-link:nth-of-type(6),
.content__text-link:nth-of-type(16) {
	color: #00e8f7;
}

.content__text-link:nth-of-type(7),
.content__text-link:nth-of-type(17) {
	color: #a753eb;
}

.content__text-link:nth-of-type(8),
.content__text-link:nth-of-type(18) {
	color: #ff2626;
}

.content__text-link:nth-of-type(9),
.content__text-link:nth-of-type(19) {
	color: #eb8e53;
}

.content__text-link:nth-of-type(10),
.content__text-link:nth-of-type(20) {
	color: #ff00e7;
}

.block[data-fx="1"] a::after,
a.content__text-link[data-fx="1"]::after,
.block[data-fx="2"] a::after,
a.content__text-link[data-fx="2"]::after {
	content: '';
	z-index: -1;
	width: 100%;
	bottom: 0.25rem;
	left: 0;
	position: absolute;
	height: 2px;
	background: currentColor;
	transform: scale3d(0,1,1);
	transform-origin: 0% 50%;
	transition: transform 0.2s cubic-bezier(0.390, 0.575, 0.565, 1.000);
}

a.content__text-link[data-fx="1"]::after,
a.content__text-link[data-fx="2"]::after {
	bottom: 0;
}

.block[data-fx="1"] a:hover::after,
a.content__text-link[data-fx="1"]:hover::after,
.block[data-fx="2"] a:hover::after,
a.content__text-link[data-fx="2"]:hover::after {
	transform: scale3d(1,1,1)
}

.block[data-fx="6"] a::after,
a.content__text-link[data-fx="6"]::after {
	content: '';
	z-index: -1;
	width: 100%;
	bottom: 0.25rem;
	left: 0;
	position: absolute;
	height: 2px;
	background: currentColor;
	transform: scale3d(0,1,1);
	transform-origin: 100% 50%;
	transition: transform 0.7s cubic-bezier(0.860, 0.000, 0.070, 1.000);
}

a.content__text-link[data-fx="6"]::after {
	bottom: 0;
}

.block[data-fx="6"] a:hover::after,
a.content__text-link[data-fx="6"]:hover::after {
	transform: scale3d(1,1,1)
}

.block[data-fx="14"] a::after,
a.content__text-link[data-fx="14"]::after {
	content: '';
	z-index: -1;
	width: 100%;
	bottom: 0.25rem;
	left: 0;
	position: absolute;
	height: 2px;
	background: currentColor;
	transform: scale3d(0,1,1);
	transform-origin: 0% 50%;
}

a.content__text-link[data-fx="14"]::after {
	bottom: 0;
}

.block[data-fx="14"] a:hover::after,
a.content__text-link[data-fx="14"]:hover::after {
	animation: loop 0.5s infinite;
}

@keyframes loop {
	0% { transform-origin: 0% 50%; transform: scale3d(0,1,1); }
	50% { transform-origin: 0% 50%; transform: scale3d(1,1,1); }
	51% { transform-origin: 100% 50%; }
	100% { transform-origin: 100% 50%; transform: scale3d(0,1,1); }
}

.hover-reveal {
	position: fixed;
	width: 200px;
	height: 150px;
	top: 0;
	left: 0;
	pointer-events: none;
	opacity: 0;
}

.hover-reveal__inner,
.hover-reveal__img {
	width: 100%;
	height: 100%;
	position: relative;
}

.hover-reveal__deco {
	width: 100%;
	height: 100%;
	position: absolute;
	top: 0;
	left: 0;
	background-color: #181314;
}

.hover-reveal__img {
	background-size: cover;
	background-position: 50% 50%;
}

@media screen and (min-width: 53em) {
	.message {
		display: none;
	}
	.frame {
		position: fixed;
		text-align: left;
		z-index: 10000;
		top: 0;
		left: 0;
		display: grid;
		align-content: space-between;
		width: 100%;
		max-width: none;
		height: 100vh;
		padding: 2rem;
		pointer-events: none;
		grid-template-columns: 50% 50%;
		grid-template-rows: auto auto auto;
		grid-template-areas: 'title links'
							'... ...'
							'... github';
	}
	.frame__title {
		grid-area: title;
		padding: 0;
	}
	.frame__links {
    grid-area: github;
    padding: 0;
    justify-self: end;
    margin-top: -20px;
		// grid-area: links;
		// padding: 0;
		// justify-self: end;
	}
	.github {
		grid-area: github;
		justify-self: end;
		margin: 0;
	}
	.frame a {
		pointer-events: auto;
	}
	.block {
		align-items: flex-start;
	}
	.content {
		position: relative;
		display: grid;
		grid-template-columns: repeat(3,33.33%);
		margin: 0 auto;
		padding-top: 20vh;
		max-width: 750px;
		min-height: 100vh;
		text-align: left;
	}
	.content__text {
		grid-column: span 3;
	}
}
              
            
!

JS

              
                console.clear()
import imagesLoaded from "https://cdn.skypack.dev/[email protected]";
import charming from "https://cdn.skypack.dev/[email protected]";
import {Pane} from "https://cdn.skypack.dev/[email protected]";
import * as EssentialsPlugin from "https://cdn.skypack.dev/@tweakpane/[email protected]"

/**
* set tweakpane
*/
const PARAMS = {
  useDefaultVal: true,
  duration: 0.88,
  cubicBezier: true,
  ease: 'Power2.easeOut',
};

const pane = new Pane()
pane.registerPlugin(EssentialsPlugin)

pane.addInput(PARAMS, 'useDefaultVal')
pane.addInput(PARAMS, 'duration', {
  min: 0.2, max: 3.0,
})

pane.addInput(PARAMS, 'cubicBezier')

const cubicBezier = pane.addBlade({
  view: 'cubicbezier',
  value: [0.2, 1.0, 0.25, 1.0],

  expanded: true,
  label: 'cubicBezier',
  picker: 'inline',
})

let ceVal = CustomEase.create("CustomEase", 
      cubicBezier.value.comps_[0] + ',' +
      cubicBezier.value.comps_[1] + ',' +
      cubicBezier.value.comps_[2] + ',' +
      cubicBezier.value.comps_[3] + ','
    )

pane.addInput(PARAMS, 'ease', {
  options: {
    'Strong.easeInOut': 'Strong.easeInOut',
    'Linear.easeNone': 'Linear.easeNone',
    'Power0.easeIn': 'Power0.easeIn',
    'Power1.easeIn': 'Power1.easeIn',
    'Power2.easeIn': 'Power2.easeIn',
    'Power3.easeIn': 'Power3.easeIn',
    'Power4.easeIn': 'Power4.easeIn',
    'Quad.easeIn': 'Quad.easeIn',
    'Cubic.easeIn': 'Cubic.easeIn',
    'Quart.easeIn': 'Quart.easeIn',
    'Quint.easeIn': 'Quint.easeIn',
    'Power0.easeOut': 'Power0.easeOut',
    'Power1.easeOut': 'Power1.easeOut',
    'Power2.easeOut': 'Power2.easeOut',
    'Power3.easeOut': 'Power3.easeOut',
    'Power4.easeOut': 'Power4.easeOut',
    'Quad.easeOut': 'Quad.easeOut',
    'Cubic.easeOut': 'Cubic.easeOut',
    'Quart.easeOut': 'Quart.easeOut',
    'Quint.easeOut': 'Quint.easeOut',
    'Elastic.easeOut': 'Elastic.easeOut',
    'Back.easeOut': 'Back.easeOut',
    'Bounce.easeOut': 'Bounce.easeOut',
    'SlowMo.easeOut': 'SlowMo.easeOut',
    'SteppedEase.easeOut': 'SteppedEase.easeOut',
    'Circ.easeOut': 'Circ.easeOut',
    'Expo.easeOut': 'Expo.easeOut',
    'Sine.easeOut': 'Sine.easeOut',
    'Power0.easeInOut': 'Power0.easeInOut',
    'Power1.easeInOut': 'Power1.easeInOut',
    'Power2.easeInOut': 'Power2.easeInOut',
    'Power3.easeInOut': 'Power3.easeInOut',
    'Power4.easeInOut': 'Power4.easeInOut',
    'Quad.easeInOut': 'Quad.easeInOut',
    'Cubic.easeInOut': 'Cubic.easeInOut',
    'Quart.easeInOut': 'Quart.easeInOut',
    'Quint.easeInOut': 'Quint.easeInOut',
    'Elastic.easeInOut': 'Elastic.easeInOut',
    'Back.easeInOut': 'Back.easeInOut',
    'Bounce.easeInOut': 'Bounce.easeInOut',
    'SlowMo.easeInOut': 'SlowMo.easeInOut',
    'SteppedEase.easeInOut': 'SteppedEase.easeInOut',
    'Circ.easeInOut': 'Circ.easeInOut',
    'Expo.easeInOut': 'Expo.easeInOut',
    'Sine.easeInOut': 'Sine.easeInOut'
  }}
)

/**
 * demo.js
 * http://www.codrops.com
 *
 * Licensed under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 * 
 * Copyright 2018, Codrops
 * http://www.codrops.com
 */
//https://github.com/codrops/ImageRevealHover/
//https://tympanus.net/codrops/2018/11/27/image-reveal-hover-effects/
{
    const mapNumber = (X,A,B,C,D) => (X-A)*(D-C)/(B-A)+C;
    // from http://www.quirksmode.org/js/events_properties.html#position
	const getMousePos = (e) => {
        let posx = 0;
        let posy = 0;
		if (!e) e = window.event;
		if (e.pageX || e.pageY) {
            posx = e.pageX;
			posy = e.pageY;
		}
		else if (e.clientX || e.clientY) 	{
			posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
			posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
		}
        return { x : posx, y : posy }
    }
    // Generate a random float.
    const getRandomFloat = (min, max) => (Math.random() * (max - min) + min).toFixed(2);

    /**
     * One class per effect. 
     * Lots of code is repeated, so that single effects can be easily used. 
     */

    // Effect 1
    class HoverImgFx1 {
        constructor(el) {
            this.DOM = {el: el};
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'hover-reveal';
            this.DOM.reveal.innerHTML = `<div class="hover-reveal__inner"><div class="hover-reveal__img" style="background-image:url(${this.DOM.el.dataset.img})"></div></div>`;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealInner = this.DOM.reveal.querySelector('.hover-reveal__inner');
            this.DOM.revealInner.style.overflow = 'hidden';
            this.DOM.revealImg = this.DOM.revealInner.querySelector('.hover-reveal__img');

            this.initEvents();
        }
        initEvents() {
            this.positionElement = (ev) => {
                const mousePos = getMousePos(ev);
                const docScrolls = {
                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
                    top : document.body.scrollTop + document.documentElement.scrollTop
                };
                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
            };
            this.mouseenterFn = (ev) => {
                this.positionElement(ev);
                this.showImage();
            };
            this.mousemoveFn = ev => requestAnimationFrame(() => {
                this.positionElement(ev);
            });
            this.mouseleaveFn = () => {
                this.hideImage();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
        }
        showImage() {
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealImg);

            this.tl = new gsap.timeline({
                onStart: () => {
                    this.DOM.reveal.style.opacity = 1;
                    gsap.set(this.DOM.el, {zIndex: 1000});
                }
            })
            .add('begin')
            .add(gsap.to(this.DOM.revealInner, PARAMS.useDefaultVal ? 0.2 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease, 
                startAt: {x: '-100%'},
                x: '0%'
            }), 'begin')
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.2 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease, 
                startAt: {x: '100%'},
                x: '0%'
            }), 'begin');
        }
        hideImage() {
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealImg);

            this.tl = new gsap.timeline({
                onStart: () => {
                    gsap.set(this.DOM.el, {zIndex: 999});
                },
                onComplete: () => {
                    gsap.set(this.DOM.el, {zIndex: ''});
                    gsap.set(this.DOM.reveal, {opacity: 0});
                }
            })
            .add('begin')
            .add(gsap.to(this.DOM.revealInner, PARAMS.useDefaultVal ? 0.2 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease,
                x: '100%'
            }), 'begin')
            
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.2 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease,
                x: '-100%'
            }), 'begin');
        }
    }

    // Effect 2
    class HoverImgFx2 {
        constructor(el) {
            this.DOM = {el: el};
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'hover-reveal';
            this.DOM.reveal.innerHTML = `<div class="hover-reveal__inner"><div class="hover-reveal__img" style="background-image:url(${this.DOM.el.dataset.img})"></div></div>`;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealInner = this.DOM.reveal.querySelector('.hover-reveal__inner');
            this.DOM.revealInner.style.overflow = 'hidden';
            this.DOM.revealImg = this.DOM.revealInner.querySelector('.hover-reveal__img');

            this.initEvents();
        }
        initEvents() {
            this.positionElement = (ev) => {
                const mousePos = getMousePos(ev);
                const docScrolls = {
                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
                    top : document.body.scrollTop + document.documentElement.scrollTop
                };
                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
            };
            this.mouseenterFn = (ev) => {
                this.positionElement(ev);
                this.showImage();
            };
            this.mousemoveFn = ev => requestAnimationFrame(() => {
                this.positionElement(ev);
            });
            this.mouseleaveFn = () => {
                this.hideImage();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
        }
        showImage() {
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealImg);

            this.tl = new gsap.timeline({
                onStart: () => {
                    this.DOM.reveal.style.opacity = 1;
                    gsap.set(this.DOM.el, {zIndex: 1000});
                }
            })
            .add('begin')
            .add(gsap.to(this.DOM.revealInner, PARAMS.useDefaultVal ? 0.4 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Quint.easeOut : PARAMS.ease,
                startAt: {x: '-100%', y: '-100%'},
                x: '0%',
                y: '0%'
            }), 'begin')
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.4 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Quint.easeOut : PARAMS.ease,
                startAt: {x: '100%', y: '100%'},
                x: '0%',
                y: '0%'
            }), 'begin');
        }
        hideImage() {
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealImg);

            this.tl = new gsap.timeline({
                onStart: () => {
                    gsap.set(this.DOM.el, {zIndex: 999});
                },
                onComplete: () => {
                    gsap.set(this.DOM.el, {zIndex: ''});
                    gsap.set(this.DOM.reveal, {opacity: 0});
                }
            })
            .add('begin')
            .add(gsap.to(this.DOM.revealInner, PARAMS.useDefaultVal ? 0.3 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Quint.easeOut : PARAMS.ease,
                x: '100%',
                y: '100%'
            }), 'begin')
            
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.3 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Quint.easeOut : PARAMS.ease,
                x: '-100%',
                y: '-100%'
            }), 'begin');
        }
    }

    // Effect 3
    class HoverImgFx3 {
        constructor(el) {
            this.DOM = {el: el};
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'hover-reveal';
            this.DOM.reveal.style.overflow = 'hidden';
            this.DOM.reveal.innerHTML = `<div class="hover-reveal__inner"><div class="hover-reveal__img" style="background-image:url(${this.DOM.el.dataset.img})"></div></div>`;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealInner = this.DOM.reveal.querySelector('.hover-reveal__inner');
            this.DOM.revealInner.style.overflow = 'hidden';
            this.DOM.revealImg = this.DOM.revealInner.querySelector('.hover-reveal__img');
            charming(this.DOM.el);
            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
            this.initEvents();
        }
        initEvents() {
            this.positionElement = (ev) => {
                const mousePos = getMousePos(ev);
                const docScrolls = {
                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
                    top : document.body.scrollTop + document.documentElement.scrollTop
                };
                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
            };
            this.mouseenterFn = (ev) => {
                this.positionElement(ev);
                this.showImage();
                this.animateLetters();
            };
            this.mousemoveFn = ev => requestAnimationFrame(() => {
                this.positionElement(ev);
            });
            this.mouseleaveFn = () => {
                this.hideImage();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
        }
        showImage() {
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealImg);

            this.tl = new gsap.timeline({
                onStart: () => {
                    this.DOM.reveal.style.opacity = 1;
                    gsap.set(this.DOM.el, {zIndex: 1000});
                }
            })
            .add('begin')
            .set([this.DOM.revealInner, this.DOM.revealImg], {transformOrigin: '50% 100%'})
            .add(gsap.to(this.DOM.revealInner, PARAMS.useDefaultVal ? 0.4 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {x: '50%', y: '120%', rotation: 50},
                x: '0%',
                y: '0%',
                rotation: 0
            }), 'begin')
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.4 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {x: '-50%', y: '-120%', rotation: -50},
                x: '0%',
                y: '0%',
                rotation: 0
            }), 'begin')
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.7 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {scale: 2},
                scale: 1
            }), 'begin');
        }
        hideImage() {
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealImg);

            this.tl = new gsap.timeline({
                onStart: () => {
                    gsap.set(this.DOM.el, {zIndex: 999});
                },
                onComplete: () => {
                    gsap.set(this.DOM.el, {zIndex: ''});
                    gsap.set(this.DOM.reveal, {opacity: 0});
                }
            })
            .add('begin')
            .add(gsap.to(this.DOM.revealInner, PARAMS.useDefaultVal ? 0.6 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                y: '-120%',
                rotation: -5
            }), 'begin')
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.6 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                y: '120%',
                rotation: 5,
                scale: 1.2
            }), 'begin')
        }
        animateLetters() {
            gsap.killTweensOf(this.DOM.letters);
            gsap.set(this.DOM.letters, {opacity: 0});
            gsap.to(this.DOM.letters, PARAMS.useDefaultVal ? 0.2 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {x: '100%'},
                x: '0%',
                opacity: 1,
                stagger: 0.03
            });
        }
    }

    // Effect 4
    class HoverImgFx4 {
        constructor(el) {
            this.DOM = {el: el};
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'hover-reveal';
            this.DOM.reveal.innerHTML = `<div class="hover-reveal__inner"><div class="hover-reveal__img" style="background-image:url(${this.DOM.el.dataset.img})"></div></div>`;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealInner = this.DOM.reveal.querySelector('.hover-reveal__inner');
            this.DOM.revealInner.style.overflow = 'hidden';
            this.DOM.revealImg = this.DOM.revealInner.querySelector('.hover-reveal__img');
            charming(this.DOM.el);
            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
            this.initEvents();
        }
        initEvents() {
            this.positionElement = (ev) => {
                const mousePos = getMousePos(ev);
                const docScrolls = {
                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
                    top : document.body.scrollTop + document.documentElement.scrollTop
                };
                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
            };
            this.mouseenterFn = (ev) => {
                this.positionElement(ev);
                this.showImage();
                this.animateLetters();
            };
            this.mousemoveFn = ev => requestAnimationFrame(() => {
                this.positionElement(ev);
            });
            this.mouseleaveFn = () => {
                this.hideImage();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
        }
        showImage() {
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealImg);

            this.tl = new gsap.timeline({
                onStart: () => {
                    this.DOM.reveal.style.opacity = 1;
                    gsap.set(this.DOM.el, {zIndex: 1000});
                }
            })
            .add('begin')
            .add(gsap.to(this.DOM.revealInner, PARAMS.useDefaultVal ? 0.8 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {opacity: 0, y: '50%', rotation: -15, scale:0},
                y: '0%',
                rotation: 0,
                opacity: 1,
                scale: 1
            }), 'begin')
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.8 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {rotation: 15, scale: 2},
                rotation: 0,
                scale: 1
            }), 'begin');
        }
        hideImage() {
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealImg);

            this.tl = new gsap.timeline({
                onStart: () => {
                    gsap.set(this.DOM.el, {zIndex: 999});
                },
                onComplete: () => {
                    gsap.set(this.DOM.el, {zIndex: ''});
                    gsap.set(this.DOM.reveal, {opacity: 0});
                }
            })
            .add('begin')
            .add(gsap.to(this.DOM.revealInner, PARAMS.useDefaultVal ? 0.15 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                y: '-40%',
                rotation: 10,
                scale: 0.9,
                opacity: 0
            }), 'begin')
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.15 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                rotation: -10,
                scale: 1.5
            }), 'begin')
        }
        animateLetters() {
            gsap.killTweensOf(this.DOM.letters);
            gsap.set(this.DOM.letters, {opacity: 0});
            gsap.to(this.DOM.letters, PARAMS.useDefaultVal ? 0.8 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {y: '50%'},
                y: '0%',
                opacity: 1,
                stagger: 0.03
            });
        }
    }

    // Effect 5
    class HoverImgFx5 {
        constructor(el) {
            this.DOM = {el: el};
            
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'hover-reveal';
            this.DOM.reveal.innerHTML = `<div class="hover-reveal__deco"></div><div class="hover-reveal__inner"><div class="hover-reveal__img" style="background-image:url(${this.DOM.el.dataset.img})"></div></div>`;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealInner = this.DOM.reveal.querySelector('.hover-reveal__inner');
            this.DOM.revealInner.style.overflow = 'hidden';
            this.DOM.revealDeco = this.DOM.reveal.querySelector('.hover-reveal__deco');
            this.DOM.revealImg = this.DOM.revealInner.querySelector('.hover-reveal__img');
            charming(this.DOM.el);
            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
            this.initEvents();
        }
        initEvents() {
            this.positionElement = (ev) => {
                const mousePos = getMousePos(ev);
                const docScrolls = {
                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
                    top : document.body.scrollTop + document.documentElement.scrollTop
                };
                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
            };
            this.mouseenterFn = (ev) => {
                this.positionElement(ev);
                this.showImage();
                this.animateLetters();
            };
            this.mousemoveFn = ev => requestAnimationFrame(() => {
                this.positionElement(ev);
            });
            this.mouseleaveFn = () => {
                this.hideImage();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
        }
        showImage() {
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealImg);
            gsap.killTweensOf(this.DOM.revealDeco);

            this.tl = new gsap.timeline({
                onStart: () => {
                    this.DOM.reveal.style.opacity = 1;
                    gsap.set(this.DOM.el, {zIndex: 1000});
                }
            })
            .set(this.DOM.revealInner, {opacity: 0})
            .add('begin')
            .add(gsap.to(this.DOM.revealDeco, PARAMS.useDefaultVal ? 0.8 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {opacity: 0, scale: 0, rotation: 35},
                opacity: 1,
                scale: 1,
                rotation: 0
            }), 'begin')
            .add(gsap.to(this.DOM.revealInner, PARAMS.useDefaultVal ? 0.8 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {scale: 0, rotation: 35},
                rotation: 0,
                scale: 1,
                opacity: 1,
                delay: 0.15
            }), 'begin')
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.8 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {rotation: -35, scale: 2},
                rotation: 0,
                scale: 1,
                delay: 0.15
            }), 'begin')
        }
        hideImage() {
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealImg);
            gsap.killTweensOf(this.DOM.revealDeco);

            this.tl = new gsap.timeline({
                onStart: () => {
                    gsap.set(this.DOM.el, {zIndex: 999});
                },
                onComplete: () => {
                    gsap.set(this.DOM.el, {zIndex: ''});
                    gsap.set(this.DOM.reveal, {opacity: 0});
                }
            })
            .add('begin')
            .add(gsap.to([this.DOM.revealDeco, this.DOM.revealInner], PARAMS.useDefaultVal ? 0.2 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                opacity: 0,
                scale: 0.9
            }), 'begin')
        }
        animateLetters() {
            gsap.killTweensOf(this.DOM.letters);
            gsap.set(this.DOM.letters, {opacity: 0});
            gsap.to(this.DOM.letters, PARAMS.useDefaultVal ? 0.1 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {y: '50%'},
                y: '0%',
                opacity: 1,
                stagger: 0.06
            });
        }
    }

    // Effect 6
    class HoverImgFx6 {
        constructor(el) {
            this.DOM = {el: el};
            
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'hover-reveal';
            this.DOM.reveal.style.overflow = 'hidden';
            this.DOM.reveal.innerHTML = `<div class="hover-reveal__deco"></div><div class="hover-reveal__inner"><div class="hover-reveal__img" style="background-image:url(${this.DOM.el.dataset.img})"></div></div>`;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealInner = this.DOM.reveal.querySelector('.hover-reveal__inner');
            this.DOM.revealInner.style.overflow = 'hidden';
            this.DOM.revealDeco = this.DOM.reveal.querySelector('.hover-reveal__deco');
            this.DOM.revealImg = this.DOM.revealInner.querySelector('.hover-reveal__img');

            this.initEvents();
        }
        initEvents() {
            this.positionElement = (ev) => {
                const mousePos = getMousePos(ev);
                const docScrolls = {
                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
                    top : document.body.scrollTop + document.documentElement.scrollTop
                };
                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
            };
            this.mouseenterFn = (ev) => {
                this.positionElement(ev);
                this.showImage();
            };
            this.mousemoveFn = ev => requestAnimationFrame(() => {
                this.positionElement(ev);
            });
            this.mouseleaveFn = () => {
                this.hideImage();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
        }
        showImage() {
            gsap.killTweensOf(this.DOM.reveal);
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealImg);
            gsap.killTweensOf(this.DOM.revealDeco);

            this.tl = new gsap.timeline({
                onStart: () => {
                    this.DOM.reveal.style.opacity = 1;
                    gsap.set(this.DOM.el, {zIndex: 1000});
                }
            })
            .add('begin')
            .set(this.DOM.revealInner, {x: '100%'})
            .set(this.DOM.revealDeco, {transformOrigin: '100% 50%'})
            .add(gsap.to(this.DOM.revealDeco, PARAMS.useDefaultVal ? 0.3 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeInOut : PARAMS.ease,
                startAt: {scaleX: 0},
                scaleX: 1
            }), 'begin')
            .set(this.DOM.revealDeco, {transformOrigin: '0% 50%'})
            .add(gsap.to(this.DOM.revealDeco, PARAMS.useDefaultVal ? 0.6 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                scaleX: 0
            }), 'begin+=0.3')
            .add(gsap.to(this.DOM.revealInner, PARAMS.useDefaultVal ? 0.6 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {x: '100%'},
                x: '0%'
            }), 'begin+=0.45')
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.6 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {x: '-100%'},
                x: '0%'
            }), 'begin+=0.45')
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 1.6 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {scale: 1.3},
                scale: 1
            }), 'begin+=0.45')
            .add(gsap.to(this.DOM.reveal, PARAMS.useDefaultVal ? 0.8 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Quint.easeOut : PARAMS.ease,
                startAt: {x: '20%', rotation: 10},
                x: '0%',
                rotation: 0
            }), 'begin');
        }
        hideImage() {
            gsap.killTweensOf(this.DOM.reveal);
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealImg);
            gsap.killTweensOf(this.DOM.revealDeco);

            this.tl = new gsap.timeline({
                onStart: () => {
                    gsap.set(this.DOM.el, {zIndex: 999});
                },
                onComplete: () => {
                    gsap.set(this.DOM.el, {zIndex: ''});
                    gsap.set(this.DOM.reveal, {opacity: 0});
                }
            })
            .add('begin')
            .add(gsap.to(this.DOM.revealInner, PARAMS.useDefaultVal ? 0.1 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease,
                x: '-100%'
            }), 'begin')
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.1 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease,
                x: '100%'
            }), 'begin')
        }
    }
 
    // Effect 7
    class HoverImgFx7 {
        constructor(el) {
            this.DOM = {el: el};
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'hover-reveal';
            this.DOM.reveal.innerHTML = `<div class="hover-reveal__deco"></div><div class="hover-reveal__inner"><div class="hover-reveal__img" style="background-image:url(${this.DOM.el.dataset.img})"></div></div>`;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealInner = this.DOM.reveal.querySelector('.hover-reveal__inner');
            this.DOM.revealDeco = this.DOM.reveal.querySelector('.hover-reveal__deco');
            this.DOM.revealImg = this.DOM.revealInner.querySelector('.hover-reveal__img');
            charming(this.DOM.el);
            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
            this.initEvents();
        }
        initEvents() {
            this.positionElement = (ev) => {
                const mousePos = getMousePos(ev);
                const docScrolls = {
                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
                    top : document.body.scrollTop + document.documentElement.scrollTop
                };
                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
            };
            this.mouseenterFn = (ev) => {
                this.positionElement(ev);
                this.showImage();
                this.animateLetters();
            };
            this.mousemoveFn = ev => requestAnimationFrame(() => {
                this.positionElement(ev);
            });
            this.mouseleaveFn = () => {
                this.hideImage();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
            window.addEventListener('resize', () => this.rect = this.DOM.reveal.getBoundingClientRect());
        }
        showImage() {
            gsap.killTweensOf(this.DOM.reveal);
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealImg);
            gsap.killTweensOf(this.DOM.revealDeco);

            this.tl = new gsap.timeline({
                onStart: () => {
                    this.DOM.reveal.style.opacity = 1;
                    gsap.set(this.DOM.el, {zIndex: 1000});
                }
            })
            .add('begin')
            .set(this.DOM.revealInner, {opacity: 0})
            .set(this.DOM.revealDeco, {transformOrigin: '-5% 50%'})
            .add(gsap.to(this.DOM.revealDeco, PARAMS.useDefaultVal ? 0.2 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Quad.easeInOut : PARAMS.ease,
                startAt: {scaleX: 0},
                scaleX: 1,
                scaleY: 0.8
            }), 'begin')
            .set(this.DOM.revealDeco, {transformOrigin: '105% 50%'})
            .add(gsap.to(this.DOM.revealDeco, PARAMS.useDefaultVal ? 0.3 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease,
                scaleX: 0,
                scaleY: 1
            }), 'begin+=0.2')
            .add(gsap.to(this.DOM.revealInner, PARAMS.useDefaultVal ? 0.9 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Elastic.easeOut.config(1,0.6) : PARAMS.ease,
                startAt: {scale: 0, opacity: 1, x: '0%'},
                scale: 1,
            }), 'begin+=0.4')
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.8 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                rotation: -15,
            }), 'begin')
            .add(gsap.to(this.DOM.reveal, PARAMS.useDefaultVal ? 1.1 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Quint.easeOut : PARAMS.ease,
                startAt: {x: '-50%', y: '10%', rotation: -35},
                x: '0%',
                y: '0%',
                rotation: 15
            }), 'begin');
        }
        hideImage() {
            gsap.killTweensOf(this.DOM.reveal);
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealImg);
            gsap.killTweensOf(this.DOM.revealDeco);

            this.tl = new gsap.timeline({
                onStart: () => {
                    gsap.set(this.DOM.el, {zIndex: 999});
                },
                onComplete: () => {
                    gsap.set(this.DOM.el, {zIndex: ''});
                    gsap.set(this.DOM.reveal, {opacity: 0});
                }
            })
            .add(gsap.to(this.DOM.revealInner, PARAMS.useDefaultVal ? 0.13 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease,
                scale: 0.8,
                opacity: 0
            }));
        }
        animateLetters() {
            gsap.killTweensOf(this.DOM.letters);
            gsap.set(this.DOM.letters, {opacity: 0});
            gsap.to(this.DOM.letters, PARAMS.useDefaultVal ? 0.8 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Elastic.easeOut.config(1,0.4) : PARAMS.ease,
                startAt: {y: '50%'},
                y: '0%',
                opacity: 1,
                stagger: 0.02
            });
        }
    }

    // Effect 8
    class HoverImgFx8 {
        constructor(el) {
            this.DOM = {el: el};
            
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'hover-reveal';
            this.DOM.reveal.innerHTML = `<div class="hover-reveal__deco"></div><div class="hover-reveal__inner"><div class="hover-reveal__img" style="background-image:url(${this.DOM.el.dataset.img})"></div></div>`;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealInner = this.DOM.reveal.querySelector('.hover-reveal__inner');
            this.DOM.revealInner.style.overflow = 'hidden';
            this.DOM.revealDeco = this.DOM.reveal.querySelector('.hover-reveal__deco');
            this.DOM.revealImg = this.DOM.revealInner.querySelector('.hover-reveal__img');
            this.rect = this.DOM.reveal.getBoundingClientRect();
            charming(this.DOM.el);
            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
            this.initEvents();
        }
        initEvents() {
            this.positionElement = (ev) => {
                const mousePos = getMousePos(ev);
                const docScrolls = {
                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
                    top : document.body.scrollTop + document.documentElement.scrollTop
                };
                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
            };
            this.mouseenterFn = (ev) => {
                this.positionElement(ev);
                this.showImage();
                this.animateLetters();
            };
            this.mousemoveFn = ev => requestAnimationFrame(() => {
                this.positionElement(ev);
            });
            this.mouseleaveFn = () => {
                this.hideImage();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
        }
        showImage() {
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealImg);
            gsap.killTweensOf(this.DOM.revealDeco);

            this.tl = new gsap.timeline({
                onStart: () => {
                    this.DOM.reveal.style.opacity = 1;
                    gsap.set(this.DOM.el, {zIndex: 1000});
                }
            })
            .set(this.DOM.revealInner, {opacity: 0})
            .add('begin')
            .set(this.DOM.revealDeco, {transformOrigin: '50% 0%'})
            .add(gsap.to(this.DOM.revealDeco, PARAMS.useDefaultVal ? 0.6 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Cubic.easeInOut : PARAMS.ease,
                startAt: {opacity: 0, x: '15%', y: '50%', scaleY: 3},
                scaleY: 1,
                opacity: 1,
                y: '-15%'
            }), 'begin')
            .add(gsap.to(this.DOM.revealInner, PARAMS.useDefaultVal ? 0.8 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {y: '100%', rotation: 3},
                opacity: 1,
                rotation: 0,
                y: '0%'
            }), 'begin+=0.4')
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 1.3 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {scale: 1.4},
                scale: 1
            }), 'begin+=0.4')
        }
        hideImage() {
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealImg);
            gsap.killTweensOf(this.DOM.revealDeco);

            this.tl = new gsap.timeline({
                onStart: () => {
                    gsap.set(this.DOM.el, {zIndex: 999});
                },
                onComplete: () => {
                    gsap.set(this.DOM.el, {zIndex: ''});
                    gsap.set(this.DOM.reveal, {opacity: 0});
                }
            })
            .add('begin')
            .add(gsap.to([this.DOM.revealDeco, this.DOM.revealInner], PARAMS.useDefaultVal ? 0.2 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                opacity: 0
            }), 'begin')
        }
        animateLetters() {
            gsap.killTweensOf(this.DOM.letters);
            gsap.set(this.DOM.letters, {opacity: 0});
            gsap.to(this.DOM.letters, PARAMS.useDefaultVal ? 0.1 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Elastic.easeOut.config(1,0.4) : PARAMS.ease,
                startAt: {y: '50%'},
                y: '0%',
                opacity: 1,
                stagger: 0.08
            });
        }
    }

    // Effect 9
    class HoverImgFx9 {
        constructor(el) {
            this.DOM = {el: el};
            
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'hover-reveal';
            this.DOM.reveal.innerHTML = `<div class="hover-reveal__deco"></div><div class="hover-reveal__inner"><div class="hover-reveal__img" style="background-image:url(${this.DOM.el.dataset.img})"></div></div>`;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealInner = this.DOM.reveal.querySelector('.hover-reveal__inner');
            this.DOM.revealInner.style.overflow = 'hidden';
            this.DOM.revealDeco = this.DOM.reveal.querySelector('.hover-reveal__deco');
            this.DOM.revealImg = this.DOM.revealInner.querySelector('.hover-reveal__img');
            charming(this.DOM.el);
            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
            this.initEvents();
        }
        initEvents() {
            this.positionElement = (ev) => {
                const mousePos = getMousePos(ev);
                const docScrolls = {
                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
                    top : document.body.scrollTop + document.documentElement.scrollTop
                };
                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
            };
            this.mouseenterFn = (ev) => {
                this.positionElement(ev);
                this.showImage();
                this.animateLetters();
            };
            this.mousemoveFn = ev => requestAnimationFrame(() => {
                this.positionElement(ev);
            });
            this.mouseleaveFn = () => {
                this.hideImage();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
        }
        showImage() {
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealImg);
            gsap.killTweensOf(this.DOM.revealDeco);

            this.tl = new gsap.timeline({
                onStart: () => {
                    this.DOM.reveal.style.opacity = 1;
                    gsap.set(this.DOM.el, {zIndex: 1000});
                }
            })
            .set([this.DOM.revealInner, this.DOM.revealImg, this.DOM.revealDeco], {transformOrigin: '120% 0%'})
            .set(this.DOM.revealInner, {opacity: 0})
            .add('begin')
            .add(gsap.to(this.DOM.revealDeco, PARAMS.useDefaultVal ? 0.8 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {opacity: 0, rotation: -80, x: '15%', y: '60%'},
                opacity: 1,
                rotation: 0,
                y: '-15%'
            }), 'begin')
            .add(gsap.to(this.DOM.revealInner, PARAMS.useDefaultVal ? 0.8 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {x: '50%', y: '150%', rotation: -25},
                opacity: 1,
                x: '0%',
                y: '0%',
                rotation: 0
            }), 'begin+=0.25')

            
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.8 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {y: '-150%', rotation: -25},
                y: '0%',
                rotation: 0
            }), 'begin+=0.25');
        }
        hideImage() {
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealImg);
            gsap.killTweensOf(this.DOM.revealDeco);

            this.tl = new gsap.timeline({
                onStart: () => {
                    gsap.set(this.DOM.el, {zIndex: 999});
                },
                onComplete: () => {
                    gsap.set(this.DOM.el, {zIndex: ''});
                    gsap.set(this.DOM.reveal, {opacity: 0});
                }
            })
            .add('begin')
            .add(gsap.to([this.DOM.revealDeco, this.DOM.revealInner], PARAMS.useDefaultVal ? 0.2 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                opacity: 0
            }), 'begin')
        }
        animateLetters() {
            gsap.killTweensOf(this.DOM.letters);
            gsap.set(this.DOM.letters, {opacity: 0});
            gsap.to(this.DOM.letters, PARAMS.useDefaultVal ? 0.1 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                opacity: 1,
                stagger: 0.08
            });
        }
    }

    // Effect 10
    class HoverImgFx10 {
        constructor(el) {
            this.DOM = {el: el};
            
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'hover-reveal';
            this.DOM.reveal.innerHTML = `<div class="hover-reveal__deco"></div><div class="hover-reveal__inner"><div class="hover-reveal__img" style="background-image:url(${this.DOM.el.dataset.img})"></div></div>`;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealInner = this.DOM.reveal.querySelector('.hover-reveal__inner');
            this.DOM.revealInner.style.overflow = 'hidden';
            this.DOM.revealDeco = this.DOM.reveal.querySelector('.hover-reveal__deco');
            this.DOM.revealImg = this.DOM.revealInner.querySelector('.hover-reveal__img');
            charming(this.DOM.el);
            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
            this.initEvents();
        }
        initEvents() {
            this.positionElement = (ev) => {
                const mousePos = getMousePos(ev);
                const docScrolls = {
                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
                    top : document.body.scrollTop + document.documentElement.scrollTop
                };
                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
            };
            this.mouseenterFn = (ev) => {
                this.positionElement(ev);
                this.showImage();
                this.animateLetters();
            };
            this.mousemoveFn = ev => requestAnimationFrame(() => {
                this.positionElement(ev);
            });
            this.mouseleaveFn = () => {
                this.hideImage();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
        }
        showImage() {
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealDeco);

            this.tl = new gsap.timeline({
                onStart: () => {
                    this.DOM.reveal.style.opacity = 1;
                    gsap.set(this.DOM.el, {zIndex: 1000});
                }
            })
            .set(this.DOM.revealInner, {opacity: 0})
            .add('begin')
            .add(gsap.to(this.DOM.revealDeco, PARAMS.useDefaultVal ? 0.5 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {scale: 0, opacity: 1, rotation: -10},
                scale: 1.6,
                rotation: 0
            }), 'begin')
            .add(gsap.to(this.DOM.revealDeco, PARAMS.useDefaultVal ? 0.3 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease,
                opacity: 0
            }), 'begin+=0.2')
            .add(gsap.to(this.DOM.revealInner, PARAMS.useDefaultVal ? 0.6 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {scale: 0, opacity: 0, rotation: 10},
                scale: 1,
                opacity: 1,
                rotation: 0
            }), 'begin+=0.2');
        }
        hideImage() {
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealDeco);

            this.tl = new gsap.timeline({
                onStart: () => {
                    gsap.set(this.DOM.el, {zIndex: 999});
                },
                onComplete: () => {
                    gsap.set(this.DOM.el, {zIndex: ''});
                    gsap.set(this.DOM.reveal, {opacity: 0});
                }
            })
            .add('begin')
            .add(gsap.to([this.DOM.revealDeco, this.DOM.revealInner], 0.2, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                opacity: 0,
                scale: 0.9
            }), 'begin')
        }
        animateLetters() {
            gsap.killTweensOf(this.DOM.letters);
            gsap.set(this.DOM.letters, {opacity: 0});
            gsap.to(this.DOM.letters, PARAMS.useDefaultVal ? 0.1 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                opacity: 1,
                stagger: 0.04
            });
        }
    }

    // Effect 11
    class HoverImgFx11 {
        constructor(el) {
            this.DOM = {el: el};
            
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'hover-reveal';
            this.DOM.reveal.style.overflow = 'hidden';
            this.DOM.reveal.innerHTML = `<div class="hover-reveal__deco"></div><div class="hover-reveal__inner"><div class="hover-reveal__img" style="background-image:url(${this.DOM.el.dataset.img})"></div></div>`;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealInner = this.DOM.reveal.querySelector('.hover-reveal__inner');
            this.DOM.revealInner.style.overflow = 'hidden';
            this.DOM.revealDeco = this.DOM.reveal.querySelector('.hover-reveal__deco');
            gsap.set(this.DOM.revealDeco, {
                width: '1%',
                height: '100%',
                background: 'white',
                left: '50%'
            });
            this.DOM.revealImg = this.DOM.revealInner.querySelector('.hover-reveal__img');
            charming(this.DOM.el);
            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
            this.initEvents();
        }
        initEvents() {
            this.positionElement = (ev) => {
                const mousePos = getMousePos(ev);
                const docScrolls = {
                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
                    top : document.body.scrollTop + document.documentElement.scrollTop
                };
                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
            };
            this.mouseenterFn = (ev) => {
                this.positionElement(ev);
                this.showImage();
                this.animateLetters();
            };
            this.mousemoveFn = ev => requestAnimationFrame(() => {
                this.positionElement(ev);
            });
            this.mouseleaveFn = () => {
                this.hideImage();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
        }
        showImage() {
            gsap.killTweensOf(this.DOM.reveal);
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealImg);
            gsap.killTweensOf(this.DOM.revealDeco);

            this.tl = new gsap.timeline({
                onStart: () => {
                    this.DOM.reveal.style.opacity = 1;
                    gsap.set(this.DOM.el, {zIndex: 1000});
                }
            })
            .add('begin')
            .set(this.DOM.revealInner, {y: '100%'})
            .set(this.DOM.revealDeco, {transformOrigin: '50% 100%'})
            .add(gsap.to(this.DOM.revealDeco, PARAMS.useDefaultVal ? 0.3 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeInOut : PARAMS.ease,
                startAt: {scaleY: 0, scaleX: 10},
                scaleY: 1,
                scaleX: 1
            }), 'begin')
            .set(this.DOM.revealDeco, {transformOrigin: '50% 0%'})
            .add(gsap.to(this.DOM.revealDeco, PARAMS.useDefaultVal ? 0.3 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                scaleY: 0
            }), 'begin+=0.3')
            .add(gsap.to(this.DOM.revealInner, PARAMS.useDefaultVal ? 0.5 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {y: '100%'},
                y: '0%'
            }), 'begin+=0.4')
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.5 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {y: '-100%'},
                y: '0%'
            }), 'begin+=0.4')
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.5 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {y: '100%'},
                y: '0%'
            }), 'begin+=0.4')
            .add(gsap.to(this.DOM.reveal, PARAMS.useDefaultVal ? 1.1 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {y: '50%', rotation: 10},
                y: '0%',
                rotation: 0
            }), 'begin');
        }
        hideImage() {
            gsap.killTweensOf(this.DOM.reveal);
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealImg);
            gsap.killTweensOf(this.DOM.revealDeco);

            this.tl = new gsap.timeline({
                onStart: () => {
                    gsap.set(this.DOM.el, {zIndex: 999});
                },
                onComplete: () => {
                    gsap.set(this.DOM.el, {zIndex: ''});
                    gsap.set(this.DOM.reveal, {opacity: 0});
                }
            })
            .add('begin')
            .add(gsap.to(this.DOM.revealInner, PARAMS.useDefaultVal ? 0.1 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease,
                y: '-100%'
            }), 'begin')
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.1 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease,
                y: '100%'
            }), 'begin')
        }
        animateLetters() {
            gsap.killTweensOf(this.DOM.letters);
            gsap.set(this.DOM.letters, {opacity: 0});
            gsap.to(this.DOM.letters, PARAMS.useDefaultVal ? 0.1 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {y: '50%'},
                y: '0%',
                opacity: 1,
                stagger: 0.06
            });
        }
    }

    // Effect 12
    class HoverImgFx12 {
        constructor(el) {
            this.DOM = {el: el};
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'hover-reveal'; 
            this.totalDecos = 7;
            let inner = '';
            for (let i = 0; i <= this.totalDecos-1; ++i) {
                inner += '<div class="hover-reveal__deco"></div>';
            }
            inner += `<div class="hover-reveal__inner"><div class="hover-reveal__img" style="background-image:url(${this.DOM.el.dataset.img})"></div></div>`
            this.DOM.reveal.innerHTML = inner;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealDecos = [...this.DOM.reveal.querySelectorAll('.hover-reveal__deco')];
            this.DOM.revealDecos.forEach((deco, pos) => {
                gsap.set(deco, {
                    width: pos === this.totalDecos-1 ? '100%' : `${getRandomFloat(40,100)}%`,
                    height: pos === this.totalDecos-1 ? '100%' : `${getRandomFloat(5,30)}%`,
                    x: pos === this.totalDecos-1 ? '0%' : `${getRandomFloat(-100,100)}%`,
                    y: pos === this.totalDecos-1 ? '0%' : `${getRandomFloat(-300,300)}%`,
                    scaleX: 0
                });
            });
            this.DOM.revealInner = this.DOM.reveal.querySelector('.hover-reveal__inner');
            this.DOM.revealInner.style.overflow = 'hidden';
            this.DOM.revealImg = this.DOM.revealInner.querySelector('.hover-reveal__img');

            this.initEvents();
        }
        initEvents() {
            this.positionElement = (ev) => {
                const mousePos = getMousePos(ev);
                const docScrolls = {
                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
                    top : document.body.scrollTop + document.documentElement.scrollTop
                };
                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
            };
            this.mouseenterFn = (ev) => {
                this.positionElement(ev);
                this.showImage();
            };
            this.mousemoveFn = ev => requestAnimationFrame(() => {
                this.positionElement(ev);
            });
            this.mouseleaveFn = () => {
                this.hideImage();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
        }
        showImage() {
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealImg);
            gsap.killTweensOf(this.DOM.revealDecos);

            this.tl = new gsap.timeline({
                onStart: () => {
                    this.DOM.reveal.style.opacity = 1;
                    gsap.set(this.DOM.el, {zIndex: 1000});
                }
            })
            .add('begin')
            .set(this.DOM.revealInner, {x: '100%', opacity: 0})
            .set(this.DOM.revealDecos, {transformOrigin: '100% 50%'})
            .to(this.DOM.revealDecos, PARAMS.useDefaultVal ? 0.3 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                scaleX: 1,
                stagger: 0.06
            }, 'begin')
            .add(gsap.to(this.DOM.revealDecos, {
                duration: getRandomFloat(0.3, 0.6),
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {transformOrigin: '0% 50%'},
                scaleX: 0,
                x: '-=5%',
                delay: 0.3,
                stagger: 0.04
            }), 'begin')
            .add(gsap.to(this.DOM.revealInner, PARAMS.useDefaultVal ? 0.6 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {x: '100%'},
                x: '0%',
                opacity: 1,
                delay: 0.75
            }), 'begin')
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.6 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {x: '-100%'},
                x: '0%',
                delay: 0.75
            }), 'begin');
        }
        hideImage() {
            gsap.killTweensOf(this.DOM.revealInner);
            gsap.killTweensOf(this.DOM.revealImg);
            gsap.killTweensOf(this.DOM.revealDecos);

            this.tl = new gsap.timeline({
                onStart: () => {
                    gsap.set(this.DOM.el, {zIndex: 999});
                },
                onComplete: () => {
                    gsap.set(this.DOM.el, {zIndex: ''});
                    gsap.set(this.DOM.reveal, {opacity: 0});
                }
            })
            .add('begin')
            .add(gsap.to(this.DOM.revealInner, PARAMS.useDefaultVal ? 0.1 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease,
                x: '-100%'
            }), 'begin')
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.1 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease,
                x: '100%'
            }), 'begin')
        }
    }

    // Effect 13
    class HoverImgFx13 {
        constructor(el) {
            this.DOM = {el: el};
            
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'hover-reveal';
            this.DOM.reveal.style.zIndex = -1;
            this.totalImages = 3;
            let inner = '';
            for (let i = 0; i <= this.totalImages-1; ++i) {
                inner += `<div class="hover-reveal__img" style="position: absolute; background-image:url(${this.DOM.el.dataset.img})"></div>`;
            }
            this.DOM.reveal.innerHTML = inner;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealImgs = [...this.DOM.reveal.querySelectorAll('.hover-reveal__img')];
            charming(this.DOM.el);
            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
            this.initEvents();
        }
        position() {
            this.rect = this.DOM.el.getBoundingClientRect();
            this.DOM.reveal.style.top = `${this.rect.top - this.DOM.reveal.offsetHeight/2}px`;
            this.DOM.reveal.style.left = `${this.rect.left - this.DOM.reveal.offsetWidth/2}px`;
        }
        initEvents() {
            this.mouseenterFn = () => {
                this.showImage();
                this.animateLetters();
            };
            this.mouseleaveFn = () => {
                this.hideImage();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
        }
        showImage() {
            gsap.killTweensOf(this.DOM.revealImgs);
            this.position();
            
            this.tl = new gsap.timeline({
                onStart: () => {
                    this.DOM.reveal.style.opacity = 1;
                }
            })
            .set([this.DOM.revealImgs], {opacity: 0})

            for (let i = 0; i <= this.totalImages-1; ++i) {
                this.tl.add(gsap.to(this.DOM.revealImgs[i], PARAMS.useDefaultVal ? 0.7 : PARAMS.duration, {
                    ease: i === this.totalImages-1 ? Expo.easeOut : Quint.easeOut,
                    startAt: {x: '30%', y: '160%', rotation: i === this.totalImages-1 ? -30 : -10},
                    x: i === this.totalImages-1 ? '10%' : '-15%',
                    y: i === this.totalImages-1 ? '10%' : '-140%',
                    rotation: -10
                }), i*0.2);
                this.tl.add(gsap.to(this.DOM.revealImgs[i], PARAMS.useDefaultVal ? 0.5 : PARAMS.duration, {
                    ease: PARAMS.useDefaultVal ? Quad.easeOut : PARAMS.ease,
                    startAt: {opacity: 1},
                    opacity: i === this.totalImages-1 ? 1 : 0
                }), i*0.2);
            }
        }
        hideImage() {
            gsap.killTweensOf(this.DOM.revealImgs);
            this.tl = new gsap.timeline({
                onComplete: () => {
                    gsap.set(this.DOM.reveal, {opacity: 0});
                }
            })
            .add(gsap.to(this.DOM.revealImgs[this.totalImages-1], PARAMS.useDefaultVal ? 0.15 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease,
                x: '-30%',
                y: '-240%',
                opacity: 0
            }))
        }
        animateLetters() {
            gsap.killTweensOf(this.DOM.letters);
            this.DOM.letters.forEach(letter => gsap.set(letter, {
                y: Math.round(Math.random()) === 0 ? '100%' : '0%',
                opacity: 0
            }));
            gsap.to(this.DOM.letters, 1, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                y: '0%',
                opacity: 1
            });
        }
    }

    // Effect 14
    class HoverImgFx14 {
        constructor(el) {
            this.DOM = {el: el};
            
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'hover-reveal';
            let inner = '';
            const imgsArr = this.DOM.el.dataset.img.split(',');
            for (let i = 0, len = imgsArr.length; i <= len-1; ++i ) {
                inner += `<div class="hover-reveal__img" style="transform-origin:0% 0%;opacity:0;position:absolute;background-image:url(${imgsArr[i]})"></div>`;
            }
            this.DOM.reveal.innerHTML = inner;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealImgs = [...this.DOM.reveal.querySelectorAll('.hover-reveal__img')];
            this.imgsTotal = this.DOM.revealImgs.length;

            this.initEvents();
        }
        initEvents() {
            this.positionElement = (ev) => {
                const mousePos = getMousePos(ev);
                const docScrolls = {
                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
                    top : document.body.scrollTop + document.documentElement.scrollTop
                };
                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
            };
            this.mouseenterFn = (ev) => {
                this.positionElement(ev);
                this.showImage();
            };
            this.mousemoveFn = ev => requestAnimationFrame(() => {
                this.positionElement(ev);
            });
            this.mouseleaveFn = () => {
                this.hideImage();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
        }
        showImage() {
            this.DOM.reveal.style.opacity = 1;
            gsap.set(this.DOM.el, {zIndex: 1000});
            gsap.set(this.DOM.revealImgs, {opacity: 0});

            const show = () => {
                gsap.killTweensOf(this.DOM.revealImgs[this.current]);
                gsap.set(this.DOM.revealImgs[this.current], {zIndex: 1000});
                gsap.to(this.DOM.revealImgs[this.current], PARAMS.useDefaultVal ? 0.4 : PARAMS.duration, {
                    ease: PARAMS.useDefaultVal ? Quint.easeOut : PARAMS.ease,
                    startAt: {opacity: 0, scale: 0.5, rotation: -15, x: '0%', y: '-10%'},
                    opacity: 1,
                    y: '0%',
                    rotation: 0,
                    scale: 1
                });
            };
            this.current = 0;
            show();
            
            const loop = () => {
                this.imgtimeout = setTimeout(() => {
                    this.DOM.revealImgs[this.current].style.zIndex = '';
                    gsap.to(this.DOM.revealImgs[this.current], PARAMS.useDefaultVal ? 0.8 : PARAMS.duration, {
                        ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                        x: `${getRandomFloat(-10,10)}%`,
                        y: `${getRandomFloat(10,60)}%`,
                        rotation: getRandomFloat(5,15),
                        opacity: 0
                    });
                    this.current= this.current < this.imgsTotal-1 ? this.current+1 : 0;
                    show();
                    loop();
                }, 500);
            }
            loop();
        }
        hideImage() {
            clearTimeout(this.imgtimeout);
            this.DOM.revealImgs[this.current].style.zIndex = '';
            this.DOM.revealImgs[this.current].style.opacity = 0;
            this.current = 0;
            gsap.set(this.DOM.el, {zIndex: ''});
            gsap.set(this.DOM.reveal, {opacity: 0})
        }
    }
        
    // Effect 15
    class HoverImgFx15 {
        constructor(el) {
            this.DOM = {el: el};
            
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'hover-reveal';
            this.totalImages = 5;
            let inner = '';
            for (let i = 0; i <= this.totalImages-1; ++i) {
                inner += `<div class="hover-reveal__img" style="position: absolute; background-image:url(${this.DOM.el.dataset.img})"></div>`;
            }
            this.DOM.reveal.innerHTML = inner;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealImgs = [...this.DOM.reveal.querySelectorAll('.hover-reveal__img')];
            charming(this.DOM.el);
            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
            this.initEvents();
        }
        initEvents() {
            this.positionElement = (ev) => {
                const mousePos = getMousePos(ev);
                const docScrolls = {
                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
                    top : document.body.scrollTop + document.documentElement.scrollTop
                };
                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
            };
            this.mouseenterFn = (ev) => {
                this.positionElement(ev);
                this.animateLetters();
                this.showImage();
            };
            this.mousemoveFn = ev => requestAnimationFrame(() => {
                this.positionElement(ev);
            });
            this.mouseleaveFn = () => {
                this.hideImage();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
        }
        showImage() {
            gsap.killTweensOf(this.DOM.revealImgs);
            this.tl = new gsap.timeline({
                onStart: () => {
                    this.DOM.reveal.style.opacity = 1;
                    gsap.set(this.DOM.el, {zIndex: 1000});
                }
            })
            .set(this.DOM.revealImgs, {opacity: 0});

            for (let i = 0; i <= this.totalImages-1; ++i) {
                gsap.set(this.DOM.revealImgs[i], {
                    x: `${(this.totalImages-1-i)*5}%`, 
                    y: `${(this.totalImages-1-i)*10}%`
                });
                
                this.tl.add(gsap.to(this.DOM.revealImgs[i], i === this.totalImages-1 ? 1.2 : 0.55, {
                    ease: i === this.totalImages-1 ? Quint.easeOut : Quad.easeOut,
                    startAt: i === this.totalImages-1 ? {opacity: 1, x: '5%', y: '10%'} : {opacity: 1},
                    opacity: i === this.totalImages-1 ? 1 : 0,
                    x: i === this.totalImages-1 ? '0%' : null,
                    y: i === this.totalImages-1 ? '0%' : null
                }), i*0.04);
            }
        }
        hideImage() {
            gsap.killTweensOf(this.DOM.revealImgs);
            this.tl = new gsap.timeline({
                onStart: () => {
                    gsap.set(this.DOM.el, {zIndex: 999});
                },
                onComplete: () => {
                    gsap.set(this.DOM.el, {zIndex: ''});
                    gsap.set(this.DOM.reveal, {opacity: 0});
                }
            })
            .add(gsap.to(this.DOM.revealImgs[this.totalImages-1], PARAMS.useDefaultVal ? 0.15 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease,
                opacity: 0
            }))
        }
        animateLetters() {
            gsap.killTweensOf(this.DOM.letters);
            this.DOM.letters.forEach((letter) => {
                const opts = Math.round(Math.random()) === 0 ? {x: '100%', y: '100%', opacity: 0} : {opacity: 0};
                gsap.set(letter, opts);
            });
            gsap.to(this.DOM.letters, PARAMS.useDefaultVal ? 1 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                x: '0%',
                y: '0%',
                opacity: 1
            });
        }
    }

    // Effect 16
    class HoverImgFx16 {
        constructor(el) {
            this.DOM = {el: el};
            
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'hover-reveal';
            this.totalImages = 10;
            let inner = '';
            for (let i = 0; i <= this.totalImages-1; ++i) {
                inner += `<div class="hover-reveal__img" style="position: absolute; background-image:url(${this.DOM.el.dataset.img})"></div>`;
            }
            this.DOM.reveal.innerHTML = inner;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealImgs = [...this.DOM.reveal.querySelectorAll('.hover-reveal__img')];
            this.rect = this.DOM.reveal.getBoundingClientRect();
            charming(this.DOM.el);
            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
            this.initEvents();
        }
        initEvents() {
            this.positionElement = (ev) => {
                const mousePos = getMousePos(ev);
                const docScrolls = {
                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
                    top : document.body.scrollTop + document.documentElement.scrollTop
                };
                this.DOM.reveal.style.top = `${mousePos.y-this.rect.height-20-docScrolls.top}px`;
                this.DOM.reveal.style.left = `${mousePos.x-this.rect.width-20-docScrolls.left}px`;
            };
            this.mouseenterFn = (ev) => {
                this.positionElement(ev);
                this.animateLetters();
                this.showImage();
            };
            this.mousemoveFn = ev => requestAnimationFrame(() => {
                this.positionElement(ev);
            });
            this.mouseleaveFn = () => {
                this.hideImage();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
        }
        showImage() {
            gsap.killTweensOf(this.DOM.revealImgs);
            this.tl = new gsap.timeline({
                onStart: () => {
                    this.DOM.reveal.style.opacity = 1;
                    gsap.set(this.DOM.el, {zIndex: 1000});
                }
            })
            .set(this.DOM.revealImgs, {opacity: 0, transformOrigin: '0% 0%'});
            
            for (let i = 0; i <= this.totalImages-1; ++i) {
                gsap.set(this.DOM.revealImgs[i], {
                    x: `${(this.totalImages-1-i)*getRandomFloat(-10,-5)}%`, 
                    y: `${(this.totalImages-1-i)*getRandomFloat(-15,-10)}%`,
                    rotation: `${getRandomFloat(-5,5)}deg`
                });
                
                this.tl.add(gsap.to(this.DOM.revealImgs[i], i === this.totalImages-1 ? 0.3 : 0.3, {
                    ease: i === this.totalImages-1 ? Quint.easeOut : Sine.easeOut,
                    startAt: i === this.totalImages-1 ? {opacity: 1, x: '-5%', y: '-10%'} : {opacity: 1},
                    opacity: i === this.totalImages-1 ? 1 : 0,
                    x: i === this.totalImages-1 ? '0%' : null,
                    y: i === this.totalImages-1 ? '0%' : null,
                    rotation: 0
                }), i*0.02);
            }
        }
        hideImage() {
            gsap.killTweensOf(this.DOM.revealImgs);
            this.tl = new gsap.timeline({
                onStart: () => {
                    gsap.set(this.DOM.el, {zIndex: 999});
                },
                onComplete: () => {
                    gsap.set(this.DOM.el, {zIndex: ''});
                    gsap.set(this.DOM.reveal, {opacity: 0});
                }
            })
            .add(gsap.to(this.DOM.revealImgs[this.totalImages-1], PARAMS.useDefaultVal ? 0.15 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease,
                opacity: 0
            }))
        }
        animateLetters() {
            gsap.killTweensOf(this.DOM.letters);
            this.DOM.letters.forEach((letter) => {
                const opts = Math.round(Math.random()) === 0 ? {x: '-100%', y: '-100%', opacity: 0} : {opacity: 0};
                gsap.set(letter, opts);
            });
            gsap.to(this.DOM.letters, PARAMS.useDefaultVal ? 0.6 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                x: '0%',
                y: '0%',
                opacity: 1
            });
        }
    }

    // Effect 17
    class HoverImgFx17 {
        constructor(el) {
            this.DOM = {el: el};
            
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'hover-reveal';
            this.totalImages = 10;
            let inner = '';
            for (let i = 0; i <= this.totalImages-1; ++i) {
                inner += `<div class="hover-reveal__img" style="position: absolute; background-image:url(${this.DOM.el.dataset.img})"></div>`;
            }
            this.DOM.reveal.innerHTML = inner;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealImgs = [...this.DOM.reveal.querySelectorAll('.hover-reveal__img')];
            charming(this.DOM.el);
            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
            this.initEvents();
        }
        initEvents() {
            this.positionElement = (ev) => {
                const mousePos = getMousePos(ev);
                const docScrolls = {
                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
                    top : document.body.scrollTop + document.documentElement.scrollTop
                };
                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
            };
            this.mouseenterFn = (ev) => {
                this.positionElement(ev);
                this.animateLetters();
                this.showImage();
            };
            this.mousemoveFn = ev => requestAnimationFrame(() => {
                this.positionElement(ev);
            });
            this.mouseleaveFn = () => {
                this.hideImage();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
        }
        showImage() {
            gsap.killTweensOf(this.DOM.revealImgs);
            this.tl = new gsap.timeline({
                onStart: () => {
                    this.DOM.reveal.style.opacity = 1;
                    gsap.set(this.DOM.el, {zIndex: 1000});
                }
            })
            .set(this.DOM.revealImgs, {opacity: 0, transformOrigin: '0% 100%'});
            
            for (let i = 0; i <= this.totalImages-1; ++i) {
                gsap.set(this.DOM.revealImgs[i], {
                    x: `${(this.totalImages-1-i)*15}%`, 
                    y: `${(this.totalImages-1-i)*-10}%`,
                    rotation: `${getRandomFloat(-7,7)}deg`,
                    scale: `${i === this.totalImages-1 ? 1 : getRandomFloat(0.2,1)}`,
                });
                
                this.tl.add(gsap.to(this.DOM.revealImgs[i], i === this.totalImages-1 ? 0.8 : 0.55, {
                    ease: i === this.totalImages-1 ? Quint.easeOut : Quad.easeInOut,
                    startAt: i === this.totalImages-1 ? {opacity: 1, x: '5%', y: '-10%'} : {opacity: 1},
                    opacity: i === this.totalImages-1 ? 1 : 0,
                    x: i === this.totalImages-1 ? '0%' : null,
                    y: i === this.totalImages-1 ? '0%' : null,
                    //scale: 1
                }), i*0.06);
            }
        }
        hideImage() {
            gsap.killTweensOf(this.DOM.revealImgs);
            this.tl = new gsap.timeline({
                onStart: () => {
                    gsap.set(this.DOM.el, {zIndex: 999});
                },
                onComplete: () => {
                    gsap.set(this.DOM.el, {zIndex: ''});
                    gsap.set(this.DOM.reveal, {opacity: 0});
                }
            })
            .add(gsap.to(this.DOM.revealImgs[this.totalImages-1], PARAMS.useDefaultVal ? 0.15 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease,
                opacity: 0
            }))
        }
        animateLetters() {
            gsap.killTweensOf(this.DOM.letters);
            this.DOM.letters.forEach((letter) => {
                const opts = Math.round(Math.random()) === 0 ? {x: '100%', y: '-100%', opacity: 0} : {opacity: 0};
                gsap.set(letter, opts);
            });
            gsap.to(this.DOM.letters, PARAMS.useDefaultVal ? 1 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                x: '0%',
                y: '0%',
                opacity: 1
            });
        }
    }

    // Effect 18
    class HoverImgFx18 {
        constructor(el) {
            this.DOM = {el: el};
            
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'hover-reveal';
            this.totalImages = 10;
            let inner = '';
            for (let i = 0; i <= this.totalImages-1; ++i) {
                inner += `<div class="hover-reveal__img" style="position: absolute; background-image:url(${this.DOM.el.dataset.img})"></div>`;
            }
            this.DOM.reveal.innerHTML = inner;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealImgs = [...this.DOM.reveal.querySelectorAll('.hover-reveal__img')];
            this.rect = this.DOM.reveal.getBoundingClientRect();
            charming(this.DOM.el);
            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
            this.initEvents();
        }
        initEvents() {
            this.positionElement = (ev) => {
                const mousePos = getMousePos(ev);
                const docScrolls = {
                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
                    top : document.body.scrollTop + document.documentElement.scrollTop
                };
                this.DOM.reveal.style.top = `${mousePos.y-this.rect.height-20-docScrolls.top}px`;
                this.DOM.reveal.style.left = `${mousePos.x-this.rect.width-20-docScrolls.left}px`;
            };
            this.mouseenterFn = (ev) => {
                this.positionElement(ev);
                this.animateLetters();
                this.showImage();
            };
            this.mousemoveFn = ev => requestAnimationFrame(() => {
                this.positionElement(ev);
            });
            this.mouseleaveFn = () => {
                this.hideImage();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
        }
        showImage() {
            gsap.killTweensOf(this.DOM.revealImgs);
            this.tl = new gsap.timeline({
                onStart: () => {
                    this.DOM.reveal.style.opacity = 1;
                    gsap.set(this.DOM.el, {zIndex: 1000});
                }
            })
            .set(this.DOM.revealImgs, {opacity: 0});

            for (let i = 0; i <= this.totalImages-1; ++i) {
                gsap.set(this.DOM.revealImgs[i], {
                    x: `${(this.totalImages-1-i)*-50}%`, 
                    y: `${(this.totalImages-1-i)*-getRandomFloat(-2,2)}%`,
                    rotation: `${i !== this.totalImages-1 ? getRandomFloat(-5,5) : 0}deg`
                });
                
                this.tl.add(gsap.to(this.DOM.revealImgs[i], i === this.totalImages-1 ? 0.4 : 0.55, {
                    ease: i === this.totalImages-1 ? Back.easeOut : Quad.easeInOut,
                    startAt: i === this.totalImages-1 ? {opacity: 1, x: '-50%', y: '0%'} : {opacity: 1},
                    opacity: i === this.totalImages-1 ? 1 : 0,
                    x: i === this.totalImages-1 ? '0%' : null,
                    y: i === this.totalImages-1 ? '0%' : null,
                }), i*0.02);
            }
        }
        hideImage() {
            gsap.killTweensOf(this.DOM.revealImgs);
            this.tl = new gsap.timeline({
                onStart: () => {
                    gsap.set(this.DOM.el, {zIndex: 999});
                },
                onComplete: () => {
                    gsap.set(this.DOM.el, {zIndex: ''});
                    gsap.set(this.DOM.reveal, {opacity: 0});
                }
            })
            .add(gsap.to(this.DOM.revealImgs[this.totalImages-1], PARAMS.useDefaultVal ? 0.15 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease,
                opacity: 0
            }))
        }
        animateLetters() {
            gsap.killTweensOf(this.DOM.letters);
            this.DOM.letters.forEach((letter) => {
                const opts = Math.round(Math.random()) === 0 ? {x: '-100%', opacity: 0} : {opacity: 0};
                gsap.set(letter, opts);
            });
            gsap.to(this.DOM.letters, PARAMS.useDefaultVal ? 1 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                x: '0%',
                opacity: 1
            });
        }
    }

    // Effect 19
    class HoverImgFx19 {
        constructor(el) {
            this.DOM = {el: el};
            
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'hover-reveal';
            this.totalImages = 35;
            let inner = '';
            for (let i = 0; i <= this.totalImages-1; ++i) {
                inner += `<div class="hover-reveal__img" style="position: absolute; background-image:url(${this.DOM.el.dataset.img})"></div>`;
            }
            this.DOM.reveal.innerHTML = inner;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealImgs = [...this.DOM.reveal.querySelectorAll('.hover-reveal__img')];
            this.rect = this.DOM.reveal.getBoundingClientRect();
            charming(this.DOM.el);
            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
            this.initEvents();
        }
        initEvents() {
            this.positionElement = (ev) => {
                const mousePos = getMousePos(ev);
                const docScrolls = {
                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
                    top : document.body.scrollTop + document.documentElement.scrollTop
                };
                this.DOM.reveal.style.top = `${mousePos.y-this.rect.height-20-docScrolls.top}px`;
                this.DOM.reveal.style.left = `${mousePos.x-this.rect.width-20-docScrolls.left}px`;
            };
            this.mouseenterFn = (ev) => {
                this.positionElement(ev);
                this.animateLetters();
                this.showImage();
            };
            this.mousemoveFn = ev => requestAnimationFrame(() => {
                this.positionElement(ev);
            });
            this.mouseleaveFn = () => {
                this.hideImage();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
        }
        showImage() {
            gsap.killTweensOf(this.DOM.revealImgs);
            this.tl = new gsap.timeline({
                onStart: () => {
                    this.DOM.reveal.style.opacity = 1;
                    gsap.set(this.DOM.el, {zIndex: 1000});
                }
            })
            .set(this.DOM.revealImgs, {opacity: 0, transformOrigin: '100% 100%'});

            for (let i = 0; i <= this.totalImages-1; ++i) {
                gsap.set(this.DOM.revealImgs[i], {
                    x: `${(this.totalImages-1-i)*-8}%`, 
                    y: `${(this.totalImages-1-i)*-5}%`,
                    rotation: `${i !== this.totalImages-1 ? -1+3*(this.totalImages-i-1) : 0}deg`,
                    scale: `${mapNumber(i,0,this.totalImages-1,0.1,1)}`
                });
                
                this.tl.add(gsap.to(this.DOM.revealImgs[i], i === this.totalImages-1 ? 0.8 : 0.55, {
                    ease: i === this.totalImages-1 ? Back.easeOut : Quint.easeOut,
                    startAt: i === this.totalImages-1 ? {opacity: 1, x: '-5%', y: '-5%', rotation: -10} : {opacity: 1},
                    opacity: i === this.totalImages-1 ? 1 : 0,
                    x: i === this.totalImages-1 ? '0%' : null,
                    y: i === this.totalImages-1 ? '0%' : null,
                    rotation: i === this.totalImages-1 ? 0 : null
                }), i*0.01);
            }
        }
        hideImage() {
            gsap.killTweensOf(this.DOM.revealImgs);
            this.tl = new gsap.timeline({
                onStart: () => {
                    gsap.set(this.DOM.el, {zIndex: 999});
                },
                onComplete: () => {
                    gsap.set(this.DOM.el, {zIndex: ''});
                    gsap.set(this.DOM.reveal, {opacity: 0});
                }
            })
            .add(gsap.to(this.DOM.revealImgs[this.totalImages-1], PARAMS.useDefaultVal ? 0.15 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease,
                opacity: 0
            }))
        }
        animateLetters() {
            gsap.killTweensOf(this.DOM.letters);
            this.DOM.letters.forEach((letter) => {
                const opts = Math.round(Math.random()) === 0 ? {x: '-200%', y: '-200%', opacity: 0} : {opacity: 0};
                gsap.set(letter, opts);
            });
            gsap.to(this.DOM.letters, PARAMS.useDefaultVal ? 0.8 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                x: '0%',
                y: '0%',
                opacity: 1
            });
        }
    }

    // Effect 20
    class HoverImgFx20 {
        constructor(el) {
            this.DOM = {el: el};
            
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'hover-reveal';
            this.totalImages = 10;
            let inner = '';
            for (let i = 0; i <= this.totalImages-1; ++i) {
                inner += i === this.totalImages-1 ? `<div class="hover-reveal__img" style="position: absolute; background-image:url(${this.DOM.el.dataset.img})"></div>` :
                                                    `<div class="hover-reveal__img" style="filter: hue-rotate(60deg) saturate(5); position: absolute; background-image:url(${this.DOM.el.dataset.img})"></div>`;
            }
            this.DOM.reveal.innerHTML = inner;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealImgs = [...this.DOM.reveal.querySelectorAll('.hover-reveal__img')];
            charming(this.DOM.el);
            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
            this.letterColor = getComputedStyle(this.DOM.el).color;
            this.initEvents();
        }
        initEvents() {
            this.positionElement = (ev) => {
                const mousePos = getMousePos(ev);
                const docScrolls = {
                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
                    top : document.body.scrollTop + document.documentElement.scrollTop
                };
                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
            };
            this.mouseenterFn = (ev) => {
                this.positionElement(ev);
                this.showImage();
                this.animateLetters();
            };
            this.mousemoveFn = ev => requestAnimationFrame(() => {
                this.positionElement(ev);
            });
            this.mouseleaveFn = () => {
                this.hideImage();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
        }
        showImage() {
            gsap.killTweensOf(this.DOM.revealImgs);
            this.tl = new gsap.timeline({
                onStart: () => {
                    this.DOM.reveal.style.opacity = 1;
                    gsap.set(this.DOM.el, {zIndex: 1000});
                }
            })
            .set([this.DOM.revealImgs], {opacity: 0});
            for (let i = 0; i <= this.totalImages-1; ++i) {
                gsap.set(this.DOM.revealImgs[i], {
                    x: i === this.totalImages-1 ? '0%' : `${getRandomFloat(-5,5)}%`, 
                    y: i === this.totalImages-1 ? '0%' : `${getRandomFloat(-5,5)}%`
                });
                
                this.tl.add(gsap.to(this.DOM.revealImgs[i], PARAMS.useDefaultVal ? 0.25 : PARAMS.duration, {
                    ease: PARAMS.useDefaultVal ? Quad.easeOut : PARAMS.ease,
                    startAt: {opacity: 1},
                    opacity: i === this.totalImages-1 ? 1 : 0
                }), i*0.04);
            }
        }
        hideImage() {
            gsap.killTweensOf(this.DOM.revealImgs);
            this.tl = new gsap.timeline({
                onStart: () => {
                    gsap.set(this.DOM.el, {zIndex: 999});
                },
                onComplete: () => {
                    gsap.set(this.DOM.el, {zIndex: ''});
                    gsap.set(this.DOM.reveal, {opacity: 0});
                }
            })
            .add(gsap.to(this.DOM.revealImgs[this.totalImages-1], PARAMS.useDefaultVal ? 0.15 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease,
                opacity: 0
            }))
        }
        animateLetters() {
            const setColor = letter => gsap.set(letter, {
                color: ['#fff', '#0ff', '#f0f'][parseInt(getRandomFloat(0,3))],
                opacity: Math.round(Math.random()) === 0 ? 1 : 0
            });
            this.DOM.letters.forEach((letter) => {
                gsap.to(letter, PARAMS.useDefaultVal ? 0.1 : PARAMS.duration, {
                    ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                    onStart: () => setColor(letter),
                    onRepeat: () => setColor(letter),
                    startAt: {x: `${getRandomFloat(-50,50)}%`, y: `${getRandomFloat(-50,50)}%`},
                    x: '0%',
                    y: '0%',
                    repeat: 3,
                    onComplete: () => gsap.set(letter, {color: this.letterColor, opacity: 1}),
                });
            });
        }
    }

    // Effect 21
    class HoverImgFx21 {
        constructor(el) {
            this.DOM = {el: el};
            
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'hover-reveal';
            this.totalImages = 15;
            let inner = '';
            for (let i = 0; i <= this.totalImages-1; ++i) {
                inner += i === this.totalImages-1 ? `<div class="hover-reveal__img" style="position: absolute; background-image:url(${this.DOM.el.dataset.img})"></div>` :
                                                    `<div class="hover-reveal__img" style="filter: hue-rotate(90deg) saturate(9); position: absolute; background-image:url(${this.DOM.el.dataset.img})"></div>`;
            }
            this.DOM.reveal.innerHTML = inner;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealImgs = [...this.DOM.reveal.querySelectorAll('.hover-reveal__img')];
            this.rect = this.DOM.reveal.getBoundingClientRect();
            charming(this.DOM.el);
            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
            this.letterColor = getComputedStyle(this.DOM.el).color;
            this.initEvents();
        }
        initEvents() {
            this.positionElement = (ev) => {
                const mousePos = getMousePos(ev);
                const docScrolls = {
                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
                    top : document.body.scrollTop + document.documentElement.scrollTop
                };
                this.DOM.reveal.style.top = `${mousePos.y-this.rect.height-20-docScrolls.top}px`;
                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
            };
            this.mouseenterFn = (ev) => {
                this.positionElement(ev);
                this.animateLetters();
                this.showImage();
            };
            this.mousemoveFn = ev => requestAnimationFrame(() => {
                this.positionElement(ev);
            });
            this.mouseleaveFn = () => {
                this.hideImage();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
        }
        showImage() {
            gsap.killTweensOf(this.DOM.revealImgs);
            this.tl = new gsap.timeline({
                onStart: () => {
                    this.DOM.reveal.style.opacity = 1;
                    gsap.set(this.DOM.el, {zIndex: 1000});
                }
            })
            .set(this.DOM.revealImgs, {opacity: 0});

            for (let i = 0; i <= this.totalImages-1; ++i) {
                gsap.set(this.DOM.revealImgs[i], {
                    x: `${i !== this.totalImages-1 ? getRandomFloat(-45,45) : 0}%`, 
                    y: `${i !== this.totalImages-1 ? getRandomFloat(-45,45) : 0}%`,
                    rotation: `${i !== this.totalImages-1 ? getRandomFloat(-10,10) : 0}`,
                    scale: `${i !== this.totalImages-1 ? getRandomFloat(0.1,1.2) : 0.9}`
                });
                
                this.tl.add(gsap.to(this.DOM.revealImgs[i], PARAMS.useDefaultVal ? 0.5 : PARAMS.duration, {
                    ease: Quint.easeOut,
                    startAt: i === this.totalImages-1 ? {opacity: 1, x: '0%', y: '0%'} : {opacity: 1},
                    opacity: i === this.totalImages-1 ? 1 : 0,
                    x: i === this.totalImages-1 ? '0%' : null,
                    y: i === this.totalImages-1 ? '0%' : null,
                    scale: i === this.totalImages-1 ? 1 : null
                }), i*0.02);
            }
        }
        hideImage() {
            gsap.killTweensOf(this.DOM.revealImgs);
            this.tl = new gsap.timeline({
                onStart: () => {
                    gsap.set(this.DOM.el, {zIndex: 999});
                },
                onComplete: () => {
                    gsap.set(this.DOM.el, {zIndex: ''});
                    gsap.set(this.DOM.reveal, {opacity: 0});
                }
            })
            .add(gsap.to(this.DOM.revealImgs[this.totalImages-1], PARAMS.useDefaultVal ? 0.15 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease,
                opacity: 0
            }))
        }
        animateLetters() {
            const setColor = letter => gsap.set(letter, {
                color: ['#fff', '#0ff', '#f0f'][parseInt(getRandomFloat(0,3))],
                opacity: Math.round(Math.random()) === 0 ? 1 : 0
            });
            this.DOM.letters.forEach((letter) => {
                gsap.to(letter, PARAMS.useDefaultVal ? 0.1 : PARAMS.duration, {
                    ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                    onStart: () => setColor(letter),
                    onRepeat: () => setColor(letter),
                    startAt: {x: `${getRandomFloat(-50,50)}%`, y: `${getRandomFloat(-50,50)}%`},
                    x: '0%',
                    y: '0%',
                    repeat: 3,
                    onComplete: () => gsap.set(letter, {color: this.letterColor, opacity: 1}),
                });
            });
        }
    }
	
    // Effect 22
    class HoverImgFx22 {
        constructor(el) {
            this.DOM = {el: el};
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'hover-reveal';
            this.DOM.reveal.innerHTML = `<div class="hover-reveal__img" style="background-image:url(${this.DOM.el.dataset.img})"></div>`;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealImg = this.DOM.reveal.querySelector('.hover-reveal__img');

            this.initEvents();
        }
        initEvents() {
            this.positionElement = (ev) => {
                const mousePos = getMousePos(ev);
                const docScrolls = {
                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
                    top : document.body.scrollTop + document.documentElement.scrollTop
                };
                this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
                this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
            };
            this.mouseenterFn = (ev) => {
                this.positionElement(ev);
                this.showImage();
            };
            this.mousemoveFn = ev => requestAnimationFrame(() => {
                this.positionElement(ev);
            });
            this.mouseleaveFn = () => {
                this.hideImage();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
        }
        showImage() {
            gsap.killTweensOf(this.DOM.revealImg);

            this.tl = new gsap.timeline({
                onStart: () => {
                    this.DOM.reveal.style.opacity = 1;
                    gsap.set(this.DOM.el, {zIndex: 1000});
                }
            })
            .add('begin')
            .set(this.DOM.revealImg, {transformOrigin: '95% 50%', x: '100%'})
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.2 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease,
                startAt: {scaleX: 0.5, scaleY: 1},
                scaleX: 1.5,
                scaleY: 0.7
            }), 'begin')
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.8 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                startAt: {rotation: 10, y: '5%', opacity: 0},
                rotation: 0,
                y: '0%',
                opacity: 1
            }), 'begin')
            .set(this.DOM.revealImg, {transformOrigin: '0% 50%'})
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.6 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                scaleX: 1,
                scaleY: 1,
                opacity: 1
            }), 'begin+=0.2')
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.6 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                x: '0%'
            }), 'begin+=0.2')
        }
        hideImage() {
            gsap.killTweensOf(this.DOM.revealImg);

            this.tl = new gsap.timeline({
                onStart: () => {
                    gsap.set(this.DOM.el, {zIndex: 999});
                },
                onComplete: () => {
                    gsap.set(this.DOM.el, {zIndex: ''});
                    gsap.set(this.DOM.reveal, {opacity: 0});
                }
            })
            .add('begin')
            .add(gsap.to(this.DOM.revealImg, PARAMS.useDefaultVal ? 0.2 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease,
                opacity: 0,
                x: '-20%'
            }), 'begin');
        }
    }    

    // Effect 23
    class HoverImgFx23 {
        constructor(el) {
            this.DOM = {el: el};
            
            this.DOM.reveal = document.createElement('div');
            this.DOM.reveal.className = 'hover-reveal';
            this.totalImages = 15;
            let inner = '';
            for (let i = 0; i <= this.totalImages-1; ++i) {
                inner += `<div class="hover-reveal__img" style="position: absolute; background-image:url(${this.DOM.el.dataset.img})"></div>`;
            }
            this.DOM.reveal.innerHTML = inner;
            this.DOM.el.appendChild(this.DOM.reveal);
            this.DOM.revealImgs = [...this.DOM.reveal.querySelectorAll('.hover-reveal__img')];
            this.rect = this.DOM.reveal.getBoundingClientRect();
            charming(this.DOM.el);
            this.DOM.letters = [...this.DOM.el.querySelectorAll('span')];
            this.initEvents();
        }
        initEvents() {
            this.positionElement = (ev) => {
                const mousePos = getMousePos(ev);
                const docScrolls = {
                    left : document.body.scrollLeft + document.documentElement.scrollLeft, 
                    top : document.body.scrollTop + document.documentElement.scrollTop
                };
                this.DOM.reveal.style.top = `${mousePos.y-this.rect.height-20-docScrolls.top}px`;
                this.DOM.reveal.style.left = `${mousePos.x-this.rect.width-20-docScrolls.left}px`;
            };
            this.mouseenterFn = (ev) => {
                this.positionElement(ev);
                this.animateLetters();
                this.showImage();
            };
            this.mousemoveFn = ev => requestAnimationFrame(() => {
                this.positionElement(ev);
            });
            this.mouseleaveFn = () => {
                this.hideImage();
            };
            
            this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
            this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
            this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
        }
        showImage() {
            gsap.killTweensOf(this.DOM.revealImgs);
            this.tl = new gsap.timeline({
                onStart: () => {
                    this.DOM.reveal.style.opacity = 1;
                    gsap.set(this.DOM.el, {zIndex: 1000});
                }
            })
            .set(this.DOM.revealImgs, {opacity: 0});

            for (let i = 0; i <= this.totalImages-1; ++i) {
                gsap.set(this.DOM.revealImgs[i], {
                    x: `${i*getRandomFloat(-10,10)}%`, 
                    y: `${i*getRandomFloat(-15,15)}%`,
                    rotation: `${i !== this.totalImages-1 ? getRandomFloat(-7,7) : 0}deg`,
                    scale: `${getRandomFloat(0.1,0.5)}`
                });
                
                this.tl.add(gsap.to(this.DOM.revealImgs[i], i === this.totalImages-1 ? 0.8 : 0.5, {
                    ease: i === this.totalImages-1 ? Expo.easeOut : Quint.easeOut,
                    startAt: i === this.totalImages-1 ? {opacity: 1, x: '0%', y: '-10%'} : {opacity: 1},
                    opacity: i === this.totalImages-1 ? 1 : 0,
                    x: i === this.totalImages-1 ? '0%' : null,
                    y: i === this.totalImages-1 ? '0%' : null,
                    scale: i === this.totalImages-1 ? 1 : 0.6
                }), i*0.04);
            }
        }
        hideImage() {
            gsap.killTweensOf(this.DOM.revealImgs);
            this.tl = new gsap.timeline({
                onStart: () => {
                    gsap.set(this.DOM.el, {zIndex: 999});
                },
                onComplete: () => {
                    gsap.set(this.DOM.el, {zIndex: ''});
                    gsap.set(this.DOM.reveal, {opacity: 0});
                }
            })
            .add(gsap.to(this.DOM.revealImgs[this.totalImages-1], 0.15, {
                ease: PARAMS.useDefaultVal ? Sine.easeOut : PARAMS.ease,
                opacity: 0
            }))
        }
        animateLetters() {
            gsap.killTweensOf(this.DOM.letters);
            this.DOM.letters.forEach((letter) => {
                const opts = Math.round(Math.random()) === 0 ? {scale: 0, opacity: 0} : {opacity: 0};
                gsap.set(letter, opts);
            });
            gsap.to(this.DOM.letters, PARAMS.useDefaultVal ? 1 : PARAMS.duration, {
                ease: PARAMS.useDefaultVal ? Expo.easeOut : PARAMS.ease,
                scale: 1,
                opacity: 1
            });
        }
    }
    
    [...document.querySelectorAll('[data-fx="1"] > a, a[data-fx="1"]')].forEach(link => new HoverImgFx1(link));
    [...document.querySelectorAll('[data-fx="2"] > a, a[data-fx="2"]')].forEach(link => new HoverImgFx2(link));
    [...document.querySelectorAll('[data-fx="3"] > a, a[data-fx="3"]')].forEach(link => new HoverImgFx3(link));
    [...document.querySelectorAll('[data-fx="4"] > a, a[data-fx="4"]')].forEach(link => new HoverImgFx4(link));
    [...document.querySelectorAll('[data-fx="5"] > a, a[data-fx="5"]')].forEach(link => new HoverImgFx5(link));
    [...document.querySelectorAll('[data-fx="6"] > a, a[data-fx="6"]')].forEach(link => new HoverImgFx6(link));
    [...document.querySelectorAll('[data-fx="7"] > a, a[data-fx="7"]')].forEach(link => new HoverImgFx7(link));
    [...document.querySelectorAll('[data-fx="8"] > a, a[data-fx="8"]')].forEach(link => new HoverImgFx8(link));
    [...document.querySelectorAll('[data-fx="9"] > a, a[data-fx="9"]')].forEach(link => new HoverImgFx9(link));
    [...document.querySelectorAll('[data-fx="10"] > a, a[data-fx="10"]')].forEach(link => new HoverImgFx10(link));
    [...document.querySelectorAll('[data-fx="11"] > a, a[data-fx="11"]')].forEach(link => new HoverImgFx11(link));
    [...document.querySelectorAll('[data-fx="12"] > a, a[data-fx="12"]')].forEach(link => new HoverImgFx12(link));
    [...document.querySelectorAll('[data-fx="13"] > a, a[data-fx="13"]')].forEach(link => new HoverImgFx13(link));
    [...document.querySelectorAll('[data-fx="14"] > a, a[data-fx="14"]')].forEach(link => new HoverImgFx14(link));
    [...document.querySelectorAll('[data-fx="15"] > a, a[data-fx="15"]')].forEach(link => new HoverImgFx15(link));
    [...document.querySelectorAll('[data-fx="16"] > a, a[data-fx="16"]')].forEach(link => new HoverImgFx16(link));
    [...document.querySelectorAll('[data-fx="17"] > a, a[data-fx="17"]')].forEach(link => new HoverImgFx17(link));
    [...document.querySelectorAll('[data-fx="18"] > a, a[data-fx="18"]')].forEach(link => new HoverImgFx18(link));
    [...document.querySelectorAll('[data-fx="19"] > a, a[data-fx="19"]')].forEach(link => new HoverImgFx19(link));
    [...document.querySelectorAll('[data-fx="20"] > a, a[data-fx="20"]')].forEach(link => new HoverImgFx20(link));
    [...document.querySelectorAll('[data-fx="21"] > a, a[data-fx="21"]')].forEach(link => new HoverImgFx21(link));
    [...document.querySelectorAll('[data-fx="22"] > a, a[data-fx="22"]')].forEach(link => new HoverImgFx22(link));
    [...document.querySelectorAll('[data-fx="23"] > a, a[data-fx="23"]')].forEach(link => new HoverImgFx23(link));

    // Demo purspose only: Preload all the images in the page..
    const contentel = document.querySelector('.content');
    [...document.querySelectorAll('.block__title, .block__link, .content__text-link')].forEach((el) => {
        const imgsArr = el.dataset.img.split(',');
        for (let i = 0, len = imgsArr.length; i <= len-1; ++i ) {
            const imgel = document.createElement('img');
            imgel.style.visibility = 'hidden';
            imgel.style.width = 0;
            imgel.src = imgsArr[i];
            imgel.className = 'preload';
            contentel.appendChild(imgel);
        }
    });
    imagesLoaded(document.querySelectorAll('.preload'), () => document.body.classList.remove('loading'));
}
              
            
!
999px

Console