8 822 Скрипты / Slider

Слайдер с анимацией css свойства clip-path

Концепт слайдера с анимацией css свойства clip-path. При наведении на изображение проявляется текст, а картинка обрезается.


HTML

<header class="header">
    <div class="header__logo">
        Tiffany Lusteg
    </div>

    <nav class="header__nav">
        <ul>
            <li>About</li>
            <li>Portfolio</li>
            <li>Contact</li>
            <li>
                <div class="header__burger">
                    <svg xmlns="http://www.w3.org/2000/svg" width="75.75" height="50.469" viewBox="0 0 75.75 50.469">
                        <path fill="#fff" data-name="Rectangle 7 copy 2" class="cls-1" d="M5615.26,681.145h75.73v7.213h-75.73v-7.213Zm0,21.638h75.73V710h-75.73v-7.212Zm0,21.638h75.73v7.212h-75.73v-7.212Z" transform="translate(-5615.25 -681.156)" />
                    </svg>
                </div>
            </li>
        </ul>

    </nav>
</header>

<main>
    <div class="slider">
        <div class="slider__side">
            <div class="slider__slide">
                <div class="slider__slide__content">
                    <div class="slider__slide__more">View More</div>
                    <div class="slider__slide__more">View More</div>
                    <div class="slider__slide__scene">
                        <span>s</span><span>c</span><span>e</span><span>n</span><span>e</span>
                    </div>
                </div>
                
                <img class="slider__slide__img" src="https://images.squarespace-cdn.com/content/v1/55e20901e4b04dab6ca7f0db/1563913615815-YO0KIDJQH4H3XSYMHZJI/ke17ZwdGBToddI8pDm48kK60W-ob1oA2Fm-j4E_9NQB7gQa3H78H3Y0txjaiv_0fDoOvxcdMmMKkDsyUqMSsMWxHk725yiiHCCLfrh8O1z4YTzHvnKhyp6Da-NYroOW3ZGjoBKy3azqku80C789l0kD6Ec8Uq9YczfrzwR7e2Mh5VMMOxnTbph8FXiclivDQnof69TlCeE0rAhj6HUpXkw/IMG_8995.JPG?format=2500w">
                
                <div class="slider__slide__number">
                    <span>4</span>
                    <span>3</span>
                </div>
            </div>
            
        
            <div class="slider__slide active">
                <div class="slider__slide__content">
                    <div class="slider__slide__more">View More</div>
                    <div class="slider__slide__more">View More</div>
                    <div class="slider__slide__scene">
                        <span>s</span><span>c</span><span>e</span><span>n</span><span>e</span>
                    </div>
                </div>
                
                <img class="slider__slide__img" src="https://images.squarespace-cdn.com/content/v1/55e20901e4b04dab6ca7f0db/1563309352183-NQPAC2JL7ROEGLDFYGBT/ke17ZwdGBToddI8pDm48kK60W-ob1oA2Fm-j4E_9NQB7gQa3H78H3Y0txjaiv_0fDoOvxcdMmMKkDsyUqMSsMWxHk725yiiHCCLfrh8O1z4YTzHvnKhyp6Da-NYroOW3ZGjoBKy3azqku80C789l0kD6Ec8Uq9YczfrzwR7e2Mh5VMMOxnTbph8FXiclivDQnof69TlCeE0rAhj6HUpXkw/D5A08949-0A59-469B-9097-CF9FE07F4BD4.JPG?format=750w">
                
                <div class="slider__slide__number">
                    <span>4</span>
                    <span>2</span>
                </div>
            </div>
            
            <div class="slider__slide">
                <div class="slider__slide__content">
                    <div class="slider__slide__more">View More</div>
                    <div class="slider__slide__more">View More</div>
                    <div class="slider__slide__scene">
                        <span>s</span><span>c</span><span>e</span><span>n</span><span>e</span>
                    </div>
                </div>
                
                <img class="slider__slide__img" src="https://images.squarespace-cdn.com/content/v1/55e20901e4b04dab6ca7f0db/1569367820673-D81JZRBQISM7SKGX1JZU/ke17ZwdGBToddI8pDm48kGDhYzKEs-g3IW1vEZk4IP57gQa3H78H3Y0txjaiv_0fDoOvxcdMmMKkDsyUqMSsMWxHk725yiiHCCLfrh8O1z4YTzHvnKhyp6Da-NYroOW3ZGjoBKy3azqku80C789l0lqfkVpRp1g_2L-WsTQRP4KxYMVT_2jf6Ixn4lDglP4s9BJebir6FMbnuZFo76Jo4Q/IMG_1398.JPG?format=2500w">
                
                <div class="slider__slide__number">
                    <span>6</span>
                    <span>7</span>
                </div>
            </div>
        </div>

        <div class="slider__side">
            <div class="slider__slide">
                <div class="slider__slide__content">
                    <div class="slider__slide__more">View More</div>
                    <div class="slider__slide__more">View More</div>
                    <div class="slider__slide__scene">
                        <span>s</span><span>c</span><span>e</span><span>n</span><span>e</span>
                    </div>
                </div>
                
                <img class="slider__slide__img" src="https://images.squarespace-cdn.com/content/v1/55e20901e4b04dab6ca7f0db/1569367842312-32029SEL3OGG7QSHWCG4/ke17ZwdGBToddI8pDm48kK60W-ob1oA2Fm-j4E_9NQB7gQa3H78H3Y0txjaiv_0fDoOvxcdMmMKkDsyUqMSsMWxHk725yiiHCCLfrh8O1z4YTzHvnKhyp6Da-NYroOW3ZGjoBKy3azqku80C789l0kD6Ec8Uq9YczfrzwR7e2Mh5VMMOxnTbph8FXiclivDQnof69TlCeE0rAhj6HUpXkw/IMG_1553.JPG?format=2500w">
                
                <div class="slider__slide__number">
                    <span>3</span>
                    <span>8</span>
                </div>
            </div>

            <div class="slider__slide active">
                <div class="slider__slide__content">
                    <div class="slider__slide__more">View More</div>
                    <div class="slider__slide__more">View More</div>
                    <div class="slider__slide__scene">
                        <span>s</span><span>c</span><span>e</span><span>n</span><span>e</span>
                    </div>
                </div>
                
                <img class="slider__slide__img" src="https://images.squarespace-cdn.com/content/v1/55e20901e4b04dab6ca7f0db/1569367726056-Q2G2BDYHESNX3WEML8EV/ke17ZwdGBToddI8pDm48kCf3-plT4th5YDY7kKLGSZN7gQa3H78H3Y0txjaiv_0fDoOvxcdMmMKkDsyUqMSsMWxHk725yiiHCCLfrh8O1z4YTzHvnKhyp6Da-NYroOW3ZGjoBKy3azqku80C789l0h8vX1l9k24HMAg-S2AFienIXE1YmmWqgE2PN2vVFAwNPldIHIfeNh3oAGoMooVv2g/ACS_0312.JPG?format=2500w">
                
                <div class="slider__slide__number">
                    <span>0</span>
                    <span>8</span>
                </div>
            </div>
            
            <div class="slider__slide">
                <div class="slider__slide__content">
                    <div class="slider__slide__more">View More</div>
                    <div class="slider__slide__more">View More</div>
                    <div class="slider__slide__scene">
                        <span>s</span><span>c</span><span>e</span><span>n</span><span>e</span>
                    </div>
                </div>
                
                <img class="slider__slide__img" src="https://images.squarespace-cdn.com/content/v1/55e20901e4b04dab6ca7f0db/1563309355280-LQE5JCH9MYYQB5EWG3ON/ke17ZwdGBToddI8pDm48kK60W-ob1oA2Fm-j4E_9NQB7gQa3H78H3Y0txjaiv_0fDoOvxcdMmMKkDsyUqMSsMWxHk725yiiHCCLfrh8O1z4YTzHvnKhyp6Da-NYroOW3ZGjoBKy3azqku80C789l0kD6Ec8Uq9YczfrzwR7e2Mh5VMMOxnTbph8FXiclivDQnof69TlCeE0rAhj6HUpXkw/DA2DDECD-F46B-4518-9B54-9DB186486344+2.JPG?format=2500w">
                
                <div class="slider__slide__number">
                    <span>3</span>
                    <span>8</span>
                </div>
            </div>
        </div>
    </div>


    <div class="controls">
        <span class="controls__icon js-down"><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
     viewBox="0 0 23.6 13.5" style="enable-background:new 0 0 23.6 13.5;" xml:space="preserve">
