[
  {
    "path": ".gitignore",
    "content": "*.DS_Store\n"
  },
  {
    "path": "README.md",
    "content": "# Image Trail Effects\nA set of effects for mouse-following image trails that show a random series of images. Inspired by the effect seen on [VLNC Studio](http://www.vlnc.studio/).\n\n![Image Trail Effects](https://tympanus.net/codrops/wp-content/uploads/2019/08/ImageTrailEffects_featured.jpg)\n\n[Article on Codrops](https://tympanus.net/codrops/?p=42696)\n\n[Demo](https://tympanus.net/Development/ImageTrailEffects/)\n\n## Credits\n\n- [TweenMax](https://greensock.com/tweenmax) by Greensock\n- [imagesLoaded](https://imagesloaded.desandro.com/) by Dave DeSandro\n- Images from [Unsplash.com](https://unsplash.com/) \n\n## License\nThis resource can be used freely if integrated or build upon in personal or commercial projects such as websites, web apps and web templates intended for sale. It is not allowed to take the resource \"as-is\" and sell it, redistribute, re-publish it, or sell \"pluginized\" versions of it. Free plugins built using this resource should have a visible mention and link to the original work. Always consider the licenses of all included libraries, scripts and images used.\n\n## Misc\n\nFollow Codrops: [Twitter](http://www.twitter.com/codrops), [Facebook](http://www.facebook.com/codrops), [Google+](https://plus.google.com/101095823814290637419), [GitHub](https://github.com/codrops), [Pinterest](http://www.pinterest.com/codrops/), [Instagram](https://www.instagram.com/codropsss/)\n\n\n[© Codrops 2019](http://www.codrops.com)\n\n\n\n\n\n"
  },
  {
    "path": "css/base.css",
    "content": "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;}\r\n*,\r\n*::after,\r\n*::before {\r\n\tbox-sizing: border-box;\r\n}\r\n\r\n:root {\r\n\tfont-size: 16px;\r\n}\r\n\r\nhtml, body {\r\n\theight: 100%;\r\n}\r\n\r\nbody {\r\n\t--color-text: #262523;\r\n    --color-bg: #efece5;\r\n    --color-link: #eca324;\r\n    --color-link-hover: #262523;\r\n    --color-title: #ffffff;\r\n    --img-maxwidth: 250px;\r\n    --blendmode-title: difference;\r\n    --filter-img: none;\r\n\tcolor: var(--color-text);\r\n\tbackground-color: var(--color-bg);\r\n\tfont-family: quiroh, sans-serif;\r\n\t-webkit-font-smoothing: antialiased;\r\n\t-moz-osx-font-smoothing: grayscale;\r\n}\r\n\r\n.demo-2 {\r\n\t--color-text: #ffffff;\r\n    --color-bg: #151413;\r\n    --color-link: #d02d55;\r\n    --color-link-hover: #ffffff;\r\n    --color-title: #232323;\r\n}\r\n\r\n.demo-3 {\r\n\t--color-text: #320065;\r\n    --color-bg: #d02d55;\r\n    --color-link: #ffffff;\r\n    --color-link-hover: #000000;\r\n    --color-title: #320065;\r\n    --filter-img: sepia(1) saturate(1) contrast(180%) brightness(80%) hue-rotate(295deg);\r\n}\r\n\r\n.demo-4 {\r\n\t--color-text: #000000;\r\n    --color-bg: #e0fafb;\r\n    --color-link: #ff3a7e;\r\n    --color-link-hover: #000000;\r\n    --color-title: #f9dae5;\r\n}\r\n\r\n.demo-5 {\r\n\t--color-text: #ffffff;\r\n    --color-bg: #485656;\r\n    --color-link: #000000;\r\n    --color-link-hover: #ffffff;\r\n    --color-title: #444c4c;\r\n    --filter-img: hue-rotate(70deg) contrast(70%);\r\n}\r\n\r\n.demo-6 {\r\n\t--color-text: #fff;\r\n    --color-bg: #000;\r\n    --color-link: #f0f0f0;\r\n    --color-link-hover: #fff;\r\n    --color-title: #fff;\r\n    --img-maxwidth: none;\r\n    --blendmode-title: overlay;\r\n}\r\n\r\n/* Page Loader */\r\n.js .loading::before {\r\n\tcontent: '';\r\n\tposition: fixed;\r\n\tz-index: 100000;\r\n\ttop: 0;\r\n\tleft: 0;\r\n\twidth: 100%;\r\n\theight: 100%;\r\n\tbackground: var(--color-bg);\r\n}\r\n\r\n.js .loading::after {\r\n\tcontent: '';\r\n\tposition: fixed;\r\n\tz-index: 100000;\r\n\ttop: 50%;\r\n\tleft: 50%;\r\n\twidth: 60px;\r\n\theight: 60px;\r\n\tmargin: -30px 0 0 -30px;\r\n\tpointer-events: none;\r\n\tborder-radius: 50%;\r\n\topacity: 0.4;\r\n\tbackground: var(--color-link);\r\n\tanimation: loaderAnim 0.7s linear infinite alternate forwards;\r\n}\r\n\r\n@keyframes loaderAnim {\r\n\tto {\r\n\t\topacity: 1;\r\n\t\ttransform: scale3d(0.5,0.5,1);\r\n\t}\r\n}\r\n\r\na {\r\n\ttext-decoration: none;\r\n\tcolor: var(--color-link);\r\n\t\r\n}\r\n\r\na:hover,\r\na:focus {\r\n\tcolor: var(--color-link-hover);\r\n\toutline: 0;\r\n}\r\n\r\n.message {\r\n\tpadding: 1rem;\r\n\tcolor: var(--color-bg);\r\n\tbackground: var(--color-text);\r\n\ttext-align: center;\r\n\tfont-weight: bold;\r\n}\r\n\r\n.frame {\r\n\tpadding: 1rem;\r\n\ttext-align: center;\r\n\tposition: relative;\r\n\tz-index: 1000;\r\n\tgrid-area: 1 / 1 / 2 / 2;\r\n\talign-self: start;\r\n}\r\n\r\n.frame__title {\r\n\tfont-size: 1rem;\r\n\tmargin: 0 0 1rem;\r\n}\r\n\r\n.frame__links {\r\n\tdisplay: inline;\r\n}\r\n\r\n.frame__github,\r\n.frame__links a:not(:last-child),\r\n.frame__demos a:not(:last-child) {\r\n\tmargin-right: 1rem;\r\n}\r\n\r\n.frame__demos {\r\n\tmargin: 1rem 0;\r\n}\r\n\r\n.frame__demo--current,\r\n.frame__demo--current:hover {\r\n\tcolor: var(--color-text);\r\n\ttext-decoration: line-through;\r\n\tletter-spacing: 40px;\r\n}\r\n\r\n.frame__pagetitle {\r\n\tmargin: 3rem 0 0 0;\r\n}\r\n\r\n.frame__pagetitle span {\r\n\tdisplay: block;\r\n\tfont-weight: normal;\r\n\tfont-size: 0.85rem;\r\n}\r\n\r\n.frame__pagetitle span::before {\r\n\tcontent: '\\2015   ';\r\n}\r\n\r\n.content {\r\n\theight: 300px;\r\n\tposition: relative;\r\n\tdisplay: flex;\r\n\tjustify-content: center;\r\n\talign-items: center;\r\n\tisolation: isolate;\r\n}\r\n\r\n.content__title {\r\n\tfont-family: forma-djr-display, sans-serif;\r\n\tfont-weight: 700;\r\n\tposition: relative;\r\n\tz-index: 10000;\r\n\tfont-size: 27vw;\r\n\tmix-blend-mode: var(--blendmode-title);\r\n\t-webkit-text-stroke: 2px var(--color-title);\r\n\ttext-stroke: 2px var(--color-title);\r\n\t-webkit-text-fill-color: transparent;\r\n\ttext-fill-color: transparent;\r\n\tcolor: transparent;\r\n\tpointer-events: none;\r\n}\r\n\r\n.content__img {\r\n\tmax-width: var(--img-maxwidth);\r\n\tposition: absolute;\r\n\ttop: 0;\r\n\tleft: 0;\r\n\topacity: 0;\r\n\twill-change: transform;\r\n\tfilter: var(--filter-img);\r\n}\r\n\r\n.content__img--full {\r\n\twidth: 100%;\r\n\theight: 100%;\r\n\tbackground-size: cover;\r\n}\r\n\r\n@media screen and (min-width: 53em) {\r\n\t:root {\r\n\t\tfont-size: 18px;\r\n\t}\r\n\tbody {\r\n\t\toverflow: hidden;\r\n\t}\r\n\t.message {\r\n\t\tdisplay: none;\r\n\t}\r\n\t.frame {\r\n\t\tposition: fixed;\r\n\t\ttext-align: left;\r\n\t\tz-index: 10000;\r\n\t\ttop: 0;\r\n\t\tleft: 0;\r\n\t\tdisplay: grid;\r\n\t\talign-content: space-between;\r\n\t\twidth: 100%;\r\n\t\tmax-width: none;\r\n\t\theight: 100vh;\r\n\t\tpadding: 2rem;\r\n\t\tpointer-events: none;\r\n\t\tgrid-template-columns: 75% 25%;\r\n\t\tgrid-template-rows: auto auto auto;\r\n\t\tgrid-template-areas: 'pagetitle github'\r\n\t\t\t\t\t\t\t'... ...'\r\n\t\t\t\t\t\t\t'title ...';\r\n\t}\r\n\t.frame__pagetitle {\r\n\t\tgrid-area: pagetitle;\r\n\t\tmargin: 0;\r\n\t}\t\r\n\t.frame__title-wrap {\r\n\t\tgrid-area: title;\r\n\t\tdisplay: flex;\r\n\t}\r\n\t.frame__title {\r\n\t\tmargin: 0;\r\n\t\tfont-weight: normal;\r\n\t}\r\n\t.frame__links {\r\n\t\tpadding: 0;\r\n\t\tmargin: 0 0 0 3rem;\r\n\t\tjustify-self: end;\r\n\t}\r\n\t.frame__demos {\r\n\t\tmargin: 0 0 0 3rem;\r\n\t}\r\n\t.frame__github {\r\n\t\tgrid-area: github;\r\n\t\tjustify-self: end;\r\n\t}\r\n\t.frame a {\r\n\t\tpointer-events: auto;\r\n\t}\r\n\t.content {\r\n\t\theight: 100vh;\r\n\t\toverflow: hidden;\r\n\t}\r\n}\r\n"
  },
  {
    "path": "index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\" class=\"no-js\">\n\t<head>\n\t\t<meta charset=\"UTF-8\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\t\t<title>Image Trail Effects | Demo 1 | Codrops</title>\n\t\t<meta name=\"description\" content=\"A set of fun effects for mouse-following image trails.\" />\n\t\t<meta name=\"keywords\" content=\"image trail, effect, web design, mouse, javascript, gsap\" />\n\t\t<meta name=\"author\" content=\"Codrops\" />\n\t\t<link rel=\"shortcut icon\" href=\"favicon.ico\">\n\t\t<link rel=\"stylesheet\" href=\"https://use.typekit.net/lpe8txe.css\">\n\t\t<link rel=\"stylesheet\" type=\"text/css\" href=\"css/base.css\" />\n\t\t<script>document.documentElement.className=\"js\";var supportsCssVars=function(){var e,t=document.createElement(\"style\");return t.innerHTML=\"root: { --tmp-var: bold; }\",document.head.appendChild(t),e=!!(window.CSS&&window.CSS.supports&&window.CSS.supports(\"font-weight\",\"var(--tmp-var)\")),t.parentNode.removeChild(t),e};supportsCssVars()||alert(\"Please view this demo in a modern browser that supports CSS Variables.\");</script></head>\n\t<body class=\"demo-1 loading\">\n\t\t<main>\n\t\t\t<div class=\"message\">Hover effect &mdash; please view on desktop.</div>\n\t\t\t<div class=\"frame\">\n\t\t\t\t<div class=\"frame__title-wrap\">\n\t\t\t\t\t<h1 class=\"frame__title\">Image Trail Effects</h1>\n\t\t\t\t\t<div class=\"frame__links\">\n\t\t\t\t\t\t<a href=\"https://tympanus.net/Development/SmoothScrollingImageEffects/\">Previous demo</a>\n\t\t\t\t\t\t<a href=\"https://tympanus.net/codrops/?p=42696\">Article</a>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"frame__demos\">\n\t\t\t\t\t\t<a href=\"index.html\" class=\"frame__demo frame__demo--current\">1</a>\n\t\t\t\t\t\t<a href=\"index2.html\" class=\"frame__demo\">2</a>\n\t\t\t\t\t\t<a href=\"index3.html\" class=\"frame__demo\">3</a>\n\t\t\t\t\t\t<a href=\"index4.html\" class=\"frame__demo\">4</a>\n\t\t\t\t\t\t<a href=\"index5.html\" class=\"frame__demo\">5</a>\n\t\t\t\t\t\t<a href=\"index6.html\" class=\"frame__demo\">6</a>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<a class=\"frame__github\" href=\"https://github.com/codrops/ImageTrailEffects/\">Github</a>\n\t\t\t\t<h2 class=\"frame__pagetitle\">Camille Moulin <span>Personality Stylist</span></h2>\n\t\t\t</div>\n\t\t\t<div class=\"content\">\n\t\t\t\t<img class=\"content__img\" src=\"img/1.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/2.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/3.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/4.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/5.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/6.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/7.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/8.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/9.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/10.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/11.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/12.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/13.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/14.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/15.jpg\" alt=\"Some image\" />\n\t\t\t\t<h3 class=\"content__title\">llssmmhh</h3>\n\t\t\t</div><!--/content-->\n\t\t</main>\n\t\t<script src=\"js/imagesloaded.pkgd.min.js\"></script>\n\t\t<script src=\"js/TweenMax.min.js\"></script>\n\t\t<script src=\"js/demo.js\"></script></body>\n</html>\n"
  },
  {
    "path": "index2.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\" class=\"no-js\">\n\t<head>\n\t\t<meta charset=\"UTF-8\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\t\t<title>Image Trail Effects | Demo 2 | Codrops</title>\n\t\t<meta name=\"description\" content=\"A set of fun effects for mouse-following image trails.\" />\n\t\t<meta name=\"keywords\" content=\"image trail, effect, web design, mouse, javascript, gsap\" />\n\t\t<meta name=\"author\" content=\"Codrops\" />\n\t\t<link rel=\"shortcut icon\" href=\"favicon.ico\">\n\t\t<link rel=\"stylesheet\" href=\"https://use.typekit.net/lpe8txe.css\">\n\t\t<link rel=\"stylesheet\" type=\"text/css\" href=\"css/base.css\" />\n\t\t<script>document.documentElement.className=\"js\";var supportsCssVars=function(){var e,t=document.createElement(\"style\");return t.innerHTML=\"root: { --tmp-var: bold; }\",document.head.appendChild(t),e=!!(window.CSS&&window.CSS.supports&&window.CSS.supports(\"font-weight\",\"var(--tmp-var)\")),t.parentNode.removeChild(t),e};supportsCssVars()||alert(\"Please view this demo in a modern browser that supports CSS Variables.\");</script></head>\n\t<body class=\"demo-2 loading\">\n\t\t<main>\n\t\t\t<div class=\"message\">Hover effect &mdash; please view on desktop.</div>\n\t\t\t<div class=\"frame\">\n\t\t\t\t<div class=\"frame__title-wrap\">\n\t\t\t\t\t<h1 class=\"frame__title\">Image Trail Effects</h1>\n\t\t\t\t\t<div class=\"frame__links\">\n\t\t\t\t\t\t<a href=\"https://tympanus.net/Development/SmoothScrollingImageEffects/\">Previous demo</a>\n\t\t\t\t\t\t<a href=\"https://tympanus.net/codrops/?p=42696\">Article</a>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"frame__demos\">\n\t\t\t\t\t\t<a href=\"index.html\" class=\"frame__demo\">1</a>\n\t\t\t\t\t\t<a href=\"index2.html\" class=\"frame__demo frame__demo--current\">2</a>\n\t\t\t\t\t\t<a href=\"index3.html\" class=\"frame__demo\">3</a>\n\t\t\t\t\t\t<a href=\"index4.html\" class=\"frame__demo\">4</a>\n\t\t\t\t\t\t<a href=\"index5.html\" class=\"frame__demo\">5</a>\n\t\t\t\t\t\t<a href=\"index6.html\" class=\"frame__demo\">6</a>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<a class=\"frame__github\" href=\"https://github.com/codrops/ImageTrailEffects/\">Github</a>\n\t\t\t\t<h2 class=\"frame__pagetitle\">Camille Moulin <span>Personality Stylist</span></h2>\n\t\t\t</div>\n\t\t\t<div class=\"content\">\n\t\t\t\t<img class=\"content__img\" src=\"img/1.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/2.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/3.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/4.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/5.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/6.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/7.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/8.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/9.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/10.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/11.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/12.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/13.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/14.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/15.jpg\" alt=\"Some image\" />\n\t\t\t\t<h3 class=\"content__title\">lllooolllzzz</h3>\n\t\t\t</div><!--/content-->\n\t\t</main>\n\t\t<script src=\"js/imagesloaded.pkgd.min.js\"></script>\n\t\t<script src=\"js/TweenMax.min.js\"></script>\n\t\t<script src=\"js/demo2.js\"></script></body>\n</html>\n"
  },
  {
    "path": "index3.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\" class=\"no-js\">\n\t<head>\n\t\t<meta charset=\"UTF-8\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\t\t<title>Image Trail Effects | Demo 3 | Codrops</title>\n\t\t<meta name=\"description\" content=\"A set of fun effects for mouse-following image trails.\" />\n\t\t<meta name=\"keywords\" content=\"image trail, effect, web design, mouse, javascript, gsap\" />\n\t\t<meta name=\"author\" content=\"Codrops\" />\n\t\t<link rel=\"shortcut icon\" href=\"favicon.ico\">\n\t\t<link rel=\"stylesheet\" href=\"https://use.typekit.net/lpe8txe.css\">\n\t\t<link rel=\"stylesheet\" type=\"text/css\" href=\"css/base.css\" />\n\t\t<script>document.documentElement.className=\"js\";var supportsCssVars=function(){var e,t=document.createElement(\"style\");return t.innerHTML=\"root: { --tmp-var: bold; }\",document.head.appendChild(t),e=!!(window.CSS&&window.CSS.supports&&window.CSS.supports(\"font-weight\",\"var(--tmp-var)\")),t.parentNode.removeChild(t),e};supportsCssVars()||alert(\"Please view this demo in a modern browser that supports CSS Variables.\");</script></head>\n\t<body class=\"demo-3 loading\">\n\t\t<main>\n\t\t\t<div class=\"message\">Hover effect &mdash; please view on desktop.</div>\n\t\t\t<div class=\"frame\">\n\t\t\t\t<div class=\"frame__title-wrap\">\n\t\t\t\t\t<h1 class=\"frame__title\">Image Trail Effects</h1>\n\t\t\t\t\t<div class=\"frame__links\">\n\t\t\t\t\t\t<a href=\"https://tympanus.net/Development/SmoothScrollingImageEffects/\">Previous demo</a>\n\t\t\t\t\t\t<a href=\"https://tympanus.net/codrops/?p=42696\">Article</a>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"frame__demos\">\n\t\t\t\t\t\t<a href=\"index.html\" class=\"frame__demo\">1</a>\n\t\t\t\t\t\t<a href=\"index2.html\" class=\"frame__demo\">2</a>\n\t\t\t\t\t\t<a href=\"index3.html\" class=\"frame__demo frame__demo--current\">3</a>\n\t\t\t\t\t\t<a href=\"index4.html\" class=\"frame__demo\">4</a>\n\t\t\t\t\t\t<a href=\"index5.html\" class=\"frame__demo\">5</a>\n\t\t\t\t\t\t<a href=\"index6.html\" class=\"frame__demo\">6</a>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<a class=\"frame__github\" href=\"https://github.com/codrops/ImageTrailEffects/\">Github</a>\n\t\t\t\t<h2 class=\"frame__pagetitle\">Camille Moulin <span>Personality Stylist</span></h2>\n\t\t\t</div>\n\t\t\t<div class=\"content\">\n\t\t\t\t<img class=\"content__img\" src=\"img/1.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/2.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/3.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/4.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/5.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/6.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/7.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/8.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/9.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/10.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/11.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/12.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/13.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/14.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/15.jpg\" alt=\"Some image\" />\n\t\t\t\t<h3 class=\"content__title\">oommgg</h3>\n\t\t\t</div><!--/content-->\n\t\t</main>\n\t\t<script src=\"js/imagesloaded.pkgd.min.js\"></script>\n\t\t<script src=\"js/TweenMax.min.js\"></script>\n\t\t<script src=\"js/demo3.js\"></script></body>\n</html>\n"
  },
  {
    "path": "index4.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\" class=\"no-js\">\n\t<head>\n\t\t<meta charset=\"UTF-8\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\t\t<title>Image Trail Effects | Demo 4 | Codrops</title>\n\t\t<meta name=\"description\" content=\"A set of fun effects for mouse-following image trails.\" />\n\t\t<meta name=\"keywords\" content=\"image trail, effect, web design, mouse, javascript, gsap\" />\n\t\t<meta name=\"author\" content=\"Codrops\" />\n\t\t<link rel=\"shortcut icon\" href=\"favicon.ico\">\n\t\t<link rel=\"stylesheet\" href=\"https://use.typekit.net/lpe8txe.css\">\n\t\t<link rel=\"stylesheet\" type=\"text/css\" href=\"css/base.css\" />\n\t\t<script>document.documentElement.className=\"js\";var supportsCssVars=function(){var e,t=document.createElement(\"style\");return t.innerHTML=\"root: { --tmp-var: bold; }\",document.head.appendChild(t),e=!!(window.CSS&&window.CSS.supports&&window.CSS.supports(\"font-weight\",\"var(--tmp-var)\")),t.parentNode.removeChild(t),e};supportsCssVars()||alert(\"Please view this demo in a modern browser that supports CSS Variables.\");</script></head>\n\t<body class=\"demo-4 loading\">\n\t\t<main>\n\t\t\t<div class=\"message\">Hover effect &mdash; please view on desktop.</div>\n\t\t\t<div class=\"frame\">\n\t\t\t\t<div class=\"frame__title-wrap\">\n\t\t\t\t\t<h1 class=\"frame__title\">Image Trail Effects</h1>\n\t\t\t\t\t<div class=\"frame__links\">\n\t\t\t\t\t\t<a href=\"https://tympanus.net/Development/SmoothScrollingImageEffects/\">Previous demo</a>\n\t\t\t\t\t\t<a href=\"https://tympanus.net/codrops/?p=42696\">Article</a>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"frame__demos\">\n\t\t\t\t\t\t<a href=\"index.html\" class=\"frame__demo\">1</a>\n\t\t\t\t\t\t<a href=\"index2.html\" class=\"frame__demo\">2</a>\n\t\t\t\t\t\t<a href=\"index3.html\" class=\"frame__demo\">3</a>\n\t\t\t\t\t\t<a href=\"index4.html\" class=\"frame__demo frame__demo--current\">4</a>\n\t\t\t\t\t\t<a href=\"index5.html\" class=\"frame__demo\">5</a>\n\t\t\t\t\t\t<a href=\"index6.html\" class=\"frame__demo\">6</a>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<a class=\"frame__github\" href=\"https://github.com/codrops/ImageTrailEffects/\">Github</a>\n\t\t\t\t<h2 class=\"frame__pagetitle\">Camille Moulin <span>Personality Stylist</span></h2>\n\t\t\t</div>\n\t\t\t<div class=\"content\">\n\t\t\t\t<img class=\"content__img\" src=\"img/1.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/2.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/3.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/4.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/5.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/6.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/7.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/8.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/9.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/10.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/11.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/12.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/13.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/14.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/15.jpg\" alt=\"Some image\" />\n\t\t\t\t<h3 class=\"content__title\">bingbong</h3>\n\t\t\t</div><!--/content-->\n\t\t</main>\n\t\t<script src=\"js/imagesloaded.pkgd.min.js\"></script>\n\t\t<script src=\"js/TweenMax.min.js\"></script>\n\t\t<script src=\"js/demo4.js\"></script></body>\n</html>\n"
  },
  {
    "path": "index5.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\" class=\"no-js\">\n\t<head>\n\t\t<meta charset=\"UTF-8\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\t\t<title>Image Trail Effects | Demo 5 | Codrops</title>\n\t\t<meta name=\"description\" content=\"A set of fun effects for mouse-following image trails.\" />\n\t\t<meta name=\"keywords\" content=\"image trail, effect, web design, mouse, javascript, gsap\" />\n\t\t<meta name=\"author\" content=\"Codrops\" />\n\t\t<link rel=\"shortcut icon\" href=\"favicon.ico\">\n\t\t<link rel=\"stylesheet\" href=\"https://use.typekit.net/lpe8txe.css\">\n\t\t<link rel=\"stylesheet\" type=\"text/css\" href=\"css/base.css\" />\n\t\t<script>document.documentElement.className=\"js\";var supportsCssVars=function(){var e,t=document.createElement(\"style\");return t.innerHTML=\"root: { --tmp-var: bold; }\",document.head.appendChild(t),e=!!(window.CSS&&window.CSS.supports&&window.CSS.supports(\"font-weight\",\"var(--tmp-var)\")),t.parentNode.removeChild(t),e};supportsCssVars()||alert(\"Please view this demo in a modern browser that supports CSS Variables.\");</script></head>\n\t<body class=\"demo-5 loading\">\n\t\t<main>\n\t\t\t<div class=\"message\">Hover effect &mdash; please view on desktop.</div>\n\t\t\t<div class=\"frame\">\n\t\t\t\t<div class=\"frame__title-wrap\">\n\t\t\t\t\t<h1 class=\"frame__title\">Image Trail Effects</h1>\n\t\t\t\t\t<div class=\"frame__links\">\n\t\t\t\t\t\t<a href=\"https://tympanus.net/Development/SmoothScrollingImageEffects/\">Previous demo</a>\n\t\t\t\t\t\t<a href=\"https://tympanus.net/codrops/?p=42696\">Article</a>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"frame__demos\">\n\t\t\t\t\t\t<a href=\"index.html\" class=\"frame__demo\">1</a>\n\t\t\t\t\t\t<a href=\"index2.html\" class=\"frame__demo\">2</a>\n\t\t\t\t\t\t<a href=\"index3.html\" class=\"frame__demo\">3</a>\n\t\t\t\t\t\t<a href=\"index4.html\" class=\"frame__demo\">4</a>\n\t\t\t\t\t\t<a href=\"index5.html\" class=\"frame__demo frame__demo--current\">5</a>\n\t\t\t\t\t\t<a href=\"index6.html\" class=\"frame__demo\">6</a>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<a class=\"frame__github\" href=\"https://github.com/codrops/ImageTrailEffects/\">Github</a>\n\t\t\t\t<h2 class=\"frame__pagetitle\">Camille Moulin <span>Personality Stylist</span></h2>\n\t\t\t</div>\n\t\t\t<div class=\"content\">\n\t\t\t\t<img class=\"content__img\" src=\"img/1.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/2.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/3.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/4.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/5.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/6.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/7.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/8.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/9.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/10.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/11.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/12.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/13.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/14.jpg\" alt=\"Some image\" />\n\t\t\t\t<img class=\"content__img\" src=\"img/15.jpg\" alt=\"Some image\" />\n\t\t\t\t<h3 class=\"content__title\">duhsduh</h3>\n\t\t\t</div><!--/content-->\n\t\t</main>\n\t\t<script src=\"js/imagesloaded.pkgd.min.js\"></script>\n\t\t<script src=\"js/TweenMax.min.js\"></script>\n\t\t<script src=\"js/demo5.js\"></script></body>\n</html>\n"
  },
  {
    "path": "index6.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\" class=\"no-js\">\n\t<head>\n\t\t<meta charset=\"UTF-8\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\t\t<title>Image Trail Effects | Demo 6 | Codrops</title>\n\t\t<meta name=\"description\" content=\"A set of fun effects for mouse-following image trails.\" />\n\t\t<meta name=\"keywords\" content=\"image trail, effect, web design, mouse, javascript, gsap\" />\n\t\t<meta name=\"author\" content=\"Codrops\" />\n\t\t<link rel=\"shortcut icon\" href=\"favicon.ico\">\n\t\t<link rel=\"stylesheet\" href=\"https://use.typekit.net/lpe8txe.css\">\n\t\t<link rel=\"stylesheet\" type=\"text/css\" href=\"css/base.css\" />\n\t\t<script>document.documentElement.className=\"js\";var supportsCssVars=function(){var e,t=document.createElement(\"style\");return t.innerHTML=\"root: { --tmp-var: bold; }\",document.head.appendChild(t),e=!!(window.CSS&&window.CSS.supports&&window.CSS.supports(\"font-weight\",\"var(--tmp-var)\")),t.parentNode.removeChild(t),e};supportsCssVars()||alert(\"Please view this demo in a modern browser that supports CSS Variables.\");</script></head>\n\t<body class=\"demo-6 loading\">\n\t\t<main>\n\t\t\t<div class=\"message\">Hover effect &mdash; please view on desktop.</div>\n\t\t\t<div class=\"frame\">\n\t\t\t\t<div class=\"frame__title-wrap\">\n\t\t\t\t\t<h1 class=\"frame__title\">Image Trail Effects</h1>\n\t\t\t\t\t<div class=\"frame__links\">\n\t\t\t\t\t\t<a href=\"https://tympanus.net/Development/SmoothScrollingImageEffects/\">Previous demo</a>\n\t\t\t\t\t\t<a href=\"https://tympanus.net/codrops/?p=42696\">Article</a>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"frame__demos\">\n\t\t\t\t\t\t<a href=\"index.html\" class=\"frame__demo\">1</a>\n\t\t\t\t\t\t<a href=\"index2.html\" class=\"frame__demo\">2</a>\n\t\t\t\t\t\t<a href=\"index3.html\" class=\"frame__demo\">3</a>\n\t\t\t\t\t\t<a href=\"index4.html\" class=\"frame__demo\">4</a>\n\t\t\t\t\t\t<a href=\"index5.html\" class=\"frame__demo\">5</a>\n\t\t\t\t\t\t<a href=\"index6.html\" class=\"frame__demo frame__demo--current\">6</a>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<a class=\"frame__github\" href=\"https://github.com/codrops/ImageTrailEffects/\">Github</a>\n\t\t\t\t<h2 class=\"frame__pagetitle\">Camille Moulin <span>Personality Stylist</span></h2>\n\t\t\t</div>\n\t\t\t<div class=\"content\">\n\t\t\t\t<div class=\"content__img content__img--full\" style=\"background-image:url(img/full1.jpg);\"></div>\n\t\t\t\t<div class=\"content__img content__img--full\" style=\"background-image:url(img/full2.jpg);\"></div>\n\t\t\t\t<div class=\"content__img content__img--full\" style=\"background-image:url(img/full3.jpg);\"></div>\n\t\t\t\t<div class=\"content__img content__img--full\" style=\"background-image:url(img/full4.jpg);\"></div>\n\t\t\t\t<div class=\"content__img content__img--full\" style=\"background-image:url(img/full5.jpg);\"></div>\n\t\t\t\t<div class=\"content__img content__img--full\" style=\"background-image:url(img/full6.jpg);\"></div>\n\t\t\t\t<div class=\"content__img content__img--full\" style=\"background-image:url(img/full7.jpg);\"></div>\n\t\t\t\t<div class=\"content__img content__img--full\" style=\"background-image:url(img/full8.jpg);\"></div>\n\t\t\t\t<div class=\"content__img content__img--full\" style=\"background-image:url(img/full9.jpg);\"></div>\n\t\t\t\t<h3 class=\"content__title\">xmxmxmx</h3>\n\t\t\t</div><!--/content-->\n\t\t</main>\n\t\t<script src=\"js/imagesloaded.pkgd.min.js\"></script>\n\t\t<script src=\"js/TweenMax.min.js\"></script>\n\t\t<script src=\"js/demo6.js\"></script></body>\n</html>\n"
  },
  {
    "path": "js/demo.js",
    "content": "/**\n* demo.js\n* http://www.codrops.com\n*\n* Licensed under the MIT license.\n* http://www.opensource.org/licenses/mit-license.php\n* \n* Copyright 2019, Codrops\n* http://www.codrops.com\n*/\n{\n    // body element\n    const body = document.body;\n\n    // helper functions\n    const MathUtils = {\n        // linear interpolation\n        lerp: (a, b, n) => (1 - n) * a + n * b,\n        // distance between two points\n        distance: (x1,y1,x2,y2) => Math.hypot(x2-x1, y2-y1)\n    }\n\n    // get the mouse position\n    const getMousePos = (ev) => {\n        let posx = 0;\n        let posy = 0;\n        if (!ev) ev = window.event;\n        if (ev.pageX || ev.pageY) {\n            posx = ev.pageX;\n            posy = ev.pageY;\n        }\n        else if (ev.clientX || ev.clientY) \t{\n            posx = ev.clientX + body.scrollLeft + docEl.scrollLeft;\n            posy = ev.clientY + body.scrollTop + docEl.scrollTop;\n        }\n        return {x: posx, y: posy};\n    }\n\n    // mousePos: current mouse position\n    // cacheMousePos: previous mouse position\n    // lastMousePos: last last recorded mouse position (at the time the last image was shown)\n    let mousePos = lastMousePos = cacheMousePos = {x: 0, y: 0};\n    \n    // update the mouse position\n    window.addEventListener('mousemove', ev => mousePos = getMousePos(ev));\n    \n    // gets the distance from the current mouse position to the last recorded mouse position\n    const getMouseDistance = () => MathUtils.distance(mousePos.x,mousePos.y,lastMousePos.x,lastMousePos.y);\n\n    class Image {\n        constructor(el) {\n            this.DOM = {el: el};\n            // image deafult styles\n            this.defaultStyle = {\n                scale: 1,\n                x: 0,\n                y: 0,\n                opacity: 0\n            };\n            // get sizes/position\n            this.getRect();\n            // init/bind events\n            this.initEvents();\n        }\n        initEvents() {\n            // on resize get updated sizes/position\n            window.addEventListener('resize', () => this.resize());\n        }\n        resize() {\n            // reset styles\n            TweenMax.set(this.DOM.el, this.defaultStyle);\n            // get sizes/position\n            this.getRect();\n        }\n        getRect() {\n            this.rect = this.DOM.el.getBoundingClientRect();\n        }\n        isActive() {\n            // check if image is animating or if it's visible\n            return TweenMax.isTweening(this.DOM.el) || this.DOM.el.style.opacity != 0;\n        }\n    }\n\n    class ImageTrail {\n        constructor() {\n            // images container\n            this.DOM = {content: document.querySelector('.content')};\n            // array of Image objs, one per image element\n            this.images = [];\n            [...this.DOM.content.querySelectorAll('img')].forEach(img => this.images.push(new Image(img)));\n            // total number of images\n            this.imagesTotal = this.images.length;\n            // upcoming image index\n            this.imgPosition = 0;\n            // zIndex value to apply to the upcoming image\n            this.zIndexVal = 1;\n            // mouse distance required to show the next image\n            this.threshold = 100;\n            // render the images\n            requestAnimationFrame(() => this.render());\n        }\n        render() {\n            // get distance between the current mouse position and the position of the previous image\n            let distance = getMouseDistance();\n            // cache previous mouse position\n            cacheMousePos.x = MathUtils.lerp(cacheMousePos.x || mousePos.x, mousePos.x, 0.1);\n            cacheMousePos.y = MathUtils.lerp(cacheMousePos.y || mousePos.y, mousePos.y, 0.1);\n\n            // if the mouse moved more than [this.threshold] then show the next image\n            if ( distance > this.threshold ) {\n                this.showNextImage();\n\n                ++this.zIndexVal;\n                this.imgPosition = this.imgPosition < this.imagesTotal-1 ? this.imgPosition+1 : 0;\n                \n                lastMousePos = mousePos;\n            }\n\n            // check when mousemove stops and all images are inactive (not visible and not animating)\n            let isIdle = true;\n            for (let img of this.images) {\n                if ( img.isActive() ) {\n                    isIdle = false;\n                    break;\n                }\n            }\n            // reset z-index initial value\n            if ( isIdle && this.zIndexVal !== 1 ) {\n                this.zIndexVal = 1;\n            }\n\n            // loop..\n            requestAnimationFrame(() => this.render());\n        }\n        showNextImage() {\n            // show image at position [this.imgPosition]\n            const img = this.images[this.imgPosition];\n            // kill any tween on the image\n            TweenMax.killTweensOf(img.DOM.el);\n\n            new TimelineMax()\n            // show the image\n            .set(img.DOM.el, {\n                startAt: {opacity: 0, scale: 1},\n                opacity: 1,\n                scale: 1,\n                zIndex: this.zIndexVal,\n                x: cacheMousePos.x - img.rect.width/2,\n                y: cacheMousePos.y - img.rect.height/2\n            }, 0)\n            // animate position\n            .to(img.DOM.el, 0.9, {\n                ease: Expo.easeOut,\n                x: mousePos.x - img.rect.width/2,\n                y: mousePos.y - img.rect.height/2\n            }, 0)\n            // then make it disappear\n            .to(img.DOM.el, 1, {\n                ease: Power1.easeOut,\n                opacity: 0\n            }, 0.4)\n            // scale down the image\n            .to(img.DOM.el, 1, {\n                ease: Quint.easeOut,\n                scale: 0.2\n            }, 0.4);\n        }\n    }\n\n    /***********************************/\n    /********** Preload stuff **********/\n\n    // Preload images\n    const preloadImages = () => {\n        return new Promise((resolve, reject) => {\n            imagesLoaded(document.querySelectorAll('.content__img'), resolve);\n        });\n    };\n    \n    // And then..\n    preloadImages().then(() => {\n        // Remove the loader\n        document.body.classList.remove('loading');\n        new ImageTrail();\n    });\n}"
  },
  {
    "path": "js/demo2.js",
    "content": "/**\n* demo2.js\n* http://www.codrops.com\n*\n* Licensed under the MIT license.\n* http://www.opensource.org/licenses/mit-license.php\n* \n* Copyright 2019, Codrops\n* http://www.codrops.com\n*/\n{\n    // body element\n    const body = document.body;\n\n    // helper functions\n    const MathUtils = {\n        // linear interpolation\n        lerp: (a, b, n) => (1 - n) * a + n * b,\n        // distance between two points\n        distance: (x1,y1,x2,y2) => Math.hypot(x2-x1, y2-y1)\n    }\n\n    // get the mouse position\n    const getMousePos = (ev) => {\n        let posx = 0;\n        let posy = 0;\n        if (!ev) ev = window.event;\n        if (ev.pageX || ev.pageY) {\n            posx = ev.pageX;\n            posy = ev.pageY;\n        }\n        else if (ev.clientX || ev.clientY) \t{\n            posx = ev.clientX + body.scrollLeft + docEl.scrollLeft;\n            posy = ev.clientY + body.scrollTop + docEl.scrollTop;\n        }\n        return {x: posx, y: posy};\n    }\n\n    // mousePos: current mouse position\n    // cacheMousePos: previous mouse position\n    // lastMousePos: last last recorded mouse position (at the time the last image was shown)\n    let mousePos = lastMousePos = cacheMousePos = {x: 0, y: 0};\n    \n    // update the mouse position\n    window.addEventListener('mousemove', ev => mousePos = getMousePos(ev));\n    \n    // gets the distance from the current mouse position to the last recorded mouse position\n    const getMouseDistance = () => MathUtils.distance(mousePos.x,mousePos.y,lastMousePos.x,lastMousePos.y);\n\n    class Image {\n        constructor(el) {\n            this.DOM = {el: el};\n            // image deafult styles\n            this.defaultStyle = {\n                x: 0,\n                y: 0,\n                opacity: 0\n            };\n            // get sizes/position\n            this.getRect();\n            // init/bind events\n            this.initEvents();\n        }\n        initEvents() {\n            // on resize get updated sizes/position\n            window.addEventListener('resize', () => this.resize());\n        }\n        resize() {\n            // reset styles\n            TweenMax.set(this.DOM.el, this.defaultStyle);\n            // get sizes/position\n            this.getRect();\n        }\n        getRect() {\n            this.rect = this.DOM.el.getBoundingClientRect();\n        }\n        isActive() {\n            // check if image is animating or if it's visible\n            return TweenMax.isTweening(this.DOM.el) || this.DOM.el.style.opacity != 0;\n        }\n    }\n\n    class ImageTrail {\n        constructor() {\n            // images container\n            this.DOM = {content: document.querySelector('.content')};\n            // array of Image objs, one per image element\n            this.images = [];\n            [...this.DOM.content.querySelectorAll('img')].forEach(img => this.images.push(new Image(img)));\n            // total number of images\n            this.imagesTotal = this.images.length;\n            // upcoming image index\n            this.imgPosition = 0;\n            // zIndex value to apply to the upcoming image\n            this.zIndexVal = 1;\n            // mouse distance required to show the next image\n            this.threshold = 100;\n            // render the images\n            requestAnimationFrame(() => this.render());\n        }\n        render() {\n            // get distance between the current mouse position and the position of the previous image\n            let distance = getMouseDistance();\n            // cache previous mouse position\n            cacheMousePos.x = MathUtils.lerp(cacheMousePos.x || mousePos.x, mousePos.x, 0.1);\n            cacheMousePos.y = MathUtils.lerp(cacheMousePos.y || mousePos.y, mousePos.y, 0.1);\n\n            // if the mouse moved more than [this.threshold] then show the next image\n            if ( distance > this.threshold ) {\n                this.showNextImage();\n\n                ++this.zIndexVal;\n                this.imgPosition = this.imgPosition < this.imagesTotal-1 ? this.imgPosition+1 : 0;\n                \n                lastMousePos = mousePos;\n            }\n\n            // check when mousemove stops and all images are inactive (not visible and not animating)\n            let isIdle = true;\n            for (let img of this.images) {\n                if ( img.isActive() ) {\n                    isIdle = false;\n                    break;\n                }\n            }\n            // reset z-index initial value\n            if ( isIdle && this.zIndexVal !== 1 ) {\n                this.zIndexVal = 1;\n            }\n\n            // loop..\n            requestAnimationFrame(() => this.render());\n        }\n        showNextImage() {\n            // show image at position [this.imgPosition]\n            const img = this.images[this.imgPosition];\n            // kill any tween on the image\n            TweenMax.killTweensOf(img.DOM.el);\n\n            new TimelineMax()\n            // show the image\n            .set(img.DOM.el, {\n                startAt: {opacity: 0},\n                opacity: 1,\n                scale: 1,\n                zIndex: this.zIndexVal,\n                x: cacheMousePos.x - img.rect.width/2,\n                y: cacheMousePos.y - img.rect.height/2\n            }, 0)\n            // animate position\n            .to(img.DOM.el, 1.8, {\n                ease: Expo.easeOut,\n                x: mousePos.x - img.rect.width/2,\n                y: mousePos.y - img.rect.height/2\n            }, 0)\n            // then make it disappear\n            .to(img.DOM.el, 0.8, {\n                ease: Power1.easeOut,\n                opacity: 0\n            }, 0.8)\n            // scale down the image\n            .to(img.DOM.el, 0.8, {\n                ease: Quint.easeInOut,\n                scale: 2\n            }, 0.8);\n        }\n    }\n\n    /***********************************/\n    /********** Preload stuff **********/\n\n    // Preload images\n    const preloadImages = () => {\n        return new Promise((resolve, reject) => {\n            imagesLoaded(document.querySelectorAll('.content__img'), resolve);\n        });\n    };\n    \n    // And then..\n    preloadImages().then(() => {\n        // Remove the loader\n        document.body.classList.remove('loading');\n        new ImageTrail();\n    });\n}"
  },
  {
    "path": "js/demo3.js",
    "content": "/**\n* demo3.js\n* http://www.codrops.com\n*\n* Licensed under the MIT license.\n* http://www.opensource.org/licenses/mit-license.php\n* \n* Copyright 2019, Codrops\n* http://www.codrops.com\n*/\n{\n    // body element\n    const body = document.body;\n\n    // helper functions\n    const MathUtils = {\n        // linear interpolation\n        lerp: (a, b, n) => (1 - n) * a + n * b,\n        // distance between two points\n        distance: (x1,y1,x2,y2) => Math.hypot(x2-x1, y2-y1)\n    }\n\n    // calculate the viewport size\n    let winsize;\n    const calcWinsize = () => winsize = {width: window.innerWidth, height: window.innerHeight};\n    calcWinsize();\n    // and recalculate on resize\n    window.addEventListener('resize', calcWinsize);\n\n    // get the mouse position\n    const getMousePos = (ev) => {\n        let posx = 0;\n        let posy = 0;\n        if (!ev) ev = window.event;\n        if (ev.pageX || ev.pageY) {\n            posx = ev.pageX;\n            posy = ev.pageY;\n        }\n        else if (ev.clientX || ev.clientY) \t{\n            posx = ev.clientX + body.scrollLeft + docEl.scrollLeft;\n            posy = ev.clientY + body.scrollTop + docEl.scrollTop;\n        }\n        return {x: posx, y: posy};\n    }\n\n    // mousePos: current mouse position\n    // cacheMousePos: previous mouse position\n    // lastMousePos: last last recorded mouse position (at the time the last image was shown)\n    let mousePos = lastMousePos = cacheMousePos = {x: 0, y: 0};\n    \n    // update the mouse position\n    window.addEventListener('mousemove', ev => mousePos = getMousePos(ev));\n    \n    // gets the distance from the current mouse position to the last recorded mouse position\n    const getMouseDistance = () => MathUtils.distance(mousePos.x,mousePos.y,lastMousePos.x,lastMousePos.y);\n\n    class Image {\n        constructor(el) {\n            this.DOM = {el: el};\n            // image deafult styles\n            this.defaultStyle = {\n                x: 0,\n                y: 0,\n                opacity: 0\n            };\n            // get sizes/position\n            this.getRect();\n            // init/bind events\n            this.initEvents();\n        }\n        initEvents() {\n            // on resize get updated sizes/position\n            window.addEventListener('resize', () => this.resize());\n        }\n        resize() {\n            // reset styles\n            TweenMax.set(this.DOM.el, this.defaultStyle);\n            // get sizes/position\n            this.getRect();\n        }\n        getRect() {\n            this.rect = this.DOM.el.getBoundingClientRect();\n        }\n        isActive() {\n            // check if image is animating or if it's visible\n            return TweenMax.isTweening(this.DOM.el) || this.DOM.el.style.opacity != 0;\n        }\n    }\n\n    class ImageTrail {\n        constructor() {\n            // images container\n            this.DOM = {content: document.querySelector('.content')};\n            // array of Image objs, one per image element\n            this.images = [];\n            [...this.DOM.content.querySelectorAll('img')].forEach(img => this.images.push(new Image(img)));\n            // total number of images\n            this.imagesTotal = this.images.length;\n            // upcoming image index\n            this.imgPosition = 0;\n            // zIndex value to apply to the upcoming image\n            this.zIndexVal = 1;\n            // mouse distance required to show the next image\n            this.threshold = 50;\n            // render the images\n            requestAnimationFrame(() => this.render());\n        }\n        render() {\n            // get distance between the current mouse position and the position of the previous image\n            let distance = getMouseDistance();\n            // cache previous mouse position\n            cacheMousePos.x = MathUtils.lerp(cacheMousePos.x || mousePos.x, mousePos.x, 0.1);\n            cacheMousePos.y = MathUtils.lerp(cacheMousePos.y || mousePos.y, mousePos.y, 0.1);\n\n            // if the mouse moved more than [this.threshold] then show the next image\n            if ( distance > this.threshold ) {\n                this.showNextImage();\n\n                ++this.zIndexVal;\n                this.imgPosition = this.imgPosition < this.imagesTotal-1 ? this.imgPosition+1 : 0;\n                \n                lastMousePos = mousePos;\n            }\n\n            // check when mousemove stops and all images are inactive (not visible and not animating)\n            let isIdle = true;\n            for (let img of this.images) {\n                if ( img.isActive() ) {\n                    isIdle = false;\n                    break;\n                }\n            }\n            // reset z-index initial value\n            if ( isIdle && this.zIndexVal !== 1 ) {\n                this.zIndexVal = 1;\n            }\n\n            // loop..\n            requestAnimationFrame(() => this.render());\n        }\n        showNextImage() {\n            // show image at position [this.imgPosition]\n            const img = this.images[this.imgPosition];\n            // kill any tween on the image\n            TweenMax.killTweensOf(img.DOM.el);\n\n            new TimelineMax()\n            // show the image\n            .set(img.DOM.el, {\n                startAt: {opacity: 0},\n                opacity: 1,\n                zIndex: this.zIndexVal,\n                x: cacheMousePos.x - img.rect.width/2,\n                y: cacheMousePos.y - img.rect.height/2\n            }, 0)\n            // animate position\n            .to(img.DOM.el, 1.6, {\n                ease: Expo.easeOut,\n                x: mousePos.x - img.rect.width/2,\n                y: mousePos.y - img.rect.height/2\n            }, 0)\n            // then make it disappear\n            .to(img.DOM.el, 1, {\n                ease: Power1.easeOut,\n                opacity: 0\n            }, 0.4)\n            // translate down the image\n            .to(img.DOM.el, 1, {\n                ease: Quint.easeInOut,\n                y: `+=${winsize.height + img.rect.height/2}`\n            }, 0.4);\n        }\n    }\n\n    /***********************************/\n    /********** Preload stuff **********/\n\n    // Preload images\n    const preloadImages = () => {\n        return new Promise((resolve, reject) => {\n            imagesLoaded(document.querySelectorAll('.content__img'), resolve);\n        });\n    };\n    \n    // And then..\n    preloadImages().then(() => {\n        // Remove the loader\n        document.body.classList.remove('loading');\n        new ImageTrail();\n    });\n}"
  },
  {
    "path": "js/demo4.js",
    "content": "/**\n* demo4.js\n* http://www.codrops.com\n*\n* Licensed under the MIT license.\n* http://www.opensource.org/licenses/mit-license.php\n* \n* Copyright 2019, Codrops\n* http://www.codrops.com\n*/\n{\n    // body element\n    const body = document.body;\n\n    // helper functions\n    const MathUtils = {\n        // linear interpolation\n        lerp: (a, b, n) => (1 - n) * a + n * b,\n        // distance between two points\n        distance: (x1,y1,x2,y2) => Math.hypot(x2-x1, y2-y1),\n        // Random float\n        getRandomFloat: (min, max) => (Math.random() * (max - min) + min).toFixed(2)\n    }\n\n    // calculate the viewport size\n    let winsize;\n    const calcWinsize = () => winsize = {width: window.innerWidth, height: window.innerHeight};\n    calcWinsize();\n    // and recalculate on resize\n    window.addEventListener('resize', calcWinsize);\n\n    // get the mouse position\n    const getMousePos = (ev) => {\n        let posx = 0;\n        let posy = 0;\n        if (!ev) ev = window.event;\n        if (ev.pageX || ev.pageY) {\n            posx = ev.pageX;\n            posy = ev.pageY;\n        }\n        else if (ev.clientX || ev.clientY) \t{\n            posx = ev.clientX + body.scrollLeft + docEl.scrollLeft;\n            posy = ev.clientY + body.scrollTop + docEl.scrollTop;\n        }\n        return {x: posx, y: posy};\n    }\n\n    // mousePos: current mouse position\n    // cacheMousePos: previous mouse position\n    // lastMousePos: last last recorded mouse position (at the time the last image was shown)\n    let mousePos = lastMousePos = cacheMousePos = {x: 0, y: 0};\n    \n    // update the mouse position\n    window.addEventListener('mousemove', ev => mousePos = getMousePos(ev));\n    \n    // gets the distance from the current mouse position to the last recorded mouse position\n    const getMouseDistance = () => MathUtils.distance(mousePos.x,mousePos.y,lastMousePos.x,lastMousePos.y);\n\n    class Image {\n        constructor(el) {\n            this.DOM = {el: el};\n            // image deafult styles\n            this.defaultStyle = {\n                rotation: 0,\n                x: 0,\n                y: 0,\n                opacity: 0\n            };\n            // get sizes/position\n            this.getRect();\n            // init/bind events\n            this.initEvents();\n        }\n        initEvents() {\n            // on resize get updated sizes/position\n            window.addEventListener('resize', () => this.resize());\n        }\n        resize() {\n            // reset styles\n            TweenMax.set(this.DOM.el, this.defaultStyle);\n            // get sizes/position\n            this.getRect();\n        }\n        getRect() {\n            this.rect = this.DOM.el.getBoundingClientRect();\n        }\n        isActive() {\n            // check if image is animating or if it's visible\n            return TweenMax.isTweening(this.DOM.el) || this.DOM.el.style.opacity != 0;\n        }\n        setRatio() {\n            this.DOM.el.style.setProperty('--img-maxwidth', `${MathUtils.getRandomFloat(150,350)}px`);\n            // get sizes/position\n            this.getRect();\n        }\n    }\n\n    class ImageTrail {\n        constructor() {\n            // images container\n            this.DOM = {content: document.querySelector('.content')};\n            // array of Image objs, one per image element\n            this.images = [];\n            [...this.DOM.content.querySelectorAll('img')].forEach(img => this.images.push(new Image(img)));\n            // total number of images\n            this.imagesTotal = this.images.length;\n            // upcoming image index\n            this.imgPosition = 0;\n            // zIndex value to apply to the upcoming image\n            this.zIndexVal = 1;\n            // mouse distance required to show the next image\n            this.threshold = 80;\n            // render the images\n            requestAnimationFrame(() => this.render());\n        }\n        render() {\n            // get distance between the current mouse position and the position of the previous image\n            let distance = getMouseDistance();\n            // cache previous mouse position\n            cacheMousePos.x = MathUtils.lerp(cacheMousePos.x || mousePos.x, mousePos.x, 0.1);\n            cacheMousePos.y = MathUtils.lerp(cacheMousePos.y || mousePos.y, mousePos.y, 0.1);\n\n            // if the mouse moved more than [this.threshold] then show the next image\n            if ( distance > this.threshold ) {\n                this.showNextImage();\n\n                ++this.zIndexVal;\n                this.imgPosition = this.imgPosition < this.imagesTotal-1 ? this.imgPosition+1 : 0;\n                \n                lastMousePos = mousePos;\n            }\n\n            // check when mousemove stops and all images are inactive (not visible and not animating)\n            let isIdle = true;\n            for (let img of this.images) {\n                if ( img.isActive() ) {\n                    isIdle = false;\n                    break;\n                }\n            }\n            // reset z-index initial value\n            if ( isIdle && this.zIndexVal !== 1 ) {\n                this.zIndexVal = 1;\n            }\n\n            // loop..\n            requestAnimationFrame(() => this.render());\n        }\n        showNextImage() {\n            // show image at position [this.imgPosition]\n            const img = this.images[this.imgPosition];\n            img.setRatio();\n            // kill any tween on the image\n            TweenMax.killTweensOf(img.DOM.el);\n\n            new TimelineMax()\n            // show the image\n            .set(img.DOM.el, {\n                startAt: {opacity: 0},\n                opacity: 1,\n                rotation: 0,\n                zIndex: this.zIndexVal,\n                x: cacheMousePos.x - img.rect.width/2,\n                y: cacheMousePos.y - img.rect.height/2\n            }, 0)\n            // animate position\n            .to(img.DOM.el, 1.6, {\n                ease: Expo.easeOut,\n                x: mousePos.x - img.rect.width/2,\n                y: mousePos.y - img.rect.height/2\n            }, 0)\n            // then make it disappear\n            .to(img.DOM.el, 0.8, {\n                ease: Power1.easeOut,\n                opacity: 0\n            }, 0.6)\n            // translate down the image\n            .to(img.DOM.el, 1, {\n                ease: Quint.easeOut,\n                x: `+=${MathUtils.getRandomFloat(-1*(winsize.width + img.rect.width/2), winsize.width + img.rect.width/2)}`,\n                y: `+=${MathUtils.getRandomFloat(-1*(winsize.height + img.rect.height/2), winsize.height + img.rect.height/2)}`,\n                rotation: MathUtils.getRandomFloat(-40,40)\n            }, 0.6);\n        }\n    }\n\n    /***********************************/\n    /********** Preload stuff **********/\n\n    // Preload images\n    const preloadImages = () => {\n        return new Promise((resolve, reject) => {\n            imagesLoaded(document.querySelectorAll('.content__img'), resolve);\n        });\n    };\n    \n    // And then..\n    preloadImages().then(() => {\n        // Remove the loader\n        document.body.classList.remove('loading');\n        new ImageTrail();\n    });\n}"
  },
  {
    "path": "js/demo5.js",
    "content": "/**\n* demo5.js\n* http://www.codrops.com\n*\n* Licensed under the MIT license.\n* http://www.opensource.org/licenses/mit-license.php\n* \n* Copyright 2019, Codrops\n* http://www.codrops.com\n*/\n{\n    // body element\n    const body = document.body;\n\n    // helper functions\n    const MathUtils = {\n        // linear interpolation\n        lerp: (a, b, n) => (1 - n) * a + n * b,\n        // distance between two points\n        distance: (x1,y1,x2,y2) => Math.hypot(x2-x1, y2-y1),\n        // Random float\n        getRandomFloat: (min, max) => (Math.random() * (max - min) + min).toFixed(2)\n    }\n\n    // calculate the viewport size\n    let winsize;\n    const calcWinsize = () => winsize = {width: window.innerWidth, height: window.innerHeight};\n    calcWinsize();\n    // and recalculate on resize\n    window.addEventListener('resize', calcWinsize);\n\n    // get the mouse position\n    const getMousePos = (ev) => {\n        let posx = 0;\n        let posy = 0;\n        if (!ev) ev = window.event;\n        if (ev.pageX || ev.pageY) {\n            posx = ev.pageX;\n            posy = ev.pageY;\n        }\n        else if (ev.clientX || ev.clientY) \t{\n            posx = ev.clientX + body.scrollLeft + docEl.scrollLeft;\n            posy = ev.clientY + body.scrollTop + docEl.scrollTop;\n        }\n        return {x: posx, y: posy};\n    }\n\n    // mousePos: current mouse position\n    // cacheMousePos: previous mouse position\n    // lastMousePos: last last recorded mouse position (at the time the last image was shown)\n    let mousePos = lastMousePos = cacheMousePos = {x: 0, y: 0};\n    \n    // update the mouse position\n    window.addEventListener('mousemove', ev => mousePos = getMousePos(ev));\n    \n    // gets the distance from the current mouse position to the last recorded mouse position\n    const getMouseDistance = () => MathUtils.distance(mousePos.x,mousePos.y,lastMousePos.x,lastMousePos.y);\n\n    class Image {\n        constructor(el) {\n            this.DOM = {el: el};\n            // image deafult styles\n            this.defaultStyle = {\n                scaleX: 1,\n                scaleY: 1,\n                x: 0,\n                y: 0,\n                opacity: 0\n            };\n            // get sizes/position\n            this.getRect();\n            // init/bind events\n            this.initEvents();\n        }\n        initEvents() {\n            // on resize get updated sizes/position\n            window.addEventListener('resize', () => this.resize());\n        }\n        resize() {\n            // reset styles\n            TweenMax.set(this.DOM.el, this.defaultStyle);\n            // get sizes/position\n            this.getRect();\n        }\n        getRect() {\n            this.rect = this.DOM.el.getBoundingClientRect();\n        }\n        isActive() {\n            // check if image is animating or if it's visible\n            return TweenMax.isTweening(this.DOM.el) || this.DOM.el.style.opacity != 0;\n        }\n    }\n\n    class ImageTrail {\n        constructor() {\n            // images container\n            this.DOM = {content: document.querySelector('.content')};\n            // array of Image objs, one per image element\n            this.images = [];\n            [...this.DOM.content.querySelectorAll('img')].forEach(img => this.images.push(new Image(img)));\n            // total number of images\n            this.imagesTotal = this.images.length;\n            // upcoming image index\n            this.imgPosition = 0;\n            // zIndex value to apply to the upcoming image\n            this.zIndexVal = 1;\n            // mouse distance required to show the next image\n            this.threshold = 100;\n            // render the images\n            requestAnimationFrame(() => this.render());\n        }\n        render() {\n            // get distance between the current mouse position and the position of the previous image\n            let distance = getMouseDistance();\n            // cache previous mouse position\n            cacheMousePos.x = MathUtils.lerp(cacheMousePos.x || mousePos.x, mousePos.x, 0.1);\n            cacheMousePos.y = MathUtils.lerp(cacheMousePos.y || mousePos.y, mousePos.y, 0.1);\n\n            // if the mouse moved more than [this.threshold] then show the next image\n            if ( distance > this.threshold ) {\n                this.showNextImage();\n\n                ++this.zIndexVal;\n                this.imgPosition = this.imgPosition < this.imagesTotal-1 ? this.imgPosition+1 : 0;\n                \n                lastMousePos = mousePos;\n            }\n\n            // check when mousemove stops and all images are inactive (not visible and not animating)\n            let isIdle = true;\n            for (let img of this.images) {\n                if ( img.isActive() ) {\n                    isIdle = false;\n                    break;\n                }\n            }\n            // reset z-index initial value\n            if ( isIdle && this.zIndexVal !== 1 ) {\n                this.zIndexVal = 1;\n            }\n\n            // loop..\n            requestAnimationFrame(() => this.render());\n        }\n        showNextImage() {\n            // show image at position [this.imgPosition]\n            const img = this.images[this.imgPosition];\n            // kill any tween on the image\n            TweenMax.killTweensOf(img.DOM.el);\n            \n            new TimelineMax()\n            // show the image\n            .set(img.DOM.el, {\n                startAt: {opacity: 0},\n                opacity: 1,\n                scaleX: 1,\n                scaleY: 1,\n                zIndex: this.zIndexVal,\n                x: mousePos.x - img.rect.width/2,\n                y: mousePos.y - img.rect.height/2,\n                transformOrigin: '50% -10%'\n            }, 0)\n            // then make it disappear\n            .to(img.DOM.el, 0.5, {\n                ease: Power1.easeOut,\n                opacity: 0\n            }, 0.4)\n            // translate down the image\n            .to(img.DOM.el, 0.2, {\n                ease: Quad.easeIn,\n                scaleX: 0.5,\n                scaleY: 2\n            }, 0.4)\n            // translate down the image\n            .to(img.DOM.el, 0.5, {\n                ease: Expo.easeOut,\n                scaleX: 0.7,\n                scaleY: 1.7,\n                y: `+=${MathUtils.getRandomFloat(winsize.height/2,winsize.height)}`\n            }, 0.6);\n        }\n    }\n\n    /***********************************/\n    /********** Preload stuff **********/\n\n    // Preload images\n    const preloadImages = () => {\n        return new Promise((resolve, reject) => {\n            imagesLoaded(document.querySelectorAll('.content__img'), resolve);\n        });\n    };\n    \n    // And then..\n    preloadImages().then(() => {\n        // Remove the loader\n        document.body.classList.remove('loading');\n        new ImageTrail();\n    });\n}"
  },
  {
    "path": "js/demo6.js",
    "content": "/**\n* demo6.js\n* http://www.codrops.com\n*\n* Licensed under the MIT license.\n* http://www.opensource.org/licenses/mit-license.php\n* \n* Copyright 2019, Codrops\n* http://www.codrops.com\n*/\n{\n    // body element\n    const body = document.body;\n\n    // helper functions\n    const MathUtils = {\n        // linear interpolation\n        lerp: (a, b, n) => (1 - n) * a + n * b,\n        // distance between two points\n        distance: (x1,y1,x2,y2) => Math.hypot(x2-x1, y2-y1)\n    }\n\n    // get the mouse position\n    const getMousePos = (ev) => {\n        let posx = 0;\n        let posy = 0;\n        if (!ev) ev = window.event;\n        if (ev.pageX || ev.pageY) {\n            posx = ev.pageX;\n            posy = ev.pageY;\n        }\n        else if (ev.clientX || ev.clientY) \t{\n            posx = ev.clientX + body.scrollLeft + docEl.scrollLeft;\n            posy = ev.clientY + body.scrollTop + docEl.scrollTop;\n        }\n        return {x: posx, y: posy};\n    }\n\n    // mousePos: current mouse position\n    // lastMousePos: last last recorded mouse position (at the time the last image was shown)\n    let mousePos = lastMousePos = {x: 0, y: 0};\n    \n    // update the mouse position\n    window.addEventListener('mousemove', ev => mousePos = getMousePos(ev));\n    \n    // gets the distance from the current mouse position to the last recorded mouse position\n    const getMouseDistance = () => MathUtils.distance(mousePos.x,mousePos.y,lastMousePos.x,lastMousePos.y);\n\n    class Image {\n        constructor(el) {\n            this.DOM = {el: el};\n            // image deafult styles\n            this.defaultStyle = {\n                x: 0,\n                y: 0,\n                opacity: 1\n            };\n            // get sizes/position\n            this.getRect();\n            // init/bind events\n            this.initEvents();\n        }\n        initEvents() {\n            // on resize get updated sizes/position\n            window.addEventListener('resize', () => this.resize());\n        }\n        resize() {\n            // reset styles\n            TweenMax.set(this.DOM.el, this.defaultStyle);\n            // get sizes/position\n            this.getRect();\n        }\n        getRect() {\n            this.rect = this.DOM.el.getBoundingClientRect();\n        }\n    }\n\n    class ImageTrail {\n        constructor() {\n            // images container\n            this.DOM = {content: document.querySelector('.content')};\n            // array of Image objs, one per image element\n            this.images = [];\n            [...this.DOM.content.querySelectorAll('div.content__img')].forEach(img => this.images.push(new Image(img)));\n            // total number of images\n            this.imagesTotal = this.images.length;\n            // upcoming image index\n            this.imgPosition = 0;\n            // zIndex value to apply to the upcoming image\n            this.zIndexVal = 1;\n            // mouse distance required to show the next image\n            this.threshold = 100;\n            this.showNextImage();\n            // render the images\n            requestAnimationFrame(() => this.render());\n        }\n        render() {\n            // get distance between the current mouse position and the position of the previous image\n            let distance = getMouseDistance();\n\n            // if the mouse moved more than [this.threshold] then show the next image\n            if ( distance > this.threshold ) {\n                this.showNextImage();\n            }\n\n            // loop..\n            requestAnimationFrame(() => this.render());\n        }\n        showNextImage() {\n            // show image at position [this.imgPosition]\n            const img = this.images[this.imgPosition];\n            // kill any tween on the image\n            TweenMax.killTweensOf(img.DOM.el);\n\n            new TimelineMax()\n            // show the image\n            .set(img.DOM.el, {\n                opacity: 1,\n                x: mousePos.x > lastMousePos.x ? 100 : -100,\n                zIndex: this.zIndexVal\n            }, 0)\n            // animate position\n            .to(img.DOM.el, 1.2, {\n                ease: Expo.easeOut,\n                x: 0\n            }, 0);\n\n            ++this.zIndexVal;\n            this.imgPosition = this.imgPosition < this.imagesTotal-1 ? this.imgPosition+1 : 0;\n            \n            lastMousePos = mousePos;\n        }\n    }\n\n    /***********************************/\n    /********** Preload stuff **********/\n\n    // Preload images\n    const preloadImages = () => {\n        return new Promise((resolve, reject) => {\n            imagesLoaded(document.querySelectorAll('.content__img'), {background: true}, resolve);\n        });\n    };\n    \n    // And then..\n    preloadImages().then(() => {\n        // Remove the loader\n        document.body.classList.remove('loading');\n        new ImageTrail();\n    });\n}"
  }
]