2 368 Codepen

Переходы с помощью анимации на GSAP

Плавные reveal эффекты реализованные на GSAP

HTML

<header class="header">
    <!-- image -->
    <figure>
        <img class="emily" src="http://deghq.com/yapp/front-labs/codepen-assets/emily.jpg" alt="">
    </figure>

    <!-- image mask -->
    <i class="mask mask-left"></i>
    <i class="mask mask-right"></i>
    <i class="mask mask-top"></i>
    <i class="mask mask-bottom"></i>

    <!-- trigger -->
    <span class="trigger" data-toggle="closed">
    </span>

    <!-- content -->
    <div class="outer-wrapper">
        <div class="outer">
            <div class="inner">
                <div class="container">
                    <div class="row">
                        <div class="col-1">&nbsp;</div>
                        <div class="col-10 text-row">
                            <span id="type" class="title uppercase">Type</span>
                            <i class="line line-long">
                                <span></span>
                            </i>
                        </div>
                        <div class="col-1">&nbsp;</div>
                    </div>
                    <div class="row">
                        <div class="col-1">&nbsp;</div>
                        <div class="col-10 text-row">
                            <span id="georgia" class="subtitle">Georgia</span>
                            <i class="line line-short">
                                <span></span>
                            </i>
                            <span id="festival" class="title">festival</span>
                        </div>
                        <div class="col-1">&nbsp;</div>
                    </div>
                    <div class="row">
                        <div class="col-1">&nbsp;</div>
                        <div class="col-10 text-row">
                            <span id="year" class="title">2015</span>
                            <i class="line line-long">
                                <span></span>
                            </i>
                            <span id="size" class="subtitle">Size 78</span>
                        </div>
                        <div class="col-1">&nbsp;</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</header>

SCSS

//FONTS
$arial: Arial, serif, sans-serif;
$georgia: Georgia, "Times New Roman", serif;

//MIXINS
// ADDS A BROWSER PREFIX TO THE PROPERTY
@mixin css3-prefix($property, $value) {
    -webkit-#{$property}: #{$value};
    -khtml-#{$property}: #{$value};
    -moz-#{$property}: #{$value};
    -ms-#{$property}: #{$value};
    -o-#{$property}: #{$value};
    #{$property}: #{$value};
}
// TRANSFORM
@mixin transform($params) {
    @include css3-prefix('transform', $params);
}
//CSS FILTERS
@mixin filter($filter-type,$filter-amount) {
    -webkit-filter: $filter-type+unquote('(#{$filter-amount})');
    -moz-filter: $filter-type+unquote('(#{$filter-amount})');
    -ms-filter: $filter-type+unquote('(#{$filter-amount})');
    -o-filter: $filter-type+unquote('(#{$filter-amount})');
    filter: $filter-type+unquote('(#{$filter-amount})');
}
// TRANSITION
@mixin transition($what: all, $length: 1s, $easing: ease-in-out) {
    @include css3-prefix('transition', $what $length $easing);
}

$typekit-fonts:    "", "";  // index [1, 2]
$typekit-fallbacks:  $georgia, $arial;

@mixin font($weight: 400, $style: normal, $font: 1) {
    $font-weight: $weight;
    $font-style:  $style;

    // Translate Weight
    @if ($weight == 100) or ($weight == thin) or ($weight == ultralight) {
        $weight: 1;
    }
    @if ($weight == 200) or ($weight == extralight) {
        $weight: 2;
    }
    @if ($weight == 300) or ($weight == light) {
        $weight: 3;
    }
    @if ($weight == 400) or ($weight == normal) or ($weight == regular) {
        $weight: 4;
    }
    @if ($weight == 500) or ($weight == medium) {
        $weight: 5;
    }
    @if ($weight == 600) or ($weight == semibold) or ($weight == demi) {
        $weight: 6;
    }
    @if ($weight == 700) or ($weight == bold) {
        $weight: 7;
    }
    @if ($weight == 800) or ($weight == extrabold) {
        $weight: 8;
    }
    @if ($weight == 900) or ($weight == black) or ($weight == heavy) {
        $weight: 9;
    }

    // Translate Style
    @if $style == normal {
        $style: n;
    }
    @else if $style == italic {
        $style: i;
    }

    // Assemble $font-family
    $primary-font:   nth($typekit-fonts, $font) + "-" + $style + $weight;
    $secondary-font: nth($typekit-fonts, $font);
    $fallback-fonts: nth($typekit-fallbacks, $font);
    $font-family:    quote($primary-font), quote($secondary-font), $fallback-fonts;

    font-family: $font-family;
    font-style:  $font-style;
    font-weight: $font-weight;
}

