content logo

React Buttons:

Circular Floating Menu Buttons at Page Corner using React

As you can see, the button we have prepared for you in this post is located in the corners of the image. This button has a hover effect. By placing the mouse cursor on the button, the other three buttons appear in front of the button and in a semicircular arc. These buttons are all gray and have a black icon. The buttons that are displayed during the hover are red and have a white icon.

#

Free Floating Buttons Code

#

React Floating Button

#

HTML Circular Button Code

#

React Circulat Floating Menu

<!-- This script got from frontendfreecode.com -->
<div id="app"></div><a style="font-size: 8pt; text-decoration: none" target="_blank" href="http://frontendfreecode.com">Free Frontend</a>
                                                                            
html, body, #app {
  height: 100%;
}
.container {
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  background: linear-gradient(to left, #3182d5, #4e54c8);
}
.container h3 {
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
  color: #ffffff;
  font-size: 6vw;
}
@media (min-width: 768px) {
  .container h3 {
    font-size: 5vw;
  }
}
@media (min-width: 992px) {
  .container h3 {
    font-size: 3vw;
  }
}
.toggle-nav {
  position: fixed;
  z-index: 10;
  width: 40px;
  height: 40px;
  display: flex;
  justify-content: flex-end;
  align-items: flex-end;
  transition: all 0.2s ease;
}
.toggle-nav button {
  border-radius: 50%;
  border: none;
  outline: none;
  cursor: pointer;
  min-width: 40px;
  min-height: 40px;
  padding: 13px;
  position: absolute;
  opacity: 0.9;
}
.toggle-nav button.main-button {
  z-index: 20;
}
.toggle-nav button.sub-button {
  opacity: 0;
  background-color: #d41672;
  color: #ffffff;
}
const { useState, useEffect, useRef, Fragment } = React;
//custom hooks
const useOutsideClick = (ref, callback) => {
  const handleClick = e => {
    if (ref.current && !ref.current.contains(e.target)) {
      callback();
    }
  };
  useEffect(() => {
    document.addEventListener('click', handleClick);
    return () => {
      document.removeEventListener('click', handleClick);
    };
  });
};
const useTouchScreenDetect = () => {
  const isSSR = typeof window === 'undefined',
  [isTouchScreen, setIsTouchScreen] = useState(false);
  useEffect(() => {
    if (!isSSR) {
      setIsTouchScreen(
      'ontouchstart' in document.documentElement ||
      navigator.maxTouchPoints > 0 ||
      navigator.msMaxTouchPoints > 0);
    }
  }, [isTouchScreen, isSSR]);
  return isTouchScreen;
};
const FloatingButton = ({ location, buttons, mainButtonIcon }) => {
  const [isHover, setIsHover] = useState(false),
  isHasTouch = useTouchScreenDetect(),
  ref = useRef(),
  radius = 25,
  buttonsLength = buttons.length,
  navigatorDimensions = radius * buttonsLength * 1.6,
  circleRadius = radius * buttonsLength;
  useOutsideClick(ref, () => {
    if (isHasTouch) {
      setIsHover(false);
    }
  });
  const setNavigatorLocation = () => {
    switch (location) {
      case 'top-left':
        return {
          container: {
            top: 10,
            right: 'auto',
            bottom: 'auto',
            left: 10 },
          mainButton: {
            top: 0,
            right: 'auto',
            bottom: 'auto',
            left: 0 } };
      case 'top-right':
        return {
          container: {
            top: 10,
            right: 10,
            bottom: 'auto',
            left: 'auto' },
          mainButton: {
            top: 0,
            right: 0,
            bottom: 'auto',
            left: 'auto' } };
      case 'bottom-left':
        return {
          container: {
            top: 'auto',
            right: 'auto',
            bottom: 10,
            left: 10 },
          mainButton: {
            top: 'auto',
            right: 'auto',
            bottom: 0,
            left: 0 } };
      default:
        return {
          container: {
            top: 'auto',
            right: 10,
            bottom: 10,
            left: 'auto' },
          mainButton: {
            top: 'auto',
            right: 0,
            bottom: 0,
            left: 'auto' } };}
  };
  const setButtonPosition = index => {
    switch (location) {
      case 'top-left':
        return {
          top: Math.round(circleRadius * Math.sin(Math.PI / 2 / (buttonsLength - 1) * index)),
          right: 'auto',
          bottom: 'auto',
          left: Math.round(circleRadius * Math.cos(Math.PI / 2 / (buttonsLength - 1) * index)) };
      case 'top-right':
        return {
          top: Math.round(circleRadius * Math.sin(Math.PI / 2 / (buttonsLength - 1) * index)),
          right: Math.round(circleRadius * Math.cos(Math.PI / 2 / (buttonsLength - 1) * index)),
          bottom: 'auto',
          left: 'auto' };
      case 'bottom-left':
        return {
          top: 'auto',
          right: 'auto',
          bottom: Math.round(circleRadius * Math.sin(Math.PI / 2 / (buttonsLength - 1) * index)),
          left: Math.round(circleRadius * Math.cos(Math.PI / 2 / (buttonsLength - 1) * index)) };
      default:
        return {
          top: 'auto',
          right: Math.round(circleRadius * Math.cos(Math.PI / 2 / (buttonsLength - 1) * index)),
          bottom: Math.round(circleRadius * Math.sin(Math.PI / 2 / (buttonsLength - 1) * index)),
          left: 'auto' };}
  };
  const mouseEnterHandler = () => {
    setIsHover(true);
  };
  const mouseLeaveHandler = () => {
    setIsHover(false);
  };
  const clickHandler = handler => {
    mouseLeaveHandler();
    handler();
  };
  const { container, mainButton } = setNavigatorLocation();
  return /*#__PURE__*/(
    React.createElement(Fragment, null,
    buttonsLength > 1 ? /*#__PURE__*/
    React.createElement("div", {
      ref: ref,
      onMouseEnter: !isHasTouch ? mouseEnterHandler : () => {},
      onMouseLeave: !isHasTouch ? mouseLeaveHandler : () => {},
      className: "toggle-nav",
      style: {
        top: container.top,
        right: container.right,
        bottom: container.bottom,
        left: container.left,
        width: isHover ? navigatorDimensions : 40,
        height: isHover ? navigatorDimensions : 40 } }, /*#__PURE__*/
    React.createElement("button", {
      className: "main-button",
      style: {
        top: mainButton.top,
        right: mainButton.right,
        bottom: mainButton.bottom,
        left: mainButton.left },
      onClick: isHasTouch ? mouseEnterHandler : () => {} },
    mainButtonIcon),
    buttons.map((el, i) => /*#__PURE__*/
    React.createElement(Fragment, { key: i }, /*#__PURE__*/
    React.createElement("button", {
      className: "sub-button",
      style: {
        opacity: isHover ? 0.9 : 0,
        top: isHover ?
        setButtonPosition(i).top :
        setButtonPosition(i).top === 'auto' ?
        'auto' :
        0,
        right: isHover ?
        setButtonPosition(i).right :
        setButtonPosition(i).right === 'auto' ?
        'auto' :
        0,
        bottom: isHover ?
        setButtonPosition(i).bottom :
        setButtonPosition(i).bottom === 'auto' ?
        'auto' :
        0,
        left: isHover ?
        setButtonPosition(i).left :
        setButtonPosition(i).left === 'auto' ?
        'auto' :
        0,
        transition: `all 0.2s 0.${i + 1}s ease` },
      onClick: () => clickHandler(el.click) },
    el.icon)))) : /*#__PURE__*/
    React.createElement("div", {
      className: "toggle-nav",
      style: {
        top: container.top,
        right: container.right,
        bottom: container.bottom,
        left: container.left,
        width: 150 } }, "Must be more than one button")));
};
FloatingButton.propTypes = {
  location: PropTypes.string,
  buttons: PropTypes.array.isRequired,
  mainButtonIcon: PropTypes.node.isRequired };
const App = () => {
  const buttons = [
  {
    icon: /*#__PURE__*/React.createElement("i", { className: "fas fa-home" }),
    click: () => console.log("clicked") },
  {
    icon: /*#__PURE__*/React.createElement("i", { className: "fas fa-briefcase" }),
    click: () => console.log("clicked") },
  {
    icon: /*#__PURE__*/React.createElement("i", { className: "fas fa-phone" }),
    click: () => console.log("clicked") }];
  return /*#__PURE__*/(
    React.createElement("div", { className: "container" }, /*#__PURE__*/
    React.createElement("h3", null, "Hover over the buttons"), /*#__PURE__*/
    React.createElement(FloatingButton, {
      location: "top-left",
      buttons: buttons,
      mainButtonIcon: /*#__PURE__*/React.createElement("i", { className: "fas fa-info" }) }), /*#__PURE__*/
    React.createElement(FloatingButton, {
      location: "top-right",
      buttons: buttons,
      mainButtonIcon: /*#__PURE__*/React.createElement("i", { className: "fas fa-info" }) }), /*#__PURE__*/
    React.createElement(FloatingButton, {
      location: "bottom-left",
      buttons: buttons,
      mainButtonIcon: /*#__PURE__*/React.createElement("i", { className: "fas fa-info" }) }), /*#__PURE__*/
    React.createElement(FloatingButton, {
      location: "bottom-right",
      buttons: buttons,
      mainButtonIcon: /*#__PURE__*/React.createElement("i", { className: "fas fa-info" }) })));
};
ReactDOM.render( /*#__PURE__*/React.createElement(App, null), document.querySelector("#app"));
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css">
<script src='https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.development.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.development.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.7.2/prop-types.js'></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- This script got from frontendfreecode.com -->

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css">
<script src='https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.development.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.development.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.7.2/prop-types.js'></script>
<style>
html, body, #app {
  height: 100%;
}
.container {
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  background: linear-gradient(to left, #3182d5, #4e54c8);
}
.container h3 {
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
  color: #ffffff;
  font-size: 6vw;
}
@media (min-width: 768px) {
  .container h3 {
    font-size: 5vw;
  }
}
@media (min-width: 992px) {
  .container h3 {
    font-size: 3vw;
  }
}
.toggle-nav {
  position: fixed;
  z-index: 10;
  width: 40px;
  height: 40px;
  display: flex;
  justify-content: flex-end;
  align-items: flex-end;
  transition: all 0.2s ease;
}
.toggle-nav button {
  border-radius: 50%;
  border: none;
  outline: none;
  cursor: pointer;
  min-width: 40px;
  min-height: 40px;
  padding: 13px;
  position: absolute;
  opacity: 0.9;
}
.toggle-nav button.main-button {
  z-index: 20;
}
.toggle-nav button.sub-button {
  opacity: 0;
  background-color: #d41672;
  color: #ffffff;
}
</style>

</head>
<body>
<div id="app"></div><div id="bcl"><a style="font-size:8pt;text-decoration:none;" href="http://www.devanswer.com">Free Frontend</a></div>
<script>
const { useState, useEffect, useRef, Fragment } = React;
//custom hooks
const useOutsideClick = (ref, callback) => {
  const handleClick = e => {
    if (ref.current && !ref.current.contains(e.target)) {
      callback();
    }
  };
  useEffect(() => {
    document.addEventListener('click', handleClick);
    return () => {
      document.removeEventListener('click', handleClick);
    };
  });
};
const useTouchScreenDetect = () => {
  const isSSR = typeof window === 'undefined',
  [isTouchScreen, setIsTouchScreen] = useState(false);
  useEffect(() => {
    if (!isSSR) {
      setIsTouchScreen(
      'ontouchstart' in document.documentElement ||
      navigator.maxTouchPoints > 0 ||
      navigator.msMaxTouchPoints > 0);
    }
  }, [isTouchScreen, isSSR]);
  return isTouchScreen;
};
const FloatingButton = ({ location, buttons, mainButtonIcon }) => {
  const [isHover, setIsHover] = useState(false),
  isHasTouch = useTouchScreenDetect(),
  ref = useRef(),
  radius = 25,
  buttonsLength = buttons.length,
  navigatorDimensions = radius * buttonsLength * 1.6,
  circleRadius = radius * buttonsLength;
  useOutsideClick(ref, () => {
    if (isHasTouch) {
      setIsHover(false);
    }
  });
  const setNavigatorLocation = () => {
    switch (location) {
      case 'top-left':
        return {
          container: {
            top: 10,
            right: 'auto',
            bottom: 'auto',
            left: 10 },
          mainButton: {
            top: 0,
            right: 'auto',
            bottom: 'auto',
            left: 0 } };
      case 'top-right':
        return {
          container: {
            top: 10,
            right: 10,
            bottom: 'auto',
            left: 'auto' },
          mainButton: {
            top: 0,
            right: 0,
            bottom: 'auto',
            left: 'auto' } };
      case 'bottom-left':
        return {
          container: {
            top: 'auto',
            right: 'auto',
            bottom: 10,
            left: 10 },
          mainButton: {
            top: 'auto',
            right: 'auto',
            bottom: 0,
            left: 0 } };
      default:
        return {
          container: {
            top: 'auto',
            right: 10,
            bottom: 10,
            left: 'auto' },
          mainButton: {
            top: 'auto',
            right: 0,
            bottom: 0,
            left: 'auto' } };}
  };
  const setButtonPosition = index => {
    switch (location) {
      case 'top-left':
        return {
          top: Math.round(circleRadius * Math.sin(Math.PI / 2 / (buttonsLength - 1) * index)),
          right: 'auto',
          bottom: 'auto',
          left: Math.round(circleRadius * Math.cos(Math.PI / 2 / (buttonsLength - 1) * index)) };
      case 'top-right':
        return {
          top: Math.round(circleRadius * Math.sin(Math.PI / 2 / (buttonsLength - 1) * index)),
          right: Math.round(circleRadius * Math.cos(Math.PI / 2 / (buttonsLength - 1) * index)),
          bottom: 'auto',
          left: 'auto' };
      case 'bottom-left':
        return {
          top: 'auto',
          right: 'auto',
          bottom: Math.round(circleRadius * Math.sin(Math.PI / 2 / (buttonsLength - 1) * index)),
          left: Math.round(circleRadius * Math.cos(Math.PI / 2 / (buttonsLength - 1) * index)) };
      default:
        return {
          top: 'auto',
          right: Math.round(circleRadius * Math.cos(Math.PI / 2 / (buttonsLength - 1) * index)),
          bottom: Math.round(circleRadius * Math.sin(Math.PI / 2 / (buttonsLength - 1) * index)),
          left: 'auto' };}
  };
  const mouseEnterHandler = () => {
    setIsHover(true);
  };
  const mouseLeaveHandler = () => {
    setIsHover(false);
  };
  const clickHandler = handler => {
    mouseLeaveHandler();
    handler();
  };
  const { container, mainButton } = setNavigatorLocation();
  return /*#__PURE__*/(
    React.createElement(Fragment, null,
    buttonsLength > 1 ? /*#__PURE__*/
    React.createElement("div", {
      ref: ref,
      onMouseEnter: !isHasTouch ? mouseEnterHandler : () => {},
      onMouseLeave: !isHasTouch ? mouseLeaveHandler : () => {},
      className: "toggle-nav",
      style: {
        top: container.top,
        right: container.right,
        bottom: container.bottom,
        left: container.left,
        width: isHover ? navigatorDimensions : 40,
        height: isHover ? navigatorDimensions : 40 } }, /*#__PURE__*/
    React.createElement("button", {
      className: "main-button",
      style: {
        top: mainButton.top,
        right: mainButton.right,
        bottom: mainButton.bottom,
        left: mainButton.left },
      onClick: isHasTouch ? mouseEnterHandler : () => {} },
    mainButtonIcon),
    buttons.map((el, i) => /*#__PURE__*/
    React.createElement(Fragment, { key: i }, /*#__PURE__*/
    React.createElement("button", {
      className: "sub-button",
      style: {
        opacity: isHover ? 0.9 : 0,
        top: isHover ?
        setButtonPosition(i).top :
        setButtonPosition(i).top === 'auto' ?
        'auto' :
        0,
        right: isHover ?
        setButtonPosition(i).right :
        setButtonPosition(i).right === 'auto' ?
        'auto' :
        0,
        bottom: isHover ?
        setButtonPosition(i).bottom :
        setButtonPosition(i).bottom === 'auto' ?
        'auto' :
        0,
        left: isHover ?
        setButtonPosition(i).left :
        setButtonPosition(i).left === 'auto' ?
        'auto' :
        0,
        transition: `all 0.2s 0.${i + 1}s ease` },
      onClick: () => clickHandler(el.click) },
    el.icon)))) : /*#__PURE__*/
    React.createElement("div", {
      className: "toggle-nav",
      style: {
        top: container.top,
        right: container.right,
        bottom: container.bottom,
        left: container.left,
        width: 150 } }, "Must be more than one button")));
};
FloatingButton.propTypes = {
  location: PropTypes.string,
  buttons: PropTypes.array.isRequired,
  mainButtonIcon: PropTypes.node.isRequired };
const App = () => {
  const buttons = [
  {
    icon: /*#__PURE__*/React.createElement("i", { className: "fas fa-home" }),
    click: () => console.log("clicked") },
  {
    icon: /*#__PURE__*/React.createElement("i", { className: "fas fa-briefcase" }),
    click: () => console.log("clicked") },
  {
    icon: /*#__PURE__*/React.createElement("i", { className: "fas fa-phone" }),
    click: () => console.log("clicked") }];
  return /*#__PURE__*/(
    React.createElement("div", { className: "container" }, /*#__PURE__*/
    React.createElement("h3", null, "Hover over the buttons"), /*#__PURE__*/
    React.createElement(FloatingButton, {
      location: "top-left",
      buttons: buttons,
      mainButtonIcon: /*#__PURE__*/React.createElement("i", { className: "fas fa-info" }) }), /*#__PURE__*/
    React.createElement(FloatingButton, {
      location: "top-right",
      buttons: buttons,
      mainButtonIcon: /*#__PURE__*/React.createElement("i", { className: "fas fa-info" }) }), /*#__PURE__*/
    React.createElement(FloatingButton, {
      location: "bottom-left",
      buttons: buttons,
      mainButtonIcon: /*#__PURE__*/React.createElement("i", { className: "fas fa-info" }) }), /*#__PURE__*/
    React.createElement(FloatingButton, {
      location: "bottom-right",
      buttons: buttons,
      mainButtonIcon: /*#__PURE__*/React.createElement("i", { className: "fas fa-info" }) })));
};
ReactDOM.render( /*#__PURE__*/React.createElement(App, null), document.querySelector("#app"));
</script>

</body>
</html>
Preview