<polygon fill="#fff" class="st0" points="23.6,11.8 11.8,0 10.1,1.7 10.1,1.7 0,11.8 1.7,13.5 11.8,3.4 21.9,13.5 "/>
</svg></span>
        <span class="controls__icon js-up"><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
     viewBox="0 0 23.6 13.5" style="enable-background:new 0 0 23.6 13.5;" xml:space="preserve">
<polygon fill="#fff" class="st0" points="23.6,11.8 11.8,0 10.1,1.7 10.1,1.7 0,11.8 1.7,13.5 11.8,3.4 21.9,13.5 "/>
</svg></span>
    </div>
    
    <div class="modal">
        <div class="modal__content">
            <div>
                <h2>What is this?</h2>
                <p>This pen is a desktop-only concept piece for Tiffany Lusteg.<p>
                <p>It was designed by <a href="https://twitter.com/tomandthatsit">@TomAndThatsIt</a> and coded by <a href="https://twitter.com/jakewhiteleydev">@jakewhiteleydev</a>.</p>

                <p>If you like the images, please checkout <a href="http://tiffanylusteg.com/" target="_blank" rel="noopener">Tiffany's website</a> to see more of her <u>awesome</u> work.</p>
                
                <p>If you like the pen, why not have a look at <a href="https://www.craftedbygc.com/">craftedbygc.com</a> to see what else we do.
            </div>
            
            <p><small>All assets in this pen are 100% copyright their respective owners. We just really like them so made this - hope you don't mind!</small></p>
        </div>
    </div>
    
    <button type="button" class="modal-trigger js-trigger">info</button>
