Initial commit

This commit is contained in:
Rick Dullaart 2022-11-18 21:40:36 +01:00
commit 8fee10ccd2
21 changed files with 1102 additions and 0 deletions

47
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,47 @@
# Contributing to this project
Please take a moment to review this document in order to make the contribution
process easy and effective for everyone involved.
## Using the issue tracker
The issue tracker is the preferred channel for [bug reports](#bugs) and
[features requests](#features), but please respect the following restrictions:
* Please **do not** use the issue tracker for personal support requests.
* Please keep the discussion **on topic** and respect the opinions of others.
<a name="bugs"></a>
## Bug reports
A bug is a _demonstrable problem_ that is caused by the code in the repository.
Good bug reports are extremely helpful - thank you!
Guidelines for bug reports:
1. **Use the GitHub issue search** &mdash; check if the issue has already been
reported.
2. **Check if the issue has been fixed** &mdash; try to reproduce it using the
latest branch in the repository.
3. **Isolate the problem** &mdash; create a [reduced test
case](http://css-tricks.com/reduced-test-cases/) and a live example.
A good bug report shouldn't leave others needing to chase you up for more
information. Please try to be as detailed as possible in your report. What is
your environment? What steps will reproduce the issue? What browser(s) and OS
experience the problem? What would you expect to be the outcome? All these
details will help people to fix any potential bugs.
<a name="features"></a>
## Feature requests
Feature requests are welcome. But take a moment to find out whether your idea
fits with the scope and aims of the project. It's up to *you* to make a strong
case to convince the project's developers of the merits of this feature. Please
provide as much detail and context as possible.

21
README.md Normal file
View File

@ -0,0 +1,21 @@
mburger CSS
================
A small collection of CSS animated hamburgers. All set up to work out of the box with the mmenu.js plugin.<br />
[Examples](https://www.mmenujs.com/mburger)
<img src="https://mmenujs.com/img/preview-mburger.png" alt="CSS animated hamburgers" width="100%" />
### Customize the hamburger
By default, the hamburger adopts to its environment pretty good,
the bars scale to fit and inherit their color for the parent element.<br />
Need help? Have a look at [the documentation](http://mmenujs.com/mburger) for examples and documentation.
### Licence
The mburger CSS is licensed under the [CC-BY-4.0 license](http://creativecommons.org/licenses/by/4.0/).
### Development
This project uses [Gulp(4)](http://gulpjs.com/) to transpile and minify SCSS to CSS.
If you are unfamiliar with Gulp, check [this tutorial](https://travismaynard.com/writing/getting-started-with-gulp) on how to get started.<br />
Run `gulp watch` in the command-line to put a watch on the files and run all scripts immediately after saving your changes.

145
bin/demo.css Normal file
View File

@ -0,0 +1,145 @@
html,
body {
padding: 0;
margin: 0;
height: 100%;
}
body {
position: relative;
background-color: #3ea7e1;
-webkit-text-size-adjust: none;
font-family: Arial, Helvetica, Verdana;
font-size: 20px;
line-height: 30px;
color: #fff;
}
h1 {
margin: 0 0 100px;
text-shadow: 8px 10px 1px rgba(0,0,0,.1);
text-transform: lowercase;
font-family: 'Pacifico', Arial, sans-serif;
font-weight: normal;
font-size: 150px;
line-height: 1;
letter-spacing: -6px;
}
pre {
font-size: 16px;
line-height: 24px;
width: 100%;
overflow: auto;
margin: 75px 0;
}
button.reset {
appearance: none;
padding: 0;
margin: 0;
box-sizing: content-box;
border: 0;
background: none;
outline: none;
color: inherit;
font-size: inherit;
text-align: left;
cursor: pointer;
}
@media (max-width: 500px) {
h1 {
font-size: 105px;
letter-spacing: -2px;
}
}
a,
a:hover {
color: #fff;
text-decoration: underline;
}
#page {
max-width: 600px;
min-width: 300px;
width: 90%;
padding: 100px 10px;
margin: auto;
}
.xmpls {
display: flex;
flex-wrap: wrap;
justify-content: center;
margin: 75px -10px;
}
.xmpl {
position: relative;
box-sizing: border-box;
width: calc( 50% - 20px );
padding-top: calc( 50% - 20px );
margin: 10px;
background: rgba(255, 255, 255, 0.05);
box-shadow: 6px 8px 1px rgba(0,0,0,.1);
transition: none 0.2s ease;
transition-property: background-color, box-shadow, transform;
text-align: center;
cursor: pointer;
}
.xmpl:hover {
background: rgba(255, 255, 255, 0.15);
box-shadow: 4px 6px 0 rgba(0,0,0,.15);
transform: translateY(2px);
}
@media (min-width: 1280px) {
.xmpls {
margin-left: -320px;
margin-right: -320px;
}
.xmpl {
width: calc( 25% - 20px );
padding-top: calc( 25% - 20px );
}
}
.xmpl > button,
.xmpl > m-burger {
--mb-animate-timeout: 0s;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.xmpl > span {
position: absolute;
bottom: 10%;
left: 0;
right: 0;
}
.xmpl .custom-button-1 {
padding: 5px 25px 5px 15px;
background-color: rgba( 255, 255, 255, 0.7 );
color: #3ea7e1;
border-radius: 30px;
white-space: nowrap;
}
.xmpl .custom-button-1 .mburger {
--mb-animate-timeout: 0s;
--mb-button-size: 40px;
--mb-bar-height: 3px;
--mb-bar-spacing: 6px;
}
.xmpl .custom-button-2 {
--mb-animate-timeout: 0s;
--mb-button-size: 80px;
--mb-bar-width: 0.5;
--mb-bar-height: 2px;
--mb-bar-spacing: 12px;
border-radius: 40px;
background-color: rgba( 255, 255, 255, 0.7 );
color: #3ea7e1;
}

80
bin/mburger.js Normal file
View File

@ -0,0 +1,80 @@
/*
* mburger webcomponent v1.3.3
* mmenujs.com/mburger
*
* Copyright (c) Fred Heusschen
* www.frebsite.nl
*
* License: CC-BY-4.0
* http://creativecommons.org/licenses/by/4.0/
*/
export const mBurger = document.createElement('template');
mBurger.innerHTML = `
<style>[__STYLES__]</style>
<b></b>
<b></b>
<b></b>
<slot></slot>`;
customElements.define('m-burger', class extends HTMLElement {
constructor() {
super();
/** The menu node. */
this.menuNode = null;
/** API for the menu. */
this.menuApi = null;
// Attach shadow DOM
var content = mBurger.content.cloneNode(true);
this.attachShadow({ mode: 'open' }).appendChild(content);
}
static get observedAttributes() {
return ['menu'];
}
attributeChangedCallback(name, oldValue, newValue) {
if (name == 'menu') {
// Initiate the new menu.
this.initMenu(newValue);
}
}
connectedCallback() {
// Open the menu when clicking the hamburger.
this.addEventListener('click', evnt => {
// If there is no API for a menu available (the menu isn't yet initiated),
// try to initiate the menu.
if (!this.menuApi) {
this.initMenu();
}
// If there is an API for a menu available,
// open the menu.
if (this.menuApi && this.menuApi.open) {
this.menuApi.open();
}
});
}
/**
* Set the menu node and API.
* @param {string} [id] The ID-attribute for the menu node.
*/
initMenu(id) {
this.menuNode = null;
this.menuApi = null;
if (!id) {
id = this.getAttribute('menu');
}
if (id) {
this.menuNode = document.getElementById(id);
}
if (this.menuNode) {
this.menuApi =
this.menuNode['mmApi'] || this.menuNode['mmenu'] || null;
}
// Change the hamburger state when opening and closing the menu.
if (this.menuApi) {
this.menuApi.bind('open:after', () => {
this.setAttribute('state', 'cross');
});
this.menuApi.bind('close:after', () => {
this.removeAttribute('state');
});
}
}
});

1
bin/webcomponent.css Normal file
View File

@ -0,0 +1 @@
:host{--mb-button-size:60px;--mb-bar-width:0.6;--mb-bar-height:4px;--mb-bar-spacing:10px;--mb-animate-timeout:0s}:host{background:0 0;border:none;border-radius:0;color:inherit;display:inline-block;position:relative;box-sizing:border-box;height:var(--mb-button-size);padding:0 0 0 var(--mb-button-size);margin:0;line-height:var(--mb-button-size);vertical-align:middle;appearance:none;outline:0;cursor:pointer}:host b{display:block;position:absolute;left:calc(var(--mb-button-size) * ((1 - var(--mb-bar-width))/ 2));width:calc(var(--mb-button-size) * var(--mb-bar-width));height:var(--mb-bar-height);border-radius:calc(var(--mb-bar-height)/ 2);background:currentColor;color:inherit;opacity:1}:host b:nth-of-type(1){bottom:calc(50% + var(--mb-bar-spacing));transition:bottom .2s ease,transform .2s ease,width .2s ease}:host b:nth-of-type(2){top:calc(50% - (var(--mb-bar-height)/ 2));transition:opacity .2s ease}:host b:nth-of-type(3){top:calc(50% + var(--mb-bar-spacing));transition:top .2s ease,transform .2s ease,width .2s ease}:host([state=cross]) b:nth-of-type(1){bottom:calc(50% - (var(--mb-bar-height)/ 2));transform:rotate(45deg)}:host([state=cross]) b:nth-of-type(2){opacity:0}:host([state=cross]) b:nth-of-type(3){top:calc(50% - (var(--mb-bar-height)/ 2));transform:rotate(-45deg)}:host([fx=collapse]) b:nth-of-type(1){transition:bottom .2s ease,margin .2s ease,transform .2s ease;transition-delay:.2s,0s,0s}:host([fx=collapse]) b:nth-of-type(2){transition:top .2s ease,opacity 0s ease;transition-delay:.3s,.3s}:host([fx=collapse]) b:nth-of-type(3){transition:top .2s ease,transform .2s ease}:host([state=cross][fx=collapse]) b:nth-of-type(1){bottom:calc(50% - var(--mb-bar-spacing) - var(--mb-bar-height));margin-bottom:calc(var(--mb-bar-spacing) + (var(--mb-bar-height)/ 2));transform:rotate(45deg);transition-delay:calc(var(--mb-animate-timeout) + .1s),calc(var(--mb-animate-timeout) + .3s),calc(var(--mb-animate-timeout) + .3s)}:host([state=cross][fx=collapse]) b:nth-of-type(2){top:calc(50% + var(--mb-bar-spacing));opacity:0;transition-delay:calc(var(--mb-animate-timeout) + 0s),calc(var(--mb-animate-timeout) + .2s)}:host([state=cross][fx=collapse]) b:nth-of-type(3){top:calc(50% - (var(--mb-bar-height)/ 2));transform:rotate(-45deg);transition-delay:calc(var(--mb-animate-timeout) + .3s),calc(var(--mb-animate-timeout) + .3s)}:host([fx=spin]) b:nth-of-type(1){transition-delay:.2s,0s}:host([fx=spin]) b:nth-of-type(2){transition-duration:0s;transition-delay:.2s}:host([fx=spin]) b:nth-of-type(3){transition-delay:.2s,0s}:host([state=cross][fx=spin]) b:nth-of-type(1){transform:rotate(135deg);transition-delay:calc(var(--mb-animate-timeout) + 0s),calc(var(--mb-animate-timeout) + .2s)}:host([state=cross][fx=spin]) b:nth-of-type(2){transition-delay:calc(var(--mb-animate-timeout) + 0s)}:host([state=cross][fx=spin]) b:nth-of-type(3){transform:rotate(225deg);transition-delay:calc(var(--mb-animate-timeout) + 0s),calc(var(--mb-animate-timeout) + .2s)}:host([fx=squeeze]) b:nth-of-type(1){transition-delay:.1s,0s}:host([fx=squeeze]) b:nth-of-type(2){transition-delay:.1s}:host([fx=squeeze]) b:nth-of-type(3){transition-delay:.1s,0s}:host([state=cross][fx=squeeze]) b:nth-of-type(1){transition-delay:calc(var(--mb-animate-timeout) + 0s),calc(var(--mb-animate-timeout) + .1s)}:host([state=cross][fx=squeeze]) b:nth-of-type(2){transition-delay:calc(var(--mb-animate-timeout) + 0s)}:host([state=cross][fx=squeeze]) b:nth-of-type(3){transition-delay:calc(var(--mb-animate-timeout) + 0s),calc(var(--mb-animate-timeout) + .1s)}:host([fx=tornado]) b:nth-of-type(1){transition:bottom .2s ease,transform .2s ease;transition-delay:.2s}:host([fx=tornado]) b:nth-of-type(2){transition:opacity 0s ease,transform .2s ease;transition-delay:.1s,.1s}:host([fx=tornado]) b:nth-of-type(3){transition:top .2s ease,transform .2s ease;transition-delay:0s}:host([state=cross][fx=tornado]) b:nth-of-type(1){transform:rotate(-135deg);transition-delay:calc(var(--mb-animate-timeout) + 0s)}:host([state=cross][fx=tornado]) b:nth-of-type(2){opacity:0;transform:rotate(-135deg);transition-delay:calc(var(--mb-animate-timeout) + .4s),calc(var(--mb-animate-timeout) + .1s)}:host([state=cross][fx=tornado]) b:nth-of-type(3){transform:rotate(-225deg);transition-delay:calc(var(--mb-animate-timeout) + .2s)}

16
composer.json Normal file
View File

@ -0,0 +1,16 @@
{
"name": "mburger-css",
"version": "1.3.3",
"authors": "Fred Heusschen <info@mmenujs.com>",
"license": "CC-BY-4.0",
"description": "A small collection of CSS animated hamburgers. All set up to work out of the box with the mmenu.js plugin.",
"keywords": [
"hamburger",
"icon",
"CSS",
"animation",
"animated",
"menu",
"navigation"
]
}

10
dist/mburger.css vendored Normal file
View File

@ -0,0 +1,10 @@
/*!
* mburger CSS v1.3.3
* mmenujs.com/mburger
*
* Copyright (c) Fred Heusschen
* www.frebsite.nl
*
* License: CC-BY-4.0
* http://creativecommons.org/licenses/by/4.0/
*/:root{--mb-button-size:60px;--mb-bar-width:0.6;--mb-bar-height:4px;--mb-bar-spacing:10px;--mb-animate-timeout:0.4s}.mburger{background:0 0;border:none;border-radius:0;color:inherit;display:inline-block;position:relative;box-sizing:border-box;height:var(--mb-button-size);padding:0 0 0 var(--mb-button-size);margin:0;line-height:var(--mb-button-size);vertical-align:middle;appearance:none;outline:0;cursor:pointer}.mburger b{display:block;position:absolute;left:calc(var(--mb-button-size) * ((1 - var(--mb-bar-width))/ 2));width:calc(var(--mb-button-size) * var(--mb-bar-width));height:var(--mb-bar-height);border-radius:calc(var(--mb-bar-height)/ 2);background:currentColor;color:inherit;opacity:1}.mburger b:nth-of-type(1){bottom:calc(50% + var(--mb-bar-spacing));transition:bottom .2s ease,transform .2s ease,width .2s ease}.mburger b:nth-of-type(2){top:calc(50% - (var(--mb-bar-height)/ 2));transition:opacity .2s ease}.mburger b:nth-of-type(3){top:calc(50% + var(--mb-bar-spacing));transition:top .2s ease,transform .2s ease,width .2s ease}.mm-wrapper_opened .mburger b:nth-of-type(1){bottom:calc(50% - (var(--mb-bar-height)/ 2));transform:rotate(45deg)}.mm-wrapper_opened .mburger b:nth-of-type(2){opacity:0}.mm-wrapper_opened .mburger b:nth-of-type(3){top:calc(50% - (var(--mb-bar-height)/ 2));transform:rotate(-45deg)}.mburger--collapse b:nth-of-type(1){transition:bottom .2s ease,margin .2s ease,transform .2s ease;transition-delay:.2s,0s,0s}.mburger--collapse b:nth-of-type(2){transition:top .2s ease,opacity 0s ease;transition-delay:.3s,.3s}.mburger--collapse b:nth-of-type(3){transition:top .2s ease,transform .2s ease}.mm-wrapper_opened .mburger--collapse b:nth-of-type(1){bottom:calc(50% - var(--mb-bar-spacing) - var(--mb-bar-height));margin-bottom:calc(var(--mb-bar-spacing) + (var(--mb-bar-height)/ 2));transform:rotate(45deg);transition-delay:calc(var(--mb-animate-timeout) + .1s),calc(var(--mb-animate-timeout) + .3s),calc(var(--mb-animate-timeout) + .3s)}.mm-wrapper_opened .mburger--collapse b:nth-of-type(2){top:calc(50% + var(--mb-bar-spacing));opacity:0;transition-delay:calc(var(--mb-animate-timeout) + 0s),calc(var(--mb-animate-timeout) + .2s)}.mm-wrapper_opened .mburger--collapse b:nth-of-type(3){top:calc(50% - (var(--mb-bar-height)/ 2));transform:rotate(-45deg);transition-delay:calc(var(--mb-animate-timeout) + .3s),calc(var(--mb-animate-timeout) + .3s)}.mburger--spin b:nth-of-type(1){transition-delay:.2s,0s}.mburger--spin b:nth-of-type(2){transition-duration:0s;transition-delay:.2s}.mburger--spin b:nth-of-type(3){transition-delay:.2s,0s}.mm-wrapper_opened .mburger--spin b:nth-of-type(1){transform:rotate(135deg);transition-delay:calc(var(--mb-animate-timeout) + 0s),calc(var(--mb-animate-timeout) + .2s)}.mm-wrapper_opened .mburger--spin b:nth-of-type(2){transition-delay:calc(var(--mb-animate-timeout) + 0s)}.mm-wrapper_opened .mburger--spin b:nth-of-type(3){transform:rotate(225deg);transition-delay:calc(var(--mb-animate-timeout) + 0s),calc(var(--mb-animate-timeout) + .2s)}.mburger--squeeze b:nth-of-type(1){transition-delay:.1s,0s}.mburger--squeeze b:nth-of-type(2){transition-delay:.1s}.mburger--squeeze b:nth-of-type(3){transition-delay:.1s,0s}.mm-wrapper_opened .mburger--squeeze b:nth-of-type(1){transition-delay:calc(var(--mb-animate-timeout) + 0s),calc(var(--mb-animate-timeout) + .1s)}.mm-wrapper_opened .mburger--squeeze b:nth-of-type(2){transition-delay:calc(var(--mb-animate-timeout) + 0s)}.mm-wrapper_opened .mburger--squeeze b:nth-of-type(3){transition-delay:calc(var(--mb-animate-timeout) + 0s),calc(var(--mb-animate-timeout) + .1s)}.mburger--tornado b:nth-of-type(1){transition:bottom .2s ease,transform .2s ease;transition-delay:.2s}.mburger--tornado b:nth-of-type(2){transition:opacity 0s ease,transform .2s ease;transition-delay:.1s,.1s}.mburger--tornado b:nth-of-type(3){transition:top .2s ease,transform .2s ease;transition-delay:0s}.mm-wrapper_opened .mburger--tornado b:nth-of-type(1){transform:rotate(-135deg);transition-delay:calc(var(--mb-animate-timeout) + 0s)}.mm-wrapper_opened .mburger--tornado b:nth-of-type(2){opacity:0;transform:rotate(-135deg);transition-delay:calc(var(--mb-animate-timeout) + .4s),calc(var(--mb-animate-timeout) + .1s)}.mm-wrapper_opened .mburger--tornado b:nth-of-type(3){transform:rotate(-225deg);transition-delay:calc(var(--mb-animate-timeout) + .2s)}

80
dist/mburger.js vendored Normal file
View File

@ -0,0 +1,80 @@
/*
* mburger webcomponent v1.3.3
* mmenujs.com/mburger
*
* Copyright (c) Fred Heusschen
* www.frebsite.nl
*
* License: CC-BY-4.0
* http://creativecommons.org/licenses/by/4.0/
*/
export const mBurger = document.createElement('template');
mBurger.innerHTML = `
<style>:host{--mb-button-size:60px;--mb-bar-width:0.6;--mb-bar-height:4px;--mb-bar-spacing:10px;--mb-animate-timeout:0s}:host{background:0 0;border:none;border-radius:0;color:inherit;display:inline-block;position:relative;box-sizing:border-box;height:var(--mb-button-size);padding:0 0 0 var(--mb-button-size);margin:0;line-height:var(--mb-button-size);vertical-align:middle;appearance:none;outline:0;cursor:pointer}:host b{display:block;position:absolute;left:calc(var(--mb-button-size) * ((1 - var(--mb-bar-width))/ 2));width:calc(var(--mb-button-size) * var(--mb-bar-width));height:var(--mb-bar-height);border-radius:calc(var(--mb-bar-height)/ 2);background:currentColor;color:inherit;opacity:1}:host b:nth-of-type(1){bottom:calc(50% + var(--mb-bar-spacing));transition:bottom .2s ease,transform .2s ease,width .2s ease}:host b:nth-of-type(2){top:calc(50% - (var(--mb-bar-height)/ 2));transition:opacity .2s ease}:host b:nth-of-type(3){top:calc(50% + var(--mb-bar-spacing));transition:top .2s ease,transform .2s ease,width .2s ease}:host([state=cross]) b:nth-of-type(1){bottom:calc(50% - (var(--mb-bar-height)/ 2));transform:rotate(45deg)}:host([state=cross]) b:nth-of-type(2){opacity:0}:host([state=cross]) b:nth-of-type(3){top:calc(50% - (var(--mb-bar-height)/ 2));transform:rotate(-45deg)}:host([fx=collapse]) b:nth-of-type(1){transition:bottom .2s ease,margin .2s ease,transform .2s ease;transition-delay:.2s,0s,0s}:host([fx=collapse]) b:nth-of-type(2){transition:top .2s ease,opacity 0s ease;transition-delay:.3s,.3s}:host([fx=collapse]) b:nth-of-type(3){transition:top .2s ease,transform .2s ease}:host([state=cross][fx=collapse]) b:nth-of-type(1){bottom:calc(50% - var(--mb-bar-spacing) - var(--mb-bar-height));margin-bottom:calc(var(--mb-bar-spacing) + (var(--mb-bar-height)/ 2));transform:rotate(45deg);transition-delay:calc(var(--mb-animate-timeout) + .1s),calc(var(--mb-animate-timeout) + .3s),calc(var(--mb-animate-timeout) + .3s)}:host([state=cross][fx=collapse]) b:nth-of-type(2){top:calc(50% + var(--mb-bar-spacing));opacity:0;transition-delay:calc(var(--mb-animate-timeout) + 0s),calc(var(--mb-animate-timeout) + .2s)}:host([state=cross][fx=collapse]) b:nth-of-type(3){top:calc(50% - (var(--mb-bar-height)/ 2));transform:rotate(-45deg);transition-delay:calc(var(--mb-animate-timeout) + .3s),calc(var(--mb-animate-timeout) + .3s)}:host([fx=spin]) b:nth-of-type(1){transition-delay:.2s,0s}:host([fx=spin]) b:nth-of-type(2){transition-duration:0s;transition-delay:.2s}:host([fx=spin]) b:nth-of-type(3){transition-delay:.2s,0s}:host([state=cross][fx=spin]) b:nth-of-type(1){transform:rotate(135deg);transition-delay:calc(var(--mb-animate-timeout) + 0s),calc(var(--mb-animate-timeout) + .2s)}:host([state=cross][fx=spin]) b:nth-of-type(2){transition-delay:calc(var(--mb-animate-timeout) + 0s)}:host([state=cross][fx=spin]) b:nth-of-type(3){transform:rotate(225deg);transition-delay:calc(var(--mb-animate-timeout) + 0s),calc(var(--mb-animate-timeout) + .2s)}:host([fx=squeeze]) b:nth-of-type(1){transition-delay:.1s,0s}:host([fx=squeeze]) b:nth-of-type(2){transition-delay:.1s}:host([fx=squeeze]) b:nth-of-type(3){transition-delay:.1s,0s}:host([state=cross][fx=squeeze]) b:nth-of-type(1){transition-delay:calc(var(--mb-animate-timeout) + 0s),calc(var(--mb-animate-timeout) + .1s)}:host([state=cross][fx=squeeze]) b:nth-of-type(2){transition-delay:calc(var(--mb-animate-timeout) + 0s)}:host([state=cross][fx=squeeze]) b:nth-of-type(3){transition-delay:calc(var(--mb-animate-timeout) + 0s),calc(var(--mb-animate-timeout) + .1s)}:host([fx=tornado]) b:nth-of-type(1){transition:bottom .2s ease,transform .2s ease;transition-delay:.2s}:host([fx=tornado]) b:nth-of-type(2){transition:opacity 0s ease,transform .2s ease;transition-delay:.1s,.1s}:host([fx=tornado]) b:nth-of-type(3){transition:top .2s ease,transform .2s ease;transition-delay:0s}:host([state=cross][fx=tornado]) b:nth-of-type(1){transform:rotate(-135deg);transition-delay:calc(var(--mb-animate-timeout) + 0s)}:host([state=cross][fx=tornado]) b:nth-of-type(2){opacity:0;transform:rotate(-135deg);transition-delay:calc(var(--mb-animate-timeout) + .4s),calc(var(--mb-animate-timeout) + .1s)}:host([state=cross][fx=tornado]) b:nth-of-type(3){transform:rotate(-225deg);transition-delay:calc(var(--mb-animate-timeout) + .2s)}</style>
<b></b>
<b></b>
<b></b>
<slot></slot>`;
customElements.define('m-burger', class extends HTMLElement {
constructor() {
super();
/** The menu node. */
this.menuNode = null;
/** API for the menu. */
this.menuApi = null;
// Attach shadow DOM
var content = mBurger.content.cloneNode(true);
this.attachShadow({ mode: 'open' }).appendChild(content);
}
static get observedAttributes() {
return ['menu'];
}
attributeChangedCallback(name, oldValue, newValue) {
if (name == 'menu') {
// Initiate the new menu.
this.initMenu(newValue);
}
}
connectedCallback() {
// Open the menu when clicking the hamburger.
this.addEventListener('click', evnt => {
// If there is no API for a menu available (the menu isn't yet initiated),
// try to initiate the menu.
if (!this.menuApi) {
this.initMenu();
}
// If there is an API for a menu available,
// open the menu.
if (this.menuApi && this.menuApi.open) {
this.menuApi.open();
}
});
}
/**
* Set the menu node and API.
* @param {string} [id] The ID-attribute for the menu node.
*/
initMenu(id) {
this.menuNode = null;
this.menuApi = null;
if (!id) {
id = this.getAttribute('menu');
}
if (id) {
this.menuNode = document.getElementById(id);
}
if (this.menuNode) {
this.menuApi =
this.menuNode['mmApi'] || this.menuNode['mmenu'] || null;
}
// Change the hamburger state when opening and closing the menu.
if (this.menuApi) {
this.menuApi.bind('open:after', () => {
this.setAttribute('state', 'cross');
});
this.menuApi.bind('close:after', () => {
this.removeAttribute('state');
});
}
}
});

72
gulpfile.js Normal file
View File

@ -0,0 +1,72 @@
/*
Tasks:
$ gulp : Runs all tasks.
$ gulp watch : Starts a watch on all tasks.
$ gulp css : Runs "css" task.
$ gulp webcomponent : Runs "webcomponent" tasks.
*/
const { src, dest, watch, parallel, series } = require('gulp');
const sass = require('gulp-sass');
const cleancss = require('gulp-clean-css');
// const concat = require('gulp-concat');
const typescript = require('gulp-typescript');
const replace = require('gulp-replace');
const fs = require('fs');
const inputDir = 'src';
const outputDir = 'dist';
const binDir = 'bin';
const css = cb => {
return src(inputDir + '/scss/mburger.scss')
.pipe(sass().on('error', sass.logError))
.pipe(cleancss())
.pipe(dest(outputDir));
};
const webcomponentJs = cb => {
return src([
inputDir + '/ts/*.d.ts', // Include all typings.
inputDir + '/ts/*.ts' // Include the needed ts files.
])
.pipe(
typescript({
target: 'es6',
module: 'es6'
})
)
.pipe(dest(binDir));
};
const webcomponentCss = cb => {
return src(inputDir + '/scss/webcomponent.scss')
.pipe(sass().on('error', sass.logError))
.pipe(cleancss())
.pipe(dest(binDir));
};
const webcomponentConcat = cb => {
var styles = fs.readFileSync(binDir + '/webcomponent.css');
return src(binDir + '/mburger.js')
.pipe(replace('[__STYLES__]', styles))
.pipe(dest(outputDir));
};
const webcomponent = series(
parallel(webcomponentCss, webcomponentJs),
webcomponentConcat
);
const watchTask = cb => {
watch(inputDir + '/scss/*.scss', parallel(css, webcomponent));
watch(inputDir + '/ts/*.ts', webcomponent);
cb();
};
exports.default = parallel(css, webcomponent);
exports.watch = watchTask;
exports.css = css;
exports.webcomponent = webcomponent;

157
index.html Normal file
View File

@ -0,0 +1,157 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="author" content="www.frebsite.nl" />
<meta content="width=600px user-scalable=yes" name="viewport" />
<meta name="robots" content="noindex, nofollow" />
<title>mburger, CSS animated hamburgers!</title>
<link type="text/css" rel="stylesheet" href="http://fonts.googleapis.com/css?family=Pacifico" />
<link type="text/css" rel="stylesheet" href="bin/demo.css" />
<link type="text/css" rel="stylesheet" href="dist/mburger.css" />
<script type="module" src="dist/mburger.js"></script>
</head>
<body>
<div id="page">
<h1>mburger</h1>
<p>A small collection of CSS animated hamburgers.
All set up to work out of the box with the mmenu.js plugin.
Click a hamburger to see the animation.
More info <a href="https://www.mmenujs.com/mburger" target="_blank">here</a>.</p>
<div class="xmpls">
<div class="xmpl">
<button class="mburger mburger--collapse">
<b></b>
<b></b>
<b></b>
</button>
<span>collapse</span>
</div>
<div class="xmpl">
<button class="mburger mburger--spin">
<b></b>
<b></b>
<b></b>
</button>
<span>spin</span>
</div>
<div class="xmpl">
<button class="mburger mburger--squeeze">
<b></b>
<b></b>
<b></b>
</button>
<span>squeeze</span>
</div>
<div class="xmpl">
<button class="mburger mburger--tornado">
<b></b>
<b></b>
<b></b>
</button>
<span>tornado</span>
</div>
</div>
<pre>
&lt;html&gt;
&lt;head&gt;
&lt;style type="text/css" rel="stylesheet" href="dist/mburger.css"&gt;
&lt;/heady&gt;
&lt;body&gt;
&lt;button class="mburger mburger--spin" href="#my-menu"&gt;
&lt;b&lt;/b&gt;
&lt;b&lt;/b&gt;
&lt;b&lt;/b&gt;
&lt;/button&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<h3>Customize the hamburger</h3>
<p>By default, the hamburger adopts to its environment pretty good,
the bars scale to fit and inherit their <code>color</code> for the parent element.</p>
<p>The hamburger is pretty easy to customize too,
just override some of the CSS values and variables.</p>
<div class="xmpls">
<div class="xmpl">
<button class="reset custom-button-1">
<span class="mburger mburger--spin">
<b></b>
<b></b>
<b></b>
<span>Menu</span>
</span>
</button>
</div>
<div class="xmpl">
<button class="custom-button-2 mburger mburger--spin">
<b></b>
<b></b>
<b></b>
</button>
</div>
</div>
<p>For more examples and the full documentation, please visit: <a href="https://www.mmenujs.com/mburger" target="_blank">mmenujs.com/mburger</a>.</p>
<br />
<h3>Native webcomponent</h3>
<p>Note that -at the time of writing (early 2019)- the native webcomponent is only (fully) supported in Chrome.</p>
<div class="xmpls">
<div class="xmpl">
<m-burger fx="collapse"></m-burger>
<span>collapse</span>
</div>
<div class="xmpl">
<m-burger fx="spin"></m-burger>
<span>spin</span>
</div>
</div>
<pre>
&lt;html&gt;
&lt;head&gt;
&lt;script type="module" src="dist/mburger.js"&gt;&lt;/script&gt;
&lt;/heady&gt;
&lt;body&gt;
&lt;m-burger fx="spin" menu="my-menu"&gt;&lt;/m-burger&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
</div>
<script>
document.addEventListener('click', ( evnt ) => {
var target = evnt.target;
let xmpl = target.closest('.xmpl');
if ( xmpl ) {
let webcomponent = xmpl.querySelector( 'm-burger' );
if ( webcomponent ) {
if ( webcomponent.getAttribute( 'state' ) ) {
webcomponent.removeAttribute( 'state' );
} else {
webcomponent.setAttribute( 'state', 'cross' );
}
} else {
xmpl.classList.toggle( 'mm-wrapper_opened' );
}
}
});
</script>
</body>
</html>

34
package.json Normal file
View File

@ -0,0 +1,34 @@
{
"name": "mburger-css",
"version": "1.3.3",
"main": "dist/mburger.css",
"module": "dist/mburger.js",
"author": "Fred Heusschen <info@mmenujs.com>",
"license": "CC-BY-4.0",
"repository": {
"type": "git",
"url": "https://github.com/FrDH/mburger-css.git"
},
"description": "A small collection of CSS animated hamburgers. All set up to work out of the box with the mmenu.js plugin.",
"keywords": [
"hamburger",
"icon",
"CSS",
"animation",
"animated",
"menu",
"navigation"
],
"scripts": {
"build": "gulp default"
},
"devDependencies": {
"fs": "0.0.1-security",
"gulp": "^4.0.0",
"gulp-clean-css": "^4.0.0",
"gulp-replace": "^1.0.0",
"gulp-sass": "^4.0.2",
"gulp-typescript": "^5.0.1",
"typescript": "^3.4.3"
}
}

85
src/scss/_base.scss Normal file
View File

@ -0,0 +1,85 @@
#{$mb_root} {
/** Size for the button. */
--mb-button-size: 60px;
/** Width for the bars, relative to the button. */
--mb-bar-width: 0.6;
/** Height for the bars.*/
--mb-bar-height: 4px;
/** Distance between bars (approximately). */
--mb-bar-spacing: 10px;
/** Timeout before starting the animation, ensures the animation starts after the menu is fully opened. */
--mb-animate-timeout: #{$mb_animate_timeout};
}
#{$mb_module} {
// Overridable values
background: transparent;
border: none;
border-radius: 0;
color: inherit;
// Button
display: inline-block;
position: relative;
box-sizing: border-box;
height: var(--mb-button-size);
padding: 0 0 0 var(--mb-button-size);
margin: 0;
line-height: var(--mb-button-size);
vertical-align: middle;
appearance: none;
outline: none;
cursor: pointer;
// Hamburger
b {
display: block;
position: absolute;
left: calc(var(--mb-button-size) * ((1 - var(--mb-bar-width)) / 2));
width: calc(var(--mb-button-size) * var(--mb-bar-width));
height: var(--mb-bar-height);
border-radius: calc(var(--mb-bar-height) / 2);
background: currentColor;
color: inherit;
opacity: 1;
// Bar 1
&:nth-of-type(1) {
bottom: calc(50% + var(--mb-bar-spacing));
transition: bottom 0.2s ease, transform 0.2s ease, width 0.2s ease;
}
// Bar 2
&:nth-of-type(2) {
top: calc(50% - (var(--mb-bar-height) / 2));
transition: opacity 0.2s ease;
}
// Bar 3
&:nth-of-type(3) {
top: calc(50% + var(--mb-bar-spacing));
transition: top 0.2s ease, transform 0.2s ease, width 0.2s ease;
}
}
}
// Cross
#{$mb_module_cross} {
b {
&:nth-of-type(1) {
bottom: calc(50% - (var(--mb-bar-height) / 2));
transform: rotate(45deg);
}
&:nth-of-type(2) {
opacity: 0;
}
&:nth-of-type(3) {
top: calc(50% - (var(--mb-bar-height) / 2));
transform: rotate(-45deg);
}
}
}

View File

@ -0,0 +1,49 @@
@if ($mb_fx_collapse) {
// Hamburger
#{$mb_module_collapse} {
b {
&:nth-of-type(1) {
transition: bottom 0.2s ease, margin 0.2s ease,
transform 0.2s ease;
transition-delay: 0.2s, 0s, 0s;
}
&:nth-of-type(2) {
transition: top 0.2s ease, opacity 0s ease;
transition-delay: 0.3s, 0.3s;
}
&:nth-of-type(3) {
transition: top 0.2s ease, transform 0.2s ease;
}
}
}
// Cross
#{$mb_module_collapse_cross} {
b {
&:nth-of-type(1) {
bottom: calc(
50% - var(--mb-bar-spacing) - var(--mb-bar-height)
);
margin-bottom: calc(
var(--mb-bar-spacing) + (var(--mb-bar-height) / 2)
);
transform: rotate(45deg);
transition-delay: calc(var(--mb-animate-timeout) + 0.1s),
calc(var(--mb-animate-timeout) + 0.3s),
calc(var(--mb-animate-timeout) + 0.3s);
}
&:nth-of-type(2) {
top: calc(50% + var(--mb-bar-spacing));
opacity: 0;
transition-delay: calc(var(--mb-animate-timeout) + 0s),
calc(var(--mb-animate-timeout) + 0.2s);
}
&:nth-of-type(3) {
top: calc(50% - (var(--mb-bar-height) / 2));
transform: rotate(-45deg);
transition-delay: calc(var(--mb-animate-timeout) + 0.3s),
calc(var(--mb-animate-timeout) + 0.3s);
}
}
}
}

36
src/scss/_fx.spin.scss Normal file
View File

@ -0,0 +1,36 @@
@if ($mb_fx_spin) {
// Hamburger
#{$mb_module_spin} {
b {
&:nth-of-type(1) {
transition-delay: 0.2s, 0s;
}
&:nth-of-type(2) {
transition-duration: 0s;
transition-delay: 0.2s;
}
&:nth-of-type(3) {
transition-delay: 0.2s, 0s;
}
}
}
// Cross
#{$mb_module_spin_cross} {
b {
&:nth-of-type(1) {
transform: rotate(135deg);
transition-delay: calc(var(--mb-animate-timeout) + 0s),
calc(var(--mb-animate-timeout) + 0.2s);
}
&:nth-of-type(2) {
transition-delay: calc(var(--mb-animate-timeout) + 0s);
}
&:nth-of-type(3) {
transform: rotate(225deg);
transition-delay: calc(var(--mb-animate-timeout) + 0s),
calc(var(--mb-animate-timeout) + 0.2s);
}
}
}
}

33
src/scss/_fx.squeeze.scss Normal file
View File

@ -0,0 +1,33 @@
@if ($mb_fx_squeeze) {
// Hamburger
#{$mb_module_squeeze} {
b {
&:nth-of-type(1) {
transition-delay: 0.1s, 0s;
}
&:nth-of-type(2) {
transition-delay: 0.1s;
}
&:nth-of-type(3) {
transition-delay: 0.1s, 0s;
}
}
}
// Cross
#{$mb_module_squeeze_cross} {
b {
&:nth-of-type(1) {
transition-delay: calc(var(--mb-animate-timeout) + 0s),
calc(var(--mb-animate-timeout) + 0.1s);
}
&:nth-of-type(2) {
transition-delay: calc(var(--mb-animate-timeout) + 0s);
}
&:nth-of-type(3) {
transition-delay: calc(var(--mb-animate-timeout) + 0s),
calc(var(--mb-animate-timeout) + 0.1s);
}
}
}
}

