Initial commit

This commit is contained in:
Alexander Bell 2018-06-04 12:59:23 -07:00
parent 36f2c92c35
commit 1fdc4e17f6
6 changed files with 379 additions and 22 deletions

View File

@ -11,11 +11,25 @@ Never ever worry about a fancy dropdown menu. This component does it for you!
# Usage
`import Menu from 'react-animated-menus'`
Component usage:
`<Menu width={"20px"} color="rgb(123, 192, 222)" />`
Replace `width` optionally width `height` but don't use both at the same time.
To keep the ratio between height and width one has to be given and the other one is calculated by the component.
One example with height:
`<Menu height={"50px"}" />`
`color` is optional. The defaul value is `rgb(255, 255, 255)` if it's not defined.
# Contact
**Github:** https://github.com/aleabodo
**Wesite:** https://alexbell.de
**Wesite:** https://alexbell.ninja
**Email:** mail@alexbell.de

51
package-lock.json generated
View File

@ -3060,6 +3060,57 @@
"integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=",
"dev": true
},
"css-loader": {
"version": "0.28.11",
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.11.tgz",
"integrity": "sha512-wovHgjAx8ZIMGSL8pTys7edA1ClmzxHeY6n/d97gg5odgsxEgKjULPR0viqyC+FWMCL9sfqoC/QCUBo62tLvPg==",
"dev": true,
"requires": {
"babel-code-frame": "6.26.0",
"css-selector-tokenizer": "0.7.0",
"cssnano": "3.10.0",
"icss-utils": "2.1.0",
"loader-utils": "1.1.0",
"lodash.camelcase": "4.3.0",
"object-assign": "4.1.1",
"postcss": "5.2.18",
"postcss-modules-extract-imports": "1.2.0",
"postcss-modules-local-by-default": "1.2.0",
"postcss-modules-scope": "1.1.0",
"postcss-modules-values": "1.3.0",
"postcss-value-parser": "3.3.0",
"source-list-map": "2.0.0"
},
"dependencies": {
"has-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
"integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
"dev": true
},
"postcss": {
"version": "5.2.18",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
"integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
"dev": true,
"requires": {
"chalk": "1.1.3",
"js-base64": "2.4.5",
"source-map": "0.5.7",
"supports-color": "3.2.3"
}
},
"supports-color": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
"integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
"dev": true,
"requires": {
"has-flag": "1.0.0"
}
}
}
},
"css-select": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",

View File

