gpt4 book ai didi

javascript - 带有 MUI 的渐变跟踪按钮

转载 作者:行者123 更新时间:2023-12-05 00:31:45 29 4
gpt4 key购买 nike

Codepen例如。我有一个悬停效果,渐变跟随鼠标光标。
我有两个 CSS 变量,--x--y declad 用于跟踪鼠标在按钮上的位置。
CSS 变量 --size , 用于修改渐变的尺寸。
background: radial-gradient(circle closest-side, pink, transparent)它在正确的位置创建渐变。Document.querySelector()EventTarget.addEventListener()'mousemove' 注册一个处理程序事件。
Element.getBoundingClientRect()CSSStyleDeclaration.setProperty()更新 --x 的值和 --y CSS 变量。
现在我尝试使用 MUI 按钮在 React Typescript 中将其重新创建为样式化组件。
我在样式化的 Button 中声明了 CSS 样式,但未应用。Button.tsx

import React from 'react';
import { styled, Theme } from '@mui/material/styles';
import { Button, SxProps } from '@mui/material';

const HoverButton = styled(Button)(({ theme }) => ({
borderRadius: 100,
".mouse-cursor-gradient-tracking": {
position: "relative",
background: "#7983ff",
padding: "0.5rem 1rem",
fontSize: "1.2rem",
border: "none",
color: theme.palette.secondary.contrastText,
cursor: "pointer",
outline: "none",
overflow: "hidden",
},

".mouse-cursor-gradient-tracking span": {
position: "relative",
},

".mouse-cursor-gradient-tracking:before": {
--size: 0,
content: '',
position: "absolute",
left: "var(--x)",
top: "var(--y)",
width: "var(--size)",
height: "var(--size)",
background: "radial-gradient(circle closest-side, pink, transparent)",
transform: "translate(-50%, -50%)",
transition: "width 0.2s ease, height 0.2s ease",
},

".mouse-cursor-gradient-tracking:hover:before": {
"--size": "200px"
},
}));

export function SubmitButton(props: { children: React.ReactNode; sx?: SxProps<Theme> }) {
let button:<Element | null> = document.querySelector('.mouse-cursor-gradient-tracking');
button.addEventListener('mousemove', e => {
let rect = e.target.getBoundingClientRect();
let x = e.clientX - rect.left;
let y = e.clientY - rect.top;
button.style.setProperty('--x', x + 'px');
button.style.setProperty('--y', y + 'px');
});

return (
<HoverButton type="submit" variant="contained" sx={props.sx}>
{props.children}<span>Hover me</span>
</HoverButton>
);
}

最佳答案

这是一个有效的codesandbox .
让我解释一下你的方法的一些缺点。

  • 命令式查询选择带有类的按钮并添加事件处理程序。如下图:
  •     let button:<Element | null> = document.querySelector('.mouse-cursor-gradient-tracking');
    button.addEventListener('mousemove', e => {
    let rect = e.target.getBoundingClientRect();
    let x = e.clientX - rect.left;
    let y = e.clientY - rect.top;
    button.style.setProperty('--x', x + 'px');
    button.style.setProperty('--y', y + 'px');
    });
    您可以改为将事件处理程序直接添加到 React 中的按钮组件。因此,React 负责将事件添加到组件中的方式。
    const Component = () => {

    const mouseDownHandler = (e) => {
    // logic here
    }

    return (<button onMouseDown={mouseDownHandler}>Click me</button>);
    };
  • 使用与 styled 混合的类或 css-in-js .

  • const HoverButton = styled(Button)(({ theme }) => ({
    ".mouse-cursor-gradient-tracking": {
    position: "relative",
    background: "#7983ff",
    },
    ".mouse-cursor-gradient-tracking span": {
    position: "relative",
    },

    ".mouse-cursor-gradient-tracking:before": {
    --size: 0,
    content: '',
    },

    ".mouse-cursor-gradient-tracking:hover:before": {
    "--size": "200px"
    },
    }));
    取而代之的是,您可以简单地执行以下操作:
    const HoverButton = styled(Button)`  
    position: relative;
    background: #7983ff;

    & > span {
    ... your code here
    }

    &:before {
    ... your code here
    }

    &:hover:before {
    ... your code here
    }
    `;

    const SubmitButton = () => {
    return <HoverButton>Text</HoverButton>
    }
    样式将直接应用于带有伪类的按钮。除非您尝试覆盖另一个库中的现有类,否则不需要您单独的自定义类(css-in-js 引擎将自己创建一个带有哈希的类)。
  • 动态更新样式。

  • button.addEventListener('mousemove', e => {
    ...other codes
    button.style.setProperty('--x', x + 'px');
    button.style.setProperty('--y', y + 'px');
    });
    这不会动态更新按钮的样式。我们可以使用可以使用第 1 点中提到的处理程序更新的状态。 1并将它们作为 Prop 传递给样式按钮并使用它来更改css值。
    这是完整的工作代码。
    import { useState } from "react";
    import { styled, Theme } from "@mui/material/styles";
    import { Button, SxProps } from "@mui/material";
    import "./styles.css";

    const StyledButton = styled(Button)<{ left: number; top: number }>`
    position: relative;
    background: #7983ff;
    padding: 0.5rem 1rem;
    font-size: 1.2rem;
    border: none;
    color: white;
    cursor: pointer;
    outline: none;
    overflow: hidden;

    &:before {
    content: "";
    left: ${({ left }) => left}px;
    top: ${({ top }) => top}px;
    position: absolute;
    width: 0;
    height: 0;
    background: radial-gradient(circle closest-side, pink, transparent);
    transform: translate(-50%, -50%);
    transition: width 0.2s ease, height 0.2s ease;
    }

    &:hover:before {
    color: red;
    width: 200px;
    height: 200px;
    }
    `;

    const SubmitButton = (props: {
    children?: React.ReactNode;
    sx?: SxProps<Theme>;
    }) => {
    const [hoverStyle, setHoverStyle] = useState({
    left: 0,
    top: 0
    });

    const handleMouseMove: React.MouseEventHandler<HTMLButtonElement> = (e) => {
    const rect = e.currentTarget.getBoundingClientRect();
    const left = e.clientX - rect.left;
    const top = e.clientY - rect.top;

    setHoverStyle({ left, top });
    };

    return (
    <StyledButton
    left={hoverStyle.left}
    top={hoverStyle.top}
    type="submit"
    variant="contained"
    sx={props.sx}
    onMouseMove={handleMouseMove}
    >
    <span>Hover me</span>
    </StyledButton>
    );
    };

    export default function App() {
    return (
    <div className="App">
    <h1>Hello CodeSandbox</h1>
    <h2>Start editing to see some magic happen!</h2>
    <SubmitButton />
    </div>
    );
    }
    资源链接:
    MUI styled() ,
    Styled component props

    关于javascript - 带有 MUI 的渐变跟踪按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73097678/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com