39
src/scss/_fx.tornado.scss Normal file
View File

@ -0,0 +1,39 @@
@if ($mb_fx_tornado) {
// Hamburger
#{$mb_module_tornado} {
b {
&:nth-of-type(1) {
transition: bottom 0.2s ease, transform 0.2s ease;
transition-delay: 0.2s;
}
&:nth-of-type(2) {
transition: opacity 0s ease, transform 0.2s ease;
transition-delay: 0.1s, 0.1s;
}
&:nth-of-type(3) {
transition: top 0.2s ease, transform 0.2s ease;
transition-delay: 0s;
}
}
}
// Cross
#{$mb_module_tornado_cross} {
b {
&:nth-of-type(1) {
transform: rotate(-135deg);
transition-delay: calc(var(--mb-animate-timeout) + 0s);
}
&:nth-of-type(2) {
opacity: 0;
transform: rotate(-135deg);
transition-delay: calc(var(--mb-animate-timeout) + 0.4s),
calc(var(--mb-animate-timeout) + 0.1s);
}
&:nth-of-type(3) {
transform: rotate(-225deg);
transition-delay: calc(var(--mb-animate-timeout) + 0.2s);
}
}
}
}

49
src/scss/_variables.scss Normal file
View File

@ -0,0 +1,49 @@
/** Selector for the root */
$mb_root: ':root' !default;
/** Selector for the button. */
$mb_module: '.mburger' !default;
$__opened: '.mm-wrapper_opened';
/** Selector for the button with the "collapse" effect. */
$mb_module_collapse: '#{$mb_module}--collapse' !default;
/** Selector for the button with the "spin" effect. */
$mb_module_spin: '#{$mb_module}--spin' !default;
/** Selector for the button with the "squeeze" effect. */
$mb_module_squeeze: '#{$mb_module}--squeeze' !default;
/** Selector for the button with the "tornado" effect. */
$mb_module_tornado: '#{$mb_module}--tornado' !default;
/** Selector for the button when the menu is opened. */
$mb_module_cross: '#{$__opened} #{$mb_module}' !default;
/** Selector for the button with the "collapse" effect when the menu is opened. */
$mb_module_collapse_cross: '#{$__opened} #{$mb_module_collapse}' !default;
/** Selector for the button with the "spin" effect when the menu is opened. */
$mb_module_spin_cross: '#{$__opened} #{$mb_module_spin}' !default;
/** Selector for the button with the "squeeze" effect when the menu is opened. */
$mb_module_squeeze_cross: '#{$__opened} #{$mb_module_squeeze}' !default;
/** Selector for the button with the "tornado" effect when the menu is opened. */
$mb_module_tornado_cross: '#{$__opened} #{$mb_module_tornado}' !default;
/** Timeout before starting the animation, ensures the animation starts after the menu is fully opened. */
$mb_animate_timeout: 0.4s !default;
/** Whether or not to include the CSS for the "collapse" animation. */
$mb_fx_collapse: true !default;
/** Whether or not to include the CSS for the "spin" animation. */
$mb_fx_spin: true !default;
/** Whether or not to include the CSS for the "squeeze" animation. */
$mb_fx_squeeze: true !default;
/** Whether or not to include the CSS for the "tornado" animation. */
$mb_fx_tornado: true !default;