@mixin font-size($psd-font-size, $psd-line-height) {
    font-size: $psd-font-size;
    line-height: ($psd-line-height)/$psd-font-size;
}

//VARIABLES
//Black
$black-100:     rgba(0,0,0,1);
$black-90:         rgba(0,0,0,0.9);
$black-80:         rgba(0,0,0,0.8);
$black-70:         rgba(0,0,0,0.7);
$black-60:         rgba(0,0,0,0.6);
$black-50:         rgba(0,0,0,0.5);
$black-40:         rgba(0,0,0,0.4);
$black-30:         rgba(0,0,0,0.3);
$black-20:         rgba(0,0,0,0.2);
$black-10:         rgba(0,0,0,0.1);

//White
$white-100:     rgba(255,255,255,1);
$white-90:         rgba(255,255,255,0.9);
$white-80:         rgba(255,255,255,0.8);
$white-70:         rgba(255,255,255,0.7);
$white-60:         rgba(255,255,255,0.6);
$white-50:         rgba(255,255,255,0.5);
$white-40:         rgba(255,255,255,0.4);
$white-30:         rgba(255,255,255,0.3);
$white-20:         rgba(255,255,255,0.2);
$white-10:         rgba(255,255,255,0.1);

//Invisible
$transparent:     rgba(255,255,255,0);

$yellow: #fbdb45;

//ANIMATIONS stuff
$hover: all, 0.2s, ease-in;
$slide: all, 0.3s,  cubic-bezier(.55,0,.1,1);
$slide-slow: all, 0.5s,  cubic-bezier(.55,0,.1,1);
$zoom: all, 1s,  cubic-bezier(.55,0,.1,1);
$zoom-slow: all, 2.4s,  cubic-bezier(.55,0,.1,1);

//GRID
$max-width:        970px; // set page max-width
$column-width:     8.3333%;    // set column width
$gutter-width:     0%;     // set gutter width
$maximum-columns:  12;       // set max number of columns

@mixin clearfix {
    zoom: 1;

    &:before, &:after {
        content: "";
        display: table;
    }

    &:after {
        clear: both;
    }
}

@mixin border-box {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}

@function columns($columns, $container-columns: $maximum-columns) {
    $width: $columns * $column-width;
    $container-width: $container-columns * $column-width;
    @return percentage($width / $container-width);
}

@function gutter($container-columns: $maximum-columns, $gutter: $gutter-width) {
    $container-width: $container-columns * $column-width + ($container-columns - 1) * $gutter-width;
    @return percentage($gutter / $container-width);
}

@function newgutter($columns, $container-columns: $maximum-columns) {
    $width: $columns * $column-width;
    $container-width: $container-columns * $column-width;
    @return percentage($width / $container-width / 2);
}


@function calcPercentage($a) {
    @return percentage($a);
}


@mixin nesting {
    padding: 0; // no padding so nested elements fit

    & > div { // affect only immediate children
        float: left;
        margin-right: gutter;
        @include border-box; // math is hard. let’s use border-box
    }
}

@mixin row {
    width: 100%; // make sure to fill its container
    max-width: $max-width; // but no more than our max width
    margin: 0 auto;
    @include clearfix; // clear our floats
    @include nesting; // add nesting styles to rows
}

@function offset-columns($columns) {
    $margin:
    $columns * $column-width + $columns * $gutter-width;
    @return $margin;
}

