An SVG navigation icon animated with GSAP
Created
February 28, 2018 03:32
-
-
Save anonymous/dff16416a87db4c824c3aa992f41bc3f to your computer and use it in GitHub Desktop.
SVG animated hamburger menu
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="container"> | |
<a class="navButton" href="#"> | |
<div> | |
<svg xmlns="http://www.w3.org/2000/svg" width="50" height="40" viewBox="0 0 50 40"> | |
<line class="topLine" fill="none" stroke="#FFF" stroke-width="4" stroke-linecap="round" stroke-miterlimit="10" x1="8" y1="16" x2="34" y2="16"/> | |
<line class="midLine" fill="none" stroke="#FFF" stroke-width="4" stroke-linecap="round" stroke-miterlimit="10" x1="8" y1="25" x2="34" y2="25"/> | |
<line class="botLine" fill="none" stroke="#FFF" stroke-width="4" stroke-linecap="round" stroke-miterlimit="10" x1="8" y1="34" x2="34" y2="34"/> | |
<polyline class="roof" fill="none" stroke="#FFF" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="5,11 21,2 37,11"/> | |
<line class="arrowBody" fill="none" stroke="#FFF" stroke-width="4" stroke-linecap="round" stroke-miterlimit="10" x1="8" y1="25" x2="48" y2="25"/> | |
<polyline class="arrowPoint" fill="none" stroke="#FFF" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="42,32 48,25 42,19"/> | |
</svg> | |
</div> | |
</a> | |
<div class="panel"> | |
<div></div> | |
<div></div> | |
<div></div> | |
</div> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var | |
navButton = $('.navButton'), | |
panel = $('.panel'), | |
topLine = $('.topLine'), | |
midLine = $('.midLine'), | |
botLine = $('.botLine'), | |
roof = $('.roof'), | |
arrowBody = $('.arrowBody'), | |
arrowPoint = $('.arrowPoint'), | |
hoverTL, homeTL, slideTween, | |
state = "closed" | |
; | |
var arrowValues = {x1: 42, y1: 25, x2: 48, y2: 25, x3: 42, y3: 25}; | |
var roofValues = {x1: 5, y1: 11, x2: 21, y2: 2, x3: 37, y3: 11}; | |
var valuesString, roofValuesString; | |
TweenMax.set([roof, arrowBody, arrowPoint], {autoAlpha: 0}); | |
TweenMax.set(navButton, {x: 315, y: 10}); | |
TweenMax.set(panel, {x: 375}); | |
//TweenMax.set(arrowPoint, {drawSVG: "50% 50%"}); | |
hoverTL = new TimelineMax({paused: true, repeat: 0}); | |
hoverTL | |
//.set(arrowPoint, {autoAlpha: 0, drawSVG: "50% 50%"}) | |
.set(arrowPoint, {autoAlpha: 0, attr: {points: "42,25 48,25 42,25"}}) | |
.to(midLine, .2, {attr: {x2: 48}, ease: Circ.easeInOut}) | |
.to([topLine,botLine], .2, {attr: {x2: 29}, ease: Circ.easeInOut}, "-=.25") | |
.set(arrowPoint, {autoAlpha: 1}) | |
//.to(arrowPoint, .25, {drawSVG: "0 100%", ease: Circ.easeOut}, "-=.25") | |
.to(arrowValues, .2, {y1: 32, y3: 18, ease: Circ.easeOut, onUpdate: function(e) { | |
valuesString = arrowValues.x1 + "," + arrowValues.y1 + " " + arrowValues.x2 + "," + arrowValues.y2 + " " + arrowValues.x3 + "," + arrowValues.y3; | |
//console.log("valuesString: " + valuesString); | |
TweenMax.set(arrowPoint, {attr: {points: valuesString}}); | |
}}) | |
; | |
//hoverTL.play(); | |
homeTL = new TimelineMax({paused: true, repeat: 0}); | |
homeTL | |
.set([topLine,midLine], {y: 0, attr: {x2: 34}}) | |
.set(roof, {attr: {points: "5,11 21,2 37,11"}}) | |
.set(roof, {autoAlpha: 1, drawSVG: "50% 50%"}) | |
.to(roof, .25, {drawSVG: "0 100%", ease: Circ.easeInOut}) | |
.to(topLine, .25, {rotation: 90, transformOrigin: "top left", attr: {x2: 23}}, "-=.25") | |
.to(midLine, .25, {rotation: -90, transformOrigin: "top right", y: -19, attr: {x2: 23}}, "-=.25") | |
; | |
navButton.on("mouseover", function(e) { | |
hoverTL.play(); | |
}); | |
navButton.on("mouseout", function(e) { | |
hoverTL.reverse(); | |
}); | |
navButton.on("click", function(e) { | |
if(state === "open") { | |
//slideTL.reverse(); | |
navButton.mouseout(); | |
navButton.off("mouseover"); | |
navButton.off("mouseout"); | |
navButton.on("mouseover", function(e) { | |
hoverTL.play(); | |
}); | |
navButton.on("mouseout", function(e) { | |
hoverTL.reverse(); | |
}); | |
homeTL.reverse(); | |
slideTween = TweenMax.to(panel, .5, {x: 375, ease: Power3.easeOut}); | |
TweenMax.to(navButton, .5, {x: 315, ease: Power3.easeOut}); | |
state = "closed"; | |
} else if(state === "closed") { | |
//slideTL.play(); | |
navButton.mouseout(); | |
navButton.off("mouseover"); | |
navButton.off("mouseout"); | |
TweenMax.delayedCall(.5, function(e) { | |
homeTL.play(); | |
}); | |
/*navButton.on("mouseover", function(e) { | |
TweenMax.to(roofValues, .25, {x1: 1, y1: 13, x3: 41, y3: 13, ease: Power2.easeInOut, onUpdate: function(e) { | |
roofValuesString = roofValues.x1 + "," + roofValues.y1 + " " + roofValues.x2 + "," + roofValues.y2 + " " + roofValues.x3 + "," + roofValues.y3; | |
//console.log("valuesString: " + valuesString); | |
TweenMax.set(roof, {attr: {points: roofValuesString}}); | |
}}); | |
TweenMax.to(roof, .25, {y: 3, ease: Power2.easeInOut}); | |
TweenMax.to(topLine, .25, {y: 5, attr: {x2: 18}, ease: Power2.easeInOut}); | |
TweenMax.to(midLine, .25, {attr: {x2: 18}, ease: Power2.easeInOut}); | |
}); | |
navButton.on("mouseout", function(e) { | |
TweenMax.to(roofValues, .25, {x1: 5, y1: 11, x3: 37, y3: 11, ease: Power2.easeInOut, onUpdate: function(e) { | |
roofValuesString = roofValues.x1 + "," + roofValues.y1 + " " + roofValues.x2 + "," + roofValues.y2 + " " + roofValues.x3 + "," + roofValues.y3; | |
//console.log("valuesString: " + valuesString); | |
TweenMax.set(roof, {attr: {points: roofValuesString}}); | |
}}); | |
TweenMax.to(roof, .25, {y: 0, ease: Power2.easeInOut}); | |
TweenMax.to(topLine, .25, {y: 0, attr: {x2: 23}, ease: Power2.easeInOut}); | |
TweenMax.to(midLine, .25, {attr: {x2: 23}, ease: Power2.easeInOut}); | |
});*/ | |
slideTween = TweenMax.to(panel, .5, {x: 50, ease: Power3.easeOut}); | |
TweenMax.to(navButton, .5, {x: 75, ease: Power3.easeOut}); | |
hoverTL.reverse(); | |
state = "open"; | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.2/TweenMax.min.js"></script> | |
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/DrawSVGPlugin.js?r=6"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@import "bourbon"; | |
$fire: #c1272d; | |
body {background-color: $fire;} | |
.container { | |
width: 375px; height: 300px; box-sizing: border-box; overflow: hidden; | |
background-color: darken($fire, 6%); | |
position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%); | |
.navButton { | |
width: 50px; height: 40px; display: block; position: relative; z-index: 1; | |
div { | |
padding-bottom: 80%; position: relative; | |
svg { | |
position: absolute; top: 0; left: 0; width: 100%; height: 100%; | |
} | |
} | |
} | |
.panel { | |
padding: 125px 50px 50px; | |
width: 325px; height: inherit; box-sizing: border-box; | |
position: absolute; top: 0; left: 0; z-index: 0; | |
background-color: darken($fire, 12%); | |
div { | |
width: auto; height: 10px; background-color: lighten($fire, 10%); | |
margin: 0 0 50px; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment