Learning React(11. React 슬라이드 메뉴)

min seung moon·2021년 8월 11일
1

Learning React

목록 보기
11/15
post-thumbnail

1. 슬라이드 메뉴

01. 슬라이드 메뉴의 작동 원리

  • 메뉴는 콘텐츠 화면의 왼쪽에 존재하며, 호출되기 전까지는 그 자리에서 대기 하고 있다
    • 이는 메뉴의 위치를 화면에 보이지 않을 때 까지 최대한 왼쪽으로 이동 시킴으로서 가능하다
    • 메뉴의 크기는 브라우저창(뷰포트)과 같다, 그래야 메뉴가 화면 전체를 덮을 수 있기 때문이다
  • 이렇게 할 수 있는 CSS
#theMenu {
	position : fixed;
    	left : 0;
        top : 0;
        transform : translated3d(-100vw, 0, 0);
        
        width : 100vw;
        height : 100vh;
}
  • 메뉴를 중앙에 배치하고 싶을 때
transform : translated3d(0vw, 0, 0);
  • 메뉴를 왼쪽 밖으로 배치하고 싶을 때
transform : translated3d(-100vw, 0, 0);
  • 슬라이드 애니메이션
    • cubic-bezier() function은 CSS에서 transition 속성 혹은 transition-timing-function 속성에서 전환 시작과 끝까지의 효과를 제어하는데 쓰인다
transition : transform .3s cubic-bezier(0, 52, 0, 1);

02. 개발 전 구성도

03. 시작하기

-1. create-react-app slidingmenu

  • public과 src 폴더를 깔끔하게 다른 파일은 지원준다

-2. public / index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Sliding Menu in React</title>
</head>
<body>
  <div id="container"></div>
</body>
</html>

-3. src / index.js

import React from 'react';
import ReactDom from 'react-dom';
import "./index.css";
import MenuContainer from "./MenuContainer";

ReactDom.render(
  <MenuContainer/>,
  document.getElementById("container")
);

-4. src / index.css

body {
  background-color: #EEE;
  font-family: sans-serif;
  padding: 25px;
  margin: 0;
  overflow: auto;
}

#container li{
  margin-bottom: 10px;
}

-5. src / MenuContainer.js

import React, {Component} from 'react';

class MenuContainer extends Component {
  render() {
    return (
      <div>
        <div>
          <p>Can you spot the item that doesn't belong?</p>
          <ul>
            <li>Lorem</li>
            <li>Ipsum</li>
            <li>Dolor</li>
            <li>Sit</li>
            <li>Bumblebees</li>
            <li>Aenean</li>
            <li>Consectetur</li>
          </ul>
        </div>
      </div>
    )
  }
}

export default MenuContainer;

04. 메뉴 보이기와 감추기

    1. 버튼을 클릭하면 슬라이드 메뉴가 화면에 나타난다
    1. 아무 곳이나 클릭하면 슬라이드 메뉴는 화면 밖으로 다시 사라진다

-1. src / MenuContainer.js

  • visible이 true이냐 false이냐에 따라 메뉴를 보이게 할지 안할지를 결정한다
import React, { Component } from "react";

class MenuContainer extends Component {
  constructor(props) {
    super(props);

    this.state = {
      visible : false,
    };

    this.handleMouseDown = this.handleMouseDown.bind(this);
    this.toggleMenu = this.toggleMenu.bind(this);
  }

  handleMouseDown(e) {
    this.toggleMenu();

    console.log("clicked");
    e.stopPropagation();
  }

  toggleMenu() {
    this.setState({
      visible : !this.state.visible
    });
  }

  render() {
    return (
      <div>
        <div>
          <p>Can you spot the item that doesn't belong?</p>
          <ul>
            <li>Lorem</li>
            <li>Ipsum</li>
            <li>Dolor</li>
            <li>Sit</li>
            <li>Bumblebees</li>
            <li>Aenean</li>
            <li>Consectetur</li>
          </ul>
        </div>
      </div>
    );
  }
}

export default MenuContainer;

-2. src / MenuButton.js

import React, { Component } from "react";
import "./MenuButton.css";

class MenuButton extends Component {
  render() {
    return (
      <button
        id="roundButton"
        onMouseDown={this.props.handleMouseDown}
      ></button>
    );
  }
}

export default MenuButton;

