react framer-motion实现彩色选项卡tab切换效果代码

代码语言:html

所属分类:选项卡

代码描述:react framer-motion实现彩色选项卡tab切换效果代码

代码标签: 彩色 选项 tab 切换 效果

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开


<!DOCTYPE html>
<html lang="en" >

<head>

  <meta charset="UTF-8">
  

  <link href="https://fonts.googleapis.com/css?family=Karla:400,700&display=swap" rel="stylesheet"> 
  
  
  
<style>
body {
  background-color: #5B37B7;
  padding: 20px;
  margin: 0;
  font-family: Helvetica, Arial, sans-serif;
  transition: background-color 0.5s ease;
}

@media (min-width: 600px) {
  body {
    padding: 30px;
  }
}

ul, li {
  list-style: none;
  padding: 0;
  margin: 0;
}

/* Tabs */
.tabs-wrapper {
  margin: 0 auto;
  max-width: 1000px;
  padding: 20px;
  border-radius: 20px;
  background: #FFF;
}

@media (min-width: 600px) {
  .tabs-wrapper {
    padding: 40px;
  }
}

.tabs {
  display: block;
  position: relative;
}

.tabs-list {
  display: flex;
}

.tabs-list__item {
  flex: 1 1 auto;
}

@media (min-width: 600px) {
  .tabs-list__item {
    flex: initial;
  }
}

.tabs-list__tab {
  text-align: center;
  display: block;
  line-height: 60px;
  padding: 0 10px;
  background: transparent;
  color: #272727;
  position: relative;
  text-decoration: none;
  font-weight: bold;
  white-space: nowrap;
  font-size: 14px;
}

@media (min-width: 600px) {
  .tabs-list__tab {
    font-size: 16px;
    padding: 0 20px;
  }
}

.tabs-list__tab span {
  position: relative;
  color: #272727;
  transition: color 600ms cubic-bezier(0.4, 0, 0.2, 1);
}

.tabs-list__tab:before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  border-radius: 30px;
}

.tabs-list__tab:hover {
}

.tabs-list__tab.active {
}

.tabs-list__tab.active:before {
  background-color: currentColor;
}

.tabs-list__tab.active.animating:before {
  background-color: transparent;
}

.tabs-list__active {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  background-color: #dacff4;
  border-radius: 30px;
  transition: background-color 600ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* Tab Content */
.tab-content {
  background: #FFFFFF;
  padding: 10px 0 0 0;
}

.tab-content p {
  margin: 0;
  margin-top: 20px;
  font-size: 16px;
  line-height: 1.6;
}
</style>




</head>

<body  >
  <div id="root"></div>
    <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/react.production.17.1.js"></script>
    <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/react-dom.production.17.1.js"></script>
    <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/framer-motion.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/react-router-dom.js"></script>
      <script  >
const { HashRouter, Switch, Route, Redirect, Link, matchPath, useLocation } = ReactRouterDOM;
const { AnimatePresence, motion } = Motion;

const debounce = (func, wait, immediate) => {
  var timeout;
  return function () {
    var context = this,args = arguments;
    var later = function () {
      timeout = null;
      if (!immediate) func.apply(context, args);
    };
    var callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    if (callNow) func.apply(context, args);
  };
};

const Active = ({ refs, activeRoute, finishAnimating, animating }) => {
  const [{ x, width, color }, setAttributes] = React.useState({
    x: 0,
    width: 0,
    color: '#272727' });


  const updateAttributes = React.useCallback(() => {
    if (refs && refs[activeRoute]) {
      console.log(refs[activeRoute].current.style);
      setAttributes({
        x: refs[activeRoute].current.offsetLeft,
        width: refs[activeRoute].current.getBoundingClientRect().width,
        color: refs[activeRoute].current.style.color });

    }
  }, [activeRoute, refs]);

  // Update attributes if active route changes (or refs change)
  React.useEffect(() => {
    updateAttributes();
  }, [activeRoute, refs, updateAttributes]);

  // After window resize, recalculate
  React.useEffect(() => {
    const recalculateAttrs = debounce(() => {
      updateAttributes();
    }, 500);

    window.addEventListener('resize', recalculateAttrs);
    return () => {
      window.removeEventListener('resize', recalculateAttrs);
    };
  });

  return /*#__PURE__*/(
    React.createElement(motion.div, {
      className: "tabs-list__active",
      animate: {
        x,
        width },

      style: {
        opacity: animating ? 1 : 0,
        backgroundColor: color },

      onAnimationComplete: finishAnimating }));


};

const Tab = React.forwardRef(
({ active, item, animating, startAnimating }, ref) => /*#__PURE__*/
React.createElement("li", {
  className: "tabs-list__item",
  key: `tab-${item.route}` }, /*#__PURE__*/

React.createElement(Link, {
  to: item.route,
  className: `tabs-list__tab ${active ? 'active' : 'inactive'} ${animating ? 'animating' : ''}`,
  ref: ref,
  onClick: startAnimating,
  style: { color: item.colour } }, /*#__PURE__*/

React.createElement("span", { style: {
    color: active ? item.bgColour : '#272727' } },
item.name))));





const Tabs = ({ items }) => {
  const [animating, setAnimating] = React.useState(false);

  const tabRefs = items.reduce((acc, item) => {
    acc[item.route] = React.createRef();
    return acc;
  }, {});

  const location = useLocation();

  // Find active path
  const active = items.find((item) =>
  matchPath(location.pathname, {
    path: `/${item.route}`,
    exact: true }));



  const .........完整代码请登录后点击上方下载按钮下载查看

网友评论0