2017-07-31 134 views
1

我想用這個例子上Tympanus.net發現創建一個很酷的動畫菜單:動畫全屏SVG覆蓋

https://tympanus.net/Development/FullscreenOverlayStyles/index9.html

對我的生活中,我無法弄清楚如何動畫路徑從左上角向右下角開放,我可以看到路徑和路徑,但我不瞭解座標。我創建了一個codepen,看看我是否可以得到它 工作,但我完全卡住了。

/*! 
 
* classie - class helper functions 
 
* from bonzo https://github.com/ded/bonzo 
 
* 
 
* classie.has(elem, 'my-class') -> true/false 
 
* classie.add(elem, 'my-new-class') 
 
* classie.remove(elem, 'my-unwanted-class') 
 
* classie.toggle(elem, 'my-class') 
 
*/ 
 

 
/*jshint browser: true, strict: true, undef: true */ 
 
/*global define: false */ 
 

 
(function(window) { 
 
    'use strict'; 
 

 
    // class helper functions from bonzo https://github.com/ded/bonzo 
 
    function classReg(className) { 
 
    return new RegExp("(^|\\s+)" + className + "(\\s+|$)"); 
 
    } 
 

 
    // classList support for class management 
 
    // altho to be fair, the api sucks because it won't accept multiple classes at once 
 
    var hasClass, addClass, removeClass; 
 

 
    if ('classList' in document.documentElement) { 
 
    hasClass = function(elem, c) { 
 
     return elem.classList.contains(c); 
 
    }; 
 
    addClass = function(elem, c) { 
 
     elem.classList.add(c); 
 
    }; 
 
    removeClass = function(elem, c) { 
 
     elem.classList.remove(c); 
 
    }; 
 
    } else { 
 
    hasClass = function(elem, c) { 
 
     return classReg(c).test(elem.className); 
 
    }; 
 
    addClass = function(elem, c) { 
 
     if (!hasClass(elem, c)) { 
 
     elem.className = elem.className + ' ' + c; 
 
     } 
 
    }; 
 
    removeClass = function(elem, c) { 
 
     elem.className = elem.className.replace(classReg(c), ' '); 
 
    }; 
 
    } 
 

 
    function toggleClass(elem, c) { 
 
    var fn = hasClass(elem, c) ? removeClass : addClass; 
 
    fn(elem, c); 
 
    } 
 

 
    var classie = { 
 
    // full names 
 
    hasClass: hasClass, 
 
    addClass: addClass, 
 
    removeClass: removeClass, 
 
    toggleClass: toggleClass, 
 
    // short names 
 
    has: hasClass, 
 
    add: addClass, 
 
    remove: removeClass, 
 
    toggle: toggleClass 
 
    }; 
 

 
    // transport 
 
    if (typeof define === 'function' && define.amd) { 
 
    // AMD 
 
    define(classie); 
 
    } else { 
 
    // browser global 
 
    window.classie = classie; 
 
    } 
 

 
})(window); 
 
