├── .gitignore ├── README.md ├── css └── base.css ├── favicon.ico ├── img ├── 1.jpg ├── 10.jpg ├── 11.jpg ├── 12.jpg ├── 13.jpg ├── 14.jpg ├── 15.jpg ├── 16.jpg ├── 17.jpg ├── 18.jpg ├── 19.jpg ├── 2.jpg ├── 20.jpg ├── 21.jpg ├── 3.jpg ├── 4.jpg ├── 5.jpg ├── 6.jpg ├── 7.jpg ├── 8.jpg ├── 9.jpg └── large │ ├── 1.jpg │ ├── 10.jpg │ ├── 11.jpg │ ├── 12.jpg │ ├── 13.jpg │ ├── 14.jpg │ ├── 15.jpg │ ├── 16.jpg │ ├── 17.jpg │ ├── 18.jpg │ ├── 19.jpg │ ├── 2.jpg │ ├── 20.jpg │ ├── 21.jpg │ ├── 3.jpg │ ├── 4.jpg │ ├── 5.jpg │ ├── 6.jpg │ ├── 7.jpg │ ├── 8.jpg │ └── 9.jpg ├── index.html ├── index2.html ├── index3.html ├── index4.html └── js ├── anime.min.js ├── demo1.js ├── demo2.js ├── demo3.js ├── demo4.js └── imagesloaded.pkgd.min.js /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Grid Reveal Effects with Anime.js 2 | 3 | Some experiments with the new staggering system of Anime.js where we try different effects for hiding and showing thumbnails in an image grid. 4 | 5 | ![Grid Reveal Effects](https://tympanus.net/codrops/wp-content/uploads/2019/02/GridRevealEffects_featured.jpg) 6 | 7 | [Article on Codrops](https://tympanus.net/codrops/?p=38214) 8 | 9 | [Demo](http://tympanus.net/Development/GridRevealEffects/) 10 | 11 | ## Credits 12 | 13 | - [anime.js](http://animejs.com/) by Julian Garnier 14 | - [imagesLoaded](https://imagesloaded.desandro.com/) by Dave DeSandro 15 | - Images from [Unsplash.com](https://unsplash.com/) 16 | 17 | 18 | ## License 19 | This 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. 20 | 21 | ## Misc 22 | 23 | Follow 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/) 24 | 25 | 26 | [© Codrops 2019](http://www.codrops.com) 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /css/base.css: -------------------------------------------------------------------------------- 1 | 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;} 2 | *, 3 | *::after, 4 | *::before { 5 | box-sizing: border-box; 6 | } 7 | 8 | :root { 9 | font-size: 16px; 10 | } 11 | 12 | body { 13 | --color-text: #fff; 14 | --color-bg: #000; 15 | --color-link: #5a45a0; 16 | --color-link-hover: #fff; 17 | --color-bg-content: #5b6598; 18 | --color-title: #fff; 19 | color: var(--color-text); 20 | background-color: var(--color-bg); 21 | font-family: linotype-didot, Didot, "Didot LT STD", "Bodoni MT", "ltc-bodoni-175", "Hoefler Text", Garamond, "Times New Roman", serif; 22 | -webkit-font-smoothing: antialiased; 23 | -moz-osx-font-smoothing: grayscale; 24 | } 25 | 26 | .hidden { 27 | pointer-events: none; 28 | visibility: hidden; 29 | position: fixed; 30 | z-index: -1; 31 | } 32 | 33 | .cursor, .cursor__inner { 34 | z-index: 9999; 35 | pointer-events: none; 36 | position: absolute; 37 | top: 0; 38 | left: 0; 39 | mix-blend-mode: difference; 40 | } 41 | 42 | .cursor__inner--circle { 43 | width: 30px; 44 | height: 30px; 45 | border-radius: 50%; 46 | border: 3px solid #de448d; 47 | } 48 | 49 | .cursor__inner--cross { 50 | width: 30px; 51 | height: 30px; 52 | } 53 | 54 | .cursor__inner--cross::before, 55 | .cursor__inner--cross::after { 56 | position: absolute; 57 | top: 0; 58 | content: ''; 59 | width: 2px; 60 | height: 100%; 61 | background: #A21020; 62 | left: calc(50% - 1px); 63 | transform: rotate(45deg); 64 | } 65 | 66 | .cursor__inner--cross::after { 67 | transform: rotate(-45deg); 68 | } 69 | 70 | .cursor__inner--text { 71 | white-space: nowrap; 72 | left: 30px; 73 | margin-top: 1px; 74 | color: #9A9A9A; 75 | } 76 | 77 | /* Page Loader */ 78 | .js .loading::before { 79 | content: ''; 80 | position: fixed; 81 | z-index: 100000; 82 | top: 0; 83 | left: 0; 84 | width: 100%; 85 | height: 100%; 86 | background: var(--color-bg); 87 | } 88 | 89 | .js .loading::after { 90 | content: ''; 91 | position: fixed; 92 | z-index: 100000; 93 | top: 50%; 94 | left: 50%; 95 | width: 60px; 96 | height: 60px; 97 | margin: -30px 0 0 -30px; 98 | pointer-events: none; 99 | border-radius: 50%; 100 | opacity: 0.4; 101 | background: var(--color-link); 102 | animation: loaderAnim 0.7s linear infinite alternate forwards; 103 | } 104 | 105 | @keyframes loaderAnim { 106 | to { 107 | opacity: 1; 108 | transform: scale3d(0.5,0.5,1); 109 | } 110 | } 111 | 112 | a { 113 | text-decoration: none; 114 | color: var(--color-link); 115 | outline: none; 116 | } 117 | 118 | a:hover, 119 | a:focus { 120 | color: var(--color-link-hover); 121 | outline: none; 122 | } 123 | 124 | .frame { 125 | padding: 3rem 5vw; 126 | text-align: center; 127 | position: fixed; 128 | z-index: 1000; 129 | width: 100%; 130 | text-transform: lowercase; 131 | } 132 | 133 | .demo-4 .frame { 134 | mix-blend-mode: color-dodge; 135 | } 136 | 137 | .frame__title-wrap { 138 | text-transform: capitalize; 139 | } 140 | 141 | .frame__title { 142 | font-size: 1rem; 143 | margin: 0 0 1rem; 144 | } 145 | 146 | .frame__links { 147 | display: inline; 148 | } 149 | 150 | .frame__links a:not(:first-child)::before { 151 | content: '|'; 152 | margin: 0 1rem 0 0; 153 | } 154 | 155 | .frame__nav a, 156 | .frame__links a:not(:last-child), 157 | .frame__demos span, .frame__demos a:not(:last-child) { 158 | margin-right: 1rem; 159 | } 160 | 161 | .frame__main { 162 | font-size: 1.5rem; 163 | margin: 0; 164 | } 165 | 166 | .frame__nav, 167 | .frame__main, 168 | .frame__version { 169 | display: none; 170 | } 171 | 172 | .frame__demos { 173 | margin: 1rem 0; 174 | } 175 | 176 | .frame__demo--current, 177 | .frame__demo--current:hover { 178 | color: var(--color-text); 179 | } 180 | 181 | .content { 182 | background-color: var(--color-bg-content); 183 | position: fixed; 184 | height: 100vh; 185 | width: 100%; 186 | display: flex; 187 | align-items: center; 188 | justify-content: center; 189 | background-position: 50% 30%; 190 | background-size: cover; 191 | background-blend-mode: soft-light; 192 | cursor: pointer; 193 | } 194 | 195 | .content__title { 196 | font-size: 10vw; 197 | will-change: transform; 198 | mix-blend-mode: overlay; 199 | text-align: center; 200 | color: var(--color-title); 201 | pointer-events: none; 202 | -webkit-touch-callout: none; 203 | -webkit-user-select: none; 204 | -moz-user-select: none; 205 | -ms-user-select: none; 206 | user-select: none; 207 | } 208 | 209 | .grid-wrap--hidden { 210 | pointer-events: none; 211 | } 212 | 213 | .grid { 214 | display: grid; 215 | width: 100%; 216 | height: 100vw; 217 | --cell-number: 12; 218 | --cell-size: 8.3333vw; 219 | grid-template-columns: repeat(auto-fill, var(--cell-size)); 220 | will-change: transform; 221 | } 222 | 223 | @media screen and (orientation: portrait) { 224 | .grid { 225 | height: auto; 226 | --cell-number: 6; 227 | --cell-size: 16.6666vw; 228 | } 229 | } 230 | 231 | .grid__item { 232 | width: 100%; 233 | height: 100%; 234 | position: relative; 235 | cursor: pointer; 236 | overflow: hidden; 237 | height: var(--cell-size); 238 | outline: 1px solid rgba(0,0,0,0.87); 239 | } 240 | 241 | .grid__item-inner { 242 | width: 100%; 243 | height: 100%; 244 | position: relative; 245 | background-position: 50% 50%; 246 | background-size: cover; 247 | } 248 | 249 | .demo-3 .grid__item-inner { 250 | background-blend-mode: color-dodge; 251 | background-color: #332d4a; 252 | } 253 | 254 | .demo-1 .grid__item-inner { 255 | filter: grayscale(1); 256 | } 257 | 258 | .grid__item-inner::after { 259 | content: ''; 260 | position: absolute; 261 | top: 0; 262 | left: 0; 263 | width: 100%; 264 | height: 100%; 265 | background: rgba(0,0,0,0.87); 266 | transition: background 0.1s ease; 267 | } 268 | 269 | .demo-4 .grid__item-inner::after { 270 | background: rgba(255,255,255,0); 271 | } 272 | 273 | .grid__item-inner:hover::after { 274 | background: rgba(0,0,0,0.77); 275 | } 276 | 277 | .demo-4 .grid__item-inner:hover::after { 278 | background: rgba(255,255,255,0.5); 279 | } 280 | 281 | @media screen and (min-width: 53em) { 282 | body { 283 | overflow: hidden; 284 | } 285 | .frame { 286 | position: fixed; 287 | text-align: left; 288 | z-index: 10000; 289 | top: 0; 290 | left: 0; 291 | display: grid; 292 | align-content: space-between; 293 | width: 100%; 294 | max-width: none; 295 | height: 100vh; 296 | padding: 2rem 2rem 2.5rem; 297 | pointer-events: none; 298 | grid-template-columns: 40% 30% 30%; 299 | grid-template-rows: auto auto auto; 300 | grid-template-areas: 'nav demos main' 301 | '... ... ...' 302 | 'title ... version'; 303 | } 304 | .frame__title-wrap { 305 | grid-area: title; 306 | display: flex; 307 | grid-column: span 2; 308 | pointer-events: auto; 309 | } 310 | .frame__title { 311 | margin: 0 2rem 0 0; 312 | } 313 | .frame__main { 314 | display: block; 315 | justify-self: end; 316 | } 317 | .frame__main::before { 318 | content: '\2015'; 319 | } 320 | .frame__nav { 321 | display: block; 322 | grid-area: nav; 323 | align-self: center; 324 | pointer-events: auto; 325 | } 326 | .frame__version { 327 | display: block; 328 | grid-area: version; 329 | justify-self: end; 330 | } 331 | .frame__demos { 332 | margin: 0; 333 | grid-area: demos; 334 | justify-self: start; 335 | align-self: center; 336 | pointer-events: auto; 337 | } 338 | .frame a { 339 | pointer-events: auto; 340 | } 341 | .grid-wrap { 342 | height: 100vh; 343 | overflow: hidden; 344 | } 345 | } 346 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/favicon.ico -------------------------------------------------------------------------------- /img/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/1.jpg -------------------------------------------------------------------------------- /img/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/10.jpg -------------------------------------------------------------------------------- /img/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/11.jpg -------------------------------------------------------------------------------- /img/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/12.jpg -------------------------------------------------------------------------------- /img/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/13.jpg -------------------------------------------------------------------------------- /img/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/14.jpg -------------------------------------------------------------------------------- /img/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/15.jpg -------------------------------------------------------------------------------- /img/16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/16.jpg -------------------------------------------------------------------------------- /img/17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/17.jpg -------------------------------------------------------------------------------- /img/18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/18.jpg -------------------------------------------------------------------------------- /img/19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/19.jpg -------------------------------------------------------------------------------- /img/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/2.jpg -------------------------------------------------------------------------------- /img/20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/20.jpg -------------------------------------------------------------------------------- /img/21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/21.jpg -------------------------------------------------------------------------------- /img/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/3.jpg -------------------------------------------------------------------------------- /img/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/4.jpg -------------------------------------------------------------------------------- /img/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/5.jpg -------------------------------------------------------------------------------- /img/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/6.jpg -------------------------------------------------------------------------------- /img/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/7.jpg -------------------------------------------------------------------------------- /img/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/8.jpg -------------------------------------------------------------------------------- /img/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/9.jpg -------------------------------------------------------------------------------- /img/large/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/large/1.jpg -------------------------------------------------------------------------------- /img/large/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/large/10.jpg -------------------------------------------------------------------------------- /img/large/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/large/11.jpg -------------------------------------------------------------------------------- /img/large/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/large/12.jpg -------------------------------------------------------------------------------- /img/large/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/large/13.jpg -------------------------------------------------------------------------------- /img/large/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/large/14.jpg -------------------------------------------------------------------------------- /img/large/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/large/15.jpg -------------------------------------------------------------------------------- /img/large/16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/large/16.jpg -------------------------------------------------------------------------------- /img/large/17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/large/17.jpg -------------------------------------------------------------------------------- /img/large/18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/large/18.jpg -------------------------------------------------------------------------------- /img/large/19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/large/19.jpg -------------------------------------------------------------------------------- /img/large/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/large/2.jpg -------------------------------------------------------------------------------- /img/large/20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/large/20.jpg -------------------------------------------------------------------------------- /img/large/21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/large/21.jpg -------------------------------------------------------------------------------- /img/large/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/large/3.jpg -------------------------------------------------------------------------------- /img/large/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/large/4.jpg -------------------------------------------------------------------------------- /img/large/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/large/5.jpg -------------------------------------------------------------------------------- /img/large/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/large/6.jpg -------------------------------------------------------------------------------- /img/large/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/large/7.jpg -------------------------------------------------------------------------------- /img/large/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/large/8.jpg -------------------------------------------------------------------------------- /img/large/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GridRevealEffects/b8a05526995dd7e4ab92edbb08c1244d7cc90057/img/large/9.jpg -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Grid Reveal Effects using anime.js | Demo 1 | Codrops 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 40 |
41 |
42 |
43 |

Grid Reveal Effects

44 | 49 |
50 |
51 | project 52 | team 53 | docs 54 |
55 | Photostream 56 | v2.0.1 57 |
58 | Effects: 59 | 1 60 | 2 61 | 3 62 | 4 63 |
64 |
65 |
66 |

Yerevan

67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |   220 |
221 | 222 | 223 | 224 | 225 | 226 | -------------------------------------------------------------------------------- /index2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Grid Reveal Effects using anime.js | Demo 2 | Codrops 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 40 |
41 |
42 |
43 |

Grid Reveal Effects

44 | 49 |
50 |
51 | project 52 | team 53 | docs 54 |
55 | Photostream 56 | v2.0.1 57 |
58 | Effects: 59 | 1 60 | 2 61 | 3 62 | 4 63 |
64 |
65 |
66 |

Yerevan

67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |   220 |
221 | 222 | 223 | 224 | 225 | 226 | -------------------------------------------------------------------------------- /index3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Grid Reveal Effects using anime.js | Demo 3 | Codrops 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 40 |
41 |
42 |
43 |

Grid Reveal Effects

44 | 49 |
50 |
51 | project 52 | team 53 | docs 54 |
55 | Photostream 56 | v2.0.1 57 |
58 | Effects: 59 | 1 60 | 2 61 | 3 62 | 4 63 |
64 |
65 |
66 |

Yerevan

67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |   220 |
221 | 222 | 223 | 224 | 225 | 226 | -------------------------------------------------------------------------------- /index4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Grid Reveal Effects using anime.js | Demo 4 | Codrops 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 40 |
41 |
42 |
43 |

Grid Reveal Effects

44 | 49 |
50 |
51 | project 52 | team 53 | docs 54 |
55 | Photostream 56 | v2.0.1 57 |
58 | Effects: 59 | 1 60 | 2 61 | 3 62 | 4 63 |
64 |
65 |
66 |

Yerevan

67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |   220 |
221 | 222 | 223 | 224 | 225 | 226 | -------------------------------------------------------------------------------- /js/anime.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * anime.js v3.0.1 3 | * (c) 2019 Julian Garnier 4 | * Released under the MIT license 5 | * animejs.com 6 | */ 7 | 8 | !function(n,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):n.anime=e()}(this,function(){"use strict";var n={update:null,begin:null,loopBegin:null,changeBegin:null,change:null,changeComplete:null,loopComplete:null,complete:null,loop:1,direction:"normal",autoplay:!0,timelineOffset:0},e={duration:1e3,delay:0,endDelay:0,easing:"easeOutElastic(1, .5)",round:0},r=["translateX","translateY","translateZ","rotate","rotateX","rotateY","rotateZ","scale","scaleX","scaleY","scaleZ","skew","skewX","skewY","perspective"],t={CSS:{},springs:{}};function a(n,e,r){return Math.min(Math.max(n,e),r)}function o(n,e){return n.indexOf(e)>-1}function i(n,e){return n.apply(null,e)}var u={arr:function(n){return Array.isArray(n)},obj:function(n){return o(Object.prototype.toString.call(n),"Object")},pth:function(n){return u.obj(n)&&n.hasOwnProperty("totalLength")},svg:function(n){return n instanceof SVGElement},inp:function(n){return n instanceof HTMLInputElement},dom:function(n){return n.nodeType||u.svg(n)},str:function(n){return"string"==typeof n},fnc:function(n){return"function"==typeof n},und:function(n){return void 0===n},hex:function(n){return/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(n)},rgb:function(n){return/^rgb/.test(n)},hsl:function(n){return/^hsl/.test(n)},col:function(n){return u.hex(n)||u.rgb(n)||u.hsl(n)},key:function(r){return!n.hasOwnProperty(r)&&!e.hasOwnProperty(r)&&"targets"!==r&&"keyframes"!==r}};function s(n){var e=/\(([^)]+)\)/.exec(n);return e?e[1].split(",").map(function(n){return parseFloat(n)}):[]}function c(n,e){var r=s(n),o=a(u.und(r[0])?1:r[0],.1,100),i=a(u.und(r[1])?100:r[1],.1,100),c=a(u.und(r[2])?10:r[2],.1,100),f=a(u.und(r[3])?0:r[3],.1,100),l=Math.sqrt(i/o),d=c/(2*Math.sqrt(i*o)),p=d<1?l*Math.sqrt(1-d*d):0,v=1,h=d<1?(d*l-f)/p:-f+l;function g(n){var r=e?e*n/1e3:n;return r=d<1?Math.exp(-r*d*l)*(v*Math.cos(p*r)+h*Math.sin(p*r)):(v+h*r)*Math.exp(-r*l),0===n||1===n?n:1-r}return e?g:function(){var e=t.springs[n];if(e)return e;for(var r=0,a=0;;)if(1===g(r+=1/6)){if(++a>=16)break}else a=0;var o=r*(1/6)*1e3;return t.springs[n]=o,o}}function f(n,e){void 0===n&&(n=1),void 0===e&&(e=.5);var r=a(n,1,10),t=a(e,.1,2);return function(n){return 0===n||1===n?n:-r*Math.pow(2,10*(n-1))*Math.sin((n-1-t/(2*Math.PI)*Math.asin(1/r))*(2*Math.PI)/t)}}function l(n){return void 0===n&&(n=10),function(e){return Math.round(e*n)*(1/n)}}var d=function(){var n=11,e=1/(n-1);function r(n,e){return 1-3*e+3*n}function t(n,e){return 3*e-6*n}function a(n){return 3*n}function o(n,e,o){return((r(e,o)*n+t(e,o))*n+a(e))*n}function i(n,e,o){return 3*r(e,o)*n*n+2*t(e,o)*n+a(e)}return function(r,t,a,u){if(0<=r&&r<=1&&0<=a&&a<=1){var s=new Float32Array(n);if(r!==t||a!==u)for(var c=0;c=.001?function(n,e,r,t){for(var a=0;a<4;++a){var u=i(e,r,t);if(0===u)return e;e-=(o(e,r,t)-n)/u}return e}(t,l,r,a):0===d?l:function(n,e,r,t,a){for(var i,u,s=0;(i=o(u=e+(r-e)/2,t,a)-n)>0?r=u:e=u,Math.abs(i)>1e-7&&++s<10;);return u}(t,u,u+e,r,a)}}}(),p=function(){var n=["Quad","Cubic","Quart","Quint","Sine","Expo","Circ","Back","Elastic"],e={In:[[.55,.085,.68,.53],[.55,.055,.675,.19],[.895,.03,.685,.22],[.755,.05,.855,.06],[.47,0,.745,.715],[.95,.05,.795,.035],[.6,.04,.98,.335],[.6,-.28,.735,.045],f],Out:[[.25,.46,.45,.94],[.215,.61,.355,1],[.165,.84,.44,1],[.23,1,.32,1],[.39,.575,.565,1],[.19,1,.22,1],[.075,.82,.165,1],[.175,.885,.32,1.275],function(n,e){return function(r){return 1-f(n,e)(1-r)}}],InOut:[[.455,.03,.515,.955],[.645,.045,.355,1],[.77,0,.175,1],[.86,0,.07,1],[.445,.05,.55,.95],[1,0,0,1],[.785,.135,.15,.86],[.68,-.55,.265,1.55],function(n,e){return function(r){return r<.5?f(n,e)(2*r)/2:1-f(n,e)(-2*r+2)/2}}]},r={linear:[.25,.25,.75,.75]},t=function(t){e[t].forEach(function(e,a){r["ease"+t+n[a]]=e})};for(var a in e)t(a);return r}();function v(n,e){if(u.fnc(n))return n;var r=n.split("(")[0],t=p[r],a=s(n);switch(r){case"spring":return c(n,e);case"cubicBezier":return i(d,a);case"steps":return i(l,a);default:return u.fnc(t)?i(t,a):i(d,t)}}function h(n){try{return document.querySelectorAll(n)}catch(n){return}}function g(n,e){for(var r=n.length,t=arguments.length>=2?arguments[1]:void 0,a=[],o=0;o1&&(r-=1),r<1/6?n+6*(e-n)*r:r<.5?e:r<2/3?n+(e-n)*(2/3-r)*6:n}if(0==i)e=r=t=u;else{var f=u<.5?u*(1+i):u+i-u*i,l=2*u-f;e=c(l,f,o+1/3),r=c(l,f,o),t=c(l,f,o-1/3)}return"rgba("+255*e+","+255*r+","+255*t+","+s+")"}(n):void 0;var e,r,t,a}function C(n){var e=/([\+\-]?[0-9#\.]+)(%|px|pt|em|rem|in|cm|mm|ex|ch|pc|vw|vh|vmin|vmax|deg|rad|turn)?$/.exec(n);if(e)return e[2]}function O(n,e){return u.fnc(n)?n(e.target,e.id,e.total):n}function P(n,e){return n.getAttribute(e)}function I(n,e,r){if(b([r,"deg","rad","turn"],C(e)))return e;var a=t.CSS[e+r];if(!u.und(a))return a;var o=document.createElement(n.tagName),i=n.parentNode&&n.parentNode!==document?n.parentNode:document.body;i.appendChild(o),o.style.position="absolute",o.style.width=100+r;var s=100/o.offsetWidth;i.removeChild(o);var c=s*parseFloat(e);return t.CSS[e+r]=c,c}function B(n,e,r){if(e in n.style){var t=e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),a=n.style[e]||getComputedStyle(n).getPropertyValue(t)||"0";return r?I(n,a,r):a}}function D(n,e){return u.dom(n)&&!u.inp(n)&&(P(n,e)||u.svg(n)&&n[e])?"attribute":u.dom(n)&&b(r,e)?"transform":u.dom(n)&&"transform"!==e&&B(n,e)?"css":null!=n[e]?"object":void 0}function T(n){if(u.dom(n)){for(var e,r=n.style.transform||"",t=/(\w+)\(([^)]*)\)/g,a=new Map;e=t.exec(r);)a.set(e[1],e[2]);return a}}function F(n,e,r,t){var a,i=o(e,"scale")?1:0+(o(a=e,"translate")||"perspective"===a?"px":o(a,"rotate")||o(a,"skew")?"deg":void 0),u=T(n).get(e)||i;return r&&(r.transforms.list.set(e,u),r.transforms.last=e),t?I(n,u,t):u}function N(n,e,r,t){switch(D(n,e)){case"transform":return F(n,e,t,r);case"css":return B(n,e,r);case"attribute":return P(n,e);default:return n[e]||0}}function A(n,e){var r=/^(\*=|\+=|-=)/.exec(n);if(!r)return n;var t=C(n)||0,a=parseFloat(e),o=parseFloat(n.replace(r[0],""));switch(r[0][0]){case"+":return a+o+t;case"-":return a-o+t;case"*":return a*o+t}}function E(n,e){if(u.col(n))return k(n);var r=C(n),t=r?n.substr(0,n.length-r.length):n;return e&&!/\s/g.test(n)?t+e:t}function L(n,e){return Math.sqrt(Math.pow(e.x-n.x,2)+Math.pow(e.y-n.y,2))}function S(n){for(var e,r=n.points,t=0,a=0;a0&&(t+=L(e,o)),e=o}return t}function j(n){if(n.getTotalLength)return n.getTotalLength();switch(n.tagName.toLowerCase()){case"circle":return o=n,2*Math.PI*P(o,"r");case"rect":return 2*P(a=n,"width")+2*P(a,"height");case"line":return L({x:P(t=n,"x1"),y:P(t,"y1")},{x:P(t,"x2"),y:P(t,"y2")});case"polyline":return S(n);case"polygon":return r=(e=n).points,S(e)+L(r.getItem(r.numberOfItems-1),r.getItem(0))}var e,r,t,a,o}function q(n,e){var r=e||{},t=r.el||function(n){for(var e=n.parentNode;u.svg(e)&&(e=e.parentNode,u.svg(e.parentNode)););return e}(n),a=t.getBoundingClientRect(),o=P(t,"viewBox"),i=a.width,s=a.height,c=r.viewBox||(o?o.split(" "):[0,0,i,s]);return{el:t,viewBox:c,x:c[0]/1,y:c[1]/1,w:i/c[2],h:s/c[3]}}function $(n,e){function r(r){void 0===r&&(r=0);var t=e+r>=1?e+r:0;return n.el.getPointAtLength(t)}var t=q(n.el,n.svg),a=r(),o=r(-1),i=r(1);switch(n.property){case"x":return(a.x-t.x)*t.w;case"y":return(a.y-t.y)*t.h;case"angle":return 180*Math.atan2(i.y-o.y,i.x-o.x)/Math.PI}}function X(n,e){var r=/-?\d*\.?\d+/g,t=E(u.pth(n)?n.totalLength:n,e)+"";return{original:t,numbers:t.match(r)?t.match(r).map(Number):[0],strings:u.str(n)||e?t.split(r):[]}}function Y(n){return g(n?m(u.arr(n)?n.map(y):y(n)):[],function(n,e,r){return r.indexOf(n)===e})}function Z(n){var e=Y(n);return e.map(function(n,r){return{target:n,id:r,total:e.length,transforms:{list:T(n)}}})}function Q(n,e){var r=x(e);if(/^spring/.test(r.easing)&&(r.duration=c(r.easing)),u.arr(n)){var t=n.length;2===t&&!u.obj(n[0])?n={value:n}:u.fnc(e.duration)||(r.duration=e.duration/t)}var a=u.arr(n)?n:[n];return a.map(function(n,r){var t=u.obj(n)&&!u.pth(n)?n:{value:n};return u.und(t.delay)&&(t.delay=r?0:e.delay),u.und(t.endDelay)&&(t.endDelay=r===a.length-1?e.endDelay:0),t}).map(function(n){return w(n,r)})}function V(n,e){var r=[],t=e.keyframes;for(var a in t&&(e=w(function(n){for(var e=g(m(n.map(function(n){return Object.keys(n)})),function(n){return u.key(n)}).reduce(function(n,e){return n.indexOf(e)<0&&n.push(e),n},[]),r={},t=function(t){var a=e[t];r[a]=n.map(function(n){var e={};for(var r in n)u.key(r)?r==a&&(e.value=n[r]):e[r]=n[r];return e})},a=0;a-1&&(U.splice(o,1),r=U.length)}else a.tick(e);t++}n()}else K=cancelAnimationFrame(K)}return n}();function en(r){void 0===r&&(r={});var t,o=0,i=0,u=0,s=0,c=null;function f(n){var e=window.Promise&&new Promise(function(n){return c=n});return n.finished=e,e}var l,d,p,v,h,m,y,b,x=(d=M(n,l=r),p=M(e,l),v=V(p,l),h=Z(l.targets),m=R(h,v),y=W(m,p),b=J,J++,w(d,{id:b,children:[],animatables:h,animations:m,duration:y.duration,delay:y.delay,endDelay:y.endDelay}));f(x);function k(){var n=x.direction;"alternate"!==n&&(x.direction="normal"!==n?"normal":"reverse"),x.reversed=!x.reversed,t.forEach(function(n){return n.reversed=x.reversed})}function C(n){return x.reversed?x.duration-n:n}function O(){o=0,i=C(x.currentTime)*(1/en.speed)}function P(n,e){e&&e.seek(n-e.timelineOffset)}function I(n){for(var e=0,r=x.animations,t=r.length;e2||(b=Math.round(b*p)/p)),v.push(b)}var k=d.length;if(k){m=d[0];for(var C=0;C0&&(x.began=!0,B("begin"),B("loopBegin")),d<=r&&0!==x.currentTime&&I(0),(d>=l&&x.currentTime!==e||!e)&&I(e),d>r&&d=e&&(i=0,x.remaining&&!0!==x.remaining&&x.remaining--,x.remaining?(o=u,B("loopComplete"),B("loopBegin"),"alternate"===x.direction&&k()):(x.paused=!0,x.completed||(x.completed=!0,B("loopComplete"),B("complete"),!x.passThrough&&"Promise"in window&&(c(),f(x)))))}return x.reset=function(){var n=x.direction;x.passThrough=!1,x.currentTime=0,x.progress=0,x.paused=!0,x.began=!1,x.changeBegan=!1,x.completed=!1,x.changeCompleted=!1,x.reversePlayback=!1,x.reversed="reverse"===n,x.remaining=x.loop,t=x.children;for(var e=s=t.length;e--;)x.children[e].reset();(x.reversed&&!0!==x.loop||"alternate"===n&&1===x.loop)&&x.remaining++,I(0)},x.set=function(n,e){return G(n,e),x},x.tick=function(n){u=n,o||(o=u),D((u+(i-o))*en.speed)},x.seek=function(n){D(C(n))},x.pause=function(){x.paused=!0,O()},x.play=function(){x.paused&&(x.completed&&x.reset(),x.paused=!1,U.push(x),O(),K||nn())},x.reverse=function(){k(),O()},x.restart=function(){x.reset(),x.play()},x.reset(),x.autoplay&&x.play(),x}function rn(n,e){for(var r=e.length;r--;)b(n,e[r].animatable.target)&&e.splice(r,1)}return"undefined"!=typeof document&&document.addEventListener("visibilitychange",function(){document.hidden?(U.forEach(function(n){return n.pause()}),_=U.slice(0),U=[]):_.forEach(function(n){return n.play()})}),en.version="3.0.1",en.speed=1,en.running=U,en.remove=function(n){for(var e=Y(n),r=U.length;r--;){var t=U[r],a=t.animations,o=t.children;rn(e,a);for(var i=o.length;i--;){var u=o[i],s=u.animations;rn(e,s),s.length||u.children.length||o.splice(i,1)}a.length||o.length||t.pause()}},en.get=N,en.set=G,en.convertPx=I,en.path=function(n,e){var r=u.str(n)?h(n)[0]:n,t=e||100;return function(n){return{property:n,el:r,svg:q(r),totalLength:j(r)*(t/100)}}},en.setDashoffset=function(n){var e=j(n);return n.setAttribute("stroke-dasharray",e),e},en.stagger=function(n,e){void 0===e&&(e={});var r=e.direction||"normal",t=e.easing?v(e.easing):null,a=e.grid,o=e.axis,i=e.from||0,s="first"===i,c="center"===i,f="last"===i,l=u.arr(n),d=l?parseFloat(n[0]):parseFloat(n),p=l?parseFloat(n[1]):0,h=C(l?n[1]:n)||0,g=e.start||0+(l?d:0),m=[],y=0;return function(n,e,u){if(s&&(i=0),c&&(i=(u-1)/2),f&&(i=u-1),!m.length){for(var v=0;v-1&&U.splice(o,1);for(var c=0;c { 14 | // y = mx + b 15 | var m = (y2 - y1) / (x2 - x1), b = y1 - m * x1; 16 | return m * currentVal + b; 17 | }, 18 | lerp: (a, b, n) => (1 - n) * a + n * b 19 | }; 20 | 21 | // Window size 22 | let winsize; 23 | const calcWinsize = () => winsize = {width: window.innerWidth, height: window.innerHeight}; 24 | calcWinsize(); 25 | window.addEventListener('resize', calcWinsize); 26 | 27 | const getMousePos = (ev) => { 28 | let posx = 0; 29 | let posy = 0; 30 | if (!ev) ev = window.event; 31 | if (ev.pageX || ev.pageY) { 32 | posx = ev.pageX; 33 | posy = ev.pageY; 34 | } 35 | else if (ev.clientX || ev.clientY) { 36 | posx = ev.clientX + body.scrollLeft + docEl.scrollLeft; 37 | posy = ev.clientY + body.scrollTop + docEl.scrollTop; 38 | } 39 | return {x: posx, y: posy}; 40 | } 41 | // Track the mouse position 42 | let mousePos = {x: winsize.width/2, y: winsize.height/2}; 43 | window.addEventListener('mousemove', ev => mousePos = getMousePos(ev)); 44 | 45 | // Custom mouse cursor. 46 | class CursorFx { 47 | constructor(el) { 48 | this.DOM = {el: el}; 49 | this.DOM.toggle = this.DOM.el.querySelector('.cursor__inner--circle'); 50 | 51 | this.DOM.title = this.DOM.el.querySelector('.cursor__inner--text'); 52 | this.bounds = { 53 | toggle: this.DOM.toggle.getBoundingClientRect(), 54 | title: this.DOM.title.getBoundingClientRect() 55 | }; 56 | this.lastMousePos = { 57 | toggle: {x: mousePos.x - this.bounds.toggle.width/2, y: mousePos.y - this.bounds.toggle.height/2}, 58 | title: {x: mousePos.x - this.bounds.title.width/2, y: mousePos.y - this.bounds.title.height/2} 59 | }; 60 | this.lastScale = 1; 61 | this.lastOpacity = 1; 62 | requestAnimationFrame(() => this.render()); 63 | } 64 | render() { 65 | // Mouse movement distance on the x-axis 66 | const diff = this.lastMousePos.toggle.x - (mousePos.x - this.bounds.toggle.width/2); 67 | // Check if mouse is on the right side of the viewport 68 | const rightSide = mousePos.x >= winsize.width/2; 69 | // Switch the side of the title element 70 | this.DOM.title.style.left = rightSide ? 'auto' : '30px'; 71 | this.DOM.title.style.right = rightSide ? '30px' : 'auto'; 72 | // The position of the title/toggle and the viewport side will determine the speed for both of these elements 73 | const lerpFactor = { 74 | toggle: rightSide ? diff < 0 ? 0.15 : 0.1 : diff < 0 ? 0.1 : 0.15, 75 | title: rightSide ? diff < 0 ? 0.1 : 0.15 : diff < 0 ? 0.15 : 0.1 76 | }; 77 | // Update the mouse position values given the previous calculated lerp value 78 | this.lastMousePos.toggle.x = MathUtils.lerp(this.lastMousePos.toggle.x, mousePos.x - this.bounds.toggle.width/2, lerpFactor.toggle); 79 | this.lastMousePos.toggle.y = MathUtils.lerp(this.lastMousePos.toggle.y, mousePos.y - this.bounds.toggle.height/2, lerpFactor.toggle); 80 | this.lastMousePos.title.x = MathUtils.lerp(this.lastMousePos.title.x, mousePos.x - this.bounds.title.width/2, lerpFactor.title); 81 | this.lastMousePos.title.y = MathUtils.lerp(this.lastMousePos.title.y, mousePos.y - this.bounds.title.height/2, lerpFactor.title); 82 | // Also the scale and opacity values for the toggle 83 | this.lastScale = MathUtils.lerp(this.lastScale, 1, 0.15); 84 | this.lastOpacity = MathUtils.lerp(this.lastOpacity, 1, 0.1); 85 | // Apply the styles 86 | this.DOM.toggle.style.transform = `translateX(${(this.lastMousePos.toggle.x)}px) translateY(${this.lastMousePos.toggle.y}px) scale(${this.lastScale})`; 87 | this.DOM.toggle.style.opacity = this.lastOpacity; 88 | this.DOM.title.style.transform = `translateX(${(this.lastMousePos.title.x)}px) translateY(${this.lastMousePos.title.y}px)`; 89 | 90 | requestAnimationFrame(() => this.render()); 91 | } 92 | setTitle(title) { 93 | // Sets the title content 94 | this.DOM.title.innerHTML = title; 95 | } 96 | click() { 97 | // Scales down and fades out the mouse toggle 98 | this.lastScale = .5; 99 | this.lastOpacity = 0; 100 | } 101 | toggle() { 102 | const isCircle = this.DOM.toggle.classList.contains('cursor__inner--circle'); 103 | this.DOM.toggle.classList[isCircle ? 'remove' : 'add']('cursor__inner--circle'); 104 | this.DOM.toggle.classList[isCircle ? 'add' : 'remove']('cursor__inner--cross'); 105 | this.DOM.title.style.opacity = isCircle ? 0 : 1; 106 | } 107 | } 108 | 109 | const cursor = new CursorFx(document.querySelector('.cursor')); 110 | 111 | class Grid { 112 | constructor(el) { 113 | this.DOM = {el: el}; 114 | // The grid element 115 | this.DOM.grid = this.DOM.el.querySelector('.grid'); 116 | // Thr grid items 117 | this.DOM.items = [...this.DOM.grid.children]; 118 | // totla number of grid items 119 | this.itemsTotal = this.DOM.items.length; 120 | // The content element ("behind" the grid) 121 | this.DOM.content = document.querySelector('.content'); 122 | this.DOM.contentTitle = this.DOM.content.querySelector('.content__title'); 123 | // Calculate heights of both the grid wrap and the grid, and also: 124 | // . the difference between them (then used for the grid/mousemove translation) 125 | // . the number of rows/columns 126 | this.calculateSize(); 127 | // The grid will be initially translated so it is in the center 128 | this.gridTranslation = {x: 0, y: -1*this.extraHeight/2}; 129 | // Linear interpolation easing percentage (for the grid movement on mouse move) 130 | this.lerpFactor = 0.04; 131 | this.initEvents(); 132 | requestAnimationFrame(() => this.render()); 133 | } 134 | calculateSize() { 135 | // The height of the grid wrap 136 | this.height = this.DOM.el.offsetHeight; 137 | // The difference between the height of the grid wrap and the height of the grid. This is the amount we can translate the grid 138 | this.extraHeight = this.DOM.grid.offsetHeight - this.height; 139 | // Number of grid columns. The CSS variable --cell-number gives us the number of rows 140 | this.columns = this.itemsTotal/getComputedStyle(this.DOM.grid).getPropertyValue('--cell-number'); 141 | // The animejs stagger function needs an array [cols,rows] 142 | this.gridDef = [this.columns, this.itemsTotal/this.columns]; 143 | } 144 | initEvents() { 145 | // Window resize event 146 | // The lerpFactor will change to 1 so theres no delay when translating the grid (or we would see the gaps on the top and bottom) 147 | window.addEventListener('resize', () => { 148 | this.lerpFactor = 1; 149 | // Recalculate.. 150 | this.calculateSize(); 151 | this.columns = this.itemsTotal/getComputedStyle(this.DOM.grid).getPropertyValue('--cell-number'); 152 | clearTimeout(this.resizeTimer); 153 | this.resizeTimer = setTimeout(() => this.lerpFactor = 0.04, 250); 154 | }); 155 | 156 | this.DOM.items.forEach((item, pos) => { 157 | // The item's title. 158 | const title = item.dataset.title; 159 | // Show the title next to the cursor. 160 | item.addEventListener('mouseenter', () => cursor.setTitle(title)); 161 | item.addEventListener('click', () => { 162 | // Position of the clicked item 163 | this.pos = pos; 164 | this.title = title; 165 | // Start the effect and show the content behind 166 | this.showContent(); 167 | // Force to show the title next to the cursor (it might not update because of the grid animation - the item under the mouse can be a different one than the one the user moved the mouse to) 168 | cursor.setTitle(title); 169 | }); 170 | }); 171 | 172 | // Show back the grid. 173 | this.DOM.content.addEventListener('click', () => this.showGrid()); 174 | } 175 | // This is where the main grid effect takes place 176 | // Animates the boxes out and reveals the content "behind" 177 | showContent() { 178 | if ( this.isAnimating ) { 179 | return false; 180 | } 181 | this.isAnimating = true; 182 | // Set the content background image and title 183 | this.DOM.content.style.backgroundImage = this.DOM.items[this.pos].querySelector('.grid__item-inner').style.backgroundImage.replace(/img/g, 'img/large'); 184 | this.DOM.contentTitle.innerHTML = this.title; 185 | // Scales down and fades out the mouse toggle 186 | cursor.click(); 187 | cursor.toggle(); 188 | 189 | this.animation = anime({ 190 | targets: this.DOM.items, 191 | duration: 20, 192 | easing: 'easeOutQuad', 193 | opacity: 0, 194 | delay: anime.stagger(70, {grid: this.gridDef, from: this.pos}) 195 | }); 196 | this.animation.finished.then(() => { 197 | // Pointer events class 198 | this.DOM.el.classList.add('grid-wrap--hidden'); 199 | this.isAnimating = false; 200 | }); 201 | 202 | /* 203 | // Animates the title 204 | anime({ 205 | targets: this.DOM.contentTitle, 206 | duration: 1700, 207 | delay: 200, 208 | easing: 'easeOutExpo', 209 | opacity: [0,1], 210 | translateY: [50,0] 211 | }); 212 | */ 213 | } 214 | showGrid() { 215 | if ( this.isAnimating ) { 216 | return false; 217 | } 218 | this.isAnimating = true; 219 | cursor.click(); 220 | cursor.toggle(); 221 | this.DOM.el.classList.remove('grid-wrap--hidden'); 222 | // Could have used the reverse() but there seems to be a bug (glitch).. 223 | this.animation = anime({ 224 | targets: this.DOM.items, 225 | duration: 20, 226 | easing: 'easeOutQuad', 227 | opacity: [0,1], 228 | delay: anime.stagger(70, {grid: this.gridDef, from: this.pos, direction: 'reverse'}) 229 | }); 230 | this.animation.finished.then(() => this.isAnimating = false); 231 | } 232 | // Translate the grid when moving the mouse 233 | render() { 234 | // The translation will be either 0 or -1*this.extraHeight depending on the position of the mouse on the y-axis 235 | this.gridTranslation.y = MathUtils.lerp(this.gridTranslation.y, Math.min(Math.max(MathUtils.lineEq(-1*this.extraHeight, 0, this.height-this.height*.1, this.height*.1, mousePos.y), -1*this.extraHeight),0), this.lerpFactor); 236 | this.DOM.grid.style.transform = `translateY(${this.gridTranslation.y}px)`; 237 | requestAnimationFrame(() => this.render()); 238 | } 239 | } 240 | 241 | // Initialize the grid 242 | new Grid(document.querySelector('.grid-wrap')); 243 | 244 | // Preload all the images in the page 245 | imagesLoaded(document.querySelectorAll('.grid__item-inner, img'), {background: true}, () => document.body.classList.remove('loading')); 246 | } -------------------------------------------------------------------------------- /js/demo2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * demo2.js 3 | * http://www.codrops.com 4 | * 5 | * Licensed under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 8 | * Copyright 2019, Codrops 9 | * http://www.codrops.com 10 | */ 11 | { 12 | const MathUtils = { 13 | lineEq: (y2, y1, x2, x1, currentVal) => { 14 | // y = mx + b 15 | var m = (y2 - y1) / (x2 - x1), b = y1 - m * x1; 16 | return m * currentVal + b; 17 | }, 18 | lerp: (a, b, n) => (1 - n) * a + n * b 19 | }; 20 | 21 | // Window size 22 | let winsize; 23 | const calcWinsize = () => winsize = {width: window.innerWidth, height: window.innerHeight}; 24 | calcWinsize(); 25 | window.addEventListener('resize', calcWinsize); 26 | 27 | const getMousePos = (ev) => { 28 | let posx = 0; 29 | let posy = 0; 30 | if (!ev) ev = window.event; 31 | if (ev.pageX || ev.pageY) { 32 | posx = ev.pageX; 33 | posy = ev.pageY; 34 | } 35 | else if (ev.clientX || ev.clientY) { 36 | posx = ev.clientX + body.scrollLeft + docEl.scrollLeft; 37 | posy = ev.clientY + body.scrollTop + docEl.scrollTop; 38 | } 39 | return {x: posx, y: posy}; 40 | } 41 | // Track the mouse position 42 | let mousePos = {x: winsize.width/2, y: winsize.height/2}; 43 | window.addEventListener('mousemove', ev => mousePos = getMousePos(ev)); 44 | 45 | // Custom mouse cursor. 46 | class CursorFx { 47 | constructor(el) { 48 | this.DOM = {el: el}; 49 | this.DOM.toggle = this.DOM.el.querySelector('.cursor__inner--circle'); 50 | 51 | this.DOM.title = this.DOM.el.querySelector('.cursor__inner--text'); 52 | this.bounds = { 53 | toggle: this.DOM.toggle.getBoundingClientRect(), 54 | title: this.DOM.title.getBoundingClientRect() 55 | }; 56 | this.lastMousePos = { 57 | toggle: {x: mousePos.x - this.bounds.toggle.width/2, y: mousePos.y - this.bounds.toggle.height/2}, 58 | title: {x: mousePos.x - this.bounds.title.width/2, y: mousePos.y - this.bounds.title.height/2} 59 | }; 60 | this.lastScale = 1; 61 | this.lastOpacity = 1; 62 | requestAnimationFrame(() => this.render()); 63 | } 64 | render() { 65 | // Mouse movement distance on the x-axis 66 | const diff = this.lastMousePos.toggle.x - (mousePos.x - this.bounds.toggle.width/2); 67 | // Check if mouse is on the right side of the viewport 68 | const rightSide = mousePos.x >= winsize.width/2; 69 | // Switch the side of the title element 70 | this.DOM.title.style.left = rightSide ? 'auto' : '30px'; 71 | this.DOM.title.style.right = rightSide ? '30px' : 'auto'; 72 | // The position of the title/toggle and the viewport side will determine the speed for both of these elements 73 | const lerpFactor = { 74 | toggle: rightSide ? diff < 0 ? 0.15 : 0.1 : diff < 0 ? 0.1 : 0.15, 75 | title: rightSide ? diff < 0 ? 0.1 : 0.15 : diff < 0 ? 0.15 : 0.1 76 | }; 77 | // Update the mouse position values given the previous calculated lerp value 78 | this.lastMousePos.toggle.x = MathUtils.lerp(this.lastMousePos.toggle.x, mousePos.x - this.bounds.toggle.width/2, lerpFactor.toggle); 79 | this.lastMousePos.toggle.y = MathUtils.lerp(this.lastMousePos.toggle.y, mousePos.y - this.bounds.toggle.height/2, lerpFactor.toggle); 80 | this.lastMousePos.title.x = MathUtils.lerp(this.lastMousePos.title.x, mousePos.x - this.bounds.title.width/2, lerpFactor.title); 81 | this.lastMousePos.title.y = MathUtils.lerp(this.lastMousePos.title.y, mousePos.y - this.bounds.title.height/2, lerpFactor.title); 82 | // Also the scale and opacity values for the toggle 83 | this.lastScale = MathUtils.lerp(this.lastScale, 1, 0.15); 84 | this.lastOpacity = MathUtils.lerp(this.lastOpacity, 1, 0.1); 85 | // Apply the styles 86 | this.DOM.toggle.style.transform = `translateX(${(this.lastMousePos.toggle.x)}px) translateY(${this.lastMousePos.toggle.y}px) scale(${this.lastScale})`; 87 | this.DOM.toggle.style.opacity = this.lastOpacity; 88 | this.DOM.title.style.transform = `translateX(${(this.lastMousePos.title.x)}px) translateY(${this.lastMousePos.title.y}px)`; 89 | 90 | requestAnimationFrame(() => this.render()); 91 | } 92 | setTitle(title) { 93 | // Sets the title content 94 | this.DOM.title.innerHTML = title; 95 | } 96 | click() { 97 | // Scales down and fades out the mouse toggle 98 | this.lastScale = .5; 99 | this.lastOpacity = 0; 100 | } 101 | toggle() { 102 | const isCircle = this.DOM.toggle.classList.contains('cursor__inner--circle'); 103 | this.DOM.toggle.classList[isCircle ? 'remove' : 'add']('cursor__inner--circle'); 104 | this.DOM.toggle.classList[isCircle ? 'add' : 'remove']('cursor__inner--cross'); 105 | this.DOM.title.style.opacity = isCircle ? 0 : 1; 106 | } 107 | } 108 | 109 | const cursor = new CursorFx(document.querySelector('.cursor')); 110 | 111 | class Grid { 112 | constructor(el) { 113 | this.DOM = {el: el}; 114 | // The grid element 115 | this.DOM.grid = this.DOM.el.querySelector('.grid'); 116 | // Thr grid items 117 | this.DOM.items = [...this.DOM.grid.children]; 118 | // totla number of grid items 119 | this.itemsTotal = this.DOM.items.length; 120 | // The content element ("behind" the grid) 121 | this.DOM.content = document.querySelector('.content'); 122 | this.DOM.contentTitle = this.DOM.content.querySelector('.content__title'); 123 | // Calculate heights of both the grid wrap and the grid, and also: 124 | // . the difference between them (then used for the grid/mousemove translation) 125 | // . the number of rows/columns 126 | this.calculateSize(); 127 | // The grid will be initially translated so it is in the center 128 | this.gridTranslation = {x: 0, y: -1*this.extraHeight/2}; 129 | // Linear interpolation easing percentage (for the grid movement on mouse move) 130 | this.lerpFactor = 0.04; 131 | this.initEvents(); 132 | requestAnimationFrame(() => this.render()); 133 | } 134 | calculateSize() { 135 | // The height of the grid wrap 136 | this.height = this.DOM.el.offsetHeight; 137 | // The difference between the height of the grid wrap and the height of the grid. This is the amount we can translate the grid 138 | this.extraHeight = this.DOM.grid.offsetHeight - this.height; 139 | // Number of grid columns. The CSS variable --cell-number gives us the number of rows 140 | this.columns = this.itemsTotal/getComputedStyle(this.DOM.grid).getPropertyValue('--cell-number'); 141 | // The animejs stagger function needs an array [cols,rows] 142 | this.gridDef = [this.columns, this.itemsTotal/this.columns]; 143 | } 144 | initEvents() { 145 | // Window resize event 146 | // The lerpFactor will change to 1 so theres no delay when translating the grid (or we would see the gaps on the top and bottom) 147 | window.addEventListener('resize', () => { 148 | this.lerpFactor = 1; 149 | // Recalculate.. 150 | this.calculateSize(); 151 | this.columns = this.itemsTotal/getComputedStyle(this.DOM.grid).getPropertyValue('--cell-number'); 152 | clearTimeout(this.resizeTimer); 153 | this.resizeTimer = setTimeout(() => this.lerpFactor = 0.04, 250); 154 | }); 155 | 156 | this.DOM.items.forEach((item, pos) => { 157 | // The item's title. 158 | const title = item.dataset.title; 159 | // Show the title next to the cursor. 160 | item.addEventListener('mouseenter', () => cursor.setTitle(title)); 161 | item.addEventListener('click', () => { 162 | // Position of the clicked item 163 | this.pos = pos; 164 | this.title = title; 165 | // Start the effect and show the content behind 166 | this.showContent(); 167 | // Force to show the title next to the cursor (it might not update because of the grid animation - the item under the mouse can be a different one than the one the user moved the mouse to) 168 | cursor.setTitle(title); 169 | }); 170 | }); 171 | 172 | // Show back the grid. 173 | this.DOM.content.addEventListener('click', () => this.showGrid()); 174 | } 175 | // This is where the main grid effect takes place 176 | // Animates the boxes out and reveals the content "behind" 177 | showContent() { 178 | if ( this.isAnimating ) { 179 | return false; 180 | } 181 | this.isAnimating = true; 182 | // Set the content background image and title 183 | this.DOM.content.style.backgroundImage = this.DOM.items[this.pos].querySelector('.grid__item-inner').style.backgroundImage.replace(/img/g, 'img/large'); 184 | this.DOM.contentTitle.innerHTML = this.title; 185 | // Scales down and fades out the mouse toggle 186 | cursor.click(); 187 | cursor.toggle(); 188 | 189 | this.animation = anime({ 190 | targets: this.DOM.items, 191 | duration: 300, 192 | easing: 'easeOutQuad', 193 | opacity: 0, 194 | scale: 0.5, 195 | delay: anime.stagger(80, {grid: this.gridDef, from: this.pos, direction: 'reverse'}) 196 | }); 197 | this.animation.finished.then(() => { 198 | // Pointer events class 199 | this.DOM.el.classList.add('grid-wrap--hidden'); 200 | this.isAnimating = false; 201 | }); 202 | } 203 | showGrid() { 204 | if ( this.isAnimating ) { 205 | return false; 206 | } 207 | this.isAnimating = true; 208 | cursor.click(); 209 | cursor.toggle(); 210 | this.DOM.el.classList.remove('grid-wrap--hidden'); 211 | // Could have used the reverse() but there seems to be a bug (glitch).. 212 | this.animation = anime({ 213 | targets: this.DOM.items, 214 | duration: 200, 215 | easing: 'easeOutQuad', 216 | opacity: [0,1], 217 | scale: [0,1], 218 | delay: anime.stagger(80, {grid: this.gridDef, from: this.pos, direction: 'reverse'}) 219 | }); 220 | this.animation.finished.then(() => this.isAnimating = false); 221 | } 222 | // Translate the grid when moving the mouse 223 | render() { 224 | // The translation will be either 0 or -1*this.extraHeight depending on the position of the mouse on the y-axis 225 | this.gridTranslation.y = MathUtils.lerp(this.gridTranslation.y, Math.min(Math.max(MathUtils.lineEq(-1*this.extraHeight, 0, this.height-this.height*.1, this.height*.1, mousePos.y), -1*this.extraHeight),0), this.lerpFactor); 226 | this.DOM.grid.style.transform = `translateY(${this.gridTranslation.y}px)`; 227 | requestAnimationFrame(() => this.render()); 228 | } 229 | } 230 | 231 | // Initialize the grid 232 | new Grid(document.querySelector('.grid-wrap')); 233 | 234 | // Preload all the images in the page 235 | imagesLoaded(document.querySelectorAll('.grid__item-inner, img'), {background: true}, () => document.body.classList.remove('loading')); 236 | } -------------------------------------------------------------------------------- /js/demo3.js: -------------------------------------------------------------------------------- 1 | /** 2 | * demo3.js 3 | * http://www.codrops.com 4 | * 5 | * Licensed under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 8 | * Copyright 2019, Codrops 9 | * http://www.codrops.com 10 | */ 11 | { 12 | const MathUtils = { 13 | lineEq: (y2, y1, x2, x1, currentVal) => { 14 | // y = mx + b 15 | var m = (y2 - y1) / (x2 - x1), b = y1 - m * x1; 16 | return m * currentVal + b; 17 | }, 18 | lerp: (a, b, n) => (1 - n) * a + n * b 19 | }; 20 | 21 | // Window size 22 | let winsize; 23 | const calcWinsize = () => winsize = {width: window.innerWidth, height: window.innerHeight}; 24 | calcWinsize(); 25 | window.addEventListener('resize', calcWinsize); 26 | 27 | const getMousePos = (ev) => { 28 | let posx = 0; 29 | let posy = 0; 30 | if (!ev) ev = window.event; 31 | if (ev.pageX || ev.pageY) { 32 | posx = ev.pageX; 33 | posy = ev.pageY; 34 | } 35 | else if (ev.clientX || ev.clientY) { 36 | posx = ev.clientX + body.scrollLeft + docEl.scrollLeft; 37 | posy = ev.clientY + body.scrollTop + docEl.scrollTop; 38 | } 39 | return {x: posx, y: posy}; 40 | } 41 | // Track the mouse position 42 | let mousePos = {x: winsize.width/2, y: winsize.height/2}; 43 | window.addEventListener('mousemove', ev => mousePos = getMousePos(ev)); 44 | 45 | // Custom mouse cursor. 46 | class CursorFx { 47 | constructor(el) { 48 | this.DOM = {el: el}; 49 | this.DOM.toggle = this.DOM.el.querySelector('.cursor__inner--circle'); 50 | 51 | this.DOM.title = this.DOM.el.querySelector('.cursor__inner--text'); 52 | this.bounds = { 53 | toggle: this.DOM.toggle.getBoundingClientRect(), 54 | title: this.DOM.title.getBoundingClientRect() 55 | }; 56 | this.lastMousePos = { 57 | toggle: {x: mousePos.x - this.bounds.toggle.width/2, y: mousePos.y - this.bounds.toggle.height/2}, 58 | title: {x: mousePos.x - this.bounds.title.width/2, y: mousePos.y - this.bounds.title.height/2} 59 | }; 60 | this.lastScale = 1; 61 | this.lastOpacity = 1; 62 | requestAnimationFrame(() => this.render()); 63 | } 64 | render() { 65 | // Mouse movement distance on the x-axis 66 | const diff = this.lastMousePos.toggle.x - (mousePos.x - this.bounds.toggle.width/2); 67 | // Check if mouse is on the right side of the viewport 68 | const rightSide = mousePos.x >= winsize.width/2; 69 | // Switch the side of the title element 70 | this.DOM.title.style.left = rightSide ? 'auto' : '30px'; 71 | this.DOM.title.style.right = rightSide ? '30px' : 'auto'; 72 | // The position of the title/toggle and the viewport side will determine the speed for both of these elements 73 | const lerpFactor = { 74 | toggle: rightSide ? diff < 0 ? 0.15 : 0.1 : diff < 0 ? 0.1 : 0.15, 75 | title: rightSide ? diff < 0 ? 0.1 : 0.15 : diff < 0 ? 0.15 : 0.1 76 | }; 77 | // Update the mouse position values given the previous calculated lerp value 78 | this.lastMousePos.toggle.x = MathUtils.lerp(this.lastMousePos.toggle.x, mousePos.x - this.bounds.toggle.width/2, lerpFactor.toggle); 79 | this.lastMousePos.toggle.y = MathUtils.lerp(this.lastMousePos.toggle.y, mousePos.y - this.bounds.toggle.height/2, lerpFactor.toggle); 80 | this.lastMousePos.title.x = MathUtils.lerp(this.lastMousePos.title.x, mousePos.x - this.bounds.title.width/2, lerpFactor.title); 81 | this.lastMousePos.title.y = MathUtils.lerp(this.lastMousePos.title.y, mousePos.y - this.bounds.title.height/2, lerpFactor.title); 82 | // Also the scale and opacity values for the toggle 83 | this.lastScale = MathUtils.lerp(this.lastScale, 1, 0.15); 84 | this.lastOpacity = MathUtils.lerp(this.lastOpacity, 1, 0.1); 85 | // Apply the styles 86 | this.DOM.toggle.style.transform = `translateX(${(this.lastMousePos.toggle.x)}px) translateY(${this.lastMousePos.toggle.y}px) scale(${this.lastScale})`; 87 | this.DOM.toggle.style.opacity = this.lastOpacity; 88 | this.DOM.title.style.transform = `translateX(${(this.lastMousePos.title.x)}px) translateY(${this.lastMousePos.title.y}px)`; 89 | 90 | requestAnimationFrame(() => this.render()); 91 | } 92 | setTitle(title) { 93 | // Sets the title content 94 | this.DOM.title.innerHTML = title; 95 | } 96 | click() { 97 | // Scales down and fades out the mouse toggle 98 | this.lastScale = .5; 99 | this.lastOpacity = 0; 100 | } 101 | toggle() { 102 | const isCircle = this.DOM.toggle.classList.contains('cursor__inner--circle'); 103 | this.DOM.toggle.classList[isCircle ? 'remove' : 'add']('cursor__inner--circle'); 104 | this.DOM.toggle.classList[isCircle ? 'add' : 'remove']('cursor__inner--cross'); 105 | this.DOM.title.style.opacity = isCircle ? 0 : 1; 106 | } 107 | } 108 | 109 | const cursor = new CursorFx(document.querySelector('.cursor')); 110 | 111 | class Grid { 112 | constructor(el) { 113 | this.DOM = {el: el}; 114 | // The grid element 115 | this.DOM.grid = this.DOM.el.querySelector('.grid'); 116 | // Thr grid items 117 | this.DOM.items = [...this.DOM.grid.children]; 118 | // totla number of grid items 119 | this.itemsTotal = this.DOM.items.length; 120 | // The content element ("behind" the grid) 121 | this.DOM.content = document.querySelector('.content'); 122 | this.DOM.contentTitle = this.DOM.content.querySelector('.content__title'); 123 | // Calculate heights of both the grid wrap and the grid, and also: 124 | // . the difference between them (then used for the grid/mousemove translation) 125 | // . the number of rows/columns 126 | this.calculateSize(); 127 | // The grid will be initially translated so it is in the center 128 | this.gridTranslation = {x: 0, y: -1*this.extraHeight/2}; 129 | // Linear interpolation easing percentage (for the grid movement on mouse move) 130 | this.lerpFactor = 0.04; 131 | this.initEvents(); 132 | requestAnimationFrame(() => this.render()); 133 | } 134 | calculateSize() { 135 | // The height of the grid wrap 136 | this.height = this.DOM.el.offsetHeight; 137 | // The difference between the height of the grid wrap and the height of the grid. This is the amount we can translate the grid 138 | this.extraHeight = this.DOM.grid.offsetHeight - this.height; 139 | // Number of grid columns. The CSS variable --cell-number gives us the number of rows 140 | this.columns = this.itemsTotal/getComputedStyle(this.DOM.grid).getPropertyValue('--cell-number'); 141 | // The animejs stagger function needs an array [cols,rows] 142 | this.gridDef = [this.columns, this.itemsTotal/this.columns]; 143 | } 144 | initEvents() { 145 | // Window resize event 146 | // The lerpFactor will change to 1 so theres no delay when translating the grid (or we would see the gaps on the top and bottom) 147 | window.addEventListener('resize', () => { 148 | this.lerpFactor = 1; 149 | // Recalculate.. 150 | this.calculateSize(); 151 | this.columns = this.itemsTotal/getComputedStyle(this.DOM.grid).getPropertyValue('--cell-number'); 152 | clearTimeout(this.resizeTimer); 153 | this.resizeTimer = setTimeout(() => this.lerpFactor = 0.04, 250); 154 | }); 155 | 156 | this.DOM.items.forEach((item, pos) => { 157 | // The item's title. 158 | const title = item.dataset.title; 159 | // Show the title next to the cursor. 160 | item.addEventListener('mouseenter', () => cursor.setTitle(title)); 161 | item.addEventListener('click', () => { 162 | // Position of the clicked item 163 | this.pos = pos; 164 | this.title = title; 165 | // Start the effect and show the content behind 166 | this.showContent(); 167 | // Force to show the title next to the cursor (it might not update because of the grid animation - the item under the mouse can be a different one than the one the user moved the mouse to) 168 | cursor.setTitle(title); 169 | }); 170 | }); 171 | 172 | // Show back the grid. 173 | this.DOM.content.addEventListener('click', () => this.showGrid()); 174 | } 175 | // This is where the main grid effect takes place 176 | // Animates the boxes out and reveals the content "behind" 177 | showContent() { 178 | if ( this.isAnimating ) { 179 | return false; 180 | } 181 | this.isAnimating = true; 182 | // Set the content background image and title 183 | this.DOM.content.style.backgroundImage = this.DOM.items[this.pos].querySelector('.grid__item-inner').style.backgroundImage.replace(/img/g, 'img/large'); 184 | this.DOM.contentTitle.innerHTML = this.title; 185 | // Scales down and fades out the mouse toggle 186 | cursor.click(); 187 | cursor.toggle(); 188 | 189 | this.animation = anime({ 190 | targets: this.DOM.items, 191 | duration: 700, 192 | easing: 'easeOutQuint', 193 | opacity: 0, 194 | translateX: anime.stagger(-3, {grid: this.gridDef, axis: 'x'}), 195 | delay: anime.stagger(50, {grid: this.gridDef}) 196 | }); 197 | this.animation.play(); 198 | this.animation.finished.then(() => { 199 | // Pointer events class 200 | this.DOM.el.classList.add('grid-wrap--hidden'); 201 | this.isAnimating = false; 202 | }); 203 | } 204 | showGrid() { 205 | if ( this.isAnimating ) { 206 | return false; 207 | } 208 | this.isAnimating = true; 209 | cursor.click(); 210 | cursor.toggle(); 211 | this.DOM.el.classList.remove('grid-wrap--hidden'); 212 | // Could have used the reverse() but there seems to be a bug (glitch).. 213 | this.animation = anime({ 214 | targets: this.DOM.items, 215 | duration: 200, 216 | easing: 'easeOutQuint', 217 | opacity: [0,1], 218 | translateX: [0, 0], 219 | delay: anime.stagger(60, {grid: this.gridDef, from: this.pos}) 220 | }); 221 | this.animation.finished.then(() => this.isAnimating = false); 222 | } 223 | // Translate the grid when moving the mouse 224 | render() { 225 | // The translation will be either 0 or -1*this.extraHeight depending on the position of the mouse on the y-axis 226 | this.gridTranslation.y = MathUtils.lerp(this.gridTranslation.y, Math.min(Math.max(MathUtils.lineEq(-1*this.extraHeight, 0, this.height-this.height*.1, this.height*.1, mousePos.y), -1*this.extraHeight),0), this.lerpFactor); 227 | this.DOM.grid.style.transform = `translateY(${this.gridTranslation.y}px)`; 228 | requestAnimationFrame(() => this.render()); 229 | } 230 | } 231 | 232 | // Initialize the grid 233 | new Grid(document.querySelector('.grid-wrap')); 234 | 235 | // Preload all the images in the page 236 | imagesLoaded(document.querySelectorAll('.grid__item-inner, img'), {background: true}, () => document.body.classList.remove('loading')); 237 | } -------------------------------------------------------------------------------- /js/demo4.js: -------------------------------------------------------------------------------- 1 | /** 2 | * demo4.js 3 | * http://www.codrops.com 4 | * 5 | * Licensed under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 8 | * Copyright 2019, Codrops 9 | * http://www.codrops.com 10 | */ 11 | { 12 | const MathUtils = { 13 | lineEq: (y2, y1, x2, x1, currentVal) => { 14 | // y = mx + b 15 | var m = (y2 - y1) / (x2 - x1), b = y1 - m * x1; 16 | return m * currentVal + b; 17 | }, 18 | lerp: (a, b, n) => (1 - n) * a + n * b 19 | }; 20 | 21 | // Window size 22 | let winsize; 23 | const calcWinsize = () => winsize = {width: window.innerWidth, height: window.innerHeight}; 24 | calcWinsize(); 25 | window.addEventListener('resize', calcWinsize); 26 | 27 | const getMousePos = (ev) => { 28 | let posx = 0; 29 | let posy = 0; 30 | if (!ev) ev = window.event; 31 | if (ev.pageX || ev.pageY) { 32 | posx = ev.pageX; 33 | posy = ev.pageY; 34 | } 35 | else if (ev.clientX || ev.clientY) { 36 | posx = ev.clientX + body.scrollLeft + docEl.scrollLeft; 37 | posy = ev.clientY + body.scrollTop + docEl.scrollTop; 38 | } 39 | return {x: posx, y: posy}; 40 | } 41 | // Track the mouse position 42 | let mousePos = {x: winsize.width/2, y: winsize.height/2}; 43 | window.addEventListener('mousemove', ev => mousePos = getMousePos(ev)); 44 | 45 | // Custom mouse cursor. 46 | class CursorFx { 47 | constructor(el) { 48 | this.DOM = {el: el}; 49 | this.DOM.toggle = this.DOM.el.querySelector('.cursor__inner--circle'); 50 | 51 | this.DOM.title = this.DOM.el.querySelector('.cursor__inner--text'); 52 | this.bounds = { 53 | toggle: this.DOM.toggle.getBoundingClientRect(), 54 | title: this.DOM.title.getBoundingClientRect() 55 | }; 56 | this.lastMousePos = { 57 | toggle: {x: mousePos.x - this.bounds.toggle.width/2, y: mousePos.y - this.bounds.toggle.height/2}, 58 | title: {x: mousePos.x - this.bounds.title.width/2, y: mousePos.y - this.bounds.title.height/2} 59 | }; 60 | this.lastScale = 1; 61 | this.lastOpacity = 1; 62 | requestAnimationFrame(() => this.render()); 63 | } 64 | render() { 65 | // Mouse movement distance on the x-axis 66 | const diff = this.lastMousePos.toggle.x - (mousePos.x - this.bounds.toggle.width/2); 67 | // Check if mouse is on the right side of the viewport 68 | const rightSide = mousePos.x >= winsize.width/2; 69 | // Switch the side of the title element 70 | this.DOM.title.style.left = rightSide ? 'auto' : '30px'; 71 | this.DOM.title.style.right = rightSide ? '30px' : 'auto'; 72 | // The position of the title/toggle and the viewport side will determine the speed for both of these elements 73 | const lerpFactor = { 74 | toggle: rightSide ? diff < 0 ? 0.15 : 0.1 : diff < 0 ? 0.1 : 0.15, 75 | title: rightSide ? diff < 0 ? 0.1 : 0.15 : diff < 0 ? 0.15 : 0.1 76 | }; 77 | // Update the mouse position values given the previous calculated lerp value 78 | this.lastMousePos.toggle.x = MathUtils.lerp(this.lastMousePos.toggle.x, mousePos.x - this.bounds.toggle.width/2, lerpFactor.toggle); 79 | this.lastMousePos.toggle.y = MathUtils.lerp(this.lastMousePos.toggle.y, mousePos.y - this.bounds.toggle.height/2, lerpFactor.toggle); 80 | this.lastMousePos.title.x = MathUtils.lerp(this.lastMousePos.title.x, mousePos.x - this.bounds.title.width/2, lerpFactor.title); 81 | this.lastMousePos.title.y = MathUtils.lerp(this.lastMousePos.title.y, mousePos.y - this.bounds.title.height/2, lerpFactor.title); 82 | // Also the scale and opacity values for the toggle 83 | this.lastScale = MathUtils.lerp(this.lastScale, 1, 0.15); 84 | this.lastOpacity = MathUtils.lerp(this.lastOpacity, 1, 0.1); 85 | // Apply the styles 86 | this.DOM.toggle.style.transform = `translateX(${(this.lastMousePos.toggle.x)}px) translateY(${this.lastMousePos.toggle.y}px) scale(${this.lastScale})`; 87 | this.DOM.toggle.style.opacity = this.lastOpacity; 88 | this.DOM.title.style.transform = `translateX(${(this.lastMousePos.title.x)}px) translateY(${this.lastMousePos.title.y}px)`; 89 | 90 | requestAnimationFrame(() => this.render()); 91 | } 92 | setTitle(title) { 93 | // Sets the title content 94 | this.DOM.title.innerHTML = title; 95 | } 96 | click() { 97 | // Scales down and fades out the mouse toggle 98 | this.lastScale = .5; 99 | this.lastOpacity = 0; 100 | } 101 | toggle() { 102 | const isCircle = this.DOM.toggle.classList.contains('cursor__inner--circle'); 103 | this.DOM.toggle.classList[isCircle ? 'remove' : 'add']('cursor__inner--circle'); 104 | this.DOM.toggle.classList[isCircle ? 'add' : 'remove']('cursor__inner--cross'); 105 | this.DOM.title.style.opacity = isCircle ? 0 : 1; 106 | } 107 | } 108 | 109 | const cursor = new CursorFx(document.querySelector('.cursor')); 110 | 111 | class Grid { 112 | constructor(el) { 113 | this.DOM = {el: el}; 114 | // The grid element 115 | this.DOM.grid = this.DOM.el.querySelector('.grid'); 116 | // Thr grid items 117 | this.DOM.items = [...this.DOM.grid.children]; 118 | this.DOM.items.forEach(item => { 119 | const rand = Math.random() < 0.5; 120 | item.style.transformOrigin = rand ? '0% 0%' : '100% 0%'; 121 | item.dataset.rotateDir = rand ? 'l' : 'r'; 122 | }) 123 | // totla number of grid items 124 | this.itemsTotal = this.DOM.items.length; 125 | // The content element ("behind" the grid) 126 | this.DOM.content = document.querySelector('.content'); 127 | this.DOM.contentTitle = this.DOM.content.querySelector('.content__title'); 128 | // Calculate heights of both the grid wrap and the grid, and also: 129 | // . the difference between them (then used for the grid/mousemove translation) 130 | // . the number of rows/columns 131 | this.calculateSize(); 132 | // The grid will be initially translated so it is in the center 133 | this.gridTranslation = {x: 0, y: -1*this.extraHeight/2}; 134 | // Linear interpolation easing percentage (for the grid movement on mouse move) 135 | this.lerpFactor = 0.04; 136 | this.initEvents(); 137 | requestAnimationFrame(() => this.render()); 138 | } 139 | calculateSize() { 140 | // The height of the grid wrap 141 | this.height = this.DOM.el.offsetHeight; 142 | // The difference between the height of the grid wrap and the height of the grid. This is the amount we can translate the grid 143 | this.extraHeight = this.DOM.grid.offsetHeight - this.height; 144 | // Number of grid columns. The CSS variable --cell-number gives us the number of rows 145 | this.columns = this.itemsTotal/getComputedStyle(this.DOM.grid).getPropertyValue('--cell-number'); 146 | // The animejs stagger function needs an array [cols,rows] 147 | this.gridDef = [this.columns, this.itemsTotal/this.columns]; 148 | } 149 | initEvents() { 150 | // Window resize event 151 | // The lerpFactor will change to 1 so theres no delay when translating the grid (or we would see the gaps on the top and bottom) 152 | window.addEventListener('resize', () => { 153 | this.lerpFactor = 1; 154 | // Recalculate.. 155 | this.calculateSize(); 156 | this.columns = this.itemsTotal/getComputedStyle(this.DOM.grid).getPropertyValue('--cell-number'); 157 | clearTimeout(this.resizeTimer); 158 | this.resizeTimer = setTimeout(() => this.lerpFactor = 0.04, 250); 159 | }); 160 | 161 | this.DOM.items.forEach((item, pos) => { 162 | // The item's title. 163 | const title = item.dataset.title; 164 | // Show the title next to the cursor. 165 | item.addEventListener('mouseenter', () => cursor.setTitle(title)); 166 | item.addEventListener('click', () => { 167 | // Position of the clicked item 168 | this.pos = pos; 169 | this.title = title; 170 | // Start the effect and show the content behind 171 | this.showContent(); 172 | // Force to show the title next to the cursor (it might not update because of the grid animation - the item under the mouse can be a different one than the one the user moved the mouse to) 173 | cursor.setTitle(title); 174 | }); 175 | }); 176 | 177 | // Show back the grid. 178 | this.DOM.content.addEventListener('click', () => this.showGrid()); 179 | } 180 | // This is where the main grid effect takes place 181 | // Animates the boxes out and reveals the content "behind" 182 | showContent() { 183 | if ( this.isAnimating ) { 184 | return false; 185 | } 186 | this.isAnimating = true; 187 | // Set the content background image and title 188 | this.DOM.content.style.backgroundImage = this.DOM.items[this.pos].querySelector('.grid__item-inner').style.backgroundImage.replace(/img/g, 'img/large'); 189 | this.DOM.contentTitle.innerHTML = this.title; 190 | // Scales down and fades out the mouse toggle 191 | cursor.click(); 192 | cursor.toggle(); 193 | 194 | this.animation = anime({ 195 | targets: this.DOM.items, 196 | opacity: [ 197 | { 198 | value: 1, duration: 500 199 | }, 200 | { 201 | value: 0, 202 | duration: 500, 203 | easing: 'easeInQuad' 204 | } 205 | ], 206 | translateY: [ 207 | { 208 | value: 0, duration: 500 209 | }, 210 | { 211 | value: () => anime.random(100,400), 212 | duration: 500, 213 | easing: 'easeInQuad' 214 | } 215 | ], 216 | rotate: [ 217 | { 218 | value: target => target.dataset.rotateDir === 'l' ? anime.random(2,15) : anime.random(-0,-15), 219 | duration: 500, 220 | easing: 'easeInOutSine' 221 | }, 222 | { 223 | value: target => target.dataset.rotateDir === 'l' ? 8 : -8, 224 | duration: 500, 225 | easing: 'easeInQuad' 226 | } 227 | ], 228 | delay: anime.stagger(350, {grid: this.gridDef, from: this.pos}) 229 | }); 230 | this.animation.play(); 231 | this.animation.finished.then(() => { 232 | // Pointer events class 233 | this.DOM.el.classList.add('grid-wrap--hidden'); 234 | this.isAnimating = false; 235 | }); 236 | } 237 | showGrid() { 238 | if ( this.isAnimating ) { 239 | return false; 240 | } 241 | this.isAnimating = true; 242 | cursor.click(); 243 | cursor.toggle(); 244 | this.DOM.el.classList.remove('grid-wrap--hidden'); 245 | // Could have used the reverse() but there seems to be a bug (glitch).. 246 | this.animation = anime({ 247 | targets: this.DOM.items, 248 | duration: 300, 249 | easing: 'easeOutExpo', 250 | opacity: [0,1], 251 | translateY: [200, 0], 252 | rotate: [0,0], 253 | delay: anime.stagger(70, {grid: this.gridDef, from: this.pos}) 254 | }); 255 | this.animation.finished.then(() => this.isAnimating = false); 256 | } 257 | // Translate the grid when moving the mouse 258 | render() { 259 | // The translation will be either 0 or -1*this.extraHeight depending on the position of the mouse on the y-axis 260 | this.gridTranslation.y = MathUtils.lerp(this.gridTranslation.y, Math.min(Math.max(MathUtils.lineEq(-1*this.extraHeight, 0, this.height-this.height*.1, this.height*.1, mousePos.y), -1*this.extraHeight),0), this.lerpFactor); 261 | this.DOM.grid.style.transform = `translateY(${this.gridTranslation.y}px)`; 262 | requestAnimationFrame(() => this.render()); 263 | } 264 | } 265 | 266 | // Initialize the grid 267 | new Grid(document.querySelector('.grid-wrap')); 268 | 269 | // Preload all the images in the page 270 | imagesLoaded(document.querySelectorAll('.grid__item-inner, img'), {background: true}, () => document.body.classList.remove('loading')); 271 | } -------------------------------------------------------------------------------- /js/imagesloaded.pkgd.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * imagesLoaded PACKAGED v4.1.4 3 | * JavaScript is all like "You images are done yet or what?" 4 | * MIT License 5 | */ 6 | 7 | !function(e,t){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",t):"object"==typeof module&&module.exports?module.exports=t():e.EvEmitter=t()}("undefined"!=typeof window?window:this,function(){function e(){}var t=e.prototype;return t.on=function(e,t){if(e&&t){var i=this._events=this._events||{},n=i[e]=i[e]||[];return n.indexOf(t)==-1&&n.push(t),this}},t.once=function(e,t){if(e&&t){this.on(e,t);var i=this._onceEvents=this._onceEvents||{},n=i[e]=i[e]||{};return n[t]=!0,this}},t.off=function(e,t){var i=this._events&&this._events[e];if(i&&i.length){var n=i.indexOf(t);return n!=-1&&i.splice(n,1),this}},t.emitEvent=function(e,t){var i=this._events&&this._events[e];if(i&&i.length){i=i.slice(0),t=t||[];for(var n=this._onceEvents&&this._onceEvents[e],o=0;o