GreenSock Tutorial - How To Create A Simple Image Slideshow
SOURCE CODE
HTML SOURCE_CODE:-
<!DOCTYPE html><html lang="en" class="no-js"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Crossroads Slideshow | Codrops</title> <link rel="stylesheet" type="text/css" href="css/base.css" /> <script>document.documentElement.className="js";var supportsCssVars=function(){var e,t=document.createElement("style");return t.innerHTML="root: { --tmp-var: bold; }",document.head.appendChild(t),e=!!(window.CSS&&window.CSS.supports&&window.CSS.supports("font-weight","var(--tmp-var)")),t.parentNode.removeChild(t),e};supportsCssVars()||alert("Please view this demo in a modern browser that supports CSS Variables.");</script> </head> <body class="loading"> <main> <div class="content"> <article class="content__item"> <div class="img-wrap img-wrap--content"> <div class="img img--content" style="background-image: url(img/1.jpg);"></div> </div> <header class="content__item-header"> <span class="content__item-header-meta">New York City, March 24</span> <h2 class="content__item-header-title">kani</h2> </header> <div class="content__item-copy"> <p class="content__item-copy-text"> In the gloomy domed livingroom of the tower Buck Mulligan’s gowned form moved briskly to and fro about the hearth, hiding and revealing its yellow glow. Two shafts of soft daylight fell across the flagged floor from the high barbacans: and at the meeting of their rays a cloud of coalsmoke and fumes of fried grease floated, turning. </p> <a href="#" class="content__item-copy-more">more +</a> </div> </article> <article class="content__item"> <div class="img-wrap img-wrap--content"> <div class="img img--content" style="background-image: url(img/2.jpg);"></div> </div> <header class="content__item-header"> <span class="content__item-header-meta">Acapulco, March 25</span> <h2 class="content__item-header-title">Bob</h2> </header> <div class="content__item-copy"> <p class="content__item-copy-text"> The key scraped round harshly twice and, when the heavy door had been set ajar, welcome light and bright air entered. Haines stood at the doorway, looking out. Stephen haled his upended valise to the table and sat down to wait. Buck Mulligan tossed the fry on to the dish beside him. Then he carried the dish and a large teapot over to the table, set them down heavily and sighed with relief. </p> <a href="#" class="content__item-copy-more">more +</a> </div> </article> <article class="content__item"> <div class="img-wrap img-wrap--content"> <div class="img img--content" style="background-image: url(img/3.jpg);"></div> </div> <header class="content__item-header"> <span class="content__item-header-meta">Brisbane, March 26</span> <h2 class="content__item-header-title">Canon</h2> </header> <div class="content__item-copy"> <p class="content__item-copy-text"> Stephen listened in scornful silence. She bows her old head to a voice that speaks to her loudly, her bonesetter, her medicineman: me she slights. To the voice that will shrive and oil for the grave all there is of her but her woman’s unclean loins, of man’s flesh made not in God’s likeness, the serpent’s prey. </p> <a href="#" class="content__item-copy-more">more +</a> </div> </article> <article class="content__item"> <div class="img-wrap img-wrap--content"> <div class="img img--content" style="background-image: url(img/4.jpg);"></div> </div> <header class="content__item-header"> <span class="content__item-header-meta">Berlin, March 27</span> <h2 class="content__item-header-title">Hill</h2> </header> <div class="content__item-copy"> <p class="content__item-copy-text"> And putting on his stiff collar and rebellious tie he spoke to them, chiding them, and to his dangling watchchain. His hands plunged and rummaged in his trunk while he called for a clean handkerchief. God, we’ll simply have to dress the character. I want puce gloves and green boots. Contradiction. </p> <a href="#" class="content__item-copy-more">more +</a> </div> </article> </div> <div class="revealer"> <div class="revealer__inner"></div> </div> <div class="grid grid--slideshow"> <figure class="grid__item grid__item--slide"> <span class="number">01</span> <div class="img-wrap"> <div class="img" style="background-image: url(img/1.jpg);"></div> </div> <figcaption class="caption">New York City, March 24</figcaption> </figure> <figure class="grid__item grid__item--slide"> <span class="number">02</span> <div class="img-wrap"> <div class="img" style="background-image: url(img/2.jpg);"></div> </div> <figcaption class="caption">Acapulco, March 25</figcaption> </figure> <figure class="grid__item grid__item--slide"> <span class="number">03</span> <div class="img-wrap"> <div class="img" style="background-image: url(img/3.jpg);"></div> </div> <figcaption class="caption">Brisbane, March 26</figcaption> </figure> <figure class="grid__item grid__item--slide"> <span class="number">04</span> <div class="img-wrap"> <div class="img" style="background-image: url(img/4.jpg);"></div> </div> <figcaption class="caption">Berlin, March 27</figcaption> </figure> <div class="titles-wrap"> <div class="grid grid--titles"> <h3 class="grid__item grid__item--title">Kani</h3> <h3 class="grid__item grid__item--title">Bob</h3> <h3 class="grid__item grid__item--title">Canon</h3> <h3 class="grid__item grid__item--title">Hill</h3> </div> </div> <div class="grid grid--interaction"> <div class="grid__item grid__item--cursor grid__item--left"></div> <div class="grid__item grid__item--cursor grid__item--center"></div> <div class="grid__item grid__item--cursor grid__item--right"></div> </div> </div> <div class="frame"> <div class="frame__mode" role="radiogroup"> <div class="frame__mode-item frame__mode-item--dark"> <input id="mode-1" type="radio" name="mode" class="frame__mode-input"></input> <label class="frame__mode-label" for="mode-1">Dark mode</label> </div> <div class="frame__mode-item"> <input id="mode-2" type="radio" name="mode" class="frame__mode-input" checked></input> <label class="frame__mode-label frame__mode-label--light" for="mode-2">Light mode</label> </div> </div> </div> </div><!-- /frame --> </main> <script src="js/imagesloaded.pkgd.min.js"></script> <script src="js/charming.min.js"></script> <script src="js/TweenMax.min.js"></script> <script src="js/demo.js"></script> </body></html>
CSS SOURCE_CODE:-
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block;}audio,canvas,video{display:inline-block;}audio:not([controls]){display:none;height:0;}[hidden]{display:none;}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;}body{margin:0;}a:focus{outline:thin dotted;}a:active,a:hover{outline:0;}h1{font-size:2em;margin:0.67em 0;}abbr[title]{border-bottom:1px dotted;}b,strong{font-weight:bold;}dfn{font-style:italic;}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0;}mark{background:#ff0;color:#000;}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em;}pre{white-space:pre-wrap;}q{quotes:"\201C" "\201D" "\2018" "\2019";}small{font-size:80%;}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sup{top:-0.5em;}sub{bottom:-0.25em;}img{border:0;}svg:not(:root){overflow:hidden;}figure{margin:0;}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em;}legend{border:0;padding:0;}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;}button,input{line-height:normal;}button,select{text-transform:none;}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}button[disabled],html input[disabled]{cursor:default;}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}textarea{overflow:auto;vertical-align:top;}table{border-collapse:collapse;border-spacing:0;}*,*::after,*::before { box-sizing: border-box;}
.debug { transform: scale(0.5);}
.debug * { outline: 1px solid red; opacity: 0.9;}
html, body { height: 100%;}
:root { font-size: 15px;}
body { --color-text: #5d5d5d; --color-bg: #e6e6ea; --color-link: #838288; --color-link-hover: #000; --color-number: #000; --color-title: #000; --color-caption: #000; --color-content: #000; --color-content-bg: var(--color-bg); --color-reveal-bg: var(--color-bg); color: var(--color-text); background-color: var(--color-bg); font-family: transat-text, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility;}
.dark-mode { --color-text: #424242; --color-bg: #101010; --color-link: #fadb2a; --color-link-hover: #fff; --color-number: #484848; --color-title: #fadb2a; --color-caption: #484848; --color-content: #dadada; --color-content-title:#fadb2a; --color-content-meta: #fff;}
/* Page Loader */.js .loading::before { content: ''; position: fixed; z-index: 100000; top: 0; left: 0; width: 100%; height: 100%; background: var(--color-bg);}
.js .loading::after { content: ''; position: fixed; z-index: 100000; top: 50%; left: 50%; width: 60px; height: 60px; margin: -30px 0 0 -30px; pointer-events: none; border-radius: 50%; opacity: 0.4; background: var(--color-link); animation: loaderAnim 0.7s linear infinite alternate forwards;}
@keyframes loaderAnim { to { opacity: 1; transform: scale3d(0.5,0.5,1); }}
a { text-decoration: none; color: var(--color-link); outline: none;}
a:hover,a:focus { color: var(--color-link-hover); outline: none;}
main { position: relative; min-height: 100vh;}
.frame { padding: 3rem 5vw 0; text-align: center; position: relative; z-index: 100;}
.frame__title { font-size: 1rem; margin: 0 0 1rem;}
.frame__links a { margin: 0 0.5rem;}
.frame__mode { margin: 1rem auto; display: flex; justify-content: center;}
.frame__mode-item { position: relative; width: 20px; height: 20px; margin: 0 0.25rem; pointer-events: auto; border-radius: 50%; background: #fff; overflow: hidden; border: 1px solid var(--color-text);}
.frame__mode-item--dark { background: #000;}
.frame__mode-label,.frame__mode-input { font-size: 0; position: absolute; opacity: 0; width: 100%; height: 100%; left: 0; top: 0; -moz-appearance: none; -webkit-appearance: none; cursor: pointer;}
.content { position: relative;}
.content__item { position: absolute; width: 100%; left: 0; top: 0; color: var(--color-content); background: var(--color-content-bg);}
.js .content__item { opacity: 0; pointer-events: none;}
.js .content__item--current { opacity: 1; pointer-events: auto; top: 16rem;}
.content__item-header { padding: 2rem 2rem 0; position: relative;}
.content__item-header-title { font-family: ivymode, sans-serif; font-weight: 600; font-size: 3rem; margin: 0; color: var(--color-content-title);}
.content__item-header-meta { text-indent: 0.25rem; display: block; color: var(--color-content-meta);}
.dark-mode .content__item-header-meta { mix-blend-mode: difference;}
.content__item-header-meta::before { content: '---------'; margin: 0 0.5rem 0 0; letter-spacing: -0.15rem;}
.content__item-copy { padding: 2rem; font-family: linotype-didot, serif;}
.revealer { position: fixed; width: 100vw; height: 100vh; top: 0; left: 0; transform: rotate(-8deg); display: flex; align-items: center; justify-content: center; pointer-events: none;}
.revealer__inner { background-color: var(--color-reveal-bg); width: 200%; height: 200%; position: relative; flex: none;}
.grid { position: absolute; display: grid; height: 400px; width: 100%; left: 0; top: 0; grid-template-columns: 30% 30% 30%; grid-column-gap: 5%; grid-template-areas: 'griditem-left griditem-center griditem-right';}
.grid--slideshow,.grid--interaction { left: -5%; width: 110%; pointer-events: none;}
.grid--slideshow { top: 17rem; transform: rotate(-8deg);}
.grid--titles { align-items: center; text-align: center; cursor: default;}
.titles-wrap { position: absolute; width: 100%; height: 100%; z-index: 1000; pointer-events: none; transform: rotate(16deg);}
.grid__item { display: flex; justify-content: center; position: relative; pointer-events: none; opacity: 0; grid-area: griditem-center;}
.grid__item--slide { flex-direction: column; width: 100%; }
.grid__item--title { font-size: 13vw; margin: 0; font-family: ivymode, sans-serif; font-weight: 600; color: var(--color-title);}
.grid__item--title span { display: inline-block;}
.grid__item--center,.grid__item--left,.grid__item--right { opacity: 1; cursor: pointer;}
.grid__item--left { grid-area: griditem-left;}
.grid__item--center { grid-area: griditem-center;}
.grid__item--right { grid-area: griditem-right;}
.grid__item--cursor { pointer-events: auto;}
.content-open .grid__item--cursor { display: none;}
.number { font-size: 2rem; -webkit-text-stroke: 1.5px var(--color-number); text-stroke: 1.5px var(--color-number); -webkit-text-fill-color: transparent; text-fill-color: transparent; color: transparent; line-height: 1; margin: 0 0 0.5rem 0; font-weight: 700;}
.img-wrap { width: 100%; overflow: hidden; position: relative; height: 100%;}
.img-wrap--content { height: 200px;}
.img { width: calc(100% + 40px); height: 100%; left: -20px; top: 0; background-size: cover; background-position: 50% 50%; position: absolute; pointer-events: none;}
.img--content { background-position: 50% 38%;}
.caption { text-transform: uppercase; letter-spacing: 0.1rem; font-size: 0.75rem; font-weight: 400; margin: 0.75rem 0 0 0; color: var(--color-caption);}
.caption::before { content: '---------'; margin: 0 0.5rem 0 0; letter-spacing: -0.15rem;}
.img-wrap,.img--content,.caption,.number,.grid__item--title,.grid__item--title span,.revealer__inner,.content__item-header-title { will-change: transform;}
.grid__item--cursor.grid__item--left::after,.grid__item--cursor.grid__item--right::after,.img-wrap--content::after { position: absolute; left: calc(50% - 30px); cursor: pointer;}
.grid__item--cursor.grid__item--left::after { top: 70%;}
.grid__item--cursor.grid__item--right::after { top: 20%;}
.grid__item--cursor.grid__item--left::after { content: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='61px' height='44px' viewBox='0 0 61 44' style='enable-background:new 0 0 61 44;' xml:space='preserve'%3E %3Cpath d='M.613 21.671L21.584.7l5.642 5.642-11.74 11.74H60.45v7.978H15.487l11.74 11.739-5.643 5.642L.613 22.469a.57.57 0 0 1 0-.798z'/%3E %3C/svg%3E");}
.grid__item--cursor.grid__item--right::after { content: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='61px' height='44px' viewBox='0 0 61 44' style='enable-background:new 0 0 61 44;' xml:space='preserve'%3E %3Cpath d='M60.287 21.671L39.316.7l-5.642 5.642 11.74 11.74H.45v7.978h44.963l-11.74 11.739 5.643 5.642 20.971-20.972a.57.57 0 0 0 0-.798z'/%3E %3C/svg%3E");}
.img-wrap--content::after { top: 0.5rem; right: 0.5rem; left: auto; transform: scale(0.5); content: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='52px' height='52px' viewBox='0 0 52 52' style='enable-background:new 0 0 52 52;' xml:space='preserve'%3E %3Cpath d='M20.921 26.67L5.791 41.75C5.485 41.743.23 36.488.224 36.18L15.32 21.073.098 5.86 5.74.22l15.19 15.24L36.161.22l5.64 5.64-15.27 15.22 15.097 15.15c-.006.307-5.262 5.562-5.569 5.568L20.921 26.67z'/%3E %3C/svg%3E");}
@media screen and (min-width: 53em) { body { overflow: hidden; } .frame { position: fixed; bottom: 0; right: 0; padding: 1rem; transition: 0.3s opacity; } .content-open + .frame { opacity: 0; pointer-events: none; } .frame__title-wrap { display: flex; align-items: center; justify-content: flex-end; } .frame__title { margin: 0; } .frame__links { margin: 0 1.5rem; } .frame__mode { margin: 0; } .frame a { pointer-events: auto; } .grid { height: 100vh; grid-template-columns: repeat(3, calc((100% - 36vw) / 3)); grid-column-gap: 18vw; } .grid--slideshow { top: 0; } .grid--interaction { grid-template-columns: repeat(3, calc(100% / 3)); grid-column-gap: 0; } .number { font-size: 4.25vw; } .img-wrap { height: 35vw; } .img-wrap--content { height: 100%; grid-area: 1 / 2 / 2 / 3; } .content { top: 0; position: absolute; height: 100vh; width: 100%; } .content__item { height: 100vh; display: grid; align-items: center; grid-template-columns: 30% 40% 30%; grid-column-gap: 0; } .js .content__item { height: 100%; } .js .content__item--current { top: 0; } .img-wrap--content { height: 100%; } .content__item-header { justify-self: center; grid-area: 1 / 1 / 2 / 3; pointer-events: none; } .content__item-header-title { font-size: 8vw; } .content__item-copy { max-width: 240px; justify-self: end; text-align: right; } .grid__item--cursor.grid__item--left::after, .grid__item--cursor.grid__item--right::after, .img-wrap--content::after { display: none; } .grid__item--cursor.grid__item--left { cursor: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='61px' height='44px' viewBox='0 0 61 44' style='enable-background:new 0 0 61 44;' xml:space='preserve'%3E %3Cpath d='M.613 21.671L21.584.7l5.642 5.642-11.74 11.74H60.45v7.978H15.487l11.74 11.739-5.643 5.642L.613 22.469a.57.57 0 0 1 0-.798z'/%3E %3C/svg%3E") 30 22, sw-resize; } .grid__item--cursor.grid__item--center { cursor: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='52px' height='52px' viewBox='0 0 52 52' style='enable-background:new 0 0 52 52;' xml:space='preserve'%3E %3Cpath d='M29.889 30.05l-.036 21.361c-.222.213-7.654.213-7.876 0l-.007-21.358-21.52.007v-7.978l21.518.036L21.96.571h7.978l-.037 21.56 21.388.037c.213.222.213 7.654 0 7.876l-21.401.007z'/%3E %3C/svg%3E") 26 26, crosshair; } .grid__item--cursor.grid__item--right { cursor: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='61px' height='44px' viewBox='0 0 61 44' style='enable-background:new 0 0 61 44;' xml:space='preserve'%3E %3Cpath d='M60.287 21.671L39.316.7l-5.642 5.642 11.74 11.74H.45v7.978h44.963l-11.74 11.739 5.643 5.642 20.971-20.972a.57.57 0 0 0 0-.798z'/%3E %3C/svg%3E") 30 22, ne-resize; } .dark-mode .grid__item--cursor.grid__item--left { cursor: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='61px' height='44px' viewBox='0 0 61 44' style='enable-background:new 0 0 61 44;' xml:space='preserve'%3E %3Cpath fill='%23bb3a3a' d='M.613 21.671L21.584.7l5.642 5.642-11.74 11.74H60.45v7.978H15.487l11.74 11.739-5.643 5.642L.613 22.469a.57.57 0 0 1 0-.798z'/%3E %3C/svg%3E") 30 22, sw-resize; } .dark-mode .grid__item--cursor.grid__item--center { cursor: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='52px' height='52px' viewBox='0 0 52 52' style='enable-background:new 0 0 52 52;' xml:space='preserve'%3E %3Cpath fill='%23bb3a3a' d='M29.889 30.05l-.036 21.361c-.222.213-7.654.213-7.876 0l-.007-21.358-21.52.007v-7.978l21.518.036L21.96.571h7.978l-.037 21.56 21.388.037c.213.222.213 7.654 0 7.876l-21.401.007z'/%3E %3C/svg%3E") 26 26, crosshair; } .dark-mode .grid__item--cursor.grid__item--right { cursor: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='61px' height='44px' viewBox='0 0 61 44' style='enable-background:new 0 0 61 44;' xml:space='preserve'%3E %3Cpath fill='%23bb3a3a' d='M60.287 21.671L39.316.7l-5.642 5.642 11.74 11.74H.45v7.978h44.963l-11.74 11.739 5.643 5.642 20.971-20.972a.57.57 0 0 0 0-.798z'/%3E %3C/svg%3E") 30 22, ne-resize; } .img-wrap--content { cursor: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='52px' height='52px' viewBox='0 0 52 52' style='enable-background:new 0 0 52 52;' xml:space='preserve'%3E %3Cpath d='M20.921 26.67L5.791 41.75C5.485 41.743.23 36.488.224 36.18L15.32 21.073.098 5.86 5.74.22l15.19 15.24L36.161.22l5.64 5.64-15.27 15.22 15.097 15.15c-.006.307-5.262 5.562-5.569 5.568L20.921 26.67z'/%3E %3C/svg%3E") 21 21, pointer; } .dark-mode .img-wrap--content { cursor: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='52px' height='52px' viewBox='0 0 52 52' style='enable-background:new 0 0 52 52;' xml:space='preserve'%3E %3Cpath fill='%23bb3a3a' d='M20.921 26.67L5.791 41.75C5.485 41.743.23 36.488.224 36.18L15.32 21.073.098 5.86 5.74.22l15.19 15.24L36.161.22l5.64 5.64-15.27 15.22 15.097 15.15c-.006.307-5.262 5.562-5.569 5.568L20.921 26.67z'/%3E %3C/svg%3E") 21 21, pointer; }}
Javascript (.js file) SOURCE_CODE:-
{ const MathUtils = { lineEq: (y2, y1, x2, x1, currentVal) => { // y = mx + b var m = (y2 - y1) / (x2 - x1), b = y1 - m * x1; return m * currentVal + b; }, lerp: (a, b, n) => (1 - n) * a + n * b, distance: (x1, x2, y1, y2) => { var a = x1 - x2; var b = y1 - y2; return Math.hypot(a,b); }, randomNumber: (min,max) => Math.floor(Math.random()*(max-min+1)+min) };
let winsize; const calcWinsize = () => winsize = {width: window.innerWidth, height: window.innerHeight}; calcWinsize(); window.addEventListener('resize', calcWinsize);
const getMousePos = (ev) => { let posx = 0; let posy = 0; if (!ev) ev = window.event; if (ev.pageX || ev.pageY) { posx = ev.pageX; posy = ev.pageY; } else if (ev.clientX || ev.clientY) { posx = ev.clientX + body.scrollLeft + docEl.scrollLeft; posy = ev.clientY + body.scrollTop + docEl.scrollTop; } return {x: posx, y: posy}; }
let mousePos = {x: winsize.width/2, y: winsize.height/2}; window.addEventListener('mousemove', ev => mousePos = getMousePos(ev));
class Slide { constructor(el, title) { this.DOM = {el: el}; this.DOM.title = title; charming(this.DOM.title); this.DOM.titleLetters = [...this.DOM.title.querySelectorAll('span')]; this.DOM.titleLetters.sort(() => Math.round(Math.random())-0.5); this.DOM.number = this.DOM.el.querySelector('.number'); this.DOM.subtitle = this.DOM.el.querySelector('.caption'); this.DOM.imgWrap = this.DOM.el.querySelector('.img-wrap'); this.DOM.img = this.DOM.imgWrap.querySelector('.img'); } move(direction, val) { return new Promise((resolve, reject) => { const tx = direction === 'left' ? '+=' + val*-1 : '+=' + val; const duration = 1.2; new TimelineMax({onComplete: resolve}) .to(this.DOM.imgWrap, duration, { x: tx, ease: Quart.easeInOut }, 0) .to(this.DOM.imgWrap, duration*.5, { scaleX: 1.3, ease: Quart.easeIn }, 0) .to(this.DOM.imgWrap, duration*.5, { scaleX: 1, ease: Quart.easeOut }, duration*.5) .to(this.DOM.number, duration*.95, { x: tx, ease: Quint.easeInOut }, 0) .to(this.DOM.subtitle, duration*1.1, { x: tx, ease: Quart.easeInOut }, 0) .to(this.DOM.title, duration*1.05, { x: tx, ease: Quart.easeInOut }, 0); }); } setCenter() { this.isCenter = true; this.DOM.el.classList.add('grid__item--center'); this.DOM.title.classList.add('grid__item--center'); TweenMax.set([this.DOM.el, this.DOM.title], {opacity: 1}); } setRight() { this.isRight = this.isCenter = false; this.isLeft = true; this.DOM.el.classList.add('grid__item--right'); this.DOM.title.classList.add('grid__item--right'); TweenMax.set([this.DOM.el, this.DOM.title], {opacity: 1}); } setLeft() { this.isLeft = this.isCenter = false; this.isRight = true; this.DOM.el.classList.add('grid__item--left'); this.DOM.title.classList.add('grid__item--left'); TweenMax.set([this.DOM.el, this.DOM.title], {opacity: 1}); } reset() { TweenMax.set([this.DOM.el, this.DOM.imgWrap, this.DOM.number, this.DOM.subtitle, this.DOM.title], {transform: 'none'}); TweenMax.set([this.DOM.el, this.DOM.title], {opacity: 0}); this.DOM.title.classList = 'grid__item grid__item--title'; this.DOM.el.classList = 'grid__item grid__item--slide'; } animateElementsOut(contentItem) { return new Promise((resolve, reject) => { const time = MathUtils.randomNumber(0,100)/500; this.elemsTimeline = new TimelineMax({onComplete: resolve}) .staggerTo(this.DOM.titleLetters, 1, { y: MathUtils.randomNumber(300,600), opacity: 0, ease: Quart.easeInOut }, 0.04, time) .staggerTo(this.DOM.titleLetters, 0.5, { scaleY: 2.2, ease: Quart.easeIn }, 0.04, time) .staggerTo(this.DOM.titleLetters, 0.5, { scaleY: 1, ease: Quart.easeOut }, 0.04, time + 0.5) .to(this.DOM.number, 1, { y: -500, opacity: 0, ease: Quart.easeInOut }, time+0.3) .to(this.DOM.imgWrap, 0.8, { y: -500, opacity: 0, ease: Quart.easeInOut }, time+0.4) .to(this.DOM.imgWrap, .4, { scaleX: 0.95, scaleY: 1.4, ease: Quart.easeIn }, time+0.4) .to(this.DOM.imgWrap, .4, { scaleX: 1, scaleY: 1, ease: Quart.easeOut }, time+0.4 + 0.4) .to(this.DOM.subtitle, 1, { y: -500, opacity: 0, ease: Quart.easeInOut }, time+0.5);
if ( this.isCenter ) { const contentItemTitle = contentItem.querySelector('.content__item-header-title'); const contentItemImg = contentItem.querySelector('.img--content'); this.elemsTimeline.to(contentItemTitle, 0.8, { ease: Expo.easeOut, startAt: {y: '100%', opacity: 0, rotation: -16}, y: '0%', rotation: 0, opacity: 1 }, time+1.3) .set(contentItemImg, {scale: 1.2}, 0) .to(contentItemImg, 0.8, { ease: Expo.easeOut, scale: 1 }, time+1.3) .to(revealer.DOM.el, 1, { ease: Quint.easeOut, y: '-100%' }, time+1.2); } }); } animateElementsIn(contentItem) { return new Promise((resolve, reject) => { const time = MathUtils.randomNumber(0,50)/500; this.elemsTimeline = new TimelineMax({onComplete: resolve}); if ( this.isCenter ) { const contentItemTitle = contentItem.querySelector('.content__item-header-title'); const contentItemImg = contentItem.querySelector('.img--content'); this.elemsTimeline.to(contentItemTitle, 1, { ease: Quint.easeOut, y: '50%', opacity: 0 }, 0) .to(contentItemImg, 1, { ease: Quint.easeOut, scale: 1.2 }, 0) .to(revealer.DOM.el, 1, { ease: Quint.easeOut, y: '0%' }, 0); } this.elemsTimeline.to(this.DOM.subtitle, 0.8, { y: 0, opacity: 1, ease: Quart.easeOut }, time) .to(this.DOM.imgWrap, 0.8, { y: 0, opacity: 1, scaleX: 1, scaleY: 1, ease: Quart.easeOut }, time+0.1) .to(this.DOM.number, 0.8, { y: 0, opacity: 1, ease: Quart.easeOut }, time+0.2) .staggerTo(this.DOM.titleLetters, 0.8, { y: 0, opacity: 1, scaleX: 1, scaleY: 1, ease: Quart.easeOut }, 0.03, time+0.1) }); } }
class Slideshow { constructor(el) { this.DOM = {el: el}; // The titles this.DOM.titlesWrap = this.DOM.el.querySelector('.titles-wrap'); this.DOM.titlesInner = this.DOM.titlesWrap.querySelector('.grid--titles'); this.DOM.titles = [...this.DOM.titlesInner.querySelectorAll('.grid__item--title')]; // The slides instances this.slides = []; [...this.DOM.el.querySelectorAll('.grid__item--slide')].forEach((slide, pos) => this.slides.push(new Slide(slide, this.DOM.titles[pos]))); // Total number of slides this.slidesTotal = this.slides.length; if ( this.slidesTotal < 4 ) return; // Center slide's position this.center = 0;
// Content Items this.DOM.contentItems = [...document.querySelectorAll('.content__item')];
// Areas (left, center, right) where to attach the navigation events. this.DOM.interaction = { left: document.querySelector('.grid__item--left'), center: document.querySelector('.grid__item--center'), right: document.querySelector('.grid__item--right') }; this.setVisibleSlides(); this.calculateGap(); this.initEvents();
let mouseMoveVals = {translation: 0, rotation: -8}; const render = () => { //if ( !this.isAnimating ) { mouseMoveVals.translation = MathUtils.lerp(mouseMoveVals.translation, MathUtils.lineEq(-15, 15, winsize.width, 0, mousePos.x), 0.03); //mouseMoveVals.rotation = MathUtils.lerp(mouseMoveVals.rotation, MathUtils.lineEq(-8.5, -7.5, winsize.width, 0, mousePos.x), 0.03); for (let i = 0; i <= this.slidesTotal - 1; ++i) { TweenMax.set(this.slides[i].DOM.img, {x: mouseMoveVals.translation}); TweenMax.set(this.DOM.titlesInner, {x: -4*mouseMoveVals.translation}); //TweenMax.set(this.DOM.el, {rotation: mouseMoveVals.rotation}); //TweenMax.set(this.DOM.titlesWrap, {rotation: -2*mouseMoveVals.rotation}); } //} requestAnimationFrame(render); } requestAnimationFrame(render); } setVisibleSlides() { this.centerSlide = this.slides[this.center]; this.rightSlide = this.slides[this.center+1 <= this.slidesTotal-1 ? this.center+1 : 0]; this.leftSlide = this.slides[this.center-1 >= 0 ? this.center-1 : this.slidesTotal-1]; this.centerSlide.setCenter(); this.rightSlide.setRight(); this.leftSlide.setLeft(); } // Distance between 2 slides // The amount to translate the elements that move when we navigate the slideshow calculateGap() { const s1 = this.slides[0].DOM.el.getBoundingClientRect(); const s2 = this.slides[1].DOM.el.getBoundingClientRect(); this.gap = MathUtils.distance(s1.left + s1.width/2, s2.left + s2.width/2, s1.top + s1.height/2, s2.top + s2.height/2); } // Initialize events initEvents() { this.clickRightFn = () => this.navigate('right'); this.DOM.interaction.right.addEventListener('click', this.clickRightFn); this.clickLeftFn = () => this.navigate('left'); this.DOM.interaction.left.addEventListener('click', this.clickLeftFn); this.clickCenterFn = () => this.openSlide(); this.DOM.interaction.center.addEventListener('click', this.clickCenterFn);
this.mouseenterCenterFn = () => { if ( this.isAnimating ) { return; } new TimelineMax() .to(this.centerSlide.DOM.imgWrap, 0.7, { ease: Expo.easeOut, scale: 1.02 }) .to(this.centerSlide.DOM.img, 1.7, { ease: Expo.easeOut, scale: 1.05 }, 0); }; this.DOM.interaction.center.addEventListener('mouseenter', this.mouseenterCenterFn);
this.mouseleaveCenterFn = () => { if ( this.isAnimating ) { return; } new TimelineMax().to(this.centerSlide.DOM.imgWrap, 0.7, { ease: Expo.easeOut, scale: 1 }) .to(this.centerSlide.DOM.img, 0.7, { ease: Expo.easeOut, scale: 1 }, 0); }; this.DOM.interaction.center.addEventListener('mouseleave', this.mouseleaveCenterFn);
this.resizeFn = () => this.calculateGap(); window.addEventListener('resize', this.resizeFn);
this.DOM.contentItems.forEach(item => { item.querySelector('.img-wrap--content').addEventListener('click', () => this.closeSlide()); }); } navigate(direction) { if ( this.isAnimating ) { return false; } this.isAnimating = true; const upcomingPos = direction === 'right' ? this.center < this.slidesTotal-2 ? this.center+2 : Math.abs(this.slidesTotal-2-this.center): this.center >= 2 ? this.center-2 : Math.abs(this.slidesTotal-2+this.center);
// Update current. this.center = direction === 'right' ? this.center < this.slidesTotal-1 ? this.center+1 : 0 : this.center > 0 ? this.center-1 : this.slidesTotal-1;
this.upcomingSlide = this.slides[upcomingPos]; this.upcomingTitle = this.upcomingSlide.DOM.title; // Position upcomingSlide / upcomingTitle TweenMax.set(this.upcomingSlide.DOM.el, {x: direction === 'right' ? this.gap*2 : -1*this.gap*2, opacity: 1}); TweenMax.set(this.upcomingTitle, {x: direction === 'right' ? this.gap*2 : -1*this.gap*2, opacity: 1}); const movingSlides = [this.upcomingSlide, this.centerSlide, this.rightSlide, this.leftSlide]; let promises = []; movingSlides.forEach(slide => promises.push(slide.move(direction === 'right' ? 'left' : 'right', this.gap))); Promise.all(promises).then(() => { // After all is moved, update the classes of the 3 visible slides and reset styles movingSlides.forEach(slide => slide.reset()); // Set it again this.setVisibleSlides(); this.isAnimating = false; }); } openSlide() { this.toggleSlide('open'); } closeSlide() { this.toggleSlide('close'); } toggleSlide(action) { if ( this.isAnimating ) { return; } this.isAnimating = true;
const contentItem = this.DOM.contentItems[this.center]; // Cursor styles related class this.DOM.el.classList[action === 'open' ? 'add' : 'remove']('content-open');
const movingSlides = [this.centerSlide, this.rightSlide, this.leftSlide]; let promises = []; movingSlides.forEach(slide => promises.push(slide[action === 'open' ? 'animateElementsOut' : 'animateElementsIn'](contentItem))); if ( action === 'open' ) { contentItem.classList.add('content__item--current'); } Promise.all(promises).then(() => { if ( action === 'close' ) { contentItem.classList.remove('content__item--current'); } this.isAnimating = false; }); } }
class Revealer { constructor(el) { this.DOM = {el: el}; this.DOM.el.style.width = `calc(100vw * ${Math.cos(8 * Math.PI/180)} + 100vh * ${Math.sin(8 * Math.PI/180)})`; this.DOM.el.style.height = `calc(100vw * ${Math.sin(8 * Math.PI/180)} + 100vh * ${Math.cos(8 * Math.PI/180)})`; } }
// Revealer element const revealer = new Revealer(document.querySelector('.revealer__inner')); // Initialize the slideshow new Slideshow(document.querySelector('.grid--slideshow'));
// Preload all the images in the page imagesLoaded(document.querySelectorAll('.img'), {background: true}, () => document.body.classList.remove('loading')); [...document.querySelectorAll('.frame__mode input[type="radio"]')].forEach(radio => radio.addEventListener('click', () => { document.body.classList[radio.parentNode.classList.contains('frame__mode-item--dark') ? 'add' : 'remove']('dark-mode'); }));}
web design video My YOUTUBE channel
HTML SOURCE_CODE:-
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Crossroads Slideshow | Codrops</title>
<link rel="stylesheet" type="text/css" href="css/base.css" />
<script>document.documentElement.className="js";var supportsCssVars=function(){var e,t=document.createElement("style");return t.innerHTML="root: { --tmp-var: bold; }",document.head.appendChild(t),e=!!(window.CSS&&window.CSS.supports&&window.CSS.supports("font-weight","var(--tmp-var)")),t.parentNode.removeChild(t),e};supportsCssVars()||alert("Please view this demo in a modern browser that supports CSS Variables.");</script>
</head>
<body class="loading">
<main>
<div class="content">
<article class="content__item">
<div class="img-wrap img-wrap--content">
<div class="img img--content" style="background-image: url(img/1.jpg);"></div>
</div>
<header class="content__item-header">
<span class="content__item-header-meta">New York City, March 24</span>
<h2 class="content__item-header-title">kani</h2>
</header>
<div class="content__item-copy">
<p class="content__item-copy-text">
In the gloomy domed livingroom of the tower Buck Mulligan’s gowned form
moved briskly to and fro about the hearth, hiding and revealing its
yellow glow. Two shafts of soft daylight fell across the flagged floor
from the high barbacans: and at the meeting of their rays a cloud of
coalsmoke and fumes of fried grease floated, turning.
</p>
<a href="#" class="content__item-copy-more">more +</a>
</div>
</article>
<article class="content__item">
<div class="img-wrap img-wrap--content">
<div class="img img--content" style="background-image: url(img/2.jpg);"></div>
</div>
<header class="content__item-header">
<span class="content__item-header-meta">Acapulco, March 25</span>
<h2 class="content__item-header-title">Bob</h2>
</header>
<div class="content__item-copy">
<p class="content__item-copy-text">
The key scraped round harshly twice and, when the heavy door had been
set ajar, welcome light and bright air entered. Haines stood at the
doorway, looking out. Stephen haled his upended valise to the table and
sat down to wait. Buck Mulligan tossed the fry on to the dish beside
him. Then he carried the dish and a large teapot over to the table, set
them down heavily and sighed with relief.
</p>
<a href="#" class="content__item-copy-more">more +</a>
</div>
</article>
<article class="content__item">
<div class="img-wrap img-wrap--content">
<div class="img img--content" style="background-image: url(img/3.jpg);"></div>
</div>
<header class="content__item-header">
<span class="content__item-header-meta">Brisbane, March 26</span>
<h2 class="content__item-header-title">Canon</h2>
</header>
<div class="content__item-copy">
<p class="content__item-copy-text">
Stephen listened in scornful silence. She bows her old head to a voice
that speaks to her loudly, her bonesetter, her medicineman: me she
slights. To the voice that will shrive and oil for the grave all there
is of her but her woman’s unclean loins, of man’s flesh made not in
God’s likeness, the serpent’s prey.
</p>
<a href="#" class="content__item-copy-more">more +</a>
</div>
</article>
<article class="content__item">
<div class="img-wrap img-wrap--content">
<div class="img img--content" style="background-image: url(img/4.jpg);"></div>
</div>
<header class="content__item-header">
<span class="content__item-header-meta">Berlin, March 27</span>
<h2 class="content__item-header-title">Hill</h2>
</header>
<div class="content__item-copy">
<p class="content__item-copy-text">
And putting on his stiff collar and rebellious tie he spoke to them,
chiding them, and to his dangling watchchain. His hands plunged and
rummaged in his trunk while he called for a clean handkerchief. God,
we’ll simply have to dress the character. I want puce gloves and green
boots. Contradiction.
</p>
<a href="#" class="content__item-copy-more">more +</a>
</div>
</article>
</div>
<div class="revealer">
<div class="revealer__inner"></div>
</div>
<div class="grid grid--slideshow">
<figure class="grid__item grid__item--slide">
<span class="number">01</span>
<div class="img-wrap">
<div class="img" style="background-image: url(img/1.jpg);"></div>
</div>
<figcaption class="caption">New York City, March 24</figcaption>
</figure>
<figure class="grid__item grid__item--slide">
<span class="number">02</span>
<div class="img-wrap">
<div class="img" style="background-image: url(img/2.jpg);"></div>
</div>
<figcaption class="caption">Acapulco, March 25</figcaption>
</figure>
<figure class="grid__item grid__item--slide">
<span class="number">03</span>
<div class="img-wrap">
<div class="img" style="background-image: url(img/3.jpg);"></div>
</div>
<figcaption class="caption">Brisbane, March 26</figcaption>
</figure>
<figure class="grid__item grid__item--slide">
<span class="number">04</span>
<div class="img-wrap">
<div class="img" style="background-image: url(img/4.jpg);"></div>
</div>
<figcaption class="caption">Berlin, March 27</figcaption>
</figure>
<div class="titles-wrap">
<div class="grid grid--titles">
<h3 class="grid__item grid__item--title">Kani</h3>
<h3 class="grid__item grid__item--title">Bob</h3>
<h3 class="grid__item grid__item--title">Canon</h3>
<h3 class="grid__item grid__item--title">Hill</h3>
</div>
</div>
<div class="grid grid--interaction">
<div class="grid__item grid__item--cursor grid__item--left"></div>
<div class="grid__item grid__item--cursor grid__item--center"></div>
<div class="grid__item grid__item--cursor grid__item--right"></div>
</div>
</div>
<div class="frame">
<div class="frame__mode" role="radiogroup">
<div class="frame__mode-item frame__mode-item--dark">
<input id="mode-1" type="radio" name="mode" class="frame__mode-input"></input>
<label class="frame__mode-label" for="mode-1">Dark mode</label>
</div>
<div class="frame__mode-item">
<input id="mode-2" type="radio" name="mode" class="frame__mode-input" checked></input>
<label class="frame__mode-label frame__mode-label--light" for="mode-2">Light mode</label>
</div>
</div>
</div>
</div><!-- /frame -->
</main>
<script src="js/imagesloaded.pkgd.min.js"></script>
<script src="js/charming.min.js"></script>
<script src="js/TweenMax.min.js"></script>
<script src="js/demo.js"></script>
</body>
</html>
CSS SOURCE_CODE:-
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block;}audio,canvas,video{display:inline-block;}audio:not([controls]){display:none;height:0;}[hidden]{display:none;}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;}body{margin:0;}a:focus{outline:thin dotted;}a:active,a:hover{outline:0;}h1{font-size:2em;margin:0.67em 0;}abbr[title]{border-bottom:1px dotted;}b,strong{font-weight:bold;}dfn{font-style:italic;}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0;}mark{background:#ff0;color:#000;}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em;}pre{white-space:pre-wrap;}q{quotes:"\201C" "\201D" "\2018" "\2019";}small{font-size:80%;}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sup{top:-0.5em;}sub{bottom:-0.25em;}img{border:0;}svg:not(:root){overflow:hidden;}figure{margin:0;}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em;}legend{border:0;padding:0;}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;}button,input{line-height:normal;}button,select{text-transform:none;}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}button[disabled],html input[disabled]{cursor:default;}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}textarea{overflow:auto;vertical-align:top;}table{border-collapse:collapse;border-spacing:0;}
*,
*::after,
*::before {
box-sizing: border-box;
}
.debug {
transform: scale(0.5);
}
.debug * {
outline: 1px solid red;
opacity: 0.9;
}
html, body {
height: 100%;
}
:root {
font-size: 15px;
}
body {
--color-text: #5d5d5d;
--color-bg: #e6e6ea;
--color-link: #838288;
--color-link-hover: #000;
--color-number: #000;
--color-title: #000;
--color-caption: #000;
--color-content: #000;
--color-content-bg: var(--color-bg);
--color-reveal-bg: var(--color-bg);
color: var(--color-text);
background-color: var(--color-bg);
font-family: transat-text, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
}
.dark-mode {
--color-text: #424242;
--color-bg: #101010;
--color-link: #fadb2a;
--color-link-hover: #fff;
--color-number: #484848;
--color-title: #fadb2a;
--color-caption: #484848;
--color-content: #dadada;
--color-content-title:#fadb2a;
--color-content-meta: #fff;
}
/* Page Loader */
.js .loading::before {
content: '';
position: fixed;
z-index: 100000;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: var(--color-bg);
}
.js .loading::after {
content: '';
position: fixed;
z-index: 100000;
top: 50%;
left: 50%;
width: 60px;
height: 60px;
margin: -30px 0 0 -30px;
pointer-events: none;
border-radius: 50%;
opacity: 0.4;
background: var(--color-link);
animation: loaderAnim 0.7s linear infinite alternate forwards;
}
@keyframes loaderAnim {
to {
opacity: 1;
transform: scale3d(0.5,0.5,1);
}
}
a {
text-decoration: none;
color: var(--color-link);
outline: none;
}
a:hover,
a:focus {
color: var(--color-link-hover);
outline: none;
}
main {
position: relative;
min-height: 100vh;
}
.frame {
padding: 3rem 5vw 0;
text-align: center;
position: relative;
z-index: 100;
}
.frame__title {
font-size: 1rem;
margin: 0 0 1rem;
}
.frame__links a {
margin: 0 0.5rem;
}
.frame__mode {
margin: 1rem auto;
display: flex;
justify-content: center;
}
.frame__mode-item {
position: relative;
width: 20px;
height: 20px;
margin: 0 0.25rem;
pointer-events: auto;
border-radius: 50%;
background: #fff;
overflow: hidden;
border: 1px solid var(--color-text);
}
.frame__mode-item--dark {
background: #000;
}
.frame__mode-label,
.frame__mode-input {
font-size: 0;
position: absolute;
opacity: 0;
width: 100%;
height: 100%;
left: 0;
top: 0;
-moz-appearance: none;
-webkit-appearance: none;
cursor: pointer;
}
.content {
position: relative;
}
.content__item {
position: absolute;
width: 100%;
left: 0;
top: 0;
color: var(--color-content);
background: var(--color-content-bg);
}
.js .content__item {
opacity: 0;
pointer-events: none;
}
.js .content__item--current {
opacity: 1;
pointer-events: auto;
top: 16rem;
}
.content__item-header {
padding: 2rem 2rem 0;
position: relative;
}
.content__item-header-title {
font-family: ivymode, sans-serif;
font-weight: 600;
font-size: 3rem;
margin: 0;
color: var(--color-content-title);
}
.content__item-header-meta {
text-indent: 0.25rem;
display: block;
color: var(--color-content-meta);
}
.dark-mode .content__item-header-meta {
mix-blend-mode: difference;
}
.content__item-header-meta::before {
content: '---------';
margin: 0 0.5rem 0 0;
letter-spacing: -0.15rem;
}
.content__item-copy {
padding: 2rem;
font-family: linotype-didot, serif;
}
.revealer {
position: fixed;
width: 100vw;
height: 100vh;
top: 0;
left: 0;
transform: rotate(-8deg);
display: flex;
align-items: center;
justify-content: center;
pointer-events: none;
}
.revealer__inner {
background-color: var(--color-reveal-bg);
width: 200%;
height: 200%;
position: relative;
flex: none;
}
.grid {
position: absolute;
display: grid;
height: 400px;
width: 100%;
left: 0;
top: 0;
grid-template-columns: 30% 30% 30%;
grid-column-gap: 5%;
grid-template-areas: 'griditem-left griditem-center griditem-right';
}
.grid--slideshow,
.grid--interaction {
left: -5%;
width: 110%;
pointer-events: none;
}
.grid--slideshow {
top: 17rem;
transform: rotate(-8deg);
}
.grid--titles {
align-items: center;
text-align: center;
cursor: default;
}
.titles-wrap {
position: absolute;
width: 100%;
height: 100%;
z-index: 1000;
pointer-events: none;
transform: rotate(16deg);
}
.grid__item {
display: flex;
justify-content: center;
position: relative;
pointer-events: none;
opacity: 0;
grid-area: griditem-center;
}
.grid__item--slide {
flex-direction: column;
width: 100%;
}
.grid__item--title {
font-size: 13vw;
margin: 0;
font-family: ivymode, sans-serif;
font-weight: 600;
color: var(--color-title);
}
.grid__item--title span {
display: inline-block;
}
.grid__item--center,
.grid__item--left,
.grid__item--right {
opacity: 1;
cursor: pointer;
}
.grid__item--left {
grid-area: griditem-left;
}
.grid__item--center {
grid-area: griditem-center;
}
.grid__item--right {
grid-area: griditem-right;
}
.grid__item--cursor {
pointer-events: auto;
}
.content-open .grid__item--cursor {
display: none;
}
.number {
font-size: 2rem;
-webkit-text-stroke: 1.5px var(--color-number);
text-stroke: 1.5px var(--color-number);
-webkit-text-fill-color: transparent;
text-fill-color: transparent;
color: transparent;
line-height: 1;
margin: 0 0 0.5rem 0;
font-weight: 700;
}
.img-wrap {
width: 100%;
overflow: hidden;
position: relative;
height: 100%;
}
.img-wrap--content {
height: 200px;
}
.img {
width: calc(100% + 40px);
height: 100%;
left: -20px;
top: 0;
background-size: cover;
background-position: 50% 50%;
position: absolute;
pointer-events: none;
}
.img--content {
background-position: 50% 38%;
}
.caption {
text-transform: uppercase;
letter-spacing: 0.1rem;
font-size: 0.75rem;
font-weight: 400;
margin: 0.75rem 0 0 0;
color: var(--color-caption);
}
.caption::before {
content: '---------';
margin: 0 0.5rem 0 0;
letter-spacing: -0.15rem;
}
.img-wrap,
.img--content,
.caption,
.number,
.grid__item--title,
.grid__item--title span,
.revealer__inner,
.content__item-header-title {
will-change: transform;
}
.grid__item--cursor.grid__item--left::after,
.grid__item--cursor.grid__item--right::after,
.img-wrap--content::after {
position: absolute;
left: calc(50% - 30px);
cursor: pointer;
}
.grid__item--cursor.grid__item--left::after {
top: 70%;
}
.grid__item--cursor.grid__item--right::after {
top: 20%;
}
.grid__item--cursor.grid__item--left::after {
content: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='61px' height='44px' viewBox='0 0 61 44' style='enable-background:new 0 0 61 44;' xml:space='preserve'%3E %3Cpath d='M.613 21.671L21.584.7l5.642 5.642-11.74 11.74H60.45v7.978H15.487l11.74 11.739-5.643 5.642L.613 22.469a.57.57 0 0 1 0-.798z'/%3E %3C/svg%3E");
}
.grid__item--cursor.grid__item--right::after {
content: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='61px' height='44px' viewBox='0 0 61 44' style='enable-background:new 0 0 61 44;' xml:space='preserve'%3E %3Cpath d='M60.287 21.671L39.316.7l-5.642 5.642 11.74 11.74H.45v7.978h44.963l-11.74 11.739 5.643 5.642 20.971-20.972a.57.57 0 0 0 0-.798z'/%3E %3C/svg%3E");
}
.img-wrap--content::after {
top: 0.5rem;
right: 0.5rem;
left: auto;
transform: scale(0.5);
content: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='52px' height='52px' viewBox='0 0 52 52' style='enable-background:new 0 0 52 52;' xml:space='preserve'%3E %3Cpath d='M20.921 26.67L5.791 41.75C5.485 41.743.23 36.488.224 36.18L15.32 21.073.098 5.86 5.74.22l15.19 15.24L36.161.22l5.64 5.64-15.27 15.22 15.097 15.15c-.006.307-5.262 5.562-5.569 5.568L20.921 26.67z'/%3E %3C/svg%3E");
}
@media screen and (min-width: 53em) {
body {
overflow: hidden;
}
.frame {
position: fixed;
bottom: 0;
right: 0;
padding: 1rem;
transition: 0.3s opacity;
}
.content-open + .frame {
opacity: 0;
pointer-events: none;
}
.frame__title-wrap {
display: flex;
align-items: center;
justify-content: flex-end;
}
.frame__title {
margin: 0;
}
.frame__links {
margin: 0 1.5rem;
}
.frame__mode {
margin: 0;
}
.frame a {
pointer-events: auto;
}
.grid {
height: 100vh;
grid-template-columns: repeat(3, calc((100% - 36vw) / 3));
grid-column-gap: 18vw;
}
.grid--slideshow {
top: 0;
}
.grid--interaction {
grid-template-columns: repeat(3, calc(100% / 3));
grid-column-gap: 0;
}
.number {
font-size: 4.25vw;
}
.img-wrap {
height: 35vw;
}
.img-wrap--content {
height: 100%;
grid-area: 1 / 2 / 2 / 3;
}
.content {
top: 0;
position: absolute;
height: 100vh;
width: 100%;
}
.content__item {
height: 100vh;
display: grid;
align-items: center;
grid-template-columns: 30% 40% 30%;
grid-column-gap: 0;
}
.js .content__item {
height: 100%;
}
.js .content__item--current {
top: 0;
}
.img-wrap--content {
height: 100%;
}
.content__item-header {
justify-self: center;
grid-area: 1 / 1 / 2 / 3;
pointer-events: none;
}
.content__item-header-title {
font-size: 8vw;
}
.content__item-copy {
max-width: 240px;
justify-self: end;
text-align: right;
}
.grid__item--cursor.grid__item--left::after,
.grid__item--cursor.grid__item--right::after,
.img-wrap--content::after {
display: none;
}
.grid__item--cursor.grid__item--left {
cursor: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='61px' height='44px' viewBox='0 0 61 44' style='enable-background:new 0 0 61 44;' xml:space='preserve'%3E %3Cpath d='M.613 21.671L21.584.7l5.642 5.642-11.74 11.74H60.45v7.978H15.487l11.74 11.739-5.643 5.642L.613 22.469a.57.57 0 0 1 0-.798z'/%3E %3C/svg%3E") 30 22, sw-resize;
}
.grid__item--cursor.grid__item--center {
cursor: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='52px' height='52px' viewBox='0 0 52 52' style='enable-background:new 0 0 52 52;' xml:space='preserve'%3E %3Cpath d='M29.889 30.05l-.036 21.361c-.222.213-7.654.213-7.876 0l-.007-21.358-21.52.007v-7.978l21.518.036L21.96.571h7.978l-.037 21.56 21.388.037c.213.222.213 7.654 0 7.876l-21.401.007z'/%3E %3C/svg%3E") 26 26, crosshair;
}
.grid__item--cursor.grid__item--right {
cursor: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='61px' height='44px' viewBox='0 0 61 44' style='enable-background:new 0 0 61 44;' xml:space='preserve'%3E %3Cpath d='M60.287 21.671L39.316.7l-5.642 5.642 11.74 11.74H.45v7.978h44.963l-11.74 11.739 5.643 5.642 20.971-20.972a.57.57 0 0 0 0-.798z'/%3E %3C/svg%3E") 30 22, ne-resize;
}
.dark-mode .grid__item--cursor.grid__item--left {
cursor: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='61px' height='44px' viewBox='0 0 61 44' style='enable-background:new 0 0 61 44;' xml:space='preserve'%3E %3Cpath fill='%23bb3a3a' d='M.613 21.671L21.584.7l5.642 5.642-11.74 11.74H60.45v7.978H15.487l11.74 11.739-5.643 5.642L.613 22.469a.57.57 0 0 1 0-.798z'/%3E %3C/svg%3E") 30 22, sw-resize;
}
.dark-mode .grid__item--cursor.grid__item--center {
cursor: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='52px' height='52px' viewBox='0 0 52 52' style='enable-background:new 0 0 52 52;' xml:space='preserve'%3E %3Cpath fill='%23bb3a3a' d='M29.889 30.05l-.036 21.361c-.222.213-7.654.213-7.876 0l-.007-21.358-21.52.007v-7.978l21.518.036L21.96.571h7.978l-.037 21.56 21.388.037c.213.222.213 7.654 0 7.876l-21.401.007z'/%3E %3C/svg%3E") 26 26, crosshair;
}
.dark-mode .grid__item--cursor.grid__item--right {
cursor: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='61px' height='44px' viewBox='0 0 61 44' style='enable-background:new 0 0 61 44;' xml:space='preserve'%3E %3Cpath fill='%23bb3a3a' d='M60.287 21.671L39.316.7l-5.642 5.642 11.74 11.74H.45v7.978h44.963l-11.74 11.739 5.643 5.642 20.971-20.972a.57.57 0 0 0 0-.798z'/%3E %3C/svg%3E") 30 22, ne-resize;
}
.img-wrap--content {
cursor: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='52px' height='52px' viewBox='0 0 52 52' style='enable-background:new 0 0 52 52;' xml:space='preserve'%3E %3Cpath d='M20.921 26.67L5.791 41.75C5.485 41.743.23 36.488.224 36.18L15.32 21.073.098 5.86 5.74.22l15.19 15.24L36.161.22l5.64 5.64-15.27 15.22 15.097 15.15c-.006.307-5.262 5.562-5.569 5.568L20.921 26.67z'/%3E %3C/svg%3E") 21 21, pointer;
}
.dark-mode .img-wrap--content {
cursor: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='52px' height='52px' viewBox='0 0 52 52' style='enable-background:new 0 0 52 52;' xml:space='preserve'%3E %3Cpath fill='%23bb3a3a' d='M20.921 26.67L5.791 41.75C5.485 41.743.23 36.488.224 36.18L15.32 21.073.098 5.86 5.74.22l15.19 15.24L36.161.22l5.64 5.64-15.27 15.22 15.097 15.15c-.006.307-5.262 5.562-5.569 5.568L20.921 26.67z'/%3E %3C/svg%3E") 21 21, pointer;
}
}
Javascript (.js file) SOURCE_CODE:-
{
const MathUtils = {
lineEq: (y2, y1, x2, x1, currentVal) => {
// y = mx + b
var m = (y2 - y1) / (x2 - x1), b = y1 - m * x1;
return m * currentVal + b;
},
lerp: (a, b, n) => (1 - n) * a + n * b,
distance: (x1, x2, y1, y2) => {
var a = x1 - x2;
var b = y1 - y2;
return Math.hypot(a,b);
},
randomNumber: (min,max) => Math.floor(Math.random()*(max-min+1)+min)
};
let winsize;
const calcWinsize = () => winsize = {width: window.innerWidth, height: window.innerHeight};
calcWinsize();
window.addEventListener('resize', calcWinsize);
const getMousePos = (ev) => {
let posx = 0;
let posy = 0;
if (!ev) ev = window.event;
if (ev.pageX || ev.pageY) {
posx = ev.pageX;
posy = ev.pageY;
}
else if (ev.clientX || ev.clientY) {
posx = ev.clientX + body.scrollLeft + docEl.scrollLeft;
posy = ev.clientY + body.scrollTop + docEl.scrollTop;
}
return {x: posx, y: posy};
}
let mousePos = {x: winsize.width/2, y: winsize.height/2};
window.addEventListener('mousemove', ev => mousePos = getMousePos(ev));
class Slide {
constructor(el, title) {
this.DOM = {el: el};
this.DOM.title = title;
charming(this.DOM.title);
this.DOM.titleLetters = [...this.DOM.title.querySelectorAll('span')];
this.DOM.titleLetters.sort(() => Math.round(Math.random())-0.5);
this.DOM.number = this.DOM.el.querySelector('.number');
this.DOM.subtitle = this.DOM.el.querySelector('.caption');
this.DOM.imgWrap = this.DOM.el.querySelector('.img-wrap');
this.DOM.img = this.DOM.imgWrap.querySelector('.img');
}
move(direction, val) {
return new Promise((resolve, reject) => {
const tx = direction === 'left' ? '+=' + val*-1 : '+=' + val;
const duration = 1.2;
new TimelineMax({onComplete: resolve})
.to(this.DOM.imgWrap, duration, {
x: tx,
ease: Quart.easeInOut
}, 0)
.to(this.DOM.imgWrap, duration*.5, {
scaleX: 1.3,
ease: Quart.easeIn
}, 0)
.to(this.DOM.imgWrap, duration*.5, {
scaleX: 1,
ease: Quart.easeOut
}, duration*.5)
.to(this.DOM.number, duration*.95, {
x: tx,
ease: Quint.easeInOut
}, 0)
.to(this.DOM.subtitle, duration*1.1, {
x: tx,
ease: Quart.easeInOut
}, 0)
.to(this.DOM.title, duration*1.05, {
x: tx,
ease: Quart.easeInOut
}, 0);
});
}
setCenter() {
this.isCenter = true;
this.DOM.el.classList.add('grid__item--center');
this.DOM.title.classList.add('grid__item--center');
TweenMax.set([this.DOM.el, this.DOM.title], {opacity: 1});
}
setRight() {
this.isRight = this.isCenter = false;
this.isLeft = true;
this.DOM.el.classList.add('grid__item--right');
this.DOM.title.classList.add('grid__item--right');
TweenMax.set([this.DOM.el, this.DOM.title], {opacity: 1});
}
setLeft() {
this.isLeft = this.isCenter = false;
this.isRight = true;
this.DOM.el.classList.add('grid__item--left');
this.DOM.title.classList.add('grid__item--left');
TweenMax.set([this.DOM.el, this.DOM.title], {opacity: 1});
}
reset() {
TweenMax.set([this.DOM.el, this.DOM.imgWrap, this.DOM.number, this.DOM.subtitle, this.DOM.title], {transform: 'none'});
TweenMax.set([this.DOM.el, this.DOM.title], {opacity: 0});
this.DOM.title.classList = 'grid__item grid__item--title';
this.DOM.el.classList = 'grid__item grid__item--slide';
}
animateElementsOut(contentItem) {
return new Promise((resolve, reject) => {
const time = MathUtils.randomNumber(0,100)/500;
this.elemsTimeline = new TimelineMax({onComplete: resolve})
.staggerTo(this.DOM.titleLetters, 1, {
y: MathUtils.randomNumber(300,600),
opacity: 0,
ease: Quart.easeInOut
}, 0.04, time)
.staggerTo(this.DOM.titleLetters, 0.5, {
scaleY: 2.2,
ease: Quart.easeIn
}, 0.04, time)
.staggerTo(this.DOM.titleLetters, 0.5, {
scaleY: 1,
ease: Quart.easeOut
}, 0.04, time + 0.5)
.to(this.DOM.number, 1, {
y: -500,
opacity: 0,
ease: Quart.easeInOut
}, time+0.3)
.to(this.DOM.imgWrap, 0.8, {
y: -500,
opacity: 0,
ease: Quart.easeInOut
}, time+0.4)
.to(this.DOM.imgWrap, .4, {
scaleX: 0.95,
scaleY: 1.4,
ease: Quart.easeIn
}, time+0.4)
.to(this.DOM.imgWrap, .4, {
scaleX: 1,
scaleY: 1,
ease: Quart.easeOut
}, time+0.4 + 0.4)
.to(this.DOM.subtitle, 1, {
y: -500,
opacity: 0,
ease: Quart.easeInOut
}, time+0.5);
if ( this.isCenter ) {
const contentItemTitle = contentItem.querySelector('.content__item-header-title');
const contentItemImg = contentItem.querySelector('.img--content');
this.elemsTimeline.to(contentItemTitle, 0.8, {
ease: Expo.easeOut,
startAt: {y: '100%', opacity: 0, rotation: -16},
y: '0%',
rotation: 0,
opacity: 1
}, time+1.3)
.set(contentItemImg, {scale: 1.2}, 0)
.to(contentItemImg, 0.8, {
ease: Expo.easeOut,
scale: 1
}, time+1.3)
.to(revealer.DOM.el, 1, {
ease: Quint.easeOut,
y: '-100%'
}, time+1.2);
}
});
}
animateElementsIn(contentItem) {
return new Promise((resolve, reject) => {
const time = MathUtils.randomNumber(0,50)/500;
this.elemsTimeline = new TimelineMax({onComplete: resolve});
if ( this.isCenter ) {
const contentItemTitle = contentItem.querySelector('.content__item-header-title');
const contentItemImg = contentItem.querySelector('.img--content');
this.elemsTimeline.to(contentItemTitle, 1, {
ease: Quint.easeOut,
y: '50%',
opacity: 0
}, 0)
.to(contentItemImg, 1, {
ease: Quint.easeOut,
scale: 1.2
}, 0)
.to(revealer.DOM.el, 1, {
ease: Quint.easeOut,
y: '0%'
}, 0);
}
this.elemsTimeline.to(this.DOM.subtitle, 0.8, {
y: 0,
opacity: 1,
ease: Quart.easeOut
}, time)
.to(this.DOM.imgWrap, 0.8, {
y: 0,
opacity: 1,
scaleX: 1,
scaleY: 1,
ease: Quart.easeOut
}, time+0.1)
.to(this.DOM.number, 0.8, {
y: 0,
opacity: 1,
ease: Quart.easeOut
}, time+0.2)
.staggerTo(this.DOM.titleLetters, 0.8, {
y: 0,
opacity: 1,
scaleX: 1,
scaleY: 1,
ease: Quart.easeOut
}, 0.03, time+0.1)
});
}
}
class Slideshow {
constructor(el) {
this.DOM = {el: el};
// The titles
this.DOM.titlesWrap = this.DOM.el.querySelector('.titles-wrap');
this.DOM.titlesInner = this.DOM.titlesWrap.querySelector('.grid--titles');
this.DOM.titles = [...this.DOM.titlesInner.querySelectorAll('.grid__item--title')];
// The slides instances
this.slides = [];
[...this.DOM.el.querySelectorAll('.grid__item--slide')].forEach((slide, pos) => this.slides.push(new Slide(slide, this.DOM.titles[pos])));
// Total number of slides
this.slidesTotal = this.slides.length;
if ( this.slidesTotal < 4 ) return;
// Center slide's position
this.center = 0;
// Content Items
this.DOM.contentItems = [...document.querySelectorAll('.content__item')];
// Areas (left, center, right) where to attach the navigation events.
this.DOM.interaction = {
left: document.querySelector('.grid__item--left'),
center: document.querySelector('.grid__item--center'),
right: document.querySelector('.grid__item--right')
};
this.setVisibleSlides();
this.calculateGap();
this.initEvents();
let mouseMoveVals = {translation: 0, rotation: -8};
const render = () => {
//if ( !this.isAnimating ) {
mouseMoveVals.translation = MathUtils.lerp(mouseMoveVals.translation, MathUtils.lineEq(-15, 15, winsize.width, 0, mousePos.x), 0.03);
//mouseMoveVals.rotation = MathUtils.lerp(mouseMoveVals.rotation, MathUtils.lineEq(-8.5, -7.5, winsize.width, 0, mousePos.x), 0.03);
for (let i = 0; i <= this.slidesTotal - 1; ++i) {
TweenMax.set(this.slides[i].DOM.img, {x: mouseMoveVals.translation});
TweenMax.set(this.DOM.titlesInner, {x: -4*mouseMoveVals.translation});
//TweenMax.set(this.DOM.el, {rotation: mouseMoveVals.rotation});
//TweenMax.set(this.DOM.titlesWrap, {rotation: -2*mouseMoveVals.rotation});
}
//}
requestAnimationFrame(render);
}
requestAnimationFrame(render);
}
setVisibleSlides() {
this.centerSlide = this.slides[this.center];
this.rightSlide = this.slides[this.center+1 <= this.slidesTotal-1 ? this.center+1 : 0];
this.leftSlide = this.slides[this.center-1 >= 0 ? this.center-1 : this.slidesTotal-1];
this.centerSlide.setCenter();
this.rightSlide.setRight();
this.leftSlide.setLeft();
}
// Distance between 2 slides
// The amount to translate the elements that move when we navigate the slideshow
calculateGap() {
const s1 = this.slides[0].DOM.el.getBoundingClientRect();
const s2 = this.slides[1].DOM.el.getBoundingClientRect();
this.gap = MathUtils.distance(s1.left + s1.width/2, s2.left + s2.width/2, s1.top + s1.height/2, s2.top + s2.height/2);
}
// Initialize events
initEvents() {
this.clickRightFn = () => this.navigate('right');
this.DOM.interaction.right.addEventListener('click', this.clickRightFn);
this.clickLeftFn = () => this.navigate('left');
this.DOM.interaction.left.addEventListener('click', this.clickLeftFn);
this.clickCenterFn = () => this.openSlide();
this.DOM.interaction.center.addEventListener('click', this.clickCenterFn);
this.mouseenterCenterFn = () => {
if ( this.isAnimating ) {
return;
}
new TimelineMax()
.to(this.centerSlide.DOM.imgWrap, 0.7, {
ease: Expo.easeOut,
scale: 1.02
})
.to(this.centerSlide.DOM.img, 1.7, {
ease: Expo.easeOut,
scale: 1.05
}, 0);
};
this.DOM.interaction.center.addEventListener('mouseenter', this.mouseenterCenterFn);
this.mouseleaveCenterFn = () => {
if ( this.isAnimating ) {
return;
}
new TimelineMax().to(this.centerSlide.DOM.imgWrap, 0.7, {
ease: Expo.easeOut,
scale: 1
})
.to(this.centerSlide.DOM.img, 0.7, {
ease: Expo.easeOut,
scale: 1
}, 0);
};
this.DOM.interaction.center.addEventListener('mouseleave', this.mouseleaveCenterFn);
this.resizeFn = () => this.calculateGap();
window.addEventListener('resize', this.resizeFn);
this.DOM.contentItems.forEach(item => {
item.querySelector('.img-wrap--content').addEventListener('click', () => this.closeSlide());
});
}
navigate(direction) {
if ( this.isAnimating ) {
return false;
}
this.isAnimating = true;
const upcomingPos = direction === 'right' ?
this.center < this.slidesTotal-2 ? this.center+2 : Math.abs(this.slidesTotal-2-this.center):
this.center >= 2 ? this.center-2 : Math.abs(this.slidesTotal-2+this.center);
// Update current.
this.center = direction === 'right' ?
this.center < this.slidesTotal-1 ? this.center+1 : 0 :
this.center > 0 ? this.center-1 : this.slidesTotal-1;
this.upcomingSlide = this.slides[upcomingPos];
this.upcomingTitle = this.upcomingSlide.DOM.title;
// Position upcomingSlide / upcomingTitle
TweenMax.set(this.upcomingSlide.DOM.el, {x: direction === 'right' ? this.gap*2 : -1*this.gap*2, opacity: 1});
TweenMax.set(this.upcomingTitle, {x: direction === 'right' ? this.gap*2 : -1*this.gap*2, opacity: 1});
const movingSlides = [this.upcomingSlide, this.centerSlide, this.rightSlide, this.leftSlide];
let promises = [];
movingSlides.forEach(slide => promises.push(slide.move(direction === 'right' ? 'left' : 'right', this.gap)));
Promise.all(promises).then(() => {
// After all is moved, update the classes of the 3 visible slides and reset styles
movingSlides.forEach(slide => slide.reset());
// Set it again
this.setVisibleSlides();
this.isAnimating = false;
});
}
openSlide() {
this.toggleSlide('open');
}
closeSlide() {
this.toggleSlide('close');
}
toggleSlide(action) {
if ( this.isAnimating ) {
return;
}
this.isAnimating = true;
const contentItem = this.DOM.contentItems[this.center];
// Cursor styles related class
this.DOM.el.classList[action === 'open' ? 'add' : 'remove']('content-open');
const movingSlides = [this.centerSlide, this.rightSlide, this.leftSlide];
let promises = [];
movingSlides.forEach(slide => promises.push(slide[action === 'open' ? 'animateElementsOut' : 'animateElementsIn'](contentItem)));
if ( action === 'open' ) {
contentItem.classList.add('content__item--current');
}
Promise.all(promises).then(() => {
if ( action === 'close' ) {
contentItem.classList.remove('content__item--current');
}
this.isAnimating = false;
});
}
}
class Revealer {
constructor(el) {
this.DOM = {el: el};
this.DOM.el.style.width = `calc(100vw * ${Math.cos(8 * Math.PI/180)} + 100vh * ${Math.sin(8 * Math.PI/180)})`;
this.DOM.el.style.height = `calc(100vw * ${Math.sin(8 * Math.PI/180)} + 100vh * ${Math.cos(8 * Math.PI/180)})`;
}
}
// Revealer element
const revealer = new Revealer(document.querySelector('.revealer__inner'));
// Initialize the slideshow
new Slideshow(document.querySelector('.grid--slideshow'));
// Preload all the images in the page
imagesLoaded(document.querySelectorAll('.img'), {background: true}, () => document.body.classList.remove('loading'));
[...document.querySelectorAll('.frame__mode input[type="radio"]')].forEach(radio => radio.addEventListener('click', () => {
document.body.classList[radio.parentNode.classList.contains('frame__mode-item--dark') ? 'add' : 'remove']('dark-mode');
}));
}
web design video My YOUTUBE channel
Comments
Post a Comment