18
src/scss/mburger.scss Normal file
View File

@ -0,0 +1,18 @@
/*!
* mburger CSS v1.3.3
* mmenujs.com/mburger
*
* Copyright (c) Fred Heusschen
* www.frebsite.nl
*
* License: CC-BY-4.0
* http://creativecommons.org/licenses/by/4.0/
*/
@import 'variables';
@import 'base';
@import 'fx.collapse';
@import 'fx.spin';
@import 'fx.squeeze';
@import 'fx.tornado';

View File

@ -0,0 +1,24 @@
// Selectors for the button.
$mb_root: ':host';
$mb_module: ':host';
$mb_module_collapse: ':host( [fx="collapse"] )';
$mb_module_spin: ':host( [fx="spin"] )';
$mb_module_squeeze: ':host( [fx="squeeze"] )';
$mb_module_tornado: ':host( [fx="tornado"] )';
// Selector for the button when the menu is opened.
$mb_module_cross: ':host( [state="cross"] )';
$mb_module_collapse_cross: ':host( [state="cross"][fx="collapse"] )';
$mb_module_spin_cross: ':host( [state="cross"][fx="spin"] )';
$mb_module_squeeze_cross: ':host( [state="cross"][fx="squeeze"] )';
$mb_module_tornado_cross: ':host( [state="cross"][fx="tornado"] )';
$mb_animate_timeout: 0s;
@import 'variables';
@import 'base';
@import 'fx.collapse';
@import 'fx.spin';
@import 'fx.squeeze';
@import 'fx.tornado';

