Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save l3dlp/d5d7cec06eb83aacb45ccbc056060442 to your computer and use it in GitHub Desktop.
Save l3dlp/d5d7cec06eb83aacb45ccbc056060442 to your computer and use it in GitHub Desktop.
A Better Material FAB Menu with SVG and GSAP

A Better Material FAB Menu with SVG and GSAP

I noticed loss of fidelity after completion of scale transforms in Safari on the iPad Mini. This MDL button element now contains an SVG circle and an SVG icon. The animation of the circle and menu is handled by TweenMax from GSAP.

A Pen by Daniel Kemper on CodePen.

License.

<body class="mdl-demo mdl-color--grey-100 mdl-color-text--grey-700 mdl-base">
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
<header class="mdl-layout__header mdl-layout__header--scroll mdl-color--primary">
<div class="mdl-layout--large-screen-only mdl-layout__header-row">
</div>
<div class="mdl-layout--large-screen-only mdl-layout__header-row">
<h3>SVG and GSAP</h3>
</div>
<div class="mdl-layout--large-screen-only mdl-layout__header-row">
</div>
<div class="mdl-layout__tab-bar mdl-js-ripple-effect mdl-color--primary-dark">
<a href="#better" class="mdl-layout__tab">Better</a>
<a class="mdl-layout__tab">Floating</a>
<a class="mdl-layout__tab">Action</a>
<a class="mdl-layout__tab">Menu</a>
<button class="mdl-button mdl-js-button mdl-button--fab mdl-js-ripple-effect mdl-button--fab-clear" id="add">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%">
<circle cx="50%" cy="50%" r="28" fill="rgb(255, 167, 38)"></circle>
</svg>
<i class="material-icons" role="presentation">whatshot</i>
<span class="visuallyhidden">Hot</span>
</button>
<div class="header__fab-menu">
<ul>
<li id="fab-close">
<i class="material-icons mdl-36" role="presentation">clear</i>
<a href="#">Close</a>
</li>
<li id="fab-group-work">
<i class="material-icons mdl-36" role="presentation">group_work</i>
<a href="https://github.com/dkemper01/d3-starter-kit" target="_blank">Share</a>
</li>
<li id="fab-group-work">
<i class="material-icons mdl-36" role="presentation">code</i>
<a href="http://tributary.io" target="_blank">Repo</a>
</li>
</ul>
</div>
</div>
</header>
<main class="mdl-layout__content">
<div class="mdl-layout__tab-panel" id="better"></div>
</main>
</div>
</body>
function showFabMenu() {
var $sender = $(this);
if ($sender.hasClass("back")) {
$sender.removeClass("back");
}
$sender.addClass("click-svg");
TweenMax.to("circle", 0.5, {
attr: {
r: 230,
fill: "rgb(239, 108, 0)"
},
ease: Bounce.easeOut
});
TweenMax.fromTo(
".header__fab-menu",
0.5,
{
skewX: 40
},
{
right: "7.0em",
skewX: 0,
skewType: "simple",
force3D: false,
opacity: "1.0",
ease: Power2.easeOut,
clearProps: "transform"
}
);
$(".mdl-button--fab > *:not(svg)").hide();
}
function hideFabMenu() {
$(".mdl-button--fab")
.removeClass("click-svg")
.addClass("back");
TweenMax.to(".header__fab-menu", 0.25, {
right: "-10.0em",
skewX: 40,
skewType: "simple",
force3D: false,
opacity: "0",
ease: Power2.easeOut
});
TweenMax.to("circle", 0.5, {
attr: {
r: 28,
fill: "rgb(255, 167, 38)"
},
ease: Bounce.easeOut
});
$(".mdl-button--fab > *:not(svg)").show();
}
function registerEvents() {
$(".mdl-button--fab").click(showFabMenu);
$("#fab-close").click(hideFabMenu);
}
window.onload = function() {
registerEvents();
};
<script src="https://storage.googleapis.com/code.getmdl.io/1.0.6/material.min.js"></script>
<script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.2/TweenMax.min.js"></script>
.button-container {
width: 50%;
height: 100%;
font-family: 'Roboto', 'Helvetica', sans-serif;
margin: 0;
padding: 0;
}
.mdl-demo .mdl-layout__header-row {
padding-left: 40px;
height: 50px;
}
.mdl-demo .mdl-layout.is-small-screen .mdl-layout__header-row h3 {
font-size: inherit;
}
.mdl-demo .mdl-layout__tab-bar-button {
display: none;
}
.mdl-demo .mdl-button > i.material-icons {
color: white;
}
.mdl-demo .mdl-layout .mdl-layout__tab-bar,
.mdl-demo .mdl-layout .mdl-layout__tab-bar-container {
overflow: visible;
}
.mdl-demo .mdl-layout__tab-bar-container {
height: 64px;
}
.mdl-demo .mdl-layout__tab-bar {
padding: 0;
padding-left: 16px;
box-sizing: border-box;
height: 100%;
width: 100%;
}
.mdl-demo .mdl-layout__tab-bar .mdl-layout__tab {
height: 64px;
line-height: 64px;
}
.mdl-demo .mdl-layout__tab-bar .mdl-layout__tab.is-active::after {
background-color: white;
height: 4px;
}
.mdl-demo main > .mdl-layout__tab-panel {
padding: 8px;
padding-top: 48px;
}
.mdl-demo #add {
position: absolute;
right: 40px;
top: 36px;
z-index: 999;
}
.mdl-demo .mdl-layout__content section:not(:last-of-type) {
position: relative;
margin-bottom: 48px;
}
.mdl-demo section.section--center {
max-width: 860px;
}
.mdl-demo #features section.section--center {
max-width: 620px;
}
.mdl-demo section > header {
display: flex;
align-items: center;
justify-content: center;
}
.mdl-demo section > .section__play-btn {
min-height: 200px;
}
.mdl-demo section > header > .material-icons {
font-size: 3rem;
}
.mdl-demo section > button {
position: absolute;
z-index: 99;
top: 8px;
right: 8px;
}
.mdl-demo .mdl-button--fab-clear {
background: none !important;
box-shadow: none !important;
}
.mdl-demo .mdl-layout:not(.is-small-screen) .click-svg {
width: 500px;
height: 500px !important;
right: -150px !important;
top: -260px !important;
}
.mdl-demo .mdl-layout .click-svg {
width: 500px;
height: 500px !important;
right: -150px !important;
top: -220px !important;
}
/* Begin Fab Menu close/back transition. Thanks to [Maeve](https://codepen.io/vcmg/pen/Pqmgdz) for this keyframe animation
which allows for the action button to snap back in it's place without having to tween another property or attribute. */
.back {
-webkit-animation: deactivate 0.3s linear forwards;
animation: deactivate 0.3s linear forwards;
}
@-webkit-keyframes deactivate {
0% {
transform: scale(10.5);
}
25% {
transform: scale(1);
}
50% {
transform: scale(0.9);
}
75% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
@keyframes deactivate {
0% {
transform: scale(10.5);
}
25% {
transform: scale(1);
}
50% {
transform: scale(0.9);
}
75% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
.header__fab-menu {
position: absolute;
right: -10.0em;
opacity: 0;
z-index: 3000;
}
.header__fab-menu li {
list-style: none;
}
.header__fab-menu li i.material-icons {
display: inline-flex;
vertical-align: middle;
cursor: pointer;
}
.header__fab-menu li a {
color: white;
text-decoration: none;
}
.header__fab-menu li .mdl-36 {
font-size: 36px;
}
.mdl-demo .mdl-layout.is-small-screen .header__fab-menu {
margin-top: 2.5em;
}
.mdl-demo .mdl-layout:not(.is-small-screen) .header__fab-menu {
top: -4.0em;
}
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
<link href="https://storage.googleapis.com/code.getmdl.io/1.0.6/material.blue-orange.min.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment