Initial commit
This commit is contained in:
232
src/components/Menu.js
Normal file
232
src/components/Menu.js
Normal 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;
|
21
src/index.js
21
src/index.js
@ -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
78
src/styles/Menu.css
Normal 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%;
|
||||
}
|
Reference in New Issue
Block a user