@mixin offset($columns, $from-direction: left) {
    @if $from-direction == left {
        float: left;
        margin-left: offset-columns($columns);
    }
    @if $from-direction == right {
        float: right;
        margin-right: offset-columns($columns);
    }
}

@mixin last {
    margin-right: 0;
    float: right;
}

/*****************************************************/
.container {
    margin-left: auto;
    margin-right: auto;
    width: $max-width;
    @include border-box;
}

.row {
    @include row();
}

$i: 1;
@while $i < ($maximum-columns + 1) {
    .col-#{$i} {
        width: columns($i);
        padding-left: gutter();
        padding-right: gutter();
    }
    $i: $i + 1;
}

//STYLE
.header {
    position: relative;
    height: 100%;
    width: 100%;
    overflow: hidden;

    figure {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: 1;

        img {
            position: absolute;
            top: 0;
            left: 50%;
            height: auto;
            width: 110%;
            @include transform(translateX(-50%));
        }
    }
}

.blur-emily {
    @include filter(blur, 12px);
}

.mask {
    position: absolute;
    display: block;
    background-color: lighten($black-100, 10%);
    z-index: 2;

    &.mask-top {
        top: 0;
        left: 0;
        width: 100%;
        height: 7%;
    }
    &.mask-bottom {
        bottom: 0;
        left: 0;
        width: 100%;
        height: 7%;
    }
    &.mask-left {
        left: 0;
        top: 0;
        height: 100%;
        width: 0;
    }
    &.mask-right {
        right: 0;
        top: 0;
        height: 100%;
        width: 0;
    }
}

.blur-mask {
    position: absolute;
    display: block;
    background-color: lighten($black-100, 10%);
    z-index: 2;

    &.mask-top {
        top: 0;
        left: 0;
        width: 100%;
        height: 5%;
    }
    &.mask-bottom {
        bottom: 0;
        left: 0;
        width: 100%;
        height: 5%;
    }
    &.mask-left {
        left: 0;
        top: 0;
        height: 100%;
        width: 50%;
    }
    &.mask-right {
        right: 0;
        top: 0;
        height: 100%;
        width: 50%;
    }
}

.trigger {
    position: absolute;
    top: 10%;
    right: 5%;
    display: block;
    width: 35px;
    height: 35px;
    border: 1px solid $white-100;
    z-index: 4;
    cursor: pointer;

    &:before {
        position: absolute;
        content: "";
        top: 0;
        right: 0;
        display: block;
        width: 100%;
        height: 100%;
        @include transform(scale(0.5));
        background-color: $yellow;
        @include transition($slide);
    }

    &:hover {
        &:before {
            @include transform(scale(0.45));
        }
    }
}

.text-row {
    padding: 15px 0;
    text-align: left;
    margin: 0 auto !important;
}

.title {
    display: inline-block;
    vertical-align: middle;
    font-family: $georgia;
    font-size: 78px;
    line-height: 1em;
    color: $white-100;
    opacity: 0;
    letter-spacing: 0.1em;

    &.uppercase {
        text-transform: uppercase;
    }
}

.subtitle {
    display: inline-block;
    vertical-align: middle;
    font-family: $georgia;
    font-size: 23px;
    line-height: 1em;
    color: $white-100;
    opacity: 0;
}

.line {
    display: inline-block;
    vertical-align: middle;
    width: 100%;
    max-width: 160px;
    margin: 0 60px 0 30px;

    span {
        height: 6px;
        display: block;
        width: 0;
        background-color: $yellow;
    }

    &.line-short {
        max-width: 40px;
    }
}

//GENERAL STUFF
html {
    height: 100% !important;
    width: 100%;
}

body {
    height: 100%;
    width: 100%;
    @include font(300, normal, 2);
    @include font-size(13px, 30px);
    color: $white-100;
    position: relative;
}

.main-wrapper {
    height: 100%;
    width: 100%;
    position: relative;
}
/*TABLE POSITIONING STUFF*/
.outer-wrapper {
    position: absolute;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;

}