</main>

SCSS

$sceneOffsets: (
    1: -300%,
    2: -150%,
    3: 0,
    4: 150%,
    5: 300%
);

@font-face {
    font-family: 'Cosi';
    src: url('https://assets.codepen.io/3453673/CosiTimes-Roman.woff') format('woff');
    font-weight: normal;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Cosi';
    src: url('https://assets.codepen.io/3453673/CosiTimes-Light.woff') format('woff');
    font-weight: 200;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Matter';
    src: url('https://assets.codepen.io/3453673/MatterSQTRIAL-Light.woff') format('woff');
    font-weight: normal;
    font-style: normal;
    font-display: swap;
}


body {
    font-family: Cosi, serif;
    font-size: 16px;
    text-rendering: optimizeLegibility;
    
    * {
        box-sizing: border-box;
    }
}

.header {
    display: flex;
    justify-content: space-between;
    position: fixed;
    width: 100%;
    top: 0;
    z-index: 10;
    text-transform: uppercase;
    
    &__logo {
        font-size: 1.1rem;
        padding: 1.3rem 2.5rem;
        background: #fff;
    }
    
    &__nav {
        list-style: none;
        margin: 0;
        font-family: Matter, sans-serif;
        font-size: .725rem;
        
        ul {
            display: flex;
            align-items: center;
            
            li {
                list-style: none;
                padding-right: 1rem;
            }
        }
    }
    
    &__burger {
        background-image: url('dаta:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="273.25" height="193.5" viewBox="0 0 273.25 193.5"><path d="M5627.77,610.482s-113.65-5.008-87.41,126.78,211.62,27.561,211.62,27.561S5943.89,648.034,5627.77,610.482Z" transform="translate(-5536.44 -610.438)"/></svg>');
        background-size: 100%;
        width: 3.1rem;
        height: 2.2rem;
        background-repeat: no-repeat;
        
        svg {
            width: 1rem; 
            height: auto;
            margin: .8rem 0 0 .8rem;
        }
    }
}