98
src/ts/mburger.ts Normal file
View File

@ -0,0 +1,98 @@
/*
* mburger webcomponent v1.3.3
* mmenujs.com/mburger
*
* Copyright (c) Fred Heusschen
* www.frebsite.nl
*
* License: CC-BY-4.0
* http://creativecommons.org/licenses/by/4.0/
*/
export const mBurger = document.createElement('template');
mBurger.innerHTML = `
<style>[__STYLES__]</style>
<b></b>
<b></b>
<b></b>
<slot></slot>`;
customElements.define(
'm-burger',
class extends HTMLElement {
/** The menu node. */
menuNode: HTMLElement = null;
/** API for the menu. */
menuApi: {
bind: Function;
open: Function;
} = null;
constructor() {
super();
// Attach shadow DOM
var content = mBurger.content.cloneNode(true);
this.attachShadow({ mode: 'open' }).appendChild(content);
}
static get observedAttributes() {
return ['menu'];
}
attributeChangedCallback(name, oldValue, newValue) {
if (name == 'menu') {
// Initiate the new menu.
this.initMenu(newValue);
}
}
connectedCallback() {
// Open the menu when clicking the hamburger.
this.addEventListener('click', evnt => {
// If there is no API for a menu available (the menu isn't yet initiated),
// try to initiate the menu.
if (!this.menuApi) {
this.initMenu();
}
// If there is an API for a menu available,
// open the menu.
if (this.menuApi && this.menuApi.open) {
this.menuApi.open();
}
});
}
/**
* Set the menu node and API.
* @param {string} [id] The ID-attribute for the menu node.
*/
initMenu(id?: string) {
this.menuNode = null;
this.menuApi = null;
if (!id) {
id = this.getAttribute('menu');
}
if (id) {
this.menuNode = document.getElementById(id);
}
if (this.menuNode) {
this.menuApi =
this.menuNode['mmApi'] || this.menuNode['mmenu'] || null;
}
// Change the hamburger state when opening and closing the menu.
if (this.menuApi) {
this.menuApi.bind('open:after', () => {
this.setAttribute('state', 'cross');
});
this.menuApi.bind('close:after', () => {
this.removeAttribute('state');
});
}
}
}
);

8
tsconfig.json Normal file
View File

@ -0,0 +1,8 @@
{
"include": [
"src/**/*"
],
"compilerOptions": {
"target": "es6"
}
}