react framer-motion实现彩色选项卡tab切换效果代码
代码语言:html
所属分类:选项卡
代码描述:react framer-motion实现彩色选项卡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