@ -5,7 +5,7 @@
"main": "./lib/index.js",
"license": "MIT",
"scripts": {
"build": "webpack"
"build": "webpack"
},
"peerDependencies": {
"prop-types": "^15.6.0",
@ -20,6 +20,7 @@
"babel-preset-env": "^1.6.1",
"babel-preset-react": "^6.16.0",
"babel-preset-stage-0": "^6.24.1",
"css-loader": "^0.28.11",
"path": "^0.12.7",
"prop-types": "^15.6.0",
"react": "^16.0.0",

232
src/components/Menu.js Normal file
View File

@ -0,0 +1,232 @@
import React, { Component } from 'react';
import anime from 'animejs'
/*
* css
*/
import '../styles/Menu.css'
class App extends Component {
constructor(props) {
super(props);
/*
* Expected props:
* - width: Int in percentage
* - OR height: Int in percentage
* - color: String
*/
this.state = {
id: this.getId(),
open: false
}
}
componentDidMount() {
//Event listener for click
document.addEventListener("click", (event) => {
const id = this.state.id;
const open = this.state.open;
if(event.target.closest('#'+id) && !open) {
this.setState({
open: true
});
}
if(!event.target.closest('#'+id) && open) {
this.setState({
open: false
});
}
});
}
componentDidUpdate() {
const id = this.state.id;
//Targets that will be triggered
var targetDots = document.querySelectorAll('#'+id+' .Menu_dot');
var targetElement = document.querySelectorAll('#'+id+' .Menu_element');
var targetElements = document.querySelector('#'+id+' .Menu_elements');
var targetMenu = document.querySelector('#'+id+'.Menu');
if(this.state.open) {
var animation = anime.timeline();
//Display elements
targetElements.style.display = "block";
//Remove hover effect
targetMenu.classList.remove("Menu_closed");
animation
.add({
targets: targetDots,
scaleX: 9,
scaleY: 10,
borderRadius: 0,
duration: 1300,
translateY: "40%",
backgroundColor: "rgb(255, 255, 255)",
easing: 'easeOutExpo'
})
.add({
targets: targetElement,
scaleX: [2,1],
opacity: 1,
duration: function(targetElements, i, l) {
return 500 + (i * 200);
},
easing: 'easeInOutQuart',
offset: '-=1100'
});
} else {
animation = anime.timeline();
const color = this.getColor();
//Remove hover effect
targetMenu.classList.add("Menu_closed");
animation
.add({
targets: targetElement,
scaleX: [1,2],
opacity: 0,
duration: function(targetElements, i, l) {
return 500 + (i * 200);
},
easing: 'easeInOutQuart'
})
.add({
targets: targetDots,
scaleX: 1,
scaleY: 1,
borderRadius: "100%",
duration: 1300,
translateY: 0,
backgroundColor: color,
easing: 'easeOutExpo',
offset: '-=500'
});
//Remove menu after animation finished
animation.complete = function() {
targetElements.style.display = "none";
};
}
}
getId() {
var random = "";
var possible = "abcdefghijklmnopqrstuvwxyz";
for (var i = 0; i < 5; i++)
random += possible.charAt(Math.floor(Math.random() * possible.length));
while(true) {
if(!document.getElementById(random)) {
return random;
}
}
}
getDimensions() {
//Input values
const inputWidth = this.props.width;
const inputHeight = this.props.height;
if(!(inputWidth ||inputHeight)) {
console.log("Please define a height OR width!");
}
console.log(inputWidth)
//Units and values seperated
if(inputWidth !== undefined) {
//Width
const unitWidth = inputWidth.replace(/[\d]+/g,"");
const valueWidth = parseFloat(inputWidth);
//Height
const unitHeight = unitWidth;
const valueHeight = valueWidth * 2.5;
return {
width: String(valueWidth) + unitWidth,
height: String(valueHeight) + unitHeight
}
}
//Height
const unitHeight = inputHeight.replace(/[\d]+/g,"");
const valueHeight = parseFloat(inputHeight);
//Width
const unitWidth = unitHeight;
const valueWidth = valueHeight / 2.5;
return {
width: String(valueWidth) + unitWidth,
height: String(valueHeight) + unitHeight
}
}
getColor() {
return this.props.color ? this.props.color : "rgb(255, 255, 255)";
}
render() {
const style = {
width: this.getDimensions().width,
height: this.getDimensions().height
};
console.log(style.height);
const styleDot = {
backgroundColor: this.getColor()
};
return (
<div style={style} id={this.state.id} className="Menu Menu_closed">
<div className="Menu_dots">
<div className="Menu_dotBox">
<div style={styleDot} className="Menu_dot">
</div>
</div>
<div className="Menu_dotBox">
<div style={styleDot} className="Menu_dot">
</div>
</div>
<div className="Menu_dotBox">
<div style={styleDot} className="Menu_dot">
</div>
</div>
</div>
<div className="Menu_elements">
<div className="Menu_button Menu_element">
Button
</div>
<div className="Menu_button Menu_element">
Button
</div>
<div className="Menu_button Menu_element">
Button
</div>
</div>
</div>
);
}
}
export default App;

View File

@ -1,24 +1,5 @@
import React, { Component } from 'react';
class Menu extends Component {
constructor(props) {
super(props);
/*
* Expected props:
* /
*/
this.currentImageIs_A = true;
}
render() {
return (
<div>
Hello
</div>
);
}
}
import Menu from './components/Menu';
export default Menu;

78
src/styles/Menu.css Normal file
View File

@ -0,0 +1,78 @@
.Menu {
position: relative;
background-color: transparent;
overflow: visible;
transition: opacity 0.5s;
border-radius: 20%;
cursor: pointer;
}
.Menu_closed:hover {
opacity: 0.7;
}
.Menu_dots {
position: absolute;
top: 0;
width: 100%;
height: 100%;
overflow: visible;
}
.Menu_dotBox {
position: relative;
width: 100%;
height: 33.33%;
background-color: transparent;
}
.Menu_dot {
position: absolute;
width: 70%;
height: 70%;
border-radius: 100%;
top: 15%;
left: 15%;
transition: opacity 0.4s;
}
.Menu:hover .Menu_dot {
opacity: 1;
}
.Menu_elements {
position: absolute;
top: -6.5%;
left: -265%;
width: 644%;
height: 306%;
background-color: transparent;
display: none;
overflow: visible;
}
.Menu_element {
position: relative;
width: 100%;
height: 33.33%;
font-size: 0.8em;
text-align: center;
padding-top: 15%;
box-sizing: border-box;
}
.Menu_button {
width: 100%;
background-color: white;
transition: background-color 0.5s, padding 0.5s;
opacity: 0;
}
.Menu_button:hover {
background-color: rgb(227, 227, 227);
padding-left: 5%;
}
.Menu_button:active {
transition: background-color 0.1s;
background-color: rgb(207, 207, 207);
padding-left: 5%;
}