(function() { 
 
    var triggerBttn = document.getElementById('trigger-overlay'), 
 
    overlay = document.querySelector('div.overlay'), 
 
    closeBttn = overlay.querySelector('button.overlay-close'); 
 
    transEndEventNames = { 
 
     'WebkitTransition': 'webkitTransitionEnd', 
 
     'MozTransition': 'transitionend', 
 
     'OTransition': 'oTransitionEnd', 
 
     'msTransition': 'MSTransitionEnd', 
 
     'transition': 'transitionend' 
 
    }, 
 
    transEndEventName = transEndEventNames[Modernizr.prefixed('transition')], 
 
    support = { 
 
     transitions: Modernizr.csstransitions 
 
    }; 
 
    s = Snap(overlay.querySelector('svg')), 
 
    path = s.select('path'), 
 
    pathConfig = { 
 
     from: path.attr('d'), 
 
     to: overlay.getAttribute('data-path-to') 
 
    }; 
 

 
    function toggleOverlay() { 
 
    if (classie.has(overlay, 'open')) { 
 
     classie.remove(overlay, 'open'); 
 
     classie.add(overlay, 'close'); 
 

 
     var onEndTransitionFn = function(ev) { 
 
     classie.remove(overlay, 'close'); 
 
     }; 
 

 
     path.animate({ 
 
     'path': pathConfig.from 
 
     }, 400, mina.linear, onEndTransitionFn); 
 
    } else if (!classie.has(overlay, 'close')) { 
 
     classie.add(overlay, 'open'); 
 
     path.animate({ 
 
     'path': pathConfig.to 
 
     }, 400, mina.linear); 
 
    } 
 
    } 
 

 
    triggerBttn.addEventListener('click', toggleOverlay); 
 
    closeBttn.addEventListener('click', toggleOverlay); 
 
})();
.svgcontainer { 
 
    width: 600px; 
 
    height: 300px; 
 
    margin: 0 auto; 
 
    border: 1px solid red; 
 
} 
 

 

 
/* Overlay style */ 
 
.overlay { 
 
    position: fixed; 
 
    width: 100%; 
 
    height: 100%; 
 
    top: 0; 
 
    left: 0; 
 
    background: rgba(28, 105, 212, 0.95); 
 
} 
 

 
/* Overlay closing cross */ 
 
.overlay .overlay-close { 
 
    width: 80px; 
 
    height: 80px; 
 
    position: absolute; 
 
    right: 20px; 
 
    top: 20px; 
 
    overflow: hidden; 
 
    border: none; 
 
    font-size: 18px; 
 
    color: white; 
 
    outline: none; 
 
    z-index: 100; 
 
} 
 

 
/* Menu style */ 
 
.overlay nav { 
 
    text-align: center; 
 
    position: relative; 
 
    top: 50%; 
 
    height: 60%; 
 
    -webkit-transform: translateY(-50%); 
 
    transform: translateY(-50%); 
 
} 
 

 
.overlay ul { 
 
    list-style: none; 
 
    padding: 0; 
 
    margin: 0 auto; 
 
    display: inline-block; 
 
    height: 100%; 
 
    position: relative; 
 
} 
 

 
.overlay ul li { 
 
    display: block; 
 
    height: 20%; 
 
    height: calc(100%/5); 
 
    min-height: 54px; 
 
    -webkit-backface-visibility: hidden; 
 
    backface-visibility: hidden; 
 
} 
 

 
.overlay ul li a { 
 
    font-size: 54px; 
 
    font-weight: 300; 
 
    display: block; 
 
    color: #fff; 
 
    -webkit-transition: color 0.2s; 
 
    transition: color 0.2s; 
 
} 
 

 
.overlay ul li a:hover, 
 
.overlay ul li a:focus { 
 
    color: #f0f0f0; 
 
} 
 

 

 
/* Effects */ 
 
.overlay-cornershape { 
 
    background: transparent; 
 
    visibility: hidden; 
 
    -webkit-transition: visibility 0s 0.5s; 
 
    transition: visibility 0s 0.5s; 
 
} 
 

 
.overlay-cornershape.open { 
 
    visibility: visible; 
 
    -webkit-transition: none; 
 
    transition: none; 
 
} 
 

 
.overlay-cornershape svg { 
 
    position: absolute; 
 
    top: 0; 
 
    left: 0; 
 
} 
 

 
.overlay-cornershape .overlay-path { 
 
    fill: rgba(153, 204, 51, 0.9); 
 
    fill: rgba(28, 105, 212, 0.95); 
 
} 
 

 
.overlay-cornershape nav, 
 
.overlay-cornershape .overlay-close { 
 
    opacity: 0; 
 
    -webkit-transition: opacity 0.4s 0.4s; 
 
    transition: opacity 0.4s 0.4s; 
 
} 
 

 
.overlay-cornershape.open nav, 
 