.outer {
    display: table;
    height: 100% !important;
    left: 0;
    min-height: 100%;
    position: absolute;
    right: 0;
    table-layout: fixed;
    top: 0;
    width: 100%;
    z-index: 2;

    .inner {
        display: table-cell;
        text-align: center;
        vertical-align: middle;
        width: 100%;
        position: relative;
    }
}

JS

Для работы потребуется jQuery и TweenMax
//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js
//cdnjs.cloudflare.com/ajax/libs/gsap/1.18.0/TweenMax.min.js
Сам скрипт
/**
 * DAnimation object is used to animate ease with bezier functions
 * example: TweenMax.to($('selector'), 1.5, {left:"80%", ease: DAnimation.bezier(0.04,0.86,0.8,1)});
 *
 * Used: https://github.com/rdallasgray/bez
 */
var DAnimation = ({
        start: 0,
        bezier: function(p0, p1, p2, p3){
            return DAnimation.polyBez([p0, p1], [p2, p3]);

        },
        polyBez: function(p1, p2) {
            var A = [null, null], B = [null, null], C = [null, null],
                bezCoOrd = function(t, ax) {
                    C[ax] = 3 * p1[ax], B[ax] = 3 * (p2[ax] - p1[ax]) - C[ax], A[ax] = 1 - C[ax] - B[ax];
                    return t * (C[ax] + t * (B[ax] + t * A[ax]));
                },
                xDeriv = function(t) {
                    return C[0] + t * (2 * B[0] + 3 * A[0] * t);
                },
                xForT = function(t) {
                    var x = t, i = 0, z;
                    while (++i < 14) {
                        z = bezCoOrd(x, 0) - t;
                        if (Math.abs(z) < 1e-3) break;
                        x -= z / xDeriv(x);
                    }
                    return x;
                };
            return function(t) {
                return bezCoOrd(xForT(t), 1);
            }
        }
    });