.slider {
    display: flex;
    height: 100vh;
    
    &__side {
        width: 50%;
        height: 100%;
        overflow: hidden;
        position: relative;
    }
    
    &__slide {
        position: absolute;
        overflow: hidden;
        height: 100%;
        width: 101%;
        visibility: hidden;
        
        &:nth-child(2n) {
            visibility: visible;
        }
        
        &.active {
            z-index: 2;
        }
        
        &__img {
            height: 100%;
            width: calc(100% + 1px);
            vertical-align: middle;
            object-fit: cover;
            position: absolute;
            clip-path: inset(0%);
            top: 0;
            left: 0;
        }
        
        &__content {
            width: 100%;
            height: 100%;
            padding: 5rem 4rem;
            position: relative;
        }
        
        &__more {
            backface-visibility: hidden;
            transform: rotate(-90deg);
            transform-origin: 0 100%;
            position: absolute;
            top: 50%;
            left: 10%;
            text-transform: uppercase;
            
            & + & {
                transform: rotate(90deg);
                transform-origin: 100% 100%;
                right: 10%;
                left: auto;
            }
        }
        
        &__number {
            font-weight: 200;
            position: absolute;
            bottom: 10%;
            right: 18%;
            font-size: 5rem;
            opacity: 0;
            transform: translateY(5rem);
            display: flex;
            
            @media(min-width: 1200px) {
                font-size: 9rem;
            }
            
            span {
                display: block;
                transform: rotateY(90deg);
                
                & + & {
                    transform: rotateY(-90deg);
                }
            }
        }
        
        &__scene {
            font-weight: 200;
            font-size: 4rem;
            margin-top: 4%;
            text-transform: uppercase;
            display: flex;
            justify-content: center;
            position: relative;
            z-index: 10;
            
            @media(min-width: 1200px) {
                font-size: 6rem;
            }
            
            span {
                opacity: 0;
                
                @for $i from 1 through 5 {
                    &:nth-child(#{$i}) {
                        transform: translate(map-get($sceneOffsets, $i), -3rem);
                    }
                }
            }
        }
    }
}

.controls {
    position: fixed;
    bottom: -7.5rem;
    left: 50%;
    z-index: 20;
    background: #000;
    height: 10rem;
    width: 10rem;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    
    &__icon {
        display: inline-block;
        color: #fff;
        width: 30%;
        margin-top: -6.9rem;
        text-align: center;
        cursor: pointer;
        
        svg {
            height: 1.25rem;
            width: 1.25rem;
        }
        
        &+& {
            transform: rotate(180deg);
            margin-top: -7.1rem;
        }
    }
}


.modal {
    opacity: 0;
    z-index: 100;
    position: absolute;
    top: 0;
    right: 0;
    height: 100%;
    width: 100%;
    backdrop-filter: blur(2px);
    transition: opacity .3s ease-in-out;
    background: rgba(0,0,0,0.1);
    pointer-events: none;
    
    &.active {
        opacity: 1;
        pointer-events: auto;
    }
    
    &__content {
        background: #fff;
        position: absolute;
        height: 60vh;
        width: 50vw;
        max-width: 600px;
        overflow-y: auto;
        top: 20vh;
        left: 50%;
        transform: translateX(-50%);
        padding: 2rem;
        font-family: 'Matter';
        line-height: 1.5;
        display: flex;
        flex-direction: column;
        justify-content: space-between;
        
        h2 {
            font-family: cosi;
        }
        
        a {
            color: #000;
        }
    }
    
    
    &-trigger {
        position: absolute;
        z-index: 100;
        bottom: 0;
        right: 0;
        background: #000;
        background-size: 100%;
        color: #fff;
        text-transform: uppercase;
        padding: .5rem 1rem;
        cursor: pointer;
        border: none;
        border-radius: none;
    }
}
так же используются шрифты:
@import url("https://p.typekit.net/p.css?s=1&k=waw8uxn&ht=tk&f=45416.45417.45420.45421&a=368074&app=typekit&e=css");

@font-face {
font-family:"ivypresto-headline";
src:url("https://use.typekit.net/af/78e26f/00000000000000003b9b474b/27/l?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=i4&v=3") format("woff2"),url("https://use.typekit.net/af/78e26f/00000000000000003b9b474b/27/d?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=i4&v=3") format("woff"),url("https://use.typekit.net/af/78e26f/00000000000000003b9b474b/27/a?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=i4&v=3") format("opentype");
font-display:auto;font-style:italic;font-weight:400;
}

@font-face {
font-family:"ivypresto-headline";
src:url("https://use.typekit.net/af/dd1fde/00000000000000003b9b474c/27/l?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3") format("woff2"),url("https://use.typekit.net/af/dd1fde/00000000000000003b9b474c/27/d?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3") format("woff"),url("https://use.typekit.net/af/dd1fde/00000000000000003b9b474c/27/a?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n4&v=3") format("opentype");
font-display:auto;font-style:normal;font-weight:400;
}

@font-face {
font-family:"ivypresto-headline";
src:url("https://use.typekit.net/af/b59b2a/00000000000000003b9b474f/27/l?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n7&v=3") format("woff2"),url("https://use.typekit.net/af/b59b2a/00000000000000003b9b474f/27/d?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n7&v=3") format("woff"),url("https://use.typekit.net/af/b59b2a/00000000000000003b9b474f/27/a?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n7&v=3") format("opentype");
font-display:auto;font-style:normal;font-weight:700;
}

