├── LICENSE ├── README.md ├── demo.html ├── infinity-burger.js └── package.json /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Zach Leatherman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # infinity-burger 2 | 3 | A new kind of hamburger menu. 4 | 5 | No library dependencies. Cuts the mustard on [`CSSStyleSheet#replaceSync`](https://caniuse.com/mdn-api_cssstylesheet_replacesync). Demo on [zachleat.com](http://www.zachleat.com/web/) and [GitHub Pages](http://zachleat.github.io/infinity-burger/demo.html). 6 | 7 | 1. Click once to start the animation. Uses a meandering horizontal position. 8 | 1. Click again to reset to the initial state, a three layer hamburger menu. 9 | 10 | ## Markup: 11 | 12 | ``` 13 | 14 | 15 | ``` 16 | 17 | ## Release Notes 18 | 19 | * `v1.0` and `v2.0`: Click states: (a) single vertical column (b) random position and rotation (c) resets back to vertical column (d) reset to three bars 20 | * `v3.0`: Simplifies the thing to two states (on and off), the menu just meanders a bit on the horizontal axis. 21 | * `v4.0`: Uses a custom element with Shadow DOM, simplifies markup and removes external stylesheet. -------------------------------------------------------------------------------- /demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Infinity Burger 7 | 12 | 13 | 14 | 15 | Back to the source code. 16 | 17 | 18 | 19 | 25 | 26 | -------------------------------------------------------------------------------- /infinity-burger.js: -------------------------------------------------------------------------------- 1 | class InfinityBurger extends HTMLElement { 2 | static register(tagName) { 3 | if("customElements" in window) { 4 | customElements.define(tagName || "infinity-burger", InfinityBurger); 5 | } 6 | } 7 | 8 | static classes = { 9 | animate: "animating" 10 | }; 11 | 12 | static props = { 13 | height: 3 // integer 14 | }; 15 | 16 | static attrs = { 17 | themeFunction: "theme-fn" 18 | }; 19 | 20 | static css = `:host { 21 | --ib-_color: var(--ib-color, #666); 22 | position: absolute; 23 | top: 1em; 24 | right: 1em; 25 | width: 1.5em; 26 | cursor: pointer; 27 | } 28 | :host div { 29 | opacity: 1; 30 | transition: transform .6s cubic-bezier(0.13, 0.49, 0.29, 0.87), 31 | opacity .6s cubic-bezier(0.13, 0.49, 0.29, 0.87); 32 | } 33 | :host div.${InfinityBurger.classes.animate} { 34 | opacity: 0; 35 | } 36 | :host div { 37 | display: block; 38 | padding-bottom: ${InfinityBurger.props.height}px; 39 | border-top: ${InfinityBurger.props.height}px solid var(--ib-_color); 40 | }`; 41 | 42 | static random( min, max ) { 43 | return Math.floor( Math.random() * ( max - min + 1 ) ) + min; 44 | } 45 | 46 | get node() { 47 | if(!this._node) { 48 | this._node = document.createElement("div"); 49 | } 50 | return this._node; 51 | } 52 | 53 | get documentWidth() { 54 | if(!this._width) { 55 | let docEl = document.documentElement; 56 | this._width = Math.max( docEl.clientWidth, docEl.scrollWidth ); 57 | } 58 | 59 | return this._width; 60 | } 61 | 62 | get documentHeight() { 63 | if(!this._height) { 64 | let docEl = document.documentElement; 65 | this._height = Math.max( docEl.clientHeight, docEl.scrollHeight ); 66 | } 67 | 68 | return this._height; 69 | } 70 | 71 | connectedCallback() { 72 | // https://caniuse.com/mdn-api_cssstylesheet_replacesync 73 | if(this.shadowRoot || !("replaceSync" in CSSStyleSheet.prototype)) { 74 | return; 75 | } 76 | 77 | this.setAttribute("aria-hidden", "true"); 78 | 79 | let root = this.attachShadow({ mode: "closed" }); 80 | let sheet = new CSSStyleSheet(); 81 | sheet.replaceSync(InfinityBurger.css); 82 | root.adoptedStyleSheets = [sheet]; 83 | 84 | this._xCoordinate = 0; 85 | this._state = 0; 86 | this._isThemed = this.hasAttribute(InfinityBurger.attrs.themeFunction); 87 | 88 | this.reset(root); 89 | 90 | this.addEventListener( 'click', () => { 91 | this._xCoordinate = 0; 92 | 93 | // reset to default state (just 3 bars) 94 | if( this._state >= 1 ) { 95 | this._state = 0; 96 | requestAnimationFrame(() => this.reset(root)); 97 | } else { 98 | // start adding hamburger layers 99 | this._state = 1; 100 | requestAnimationFrame( () => this.addLayer(root) ); 101 | } 102 | }, false ); 103 | } 104 | 105 | reset(root) { 106 | this._count = 0; 107 | 108 | root.replaceChildren(); 109 | for(let j=0, k=3; j this.addLayer(root) ); 134 | } // else, complete 135 | } 136 | } 137 | } 138 | 139 | InfinityBurger.register(); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "infinity-burger", 3 | "version": "4.0.1", 4 | "description": "A new kind of hamburger menu.", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/zachleat/infinity-burger.git" 8 | }, 9 | "scripts": { 10 | "start": "npx http-server ." 11 | }, 12 | "keywords": [ 13 | "hamburger", 14 | "menu" 15 | ], 16 | "author": "zachleat (http://zachleat.com/)", 17 | "license": "MIT", 18 | "bugs": { 19 | "url": "https://github.com/zachleat/infinity-burger/issues" 20 | }, 21 | "homepage": "https://github.com/zachleat/infinity-burger#readme" 22 | } 23 | --------------------------------------------------------------------------------