//CUSTOM JS CODE
(function ($) {
    'use strict';

    //VIEWPORT
    var w = $( window );
    
    //ANIMATION
    var animationTrigger = $('.trigger');

    var maskTop = $('.mask-top');
    var maskBottom = $('.mask-bottom');
    var maskLeft = $('.mask-left');
    var maskRight = $('.mask-right');

    var emily = $('.emily');

    var lineLong = $('.line-long').find(' span ');
    var lineShort = $('.line-short').find(' span ');

    var type = $('#type');
    var georgia = $('#georgia');
    var festival = $('#festival');
    var year = $('#year');
    var size = $('#size');

    var main = {

        init: function () {
            var self = this;
            //GSAP ANIMATE
            main.animate();
        },

        //GSAP ANIMATION
        animate: function (){
          
            //OPEN
            function openAnimation() {
                TweenMax.to(maskTop, 1.4,
                    {
                        height: "10%", ease: DAnimation.bezier(0.930, 0.035, 0.350, 0.815)
                    }
                );
                TweenMax.to(maskBottom, 1.4,
                    {
                        height: "10%", ease: DAnimation.bezier(0.930, 0.035, 0.350, 0.815)
                    }
                );
                TweenMax.to(maskLeft, 1.4,
                    {
                        width: "40%", ease: DAnimation.bezier(0.930, 0.035, 0.350, 0.815)
                    }
                );
                TweenMax.to(maskRight, 1.2,
                    {
                        //width: "20%", ease: Expo.easeInOut
                        width: "20%", ease: DAnimation.bezier(0.930, 0.035, 0.350, 0.815)
                    }
                );
                TweenMax.to(emily, 1.8,
                    {
                        scale: 1.1, top: "-5%", left: "55%", ease:  DAnimation.bezier(0.930, 0.035, 0.350, 0.815)
                    }
                );
                TweenMax.to(lineLong, 1,
                    {
                        width: "100%", delay: 0.4, ease: DAnimation.bezier(0.930, 0.035, 0.350, 0.815)
                    }
                );
                TweenMax.to(lineShort, 1,
                    {
                        width: "100%", delay: 1, ease: Power3.easeOut
                    }
                );
                TweenMax.fromTo(type, 1.8,
                    {
                        x: -200, opacity: 0
                    },

                    {
                        x: 0, opacity: 1, delay: 0.8, ease: Power3.easeOut
                    }
                );
                TweenMax.fromTo(year, 1.8,
                    {
                        x: -200, opacity: 0
                    },

                    {
                        x: 0, opacity: 1, delay: 0.8, ease: Power3.easeOut
                    }
                );
                TweenMax.fromTo(georgia, 2,
                    {
                        x: -200, opacity: 0
                    },

                    {
                        x: 0, opacity: 1, delay: 1, ease: Power3.easeOut
                    }
                );
                TweenMax.fromTo(festival, 1.8,
                    {
                        x: 200, opacity: 0
                    },

                    {
                        x: 0, opacity: 1, delay: 0.8, ease: Power3.easeOut
                    }
                );
                TweenMax.fromTo(size, 2,
                    {
                        x: 200, opacity: 0
                    },

                    {
                        x: 0, opacity: 1, delay: 1, ease: Power3.easeOut
                    }
                );
            }
            
            //CLOSE
            function closeAnimation() {
                TweenMax.to(maskTop, 1,
                    {
                        height: "7%", ease: DAnimation.bezier(0.930, 0.035, 0.350, 0.815)
                    }
                );
                TweenMax.to(maskBottom, 1,
                    {
                        height: "7%", ease: DAnimation.bezier(0.930, 0.035, 0.350, 0.815)
                    }
                );
                TweenMax.to(maskLeft, 1,
                    {
                        width: 0, ease: DAnimation.bezier(0.930, 0.035, 0.350, 0.815)
                    }
                );
                TweenMax.to(maskRight, 1,
                    {
                        width: 0, ease: DAnimation.bezier(0.930, 0.035, 0.350, 0.815)
                    }
                );
                TweenMax.to(emily, 1.8,
                    {
                        scale: 1, top: 0, left: "50%", delay: 0., ease: Expo.easeOut
                    }
                );
                TweenMax.to(lineLong, 0.8,
                    {
                        width: 0, delay: 0.4, ease: DAnimation.bezier(0.930, 0.035, 0.350, 0.815)
                    }
                );
                TweenMax.to(lineShort, 0.8,
                    {
                        width: 0, delay: 0.4, ease: DAnimation.bezier(0.930, 0.035, 0.350, 0.815)
                    }
                );
                TweenMax.fromTo(type, 1,
                    {
                        x: 0, opacity: 1
                    },

                    {
                        x: -200, opacity: 0, ease: Power3.easeIn
                    }
                );
                TweenMax.fromTo(year, 1,
                    {
                        x: 0, opacity: 1
                    },

                    {
                        x: -200, opacity: 0, ease: Power3.easeIn
                    }
                );
                TweenMax.fromTo(georgia, 0.6,
                    {
                        x: 0, opacity: 1
                    },

                    {
                        x: -200, opacity: 0, ease: Power3.easeIn
                    }
                );
                TweenMax.fromTo(festival, 1,
                    {
                        x: 0, opacity: 1
                    },

                    {
                        x: 200, opacity: 0, ease: Power3.easeIn
                    }
                );
                TweenMax.fromTo(size, 0.6,
                    {
                        x: 0, opacity: 1
                    },

                    {
                        x: 200, opacity: 0, ease: Power3.easeIn
                    }
                );
            }

            animationTrigger.click(function(){
                if($(this).attr('data-toggle') == 'closed') {
                    $(this).attr('data-toggle', 'opened');
                    openAnimation();
                }
                else if($(this).attr('data-toggle', 'opened')) {
                    $(this).attr('data-toggle', 'closed');
                    closeAnimation();
                }
            });
        }
    };

    $(window).resize(function () {
    });
    return main.init();
}($));

Комментарии

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

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