@font-face {
font-family:"ivypresto-headline";
src:url("https://use.typekit.net/af/5b5c92/00000000000000003b9b4750/27/l?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=i7&v=3") format("woff2"),url("https://use.typekit.net/af/5b5c92/00000000000000003b9b4750/27/d?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=i7&v=3") format("woff"),url("https://use.typekit.net/af/5b5c92/00000000000000003b9b4750/27/a?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=i7&v=3") format("opentype");
font-display:auto;font-style:italic;font-weight:700;
}

.tk-ivypresto-headline { font-family: "ivypresto-headline",serif; }

JS

рекомендуется пропустить js код через транскомпилятор Babel
E = new window.E;

window.onload = () => {
    const modal = document.querySelector('.modal')
    const navTl = gsap.timeline({ defaults: {duration: 1}})
    
    let slides = [...document.querySelectorAll('.slider__slide')]
    let slideTl = []
    
    // add all slide timelines
    for (let i = 0; i < slides.length; i++) {
        const slide = slides[i]
        const viewMore = slide.querySelectorAll('.slider__slide__more')
        const scene = slide.querySelectorAll('.slider__slide__scene span')
        const img = slide.querySelector('.slider__slide__img')
        const number = slide.querySelector('.slider__slide__number')
        const numbers = number.querySelectorAll('span')
        const tl = gsap.timeline({paused: true, defaults: {duration: 1.1, ease: "power2.inOut"}})
        
        tl
            .to(img, {
                clipPath: 'inset(18%)',
                scale: 0.95
            }, 0)
            .to(viewMore[0], { x: '2rem', }, 0) 
            .to(viewMore[1], { x: '-2rem', },  0) 
            .to(number, { y: '0rem', duration: 1 }, 0.3)
            .to(number, { opacity: 1 }, 0.4)
            .to(numbers, { rotateY: 0, duration: 1.6 }, 0)
            .to(scene, {
                x: '0%',
                y: 0,
                opacity: 1,
                duration: 1.2
            }, 0.2)
        
        slideTl.push(tl)
    }
    
    // hover interaction
    E.on('mouseenter mouseleave', '.slider__slide', (e) => {
        const slide = e.target
                
        const tl = slideTl[slides.indexOf(slide)]
        
        if (e.type === 'mouseenter') {
            tl.play()
        } else {
            tl.reverse()
        }
    })
    
    // Next button
    E.on('click', '.js-up, .js-down', e => {
        const sides = document.querySelectorAll('.slider__side')
        
        if (navTl.isActive() === false) {
            navTl.clear()
            
            sides.forEach((side, k) => {
                const slides = side.querySelectorAll('.slider__slide')
                let activeSlide, nextSlide, initialClip;

                if (e.target.classList.contains('js-up')) {
                    initialClip = k === 0 ? 'inset(100% 0 0%)' : 'inset(0 0 100%)'
                } else {
                    initialClip = k === 1 ? 'inset(100% 0 0%)' : 'inset(0 0 100%)'
                }

                for (let i = 0; i < slides.length; i++) {
                    if (slides[i].classList.contains('active')) {
                        activeSlide = slides[i]
                        nextSlide = slides[i+1] || slides[0]
                        break
                    }
                }

                activeSlide.classList.remove('active')
                nextSlide.classList.add('active')

                gsap.set(nextSlide, {
                    autoAlpha: 1,
                    scale: 1.2,
                    clipPath: initialClip
                })

                navTl.to(nextSlide, {
                    clipPath: 'inset(0% 0 0%)',
                    scale: 1,
                    ease: 'power2.inOut',
                    duration: 1,
                    onComplete: () => {
                        gsap.set(activeSlide, {autoAlpha: 0})
                    }
                }, 0)
            })
        }
    })
    
    // Modal
    E.on('click', '.js-trigger', (e) => modal.classList.add('active'))
    E.on('click', '.modal', (e) => modal.classList.remove('active'))

};
Дополнительно подключена библиотека удобного управления событиями:
https://cdn.jsdelivr.net/npm/@unseenco/e@1.7.0/dist/e.js
и библиотека GSAP для анимаций:
https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js

Комментарии

  • Facebook
  • Вконтакте

Похожие статьи