.overlay-cornershape.open .overlay-close { 
 
    opacity: 1; 
 
    -webkit-transition-delay: 0.4s; 
 
    transition-delay: 0.4s; 
 
} 
 

 
.overlay-cornershape.close nav, 
 
.overlay-cornershape.close .overlay-close { 
 
    -webkit-transition-delay: 0s; 
 
    transition-delay: 0s; 
 
} 
 

 
@media screen and (max-height: 30.5em) { 
 
    .overlay nav { 
 
    height: 70%; 
 
    font-size: 34px; 
 
    } 
 
    .overlay ul li { 
 
    min-height: 34px; 
 
    } 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.5.1/snap.svg-min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js"></script> 
 

 
<div class="container"> 
 
    <button id="trigger-overlay" type="button">Open Overlay</button> 
 
</div> 
 
<!-- /container --> 
 
<!-- open/close --> 
 
<div class="overlay overlay-cornershape" data-path-to="m 0,0 1439.999975,0 0,805.99999 -1439.999975,0 z"> 
 
    <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 1440 806" preserveAspectRatio="none"> 
 
    <path class="overlay-path" d="m 0,0 1439.999975,0 0,805.99999 0,-805.99999 z" /> 
 
    </svg> 
 
    <button type="button" class="overlay-close">Close</button> 
 
    <nav> 
 
    <ul> 
 
     <li><a href="#">Home</a></li> 
 
     <li><a href="#">About</a></li> 
 
     <li><a href="#">Work</a></li> 
 
     <li><a href="#">Clients</a></li> 
 
     <li><a href="#">Contact</a></li> 
 
    </ul> 
 
    </nav> 
 
</div>

https://codepen.io/jenkinspg/pen/wqGMoV

請某人能幫助我嗎?

回答

3

你必須扭轉(水平翻轉)兩個路徑定義。可能不明顯的是他們使用的是小寫的m,所以每個座標對都是相對於最後一個座標對的。

因此,例如,在原來的啓動路徑是:

m 0,0 1440,0 0,806 0,-806 z 

這些點左上,右上,右下,右上(按順序)。它動畫爲:

m 0,0 1440,0 0,806 -1440,0 z 

或者:左上角,右上角,右下角,左下角。換句話說,最後一點從右上角移動到左下角。

要從左上到右下轉而我們必須顛倒該形狀中座標的順序。所以從:

m 1440,0 -1440,0 0,806 0,-806 z (TR, TL, BL, TL) 

到:

m 1440,0 -1440,0 0,806 1440,0 z (TR, TL, BL, BR) 

/*! 
 
* classie - class helper functions 
 
* from bonzo https://github.com/ded/bonzo 
 
* 
 
* classie.has(elem, 'my-class') -> true/false 
 
* classie.add(elem, 'my-new-class') 
 
* classie.remove(elem, 'my-unwanted-class') 
 
* classie.toggle(elem, 'my-class') 
 
*/ 
 

 
/*jshint browser: true, strict: true, undef: true */ 
 
/*global define: false */ 
 

 
(function(window) { 
 
    'use strict'; 
 

 
    // class helper functions from bonzo https://github.com/ded/bonzo 
 
    function classReg(className) { 
 
    return new RegExp("(^|\\s+)" + className + "(\\s+|$)"); 
 
    } 
 

 
    // classList support for class management 
 
    // altho to be fair, the api sucks because it won't accept multiple classes at once 
 
    var hasClass, addClass, removeClass; 
 

 
    if ('classList' in document.documentElement) { 
 
    hasClass = function(elem, c) { 
 
     return elem.classList.contains(c); 
 
    }; 
 
    addClass = function(elem, c) { 
 
     elem.classList.add(c); 
 
    }; 
 
    removeClass = function(elem, c) { 
 
     elem.classList.remove(c); 
 
    }; 
 
    } else { 
 
    hasClass = function(elem, c) { 
 
     return classReg(c).test(elem.className); 
 
    }; 
 
    addClass = function(elem, c) { 
 
     if (!hasClass(elem, c)) { 
 
     elem.className = elem.className + ' ' + c; 
 
     } 
 
    }; 
 
    removeClass = function(elem, c) { 
 
     elem.className = elem.className.replace(classReg(c), ' '); 
 
    }; 
 
    } 
 

 
    function toggleClass(elem, c) { 
 
    var fn = hasClass(elem, c) ? removeClass : addClass; 
 
    fn(elem, c); 
 
    } 
 

 
    var classie = { 
 
    // full names 
 
    hasClass: hasClass, 
 
    addClass: addClass, 
 
    removeClass: removeClass, 
 
    toggleClass: toggleClass, 
 
    // short names 
 
    has: hasClass, 
 
    add: addClass, 
 
    remove: removeClass, 
 
    toggle: toggleClass 
 
    }; 
 

 
    // transport 
 
    if (typeof define === 'function' && define.amd) { 
 
    // AMD 
 
    define(classie); 
 
    } else { 
 
    // browser global 
 
    window.classie = classie; 
 
    } 
 

 
})(window); 
 
(function() { 
 
    var triggerBttn = document.getElementById('trigger-overlay'), 
 
    overlay = document.querySelector('div.overlay'), 
 
    closeBttn = overlay.querySelector('button.overlay-close'); 
 
    transEndEventNames = { 
 
     'WebkitTransition': 'webkitTransitionEnd', 
 
     'MozTransition': 'transitionend', 
 
     'OTransition': 'oTransitionEnd', 
 
     'msTransition': 'MSTransitionEnd', 
 
     'transition': 'transitionend' 
 
    }, 
 
    transEndEventName = transEndEventNames[Modernizr.prefixed('transition')], 
 
    support = { 
 
     transitions: Modernizr.csstransitions 
 
    }; 
 
    s = Snap(overlay.querySelector('svg')), 
 
    path = s.select('path'), 
 
    pathConfig = { 
 
     from: path.attr('d'), 
 
     to: overlay.getAttribute('data-path-to') 
 
    }; 
 

 
    function toggleOverlay() { 
 
    if (classie.has(overlay, 'open')) { 
 
     classie.remove(overlay, 'open'); 
 
     classie.add(overlay, 'close'); 
 

 
     var onEndTransitionFn = function(ev) { 
 
     classie.remove(overlay, 'close'); 
 
     }; 
 

 
     path.animate({ 
 
     'path': pathConfig.from 
 
     }, 400, mina.linear, onEndTransitionFn); 
 
    } else if (!classie.has(overlay, 'close')) { 
 
     classie.add(overlay, 'open'); 
 
     path.animate({ 
 
     'path': pathConfig.to 
 
     }, 400, mina.linear); 
 
    } 
 
    } 
 

 
    triggerBttn.addEventListener('click', toggleOverlay); 
 
    closeBttn.addEventListener('click', toggleOverlay); 
 
})();
.svgcontainer { 
 
    width: 600px; 
 
    height: 300px; 
 
    margin: 0 auto; 
 
    border: 1px solid red; 
 
} 
 

 

 
/* Overlay style */ 
 
.overlay { 
 
    position: fixed; 
 
    width: 100%; 
 
    height: 100%; 
 
    top: 0; 
 
    left: 0; 
 
    background: rgba(28, 105, 212, 0.95); 
 
} 
 

 
/* Overlay closing cross */ 
 
.overlay .overlay-close { 
 
    width: 80px; 
 
    height: 80px; 
 
    position: absolute; 
 
    right: 20px; 
 
    top: 20px; 
 
    overflow: hidden; 
 
    border: none; 
 
    font-size: 18px; 
 
    color: white; 
 
    outline: none; 
 
    z-index: 100; 
 
} 
 

 
/* Menu style */ 
 
.overlay nav { 
 
    text-align: center; 
 
    position: relative; 
 
    top: 50%; 
 
    height: 60%; 
 
    -webkit-transform: translateY(-50%); 
 
    transform: translateY(-50%); 
 
} 
 

 
.overlay ul { 
 
    list-style: none; 
 
    padding: 0; 
 
    margin: 0 auto; 
 
    display: inline-block; 
 
    height: 100%; 
 
    position: relative; 
 
} 
 

 
.overlay ul li { 
 
    display: block; 
 
    height: 20%; 
 
    height: calc(100%/5); 
 
    min-height: 54px; 
 
    -webkit-backface-visibility: hidden; 
 
    backface-visibility: hidden; 
 
} 
 

 
.overlay ul li a { 
 
    font-size: 54px; 
 
    font-weight: 300; 
 
    display: block; 
 
    color: #fff; 
 
    -webkit-transition: color 0.2s; 
 
    transition: color 0.2s; 
 
} 
 

 
.overlay ul li a:hover, 
 
.overlay ul li a:focus { 
 
    color: #f0f0f0; 
 
} 
 

 

 
/* Effects */ 
 
.overlay-cornershape { 
 
    background: transparent; 
 
    visibility: hidden; 
 
    -webkit-transition: visibility 0s 0.5s; 
 
    transition: visibility 0s 0.5s; 
 
} 
 

 
.overlay-cornershape.open { 
 
    visibility: visible; 
 
    -webkit-transition: none; 
 
    transition: none; 
 
} 
 

 
.overlay-cornershape svg { 
 
    position: absolute; 
 
    top: 0; 
 
    left: 0; 
 
} 
 

 
.overlay-cornershape .overlay-path { 
 
    fill: rgba(153, 204, 51, 0.9); 
 
    fill: rgba(28, 105, 212, 0.95); 
 
} 
 

 
.overlay-cornershape nav, 
 
.overlay-cornershape .overlay-close { 
 
    opacity: 0; 
 
    -webkit-transition: opacity 0.4s 0.4s; 
 
    transition: opacity 0.4s 0.4s; 
 
} 
 

 
.overlay-cornershape.open nav, 
 
.overlay-cornershape.open .overlay-close { 
 
    opacity: 1; 
 
    -webkit-transition-delay: 0.4s; 
 
    transition-delay: 0.4s; 
 
} 
 

 
.overlay-cornershape.close nav, 
 
.overlay-cornershape.close .overlay-close { 
 
    -webkit-transition-delay: 0s; 
 
    transition-delay: 0s; 
 
} 
 

 
@media screen and (max-height: 30.5em) { 
 
    .overlay nav { 
 
    height: 70%; 
 
    font-size: 34px; 
 
    } 
 
    .overlay ul li { 
 
    min-height: 34px; 
 
    } 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.5.1/snap.svg-min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js"></script> 
 

 
<div class="container"> 
 
    <button id="trigger-overlay" type="button">Open Overlay</button> 
 
</div> 
 
<!-- /container --> 
 
<!-- open/close --> 
 
<div class="overlay overlay-cornershape" data-path-to="m 1440,0 -1440,0 0,806 1440,0 z"> 
 
    <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 1440 806" preserveAspectRatio="none"> 
 
    <path class="overlay-path" d="m 1440,0 -1440,0 0,806 0,-806 z" /> 
 
    </svg> 
 
    <button type="button" class="overlay-close">Close</button> 
 
    <nav> 
 
    <ul> 
 
     <li><a href="#">Home</a></li> 
 
     <li><a href="#">About</a></li> 
 
     <li><a href="#">Work</a></li> 
 
     <li><a href="#">Clients</a></li> 
 
     <li><a href="#">Contact</a></li> 
 
    </ul> 
 
    </nav> 
 
</div>

+0

哇,謝謝保羅,才使得這麼多的意義!謝謝 :) – user3327812