├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── css └── base.css ├── favicon.ico ├── img ├── 1.avif ├── 1.png ├── 10.avif ├── 10.png ├── 11.avif ├── 11.png ├── 12.avif ├── 12.png ├── 13.avif ├── 13.png ├── 14.avif ├── 14.png ├── 15.avif ├── 15.png ├── 2.avif ├── 2.png ├── 3.avif ├── 3.png ├── 4.avif ├── 4.png ├── 5.avif ├── 5.png ├── 6.avif ├── 6.png ├── 7.avif ├── 7.png ├── 8.avif ├── 8.png ├── 9.avif └── 9.png ├── index.html ├── index2.html └── js └── vanilla-tilt.js /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .cache 3 | .parcel-cache 4 | package-lock.json -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2009 - 2021 [Codrops](https://tympanus.net/codrops) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 3D Perspective Glitch Hover Effect 2 | 3 | A fun hover effect that shows a pixelated image with a glitch animation as seen on [buōy's website](https://buoy.work/gallery/). 4 | 5 | ![Image Title](https://tympanus.net/codrops/wp-content/uploads/2022/09/GlitchPers_feat.jpg) 6 | 7 | [Article on Codrops](https://tympanus.net/codrops/?p=64948) 8 | 9 | [Demo](http://tympanus.net/Development/GlitchPerspective/) 10 | 11 | 12 | ## Installation 13 | 14 | Install dependencies: 15 | 16 | ``` 17 | npm install 18 | ``` 19 | 20 | Compile the code for development and start a local server: 21 | 22 | ``` 23 | npm start 24 | ``` 25 | 26 | Create the build: 27 | 28 | ``` 29 | npm run build 30 | ``` 31 | 32 | ## Credits 33 | 34 | - Images from [Unsplash](https://unsplash.com/) 35 | 36 | ## Misc 37 | 38 | Follow Codrops: [Twitter](http://www.twitter.com/codrops), [Facebook](http://www.facebook.com/codrops), [GitHub](https://github.com/codrops), [Instagram](https://www.instagram.com/codropsss/) 39 | 40 | ## License 41 | [MIT](LICENSE) 42 | 43 | Made with :blue_heart: by [Codrops](http://www.codrops.com) 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /css/base.css: -------------------------------------------------------------------------------- 1 | *, 2 | *::after, 3 | *::before { 4 | box-sizing: border-box; 5 | } 6 | 7 | :root { 8 | font-size: 16px; 9 | --color-text: #000; 10 | --color-bg: #3124c7; 11 | --color-link: #fff; 12 | --color-link-hover: #000; 13 | --color-label: #fff; 14 | --content-hover: #f3727e; 15 | /* Glitch variables */ 16 | --gap-horizontal: 20px; 17 | --gap-vertical: 5px; 18 | --time-anim: 1s; 19 | --blend-mode-1: none; 20 | --blend-mode-2: color-dodge; 21 | --blend-mode-3: luminosity; 22 | --blend-mode-4: none; 23 | --blend-mode-5: none; 24 | --blend-color-1: #f3727e; 25 | --blend-color-2: #f3727e; 26 | --blend-color-3: #3124c7; 27 | --blend-color-4: #3124c7; 28 | --blend-color-5: #f3727e; 29 | /* Rotation variables */ 30 | --rotate-time: 0.5s; 31 | --rotate-easing: cubic-bezier(0.2,1,0.3,1); 32 | /* Cover variables */ 33 | --fade-out-time: 0.25s; 34 | --fade-in-time: 0.25s; 35 | --fade-out-easing: ease-out; 36 | --fade-in-easing: ease-out; 37 | } 38 | 39 | .demo-2 { 40 | --color-bg: #6d5c5b; 41 | --content-hover: #000; 42 | } 43 | 44 | body { 45 | margin: 0; 46 | color: var(--color-text); 47 | background-color: var(--color-bg); 48 | font-family: widescreen-ex, sans-serif; 49 | -webkit-font-smoothing: antialiased; 50 | -moz-osx-font-smoothing: grayscale; 51 | overflow-x: hidden; 52 | } 53 | 54 | /* Page Loader */ 55 | .js .loading::before, 56 | .js .loading::after { 57 | content: ''; 58 | position: fixed; 59 | z-index: 1000; 60 | } 61 | 62 | .js .loading::before { 63 | top: 0; 64 | left: 0; 65 | width: 100%; 66 | height: 100%; 67 | background: var(--color-bg); 68 | } 69 | 70 | .js .loading::after { 71 | top: 50%; 72 | left: 50%; 73 | width: 60px; 74 | height: 60px; 75 | margin: -30px 0 0 -30px; 76 | border-radius: 50%; 77 | opacity: 0.4; 78 | background: var(--color-link); 79 | animation: loaderAnim 0.7s linear infinite alternate forwards; 80 | 81 | } 82 | 83 | @keyframes loaderAnim { 84 | to { 85 | opacity: 1; 86 | transform: scale3d(0.5,0.5,1); 87 | } 88 | } 89 | 90 | a { 91 | text-decoration: none; 92 | color: var(--color-link); 93 | outline: none; 94 | cursor: pointer; 95 | } 96 | 97 | a:hover { 98 | color: var(--color-link-hover); 99 | outline: none; 100 | } 101 | 102 | /* Better focus styles from https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible */ 103 | a:focus { 104 | /* Provide a fallback style for browsers 105 | that don't support :focus-visible */ 106 | outline: none; 107 | background: lightgrey; 108 | } 109 | 110 | a:focus:not(:focus-visible) { 111 | /* Remove the focus indicator on mouse-focus for browsers 112 | that do support :focus-visible */ 113 | background: transparent; 114 | } 115 | 116 | a:focus-visible { 117 | /* Draw a very noticeable focus style for 118 | keyboard-focus on browsers that do support 119 | :focus-visible */ 120 | outline: 2px solid red; 121 | background: transparent; 122 | } 123 | 124 | .unbutton { 125 | background: none; 126 | border: 0; 127 | padding: 0; 128 | margin: 0; 129 | font: inherit; 130 | cursor: pointer; 131 | } 132 | 133 | .unbutton:focus { 134 | outline: none; 135 | } 136 | 137 | .frame { 138 | padding: 1rem 2rem; 139 | text-transform: uppercase; 140 | } 141 | 142 | .frame__title-main { 143 | font-size: 1rem; 144 | margin: 0; 145 | font-weight: normal; 146 | } 147 | 148 | .frame__title-back { 149 | position: relative; 150 | display: flex; 151 | align-items: flex-end; 152 | margin-bottom: 0.15rem; 153 | } 154 | 155 | .frame__title-back span { 156 | display: none; 157 | } 158 | 159 | .frame__title-back svg { 160 | fill: var(--color-text); 161 | } 162 | 163 | .frame__title-prev { 164 | margin: 0 2rem 0 0; 165 | } 166 | 167 | .frame__demo { 168 | margin: 0 1rem 0 0; 169 | } 170 | 171 | .frame__demo--current { 172 | color: var(--color-link-hover); 173 | } 174 | 175 | .intro { 176 | padding: 10vh 2rem 10vh; 177 | margin-bottom: 2rem; 178 | } 179 | 180 | .intro__title { 181 | grid-area: title; 182 | font-family: widescreen-ex, sans-serif; 183 | font-weight: 800; 184 | font-size: clamp(2rem,12vw,10rem); 185 | line-height: 1; 186 | margin: 0; 187 | } 188 | 189 | .intro__title span { 190 | text-transform: uppercase; 191 | -webkit-text-stroke: 1px #000; 192 | text-stroke: 1px #000; 193 | -webkit-text-fill-color: transparent; 194 | text-fill-color: transparent; 195 | color: transparent; 196 | text-shadow: -10px 10px 0 #000; 197 | } 198 | 199 | .intro__title em { 200 | font-family: park-lane, serif; 201 | font-weight: 300; 202 | font-style: normal; 203 | display: block; 204 | margin: -2.5vw 0 0 0; 205 | text-transform: uppercase; 206 | font-size: clamp(2rem,10vw,10rem); 207 | -webkit-text-stroke: 1px #000; 208 | text-stroke: 1px #000; 209 | -webkit-text-fill-color: var(--color-bg); 210 | text-fill-color: var(--color-bg); 211 | color: var(--color-bg); 212 | } 213 | 214 | .intro__description { 215 | margin: 1.75vw 0 0 0; 216 | grid-area: desc; 217 | font-weight: 500; 218 | font-size: clamp(1rem, 2vw, 1.25rem); 219 | max-width: 350px; 220 | } 221 | 222 | .intro__button { 223 | grid-area: button; 224 | border: 1px solid var(--color-text); 225 | background: var(--color-bg); 226 | box-shadow: 1px 2px 0 #000; 227 | font-size: 1.25rem; 228 | padding: 1rem 2rem; 229 | border-radius: 1.25rem; 230 | justify-self: end; 231 | font-weight: bold; 232 | text-transform: uppercase; 233 | margin-top: 1rem; 234 | } 235 | 236 | .intro__button:hover, 237 | .intro__button:focus { 238 | transform: translate3d(1px,2px,0); 239 | box-shadow: 0px 0px 0 #000; 240 | } 241 | 242 | .content { 243 | display: grid; 244 | grid-gap: 1.5rem; 245 | margin: 0 auto; 246 | padding-bottom: 30vh; 247 | grid-template-columns: repeat(auto-fill, minmax(350px,1fr)); 248 | } 249 | 250 | .item { 251 | aspect-ratio: 0.8; 252 | cursor: pointer; 253 | display: grid; 254 | grid-template-columns: 100%; 255 | grid-template-rows: 100%; 256 | perspective: 1000px; 257 | overflow: hidden; 258 | position: relative; 259 | margin: 0; 260 | } 261 | 262 | .demo-2 .item { 263 | overflow: visible; 264 | } 265 | 266 | .demo-2 .item--oh { 267 | overflow: hidden; 268 | } 269 | 270 | .item__img { 271 | grid-area: 1 / 1 / -1 / -1; 272 | position: relative; 273 | opacity: 0; 274 | width: 100%; 275 | height: 100%; 276 | } 277 | 278 | .item:hover .item__img { 279 | opacity: 1; 280 | transition: transform var(--rotate-time) var(--rotate-easing); 281 | transform: translateZ(-200px) rotateX(60deg) rotateY(0) rotateZ(-35deg); 282 | } 283 | 284 | .glitch { 285 | display: grid; 286 | place-items: center; 287 | } 288 | 289 | .glitch__img { 290 | grid-area: 1 / 1 / -1 / -1; 291 | background-image: var(--img); 292 | background-position: 50% 50%; 293 | background-size: cover; 294 | image-rendering: pixelated; 295 | width: 100%; 296 | height: 100%; 297 | background-color: var(--blend-color-1); 298 | transform: translate3d(0,0,0); 299 | background-blend-mode: var(--blend-mode-1); 300 | } 301 | 302 | .glitch__img:nth-child(2) { 303 | background-color: var(--blend-color-2); 304 | background-blend-mode: var(--blend-mode-2); 305 | } 306 | 307 | .glitch__img:nth-child(3) { 308 | background-color: var(--blend-color-3); 309 | background-blend-mode: var(--blend-mode-3); 310 | } 311 | 312 | .glitch__img:nth-child(4) { 313 | background-color: var(--blend-color-4); 314 | background-blend-mode: var(--blend-mode-4); 315 | } 316 | 317 | .glitch__img:nth-child(5) { 318 | background-color: var(--blend-color-5); 319 | background-blend-mode: var(--blend-mode-5); 320 | } 321 | 322 | /* Hide all images except the first one */ 323 | .glitch__img:nth-child(n+2) { 324 | opacity: 0; 325 | } 326 | 327 | /* Hovers */ 328 | 329 | /* On hover we show the 2nd, 3rd, 4th and 5th image*/ 330 | .item:hover .glitch__img:nth-child(n+2) { 331 | opacity: 1; 332 | } 333 | 334 | /* Hover animations for horizontal case */ 335 | .item:hover .glitch__img:nth-child(2) { 336 | transform: translate3d(var(--gap-horizontal),0,0); 337 | animation: glitch-anim-1-horizontal var(--time-anim) infinite linear alternate; 338 | } 339 | 340 | .item:hover .glitch__img:nth-child(3) { 341 | transform: translate3d(calc(-1 * var(--gap-horizontal)),0,0); 342 | animation: glitch-anim-2-horizontal var(--time-anim) infinite linear alternate; 343 | } 344 | 345 | .item:hover .glitch__img:nth-child(4) { 346 | transform: translate3d(0, calc(-1 * var(--gap-vertical)), 0) scale3d(-1,-1,1); 347 | animation: glitch-anim-3-horizontal var(--time-anim) infinite linear alternate; 348 | } 349 | 350 | /* Hover flash animation on last image */ 351 | .item:hover .glitch__img:nth-child(5) { 352 | animation: glitch-anim-flash 0.5s steps(1,end) infinite; 353 | } 354 | 355 | /* Animations */ 356 | 357 | /* Horizontal */ 358 | @keyframes glitch-anim-1-horizontal { 359 | 0% { 360 | -webkit-clip-path: polygon(0 2%, 100% 2%, 100% 5%, 0 5%); 361 | clip-path: polygon(0 2%, 100% 2%, 100% 5%, 0 5%); 362 | } 363 | 10% { 364 | -webkit-clip-path: polygon(0 15%, 100% 15%, 100% 15%, 0 15%); 365 | clip-path: polygon(0 15%, 100% 15%, 100% 15%, 0 15%); 366 | } 367 | 20% { 368 | -webkit-clip-path: polygon(0 10%, 100% 10%, 100% 20%, 0 20%); 369 | clip-path: polygon(0 10%, 100% 10%, 100% 20%, 0 20%); 370 | } 371 | 30% { 372 | -webkit-clip-path: polygon(0 1%, 100% 1%, 100% 2%, 0 2%); 373 | clip-path: polygon(0 1%, 100% 1%, 100% 2%, 0 2%); 374 | } 375 | 40% { 376 | -webkit-clip-path: polygon(0 33%, 100% 33%, 100% 33%, 0 33%); 377 | clip-path: polygon(0 33%, 100% 33%, 100% 33%, 0 33%); 378 | } 379 | 50% { 380 | -webkit-clip-path: polygon(0 44%, 100% 44%, 100% 44%, 0 44%); 381 | clip-path: polygon(0 44%, 100% 44%, 100% 44%, 0 44%); 382 | } 383 | 60% { 384 | -webkit-clip-path: polygon(0 50%, 100% 50%, 100% 20%, 0 20%); 385 | clip-path: polygon(0 50%, 100% 50%, 100% 20%, 0 20%); 386 | } 387 | 70% { 388 | -webkit-clip-path: polygon(0 70%, 100% 70%, 100% 70%, 0 70%); 389 | clip-path: polygon(0 70%, 100% 70%, 100% 70%, 0 70%); 390 | } 391 | 80% { 392 | -webkit-clip-path: polygon(0 80%, 100% 80%, 100% 80%, 0 80%); 393 | clip-path: polygon(0 80%, 100% 80%, 100% 80%, 0 80%); 394 | } 395 | 90% { 396 | -webkit-clip-path: polygon(0 50%, 100% 50%, 100% 55%, 0 55%); 397 | clip-path: polygon(0 50%, 100% 50%, 100% 55%, 0 55%); 398 | } 399 | 100% { 400 | -webkit-clip-path: polygon(0 70%, 100% 70%, 100% 80%, 0 80%); 401 | clip-path: polygon(0 70%, 100% 70%, 100% 80%, 0 80%); 402 | } 403 | } 404 | 405 | @keyframes glitch-anim-2-horizontal { 406 | 0% { 407 | -webkit-clip-path: polygon(0 25%, 100% 25%, 100% 30%, 0 30%); 408 | clip-path: polygon(0 25%, 100% 25%, 100% 30%, 0 30%); 409 | } 410 | 15% { 411 | -webkit-clip-path: polygon(0 3%, 100% 3%, 100% 3%, 0 3%); 412 | clip-path: polygon(0 3%, 100% 3%, 100% 3%, 0 3%); 413 | } 414 | 22% { 415 | -webkit-clip-path: polygon(0 5%, 100% 5%, 100% 20%, 0 20%); 416 | clip-path: polygon(0 5%, 100% 5%, 100% 20%, 0 20%); 417 | } 418 | 31% { 419 | -webkit-clip-path: polygon(0 20%, 100% 20%, 100% 20%, 0 20%); 420 | clip-path: polygon(0 20%, 100% 20%, 100% 20%, 0 20%); 421 | } 422 | 45% { 423 | -webkit-clip-path: polygon(0 40%, 100% 40%, 100% 40%, 0 40%); 424 | clip-path: polygon(0 40%, 100% 40%, 100% 40%, 0 40%); 425 | } 426 | 51% { 427 | -webkit-clip-path: polygon(0 52%, 100% 52%, 100% 59%, 0 59%); 428 | clip-path: polygon(0 52%, 100% 52%, 100% 59%, 0 59%); 429 | } 430 | 63% { 431 | -webkit-clip-path: polygon(0 60%, 100% 60%, 100% 60%, 0 60%); 432 | clip-path: polygon(0 60%, 100% 60%, 100% 60%, 0 60%); 433 | } 434 | 76% { 435 | -webkit-clip-path: polygon(0 75%, 100% 75%, 100% 75%, 0 75%); 436 | clip-path: polygon(0 75%, 100% 75%, 100% 75%, 0 75%); 437 | } 438 | 81% { 439 | -webkit-clip-path: polygon(0 65%, 100% 65%, 100% 40%, 0 40%); 440 | clip-path: polygon(0 65%, 100% 65%, 100% 40%, 0 40%); 441 | } 442 | 94% { 443 | -webkit-clip-path: polygon(0 45%, 100% 45%, 100% 50%, 0 50%); 444 | clip-path: polygon(0 45%, 100% 45%, 100% 50%, 0 50%); 445 | } 446 | 100% { 447 | -webkit-clip-path: polygon(0 14%, 100% 14%, 100% 33%, 0 33%); 448 | clip-path: polygon(0 14%, 100% 14%, 100% 33%, 0 33%); 449 | } 450 | } 451 | 452 | @keyframes glitch-anim-3-horizontal { 453 | 0% { 454 | -webkit-clip-path: polygon(0 1%, 100% 1%, 100% 3%, 0 3%); 455 | clip-path: polygon(0 1%, 100% 1%, 100% 3%, 0 3%); 456 | } 457 | 5% { 458 | -webkit-clip-path: polygon(0 10%, 100% 10%, 100% 9%, 0 9%); 459 | clip-path: polygon(0 10%, 100% 10%, 100% 9%, 0 9%); 460 | } 461 | 10% { 462 | -webkit-clip-path: polygon(0 5%, 100% 5%, 100% 6%, 0 6%); 463 | clip-path: polygon(0 5%, 100% 5%, 100% 6%, 0 6%); 464 | } 465 | 25% { 466 | -webkit-clip-path: polygon(0 20%, 100% 20%, 100% 20%, 0 20%); 467 | clip-path: polygon(0 20%, 100% 20%, 100% 20%, 0 20%); 468 | } 469 | 27% { 470 | -webkit-clip-path: polygon(0 10%, 100% 10%, 100% 10%, 0 10%); 471 | clip-path: polygon(0 10%, 100% 10%, 100% 10%, 0 10%); 472 | } 473 | 30% { 474 | -webkit-clip-path: polygon(0 30%, 100% 30%, 100% 25%, 0 25%); 475 | clip-path: polygon(0 30%, 100% 30%, 100% 25%, 0 25%); 476 | } 477 | 33% { 478 | -webkit-clip-path: polygon(0 15%, 100% 15%, 100% 16%, 0 16%); 479 | clip-path: polygon(0 15%, 100% 15%, 100% 16%, 0 16%); 480 | } 481 | 37% { 482 | -webkit-clip-path: polygon(0 40%, 100% 40%, 100% 39%, 0 39%); 483 | clip-path: polygon(0 40%, 100% 40%, 100% 39%, 0 39%); 484 | } 485 | 40% { 486 | -webkit-clip-path: polygon(0 20%, 100% 20%, 100% 21%, 0 21%); 487 | clip-path: polygon(0 20%, 100% 20%, 100% 21%, 0 21%); 488 | } 489 | 45% { 490 | -webkit-clip-path: polygon(0 60%, 100% 60%, 100% 55%, 0 55%); 491 | clip-path: polygon(0 60%, 100% 60%, 100% 55%, 0 55%); 492 | } 493 | 50% { 494 | -webkit-clip-path: polygon(0 30%, 100% 30%, 100% 31%, 0 31%); 495 | clip-path: polygon(0 30%, 100% 30%, 100% 31%, 0 31%); 496 | } 497 | 53% { 498 | -webkit-clip-path: polygon(0 70%, 100% 70%, 100% 69%, 0 69%); 499 | clip-path: polygon(0 70%, 100% 70%, 100% 69%, 0 69%); 500 | } 501 | 57% { 502 | -webkit-clip-path: polygon(0 40%, 100% 40%, 100% 41%, 0 41%); 503 | clip-path: polygon(0 40%, 100% 40%, 100% 41%, 0 41%); 504 | } 505 | 60% { 506 | -webkit-clip-path: polygon(0 80%, 100% 80%, 100% 75%, 0 75%); 507 | clip-path: polygon(0 80%, 100% 80%, 100% 75%, 0 75%); 508 | } 509 | 65% { 510 | -webkit-clip-path: polygon(0 50%, 100% 50%, 100% 51%, 0 51%); 511 | clip-path: polygon(0 50%, 100% 50%, 100% 51%, 0 51%); 512 | } 513 | 70% { 514 | -webkit-clip-path: polygon(0 90%, 100% 90%, 100% 90%, 0 90%); 515 | clip-path: polygon(0 90%, 100% 90%, 100% 90%, 0 90%); 516 | } 517 | 73% { 518 | -webkit-clip-path: polygon(0 60%, 100% 60%, 100% 60%, 0 60%); 519 | clip-path: polygon(0 60%, 100% 60%, 100% 60%, 0 60%); 520 | } 521 | 80% { 522 | -webkit-clip-path: polygon(0 100%, 100% 100%, 100% 99%, 0 99%); 523 | clip-path: polygon(0 100%, 100% 100%, 100% 99%, 0 99%); 524 | } 525 | 100% { 526 | -webkit-clip-path: polygon(0 70%, 100% 70%, 100% 71%, 0 71%); 527 | clip-path: polygon(0 70%, 100% 70%, 100% 71%, 0 71%); 528 | } 529 | } 530 | 531 | /* Vertical */ 532 | @keyframes glitch-anim-1-vertical { 533 | 0% { 534 | -webkit-clip-path: polygon(2% 0, 5% 0, 5% 100%, 2% 100%); 535 | clip-path: polygon(2% 0, 5% 0, 5% 100%, 2% 100%); 536 | } 537 | 10% { 538 | -webkit-clip-path: polygon(15% 0, 15% 0, 15% 100%, 15% 100%); 539 | clip-path: polygon(15% 0, 15% 0, 15% 100%, 15% 100%); 540 | } 541 | 20% { 542 | -webkit-clip-path: polygon(10% 0, 20% 0, 20% 100%, 10% 100%); 543 | clip-path: polygon(10% 0, 20% 0, 20% 100%, 10% 100%); 544 | } 545 | 30% { 546 | -webkit-clip-path: polygon(1% 0, 2% 0, 2% 100%, 1% 100%); 547 | clip-path: polygon(1% 0, 2% 0, 2% 100%, 1% 100%); 548 | } 549 | 40% { 550 | -webkit-clip-path: polygon(33% 0, 33% 0, 33% 100%, 33% 100%); 551 | clip-path: polygon(33% 0, 33% 0, 33% 100%, 33% 100%); 552 | } 553 | 50% { 554 | -webkit-clip-path: polygon(44% 0, 44% 0, 44% 100%, 44% 100%); 555 | clip-path: polygon(44% 0, 44% 0, 44% 100%, 44% 100%); 556 | } 557 | 60% { 558 | -webkit-clip-path: polygon(50% 0, 20% 0, 20% 100%, 50% 100%); 559 | clip-path: polygon(50% 0, 20% 0, 20% 100%, 50% 100%); 560 | } 561 | 70% { 562 | -webkit-clip-path: polygon(70% 0, 70% 0, 70% 100% 70%, 70% 100%); 563 | clip-path: polygon(70% 0, 70% 0, 70% 100% 70%, 70% 100%); 564 | } 565 | 80% { 566 | -webkit-clip-path: polygon(80% 0, 80% 0, 80% 100% 80%, 80% 100%); 567 | clip-path: polygon(80% 0, 80% 0, 80% 100% 80%, 80% 100%); 568 | } 569 | 90% { 570 | -webkit-clip-path: polygon(50% 0, 55% 0, 55% 100%, 50% 100%); 571 | clip-path: polygon(50% 0, 55% 0, 55% 100%, 50% 100%); 572 | } 573 | 100% { 574 | -webkit-clip-path: polygon(70% 0, 80% 0, 80% 100%, 70% 100%); 575 | clip-path: polygon(70% 0, 80% 0, 80% 100%, 70% 100%); 576 | } 577 | } 578 | 579 | @keyframes glitch-anim-2-vertical { 580 | 0% { 581 | -webkit-clip-path: polygon(25% 0, 30% 0, 30% 100%, 25% 100%); 582 | clip-path: polygon(25% 0, 30% 0, 30% 100%, 25% 100%); 583 | } 584 | 15% { 585 | -webkit-clip-path: polygon(3% 0, 3% 0, 3% 100%, 3% 100%); 586 | clip-path: polygon(3% 0, 3% 0, 3% 100%, 3% 100%); 587 | } 588 | 22% { 589 | -webkit-clip-path: polygon(5% 0, 20% 0, 20% 100%, 5% 100%); 590 | clip-path: polygon(5% 0, 20% 0, 20% 100%, 5% 100%); 591 | } 592 | 31% { 593 | -webkit-clip-path: polygon(20% 0, 20% 0, 20% 100%, 20% 100%); 594 | clip-path: polygon(20% 0, 20% 0, 20% 100%, 20% 100%); 595 | } 596 | 45% { 597 | -webkit-clip-path: polygon(40% 0, 40% 0, 40% 100%, 40% 100%); 598 | clip-path: polygon(40% 0, 40% 0, 40% 100%, 40% 100%); 599 | } 600 | 51% { 601 | -webkit-clip-path: polygon(52% 0, 59% 0, 59% 100%, 52% 100%); 602 | clip-path: polygon(52% 0, 59% 0, 59% 100%, 52% 100%); 603 | } 604 | 63% { 605 | -webkit-clip-path: polygon(60% 0, 60% 0, 60% 100%, 60% 100%); 606 | clip-path: polygon(60% 0, 60% 0, 60% 100%, 60% 100%); 607 | } 608 | 76% { 609 | -webkit-clip-path: polygon(75% 0, 75% 0, 75% 100%, 75% 100%); 610 | clip-path: polygon(75% 0, 75% 0, 75% 100%, 75% 100%); 611 | } 612 | 81% { 613 | -webkit-clip-path: polygon(65% 0, 40% 0, 40% 100%, 65% 100%); 614 | clip-path: polygon(65% 0, 40% 0, 40% 100%, 65% 100%); 615 | } 616 | 94% { 617 | -webkit-clip-path: polygon(45% 0, 50% 0, 50% 100%, 45% 100%); 618 | clip-path: polygon(45% 0, 50% 0, 50% 100%, 45% 100%); 619 | } 620 | 100% { 621 | -webkit-clip-path: polygon(14% 0, 33% 0, 33% 100%, 14% 100%); 622 | clip-path: polygon(14% 0, 33% 0, 33% 100%, 14% 100%); 623 | } 624 | } 625 | 626 | @keyframes glitch-anim-3-vertical { 627 | 0% { 628 | -webkit-clip-path: polygon(1% 0, 3% 0, 3% 100%, 1% 100%); 629 | clip-path: polygon(1% 0, 3% 0, 3% 100%, 1% 100%); 630 | } 631 | 5% { 632 | -webkit-clip-path: polygon(10% 0, 9% 0, 9% 100%, 10% 100%); 633 | clip-path: polygon(10% 0, 9% 0, 9% 100%, 10% 100%); 634 | } 635 | 10% { 636 | -webkit-clip-path: polygon(5% 0, 6% 0 6% 100%, 5% 100%); 637 | clip-path: polygon(5% 0, 6% 0 6% 100%, 5% 100%); 638 | } 639 | 25% { 640 | -webkit-clip-path: polygon(20% 0, 20% 0, 20% 100%, 20% 100%); 641 | clip-path: polygon(20% 0, 20% 0, 20% 100%, 20% 100%); 642 | } 643 | 27% { 644 | -webkit-clip-path: polygon(10% 0, 10% 0, 10% 100%, 10% 100%); 645 | clip-path: polygon(10% 0, 10% 0, 10% 100%, 10% 100%); 646 | } 647 | 30% { 648 | -webkit-clip-path: polygon(30% 0, 25% 0, 25% 100%, 30% 100%); 649 | clip-path: polygon(30% 0, 25% 0, 25% 100%, 30% 100%); 650 | } 651 | 33% { 652 | -webkit-clip-path: polygon(15% 0, 16% 0, 16% 100%, 15% 100%);; 653 | clip-path: polygon(15% 0, 16% 0, 16% 100%, 15% 100%); 654 | } 655 | 37% { 656 | -webkit-clip-path: polygon(40% 0, 39% 0, 39% 100%, 40% 100%);; 657 | clip-path: polygon(40% 0, 39% 0, 39% 100%, 40% 100%); 658 | } 659 | 40% { 660 | -webkit-clip-path: polygon(20% 0, 21% 0, 21% 100%, 20% 100%); 661 | clip-path: polygon(20% 0, 21% 0, 21% 100%, 20% 100%); 662 | } 663 | 45% { 664 | -webkit-clip-path: polygon(60% 0, 55% 0, 55% 100%, 60% 100%); 665 | clip-path: polygon(60% 0, 55% 0, 55% 100%, 60% 100%); 666 | } 667 | 50% { 668 | -webkit-clip-path: polygon(30% 0, 31% 0, 31% 100%, 30% 100%); 669 | clip-path: polygon(30% 0, 31% 0, 31% 100%, 30% 100%); 670 | } 671 | 53% { 672 | -webkit-clip-path: polygon(70% 0, 69% 0, 69% 100%, 70% 100%); 673 | clip-path: polygon(70% 0, 69% 0, 69% 100%, 70% 100%); 674 | } 675 | 57% { 676 | -webkit-clip-path: polygon(40% 0, 41% 0, 41% 100%, 40% 100%); 677 | clip-path: polygon(40% 0, 41% 0, 41% 100%, 40% 100%); 678 | } 679 | 60% { 680 | -webkit-clip-path: polygon(80% 0, 75% 0, 75% 100%, 80% 100%); 681 | clip-path: polygon(80% 0, 75% 0, 75% 100%, 80% 100%); 682 | } 683 | 65% { 684 | -webkit-clip-path: polygon(50% 0, 51% 0, 51% 100%, 50% 100%); 685 | clip-path: polygon(50% 0, 51% 0, 51% 100%, 50% 100%); 686 | } 687 | 70% { 688 | -webkit-clip-path: polygon(90% 0, 90% 0, 90% 100%, 90% 100%); 689 | clip-path: polygon(90% 0, 90% 0, 90% 100%, 90% 100%); 690 | } 691 | 73% { 692 | -webkit-clip-path: polygon(60% 0, 60% 0, 60% 100%, 60% 100%); 693 | clip-path: polygon(60% 0, 60% 0, 60% 100%, 60% 100%); 694 | } 695 | 80% { 696 | -webkit-clip-path: polygon(100% 0, 99% 0, 99% 100%, 100% 100%); 697 | clip-path: polygon(100% 0, 99% 0, 99% 100%, 100% 100%); 698 | } 699 | 100% { 700 | -webkit-clip-path: polygon(70% 0, 71% 0, 71% 100%, 70% 100%); 701 | clip-path: polygon(70% 0, 71% 0, 71% 100%, 70% 100%); 702 | } 703 | } 704 | 705 | /* Flash */ 706 | @keyframes glitch-anim-flash { 707 | 0% { 708 | opacity: 0.2; 709 | transform: translate3d(var(--gap-horizontal), var(--gap-vertical), 0); 710 | } 711 | 33%, 100% { 712 | opacity: 0; 713 | transform: translate3d(0,0,0); 714 | } 715 | } 716 | 717 | .item__cover { 718 | grid-area: 1 / 1 / -1 / -1; 719 | background-size: cover; 720 | background-position: 50% 50%; 721 | position: relative; 722 | transition: opacity var(--fade-in-time) var(--fade-in-easing); 723 | pointer-events: none; 724 | } 725 | 726 | .item__cover::after { 727 | content: ''; 728 | position: absolute; 729 | width: 100%; 730 | height: 100%; 731 | background: linear-gradient(0deg,rgb(54 58 199 / 38%), rgba(0,0,0,0.2)); 732 | } 733 | 734 | .item:hover .item__cover { 735 | opacity: 0; 736 | transition: opacity var(--fade-out-time) var(--fade-out-easing); 737 | } 738 | 739 | .item__content { 740 | display: flex; 741 | flex-direction: column; 742 | pointer-events: none; 743 | padding: 1.5rem; 744 | position: relative; 745 | grid-area: 1 / 1 / -1 / -1; 746 | color: var(--color-label); 747 | } 748 | 749 | .item__content-title { 750 | font-family: park-lane, serif; 751 | font-weight: 300; 752 | font-style: normal; 753 | font-size: clamp(3rem,4vw,5rem); 754 | line-height: 1; 755 | margin: 0; 756 | } 757 | 758 | .item:hover .item__content-title, 759 | .item:hover .item__content-label { 760 | color: var(--content-hover); 761 | } 762 | 763 | .item__content-label { 764 | margin: auto 0 0; 765 | } 766 | 767 | blockquote { 768 | font-weight: 500; 769 | font-size: clamp(1rem, 2vw, 1.25rem); 770 | } 771 | 772 | @media screen and (min-width: 53em) { 773 | .frame { 774 | text-align: center; 775 | display: grid; 776 | grid-template-columns: auto auto; 777 | grid-template-rows: auto auto; 778 | grid-template-areas: 'title sponsor' 'demos demos'; 779 | grid-row-gap: 1rem; 780 | align-content: space-between; 781 | } 782 | .frame__title { 783 | grid-area: title; 784 | display: grid; 785 | grid-auto-flow: column; 786 | grid-template-columns: auto auto 1fr; 787 | align-items: start; 788 | justify-items: flex-start; 789 | } 790 | .frame__demos { 791 | grid-area: demos; 792 | justify-self: end; 793 | } 794 | .frame__demo { 795 | margin: 0 0 0 1rem; 796 | } 797 | .intro { 798 | display: grid; 799 | grid-column-gap: 1rem; 800 | grid-template-areas: 'title desc' 801 | 'title button'; 802 | justify-content: space-between; 803 | align-items: start; 804 | text-align: right; 805 | } 806 | } 807 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/favicon.ico -------------------------------------------------------------------------------- /img/1.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/1.avif -------------------------------------------------------------------------------- /img/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/1.png -------------------------------------------------------------------------------- /img/10.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/10.avif -------------------------------------------------------------------------------- /img/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/10.png -------------------------------------------------------------------------------- /img/11.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/11.avif -------------------------------------------------------------------------------- /img/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/11.png -------------------------------------------------------------------------------- /img/12.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/12.avif -------------------------------------------------------------------------------- /img/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/12.png -------------------------------------------------------------------------------- /img/13.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/13.avif -------------------------------------------------------------------------------- /img/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/13.png -------------------------------------------------------------------------------- /img/14.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/14.avif -------------------------------------------------------------------------------- /img/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/14.png -------------------------------------------------------------------------------- /img/15.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/15.avif -------------------------------------------------------------------------------- /img/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/15.png -------------------------------------------------------------------------------- /img/2.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/2.avif -------------------------------------------------------------------------------- /img/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/2.png -------------------------------------------------------------------------------- /img/3.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/3.avif -------------------------------------------------------------------------------- /img/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/3.png -------------------------------------------------------------------------------- /img/4.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/4.avif -------------------------------------------------------------------------------- /img/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/4.png -------------------------------------------------------------------------------- /img/5.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/5.avif -------------------------------------------------------------------------------- /img/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/5.png -------------------------------------------------------------------------------- /img/6.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/6.avif -------------------------------------------------------------------------------- /img/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/6.png -------------------------------------------------------------------------------- /img/7.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/7.avif -------------------------------------------------------------------------------- /img/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/7.png -------------------------------------------------------------------------------- /img/8.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/8.avif -------------------------------------------------------------------------------- /img/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/8.png -------------------------------------------------------------------------------- /img/9.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/9.avif -------------------------------------------------------------------------------- /img/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/GlitchPerspective/80f9295118011ad55691398d2cec220ecf8c8f74/img/9.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 3D Perspective Glitch Hover Effect | Demo 1 | Codrops 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |
19 |
20 | Previous demo 21 |

3D Perspective Glitch Hover Effect

22 | 23 | Back to the article 24 | 25 | 26 | 27 |
28 | 32 |
33 |
34 |

35 | Techno 36 | workshop 37 |

38 |

39 | Techno Workshop is a collective of the weirdest creative minds. We share art and inspiration and create design contests to showcase futile but cute additions to the consumer world. 40 |

41 | 42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |

Wallace
MacKenzie

55 | 56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |

Gunnar
Redsocks

69 | 70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |

Frankie
Tankie

83 | 84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |

Helder
Brunckhorst

97 | 98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |

Bolder
Da Mouth

111 | 112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |

Marie
Sockamoodle

125 | 126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |

Walter
Meckage

139 | 140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |

Kelly
Braylor

153 | 154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |

Fundo
Constanza

167 | 168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |

Bernie
Kunst

181 | 182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |

Sandra
M. Lester

195 | 196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |

Mister
DonGold

209 | 210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |

Laura
Murdoch

223 | 224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |

John
Van Hoff

237 | 238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |

Armin
Harbinger

251 | 252 |
253 |
254 |
255 |
256 |

The disruption of everyday reality, effects on instinct
257 | rational, irrational, expression, depression, to be persuaded.
258 | Assessments, values, from glancing in a mirror and the wider
259 | significance of commentaries, refrains, classifieds, link to chaos!
260 | The exploitation and denial of confirmation
261 | Pre-conceptions, non-threatening; bright lights. 262 |

263 |

Enamour encore by Sunny Jetsun

264 |
265 |
266 | 267 | 268 | 269 | -------------------------------------------------------------------------------- /index2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 3D Perspective Glitch Hover Effect | Demo 2 | Codrops 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |
19 |
20 | Previous demo 21 |

3D Perspective Glitch Hover Effect

22 | 23 | Back to the article 24 | 25 | 26 | 27 |
28 | 32 |
33 |
34 |

35 | Techno 36 | workshop 37 |

38 |

39 | Techno Workshop is a collective of the weirdest creative minds. We share art and inspiration and create design contests to showcase futile but cute additions to the consumer world. 40 |

41 | 42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |

Wallace
MacKenzie

55 | 56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |

Gunnar
Redsocks

69 | 70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |

Frankie
Tankie

83 | 84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |

Helder
Brunckhorst

97 | 98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |

Bolder
Da Mouth

111 | 112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |

Marie
Sockamoodle

125 | 126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |

Walter
Meckage

139 | 140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |

Kelly
Braylor

153 | 154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |

Fundo
Constanza

167 | 168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |

Bernie
Kunst

181 | 182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |

Sandra
M. Lester

195 | 196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |

Mister
DonGold

209 | 210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |

Laura
Murdoch

223 | 224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |

John
Van Hoff

237 | 238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |

Armin
Harbinger

251 | 252 |
253 |
254 |
255 |
256 |

The disruption of everyday reality, effects on instinct
257 | rational, irrational, expression, depression, to be persuaded.
258 | Assessments, values, from glancing in a mirror and the wider
259 | significance of commentaries, refrains, classifieds, link to chaos!
260 | The exploitation and denial of confirmation
261 | Pre-conceptions, non-threatening; bright lights. 262 |

263 |

Enamour encore by Sunny Jetsun

264 |
265 |
266 | 267 | 268 | 269 | 270 | -------------------------------------------------------------------------------- /js/vanilla-tilt.js: -------------------------------------------------------------------------------- 1 | var VanillaTilt = (function () { 2 | 'use strict'; 3 | 4 | /** 5 | * Created by Sergiu Șandor (micku7zu) on 1/27/2017. 6 | * Original idea: https://github.com/gijsroge/tilt.js 7 | * MIT License. 8 | * Version 1.7.2 9 | */ 10 | 11 | class VanillaTilt { 12 | constructor(element, settings = {}) { 13 | if (!(element instanceof Node)) { 14 | throw ("Can't initialize VanillaTilt because " + element + " is not a Node."); 15 | } 16 | 17 | this.width = null; 18 | this.height = null; 19 | this.clientWidth = null; 20 | this.clientHeight = null; 21 | this.left = null; 22 | this.top = null; 23 | 24 | // for Gyroscope sampling 25 | this.gammazero = null; 26 | this.betazero = null; 27 | this.lastgammazero = null; 28 | this.lastbetazero = null; 29 | 30 | this.transitionTimeout = null; 31 | this.updateCall = null; 32 | this.event = null; 33 | 34 | this.updateBind = this.update.bind(this); 35 | this.resetBind = this.reset.bind(this); 36 | 37 | this.element = element; 38 | this.settings = this.extendSettings(settings); 39 | 40 | this.reverse = this.settings.reverse ? -1 : 1; 41 | this.glare = VanillaTilt.isSettingTrue(this.settings.glare); 42 | this.glarePrerender = VanillaTilt.isSettingTrue(this.settings["glare-prerender"]); 43 | this.fullPageListening = VanillaTilt.isSettingTrue(this.settings["full-page-listening"]); 44 | this.gyroscope = VanillaTilt.isSettingTrue(this.settings.gyroscope); 45 | this.gyroscopeSamples = this.settings.gyroscopeSamples; 46 | 47 | this.elementListener = this.getElementListener(); 48 | 49 | if (this.glare) { 50 | this.prepareGlare(); 51 | } 52 | 53 | if (this.fullPageListening) { 54 | this.updateClientSize(); 55 | } 56 | 57 | this.addEventListeners(); 58 | this.reset(); 59 | this.updateInitialPosition(); 60 | } 61 | 62 | static isSettingTrue(setting) { 63 | return setting === "" || setting === true || setting === 1; 64 | } 65 | 66 | /** 67 | * Method returns element what will be listen mouse events 68 | * @return {Node} 69 | */ 70 | getElementListener() { 71 | if (this.fullPageListening) { 72 | return window.document; 73 | } 74 | 75 | if (typeof this.settings["mouse-event-element"] === "string") { 76 | const mouseEventElement = document.querySelector(this.settings["mouse-event-element"]); 77 | 78 | if (mouseEventElement) { 79 | return mouseEventElement; 80 | } 81 | } 82 | 83 | if (this.settings["mouse-event-element"] instanceof Node) { 84 | return this.settings["mouse-event-element"]; 85 | } 86 | 87 | return this.element; 88 | } 89 | 90 | /** 91 | * Method set listen methods for this.elementListener 92 | * @return {Node} 93 | */ 94 | addEventListeners() { 95 | this.onMouseEnterBind = this.onMouseEnter.bind(this); 96 | this.onMouseMoveBind = this.onMouseMove.bind(this); 97 | this.onMouseLeaveBind = this.onMouseLeave.bind(this); 98 | this.onWindowResizeBind = this.onWindowResize.bind(this); 99 | this.onDeviceOrientationBind = this.onDeviceOrientation.bind(this); 100 | 101 | this.elementListener.addEventListener("mouseenter", this.onMouseEnterBind); 102 | this.elementListener.addEventListener("mouseleave", this.onMouseLeaveBind); 103 | this.elementListener.addEventListener("mousemove", this.onMouseMoveBind); 104 | 105 | if (this.glare || this.fullPageListening) { 106 | window.addEventListener("resize", this.onWindowResizeBind); 107 | } 108 | 109 | if (this.gyroscope) { 110 | window.addEventListener("deviceorientation", this.onDeviceOrientationBind); 111 | } 112 | } 113 | 114 | /** 115 | * Method remove event listeners from current this.elementListener 116 | */ 117 | removeEventListeners() { 118 | this.elementListener.removeEventListener("mouseenter", this.onMouseEnterBind); 119 | this.elementListener.removeEventListener("mouseleave", this.onMouseLeaveBind); 120 | this.elementListener.removeEventListener("mousemove", this.onMouseMoveBind); 121 | 122 | if (this.gyroscope) { 123 | window.removeEventListener("deviceorientation", this.onDeviceOrientationBind); 124 | } 125 | 126 | if (this.glare || this.fullPageListening) { 127 | window.removeEventListener("resize", this.onWindowResizeBind); 128 | } 129 | } 130 | 131 | destroy() { 132 | clearTimeout(this.transitionTimeout); 133 | if (this.updateCall !== null) { 134 | cancelAnimationFrame(this.updateCall); 135 | } 136 | 137 | this.reset(); 138 | 139 | this.removeEventListeners(); 140 | this.element.vanillaTilt = null; 141 | delete this.element.vanillaTilt; 142 | 143 | this.element = null; 144 | } 145 | 146 | onDeviceOrientation(event) { 147 | if (event.gamma === null || event.beta === null) { 148 | return; 149 | } 150 | 151 | this.updateElementPosition(); 152 | 153 | if (this.gyroscopeSamples > 0) { 154 | this.lastgammazero = this.gammazero; 155 | this.lastbetazero = this.betazero; 156 | 157 | if (this.gammazero === null) { 158 | this.gammazero = event.gamma; 159 | this.betazero = event.beta; 160 | } else { 161 | this.gammazero = (event.gamma + this.lastgammazero) / 2; 162 | this.betazero = (event.beta + this.lastbetazero) / 2; 163 | } 164 | 165 | this.gyroscopeSamples -= 1; 166 | } 167 | 168 | const totalAngleX = this.settings.gyroscopeMaxAngleX - this.settings.gyroscopeMinAngleX; 169 | const totalAngleY = this.settings.gyroscopeMaxAngleY - this.settings.gyroscopeMinAngleY; 170 | 171 | const degreesPerPixelX = totalAngleX / this.width; 172 | const degreesPerPixelY = totalAngleY / this.height; 173 | 174 | const angleX = event.gamma - (this.settings.gyroscopeMinAngleX + this.gammazero); 175 | const angleY = event.beta - (this.settings.gyroscopeMinAngleY + this.betazero); 176 | 177 | const posX = angleX / degreesPerPixelX; 178 | const posY = angleY / degreesPerPixelY; 179 | 180 | if (this.updateCall !== null) { 181 | cancelAnimationFrame(this.updateCall); 182 | } 183 | 184 | this.event = { 185 | clientX: posX + this.left, 186 | clientY: posY + this.top, 187 | }; 188 | 189 | this.updateCall = requestAnimationFrame(this.updateBind); 190 | } 191 | 192 | onMouseEnter() { 193 | this.updateElementPosition(); 194 | this.element.style.willChange = "transform"; 195 | this.setTransition(); 196 | } 197 | 198 | onMouseMove(event) { 199 | if (this.updateCall !== null) { 200 | cancelAnimationFrame(this.updateCall); 201 | } 202 | 203 | this.event = event; 204 | this.updateCall = requestAnimationFrame(this.updateBind); 205 | } 206 | 207 | onMouseLeave() { 208 | this.setTransition(); 209 | 210 | if (this.settings.reset) { 211 | requestAnimationFrame(this.resetBind); 212 | } 213 | } 214 | 215 | reset() { 216 | this.event = { 217 | clientX: this.left + this.width / 2, 218 | clientY: this.top + this.height / 2 219 | }; 220 | 221 | if (this.element && this.element.style) { 222 | this.element.style.transform = `perspective(${this.settings.perspective}px) ` + 223 | `rotateX(0deg) ` + 224 | `rotateY(0deg) ` + 225 | `scale3d(1, 1, 1)`; 226 | } 227 | 228 | this.resetGlare(); 229 | } 230 | 231 | resetGlare() { 232 | if (this.glare) { 233 | this.glareElement.style.transform = "rotate(180deg) translate(-50%, -50%)"; 234 | this.glareElement.style.opacity = "0"; 235 | } 236 | } 237 | 238 | updateInitialPosition() { 239 | if (this.settings.startX === 0 && this.settings.startY === 0) { 240 | return; 241 | } 242 | 243 | this.onMouseEnter(); 244 | 245 | if (this.fullPageListening) { 246 | this.event = { 247 | clientX: (this.settings.startX + this.settings.max) / (2 * this.settings.max) * this.clientWidth, 248 | clientY: (this.settings.startY + this.settings.max) / (2 * this.settings.max) * this.clientHeight 249 | }; 250 | } else { 251 | this.event = { 252 | clientX: this.left + ((this.settings.startX + this.settings.max) / (2 * this.settings.max) * this.width), 253 | clientY: this.top + ((this.settings.startY + this.settings.max) / (2 * this.settings.max) * this.height) 254 | }; 255 | } 256 | 257 | 258 | let backupScale = this.settings.scale; 259 | this.settings.scale = 1; 260 | this.update(); 261 | this.settings.scale = backupScale; 262 | this.resetGlare(); 263 | } 264 | 265 | getValues() { 266 | let x, y; 267 | 268 | if (this.fullPageListening) { 269 | x = this.event.clientX / this.clientWidth; 270 | y = this.event.clientY / this.clientHeight; 271 | } else { 272 | x = (this.event.clientX - this.left) / this.width; 273 | y = (this.event.clientY - this.top) / this.height; 274 | } 275 | 276 | x = Math.min(Math.max(x, 0), 1); 277 | y = Math.min(Math.max(y, 0), 1); 278 | 279 | let tiltX = (this.reverse * (this.settings.max - x * this.settings.max * 2)).toFixed(2); 280 | let tiltY = (this.reverse * (y * this.settings.max * 2 - this.settings.max)).toFixed(2); 281 | let angle = Math.atan2(this.event.clientX - (this.left + this.width / 2), -(this.event.clientY - (this.top + this.height / 2))) * (180 / Math.PI); 282 | 283 | return { 284 | tiltX: tiltX, 285 | tiltY: tiltY, 286 | percentageX: x * 100, 287 | percentageY: y * 100, 288 | angle: angle 289 | }; 290 | } 291 | 292 | updateElementPosition() { 293 | let rect = this.element.getBoundingClientRect(); 294 | 295 | this.width = this.element.offsetWidth; 296 | this.height = this.element.offsetHeight; 297 | this.left = rect.left; 298 | this.top = rect.top; 299 | } 300 | 301 | update() { 302 | let values = this.getValues(); 303 | 304 | this.element.style.transform = "perspective(" + this.settings.perspective + "px) " + 305 | "rotateX(" + (this.settings.axis === "x" ? 0 : values.tiltY) + "deg) " + 306 | "rotateY(" + (this.settings.axis === "y" ? 0 : values.tiltX) + "deg) " + 307 | "scale3d(" + this.settings.scale + ", " + this.settings.scale + ", " + this.settings.scale + ")"; 308 | 309 | if (this.glare) { 310 | this.glareElement.style.transform = `rotate(${values.angle}deg) translate(-50%, -50%)`; 311 | this.glareElement.style.opacity = `${values.percentageY * this.settings["max-glare"] / 100}`; 312 | } 313 | 314 | this.element.dispatchEvent(new CustomEvent("tiltChange", { 315 | "detail": values 316 | })); 317 | 318 | this.updateCall = null; 319 | } 320 | 321 | /** 322 | * Appends the glare element (if glarePrerender equals false) 323 | * and sets the default style 324 | */ 325 | prepareGlare() { 326 | // If option pre-render is enabled we assume all html/css is present for an optimal glare effect. 327 | if (!this.glarePrerender) { 328 | // Create glare element 329 | const jsTiltGlare = document.createElement("div"); 330 | jsTiltGlare.classList.add("js-tilt-glare"); 331 | 332 | const jsTiltGlareInner = document.createElement("div"); 333 | jsTiltGlareInner.classList.add("js-tilt-glare-inner"); 334 | 335 | jsTiltGlare.appendChild(jsTiltGlareInner); 336 | this.element.appendChild(jsTiltGlare); 337 | } 338 | 339 | this.glareElementWrapper = this.element.querySelector(".js-tilt-glare"); 340 | this.glareElement = this.element.querySelector(".js-tilt-glare-inner"); 341 | 342 | if (this.glarePrerender) { 343 | return; 344 | } 345 | 346 | Object.assign(this.glareElementWrapper.style, { 347 | "position": "absolute", 348 | "top": "0", 349 | "left": "0", 350 | "width": "100%", 351 | "height": "100%", 352 | "overflow": "hidden", 353 | "pointer-events": "none" 354 | }); 355 | 356 | Object.assign(this.glareElement.style, { 357 | "position": "absolute", 358 | "top": "50%", 359 | "left": "50%", 360 | "pointer-events": "none", 361 | "background-image": `linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%)`, 362 | "transform": "rotate(180deg) translate(-50%, -50%)", 363 | "transform-origin": "0% 0%", 364 | "opacity": "0", 365 | }); 366 | 367 | this.updateGlareSize(); 368 | } 369 | 370 | updateGlareSize() { 371 | if (this.glare) { 372 | const glareSize = (this.element.offsetWidth > this.element.offsetHeight ? this.element.offsetWidth : this.element.offsetHeight) * 2; 373 | 374 | Object.assign(this.glareElement.style, { 375 | "width": `${glareSize}px`, 376 | "height": `${glareSize}px`, 377 | }); 378 | } 379 | } 380 | 381 | updateClientSize() { 382 | this.clientWidth = window.innerWidth 383 | || document.documentElement.clientWidth 384 | || document.body.clientWidth; 385 | 386 | this.clientHeight = window.innerHeight 387 | || document.documentElement.clientHeight 388 | || document.body.clientHeight; 389 | } 390 | 391 | onWindowResize() { 392 | this.updateGlareSize(); 393 | this.updateClientSize(); 394 | } 395 | 396 | setTransition() { 397 | clearTimeout(this.transitionTimeout); 398 | this.element.style.transition = this.settings.speed + "ms " + this.settings.easing; 399 | if (this.glare) this.glareElement.style.transition = `opacity ${this.settings.speed}ms ${this.settings.easing}`; 400 | 401 | this.transitionTimeout = setTimeout(() => { 402 | this.element.style.transition = ""; 403 | if (this.glare) { 404 | this.glareElement.style.transition = ""; 405 | } 406 | }, this.settings.speed); 407 | 408 | } 409 | 410 | /** 411 | * Method return patched settings of instance 412 | * @param {boolean} settings.reverse - reverse the tilt direction 413 | * @param {number} settings.max - max tilt rotation (degrees) 414 | * @param {startX} settings.startX - the starting tilt on the X axis, in degrees. Default: 0 415 | * @param {startY} settings.startY - the starting tilt on the Y axis, in degrees. Default: 0 416 | * @param {number} settings.perspective - Transform perspective, the lower the more extreme the tilt gets 417 | * @param {string} settings.easing - Easing on enter/exit 418 | * @param {number} settings.scale - 2 = 200%, 1.5 = 150%, etc.. 419 | * @param {number} settings.speed - Speed of the enter/exit transition 420 | * @param {boolean} settings.transition - Set a transition on enter/exit 421 | * @param {string|null} settings.axis - What axis should be disabled. Can be X or Y 422 | * @param {boolean} settings.glare - What axis should be disabled. Can be X or Y 423 | * @param {number} settings.max-glare - the maximum "glare" opacity (1 = 100%, 0.5 = 50%) 424 | * @param {boolean} settings.glare-prerender - false = VanillaTilt creates the glare elements for you, otherwise 425 | * @param {boolean} settings.full-page-listening - If true, parallax effect will listen to mouse move events on the whole document, not only the selected element 426 | * @param {string|object} settings.mouse-event-element - String selector or link to HTML-element what will be listen mouse events 427 | * @param {boolean} settings.reset - false = If the tilt effect has to be reset on exit 428 | * @param {gyroscope} settings.gyroscope - Enable tilting by deviceorientation events 429 | * @param {gyroscopeSensitivity} settings.gyroscopeSensitivity - Between 0 and 1 - The angle at which max tilt position is reached. 1 = 90deg, 0.5 = 45deg, etc.. 430 | * @param {gyroscopeSamples} settings.gyroscopeSamples - How many gyroscope moves to decide the starting position. 431 | */ 432 | extendSettings(settings) { 433 | let defaultSettings = { 434 | reverse: false, 435 | max: 15, 436 | startX: 0, 437 | startY: 0, 438 | perspective: 1000, 439 | easing: "cubic-bezier(.03,.98,.52,.99)", 440 | scale: 1, 441 | speed: 300, 442 | transition: true, 443 | axis: null, 444 | glare: false, 445 | "max-glare": 1, 446 | "glare-prerender": false, 447 | "full-page-listening": false, 448 | "mouse-event-element": null, 449 | reset: true, 450 | gyroscope: true, 451 | gyroscopeMinAngleX: -45, 452 | gyroscopeMaxAngleX: 45, 453 | gyroscopeMinAngleY: -45, 454 | gyroscopeMaxAngleY: 45, 455 | gyroscopeSamples: 10 456 | }; 457 | 458 | let newSettings = {}; 459 | for (var property in defaultSettings) { 460 | if (property in settings) { 461 | newSettings[property] = settings[property]; 462 | } else if (this.element.hasAttribute("data-tilt-" + property)) { 463 | let attribute = this.element.getAttribute("data-tilt-" + property); 464 | try { 465 | newSettings[property] = JSON.parse(attribute); 466 | } catch (e) { 467 | newSettings[property] = attribute; 468 | } 469 | 470 | } else { 471 | newSettings[property] = defaultSettings[property]; 472 | } 473 | } 474 | 475 | return newSettings; 476 | } 477 | 478 | static init(elements, settings) { 479 | if (elements instanceof Node) { 480 | elements = [elements]; 481 | } 482 | 483 | if (elements instanceof NodeList) { 484 | elements = [].slice.call(elements); 485 | } 486 | 487 | if (!(elements instanceof Array)) { 488 | return; 489 | } 490 | 491 | elements.forEach((element) => { 492 | if (!("vanillaTilt" in element)) { 493 | element.vanillaTilt = new VanillaTilt(element, settings); 494 | } 495 | }); 496 | } 497 | } 498 | 499 | if (typeof document !== "undefined") { 500 | /* expose the class to window */ 501 | window.VanillaTilt = VanillaTilt; 502 | 503 | /** 504 | * Auto load 505 | */ 506 | VanillaTilt.init(document.querySelectorAll("[data-tilt]")); 507 | } 508 | 509 | return VanillaTilt; 510 | 511 | }()); --------------------------------------------------------------------------------