-3. (버튼제작) src / MenuButton.css

#roundButton {
  background-color: #96D9FF;
  margin-bottom: 20px;
  width: 50px;
  height: 50px;
  border-radius: 50%;
  border: 10px solid #0065A6;
  outline: none;
  transition: all .2s cubic-bezier(0, 1.26, .8, 1.28);
}

#roundButton:hover {
  background-color: #96D9FF;
  cursor: pointer;
  border-color: #003557;
  transform: scale(1.2, 1.2);
}

#roundButton:active {
  border-color: #003557;
  background-color: #FFF;
}

-4. src / MenuContainer.js

import React, { Component } from "react";
import MenuButton from "./MenuButton";

class MenuContainer extends Component {
  constructor(props) {
    super(props);

    this.state = {
      visible: false,
    };

    this.handleMouseDown = this.handleMouseDown.bind(this);
    this.toggleMenu = this.toggleMenu.bind(this);
  }

  handleMouseDown(e) {
    this.toggleMenu();

    console.log("clicked");
    e.stopPropagation();
  }

  toggleMenu() {
    this.setState({
      visible: !this.state.visible,
    });
  }

  render() {
    return (
      <div>
        <MenuButton handleMouseDown={this.handleMouseDown} />
        <div>
          <p>Can you spot the item that doesn't belong?</p>
          <ul>
            <li>Lorem</li>
            <li>Ipsum</li>
            <li>Dolor</li>
            <li>Sit</li>
            <li>Bumblebees</li>
            <li>Aenean</li>
            <li>Consectetur</li>
          </ul>
        </div>
      </div>
    );
  }
}

export default MenuContainer;



-4. (메뉴 제작) src / Menu.js

import React, { Component } from "react";
import "./Menu.css";

class Menu extends Component {
  render() {
    var visibility = "hide";

    if (this.props.menuVisibility) {
      visibility = "show";
    }
    return (
      <div
        id="flyoutMenu"
        onMouseDown={this.props.handleMouseDown}
        className={visibility}
      >
        <h2>
          <a href="/">Home</a>
        </h2>
        <h2>
          <a href="/">About</a>
        </h2>
        <h2>
          <a href="/">Contact</a>
        </h2>
        <h2>
          <a href="/">Search</a>
        </h2>
      </div>
    );
  }
}

export default Menu;

-5. src / Menu.css

#flyoutMenu {
  width: 100vw;
  height: 100vh;
  background-color: #FFE600;
  position: fixed;
  top: 0;
  left: 0;
  transition: transform .3s cubic-bezier(0, .52, 0, 1);
  overflow: scroll;
  z-index: 1000;
}

#flyoutMenu.hide {
  transform: translate3d(-100vw, 0, 0);
}

#flyoutMenu.show {
  transform: translate3d(0vw, 0, 0);
  overflow: hidden;
}

#flyoutMenu h2 a {
  color: #333;
  margin-left: 15px;
  text-decoration: none;
}

#flyoutMenu h2 a:hover {
  text-decoration: underline;
}

-6. src / MenuContainer.js

import React, { Component } from "react";
import MenuButton from "./MenuButton";
import Menu from "./Menu";

class MenuContainer extends Component {
  constructor(props) {
    super(props);

    this.state = {
      visible: false,
    };

    this.handleMouseDown = this.handleMouseDown.bind(this);
    this.toggleMenu = this.toggleMenu.bind(this);
  }

  handleMouseDown(e) {
    this.toggleMenu();

    console.log("clicked");
    e.stopPropagation();
  }

  toggleMenu() {
    this.setState({
      visible: !this.state.visible,
    });
  }

  render() {
    return (
      <div>
        <MenuButton handleMouseDown={this.handleMouseDown} />
        <Menu
          handleMouseDown={this.handleMouseDown}
          menuVisibility={this.state.visible}
        />
        <div>
          <p>Can you spot the item that doesn't belong?</p>
          <ul>
            <li>Lorem</li>
            <li>Ipsum</li>
            <li>Dolor</li>
            <li>Sit</li>
            <li>Bumblebees</li>
            <li>Aenean</li>
            <li>Consectetur</li>
          </ul>
        </div>
      </div>
    );
  }
}

export default MenuContainer;





profile
아직까지는 코린이!

0개의 댓글

관련 채용 정보