mirror of
https://github.com/ant-design/ant-design.git
synced 2024-12-15 00:29:12 +08:00
4489eec5b1
* docs: add banner mouse effect animation * refactor to useRef * refactor to react way * refactor to hooks * type: add type * fix: fix error * fix: fix error * fix: update RTL --------- Co-authored-by: 栗嘉男 <574980606@qq.com>
74 lines
2.0 KiB
TypeScript
74 lines
2.0 KiB
TypeScript
import React, { startTransition } from 'react';
|
|
import { ConfigProvider } from 'antd';
|
|
|
|
const getTransformRotateStyle = (
|
|
event: React.MouseEvent<HTMLDivElement, MouseEvent>,
|
|
currentTarget: EventTarget & HTMLDivElement,
|
|
multiple: number,
|
|
isRTL: boolean,
|
|
): string => {
|
|
const box = currentTarget?.getBoundingClientRect();
|
|
const calcX = -(event.clientY - box.y - box.height / 2) / multiple;
|
|
const calcY = (event.clientX - box.x - box.width / 2) / multiple;
|
|
return isRTL
|
|
? `rotate3d(${24 + calcX}, ${83 + calcY}, -45, 57deg)`
|
|
: `rotate3d(${24 + calcX}, ${-83 + calcY}, 45, 57deg)`;
|
|
};
|
|
|
|
const useMouseTransform = ({ transitionDuration = 500, multiple = 36 } = {}) => {
|
|
const [componentsBlockStyle, setComponentsBlockStyle] = React.useState<React.CSSProperties>({});
|
|
|
|
const { direction } = React.useContext(ConfigProvider.ConfigContext);
|
|
|
|
const isRTL = direction === 'rtl';
|
|
|
|
const onMouseMove: React.MouseEventHandler<HTMLDivElement> = (event) => {
|
|
const { currentTarget } = event;
|
|
startTransition(() => {
|
|
setComponentsBlockStyle((style) => ({
|
|
...style,
|
|
transform: getTransformRotateStyle(event, currentTarget, multiple, isRTL),
|
|
}));
|
|
});
|
|
};
|
|
|
|
const onMouseEnter: React.MouseEventHandler<HTMLDivElement> = () => {
|
|
startTransition(() => {
|
|
setComponentsBlockStyle((style) => ({
|
|
...style,
|
|
transition: `transform ${transitionDuration / 1000}s`,
|
|
}));
|
|
});
|
|
|
|
setTimeout(() => {
|
|
startTransition(() => {
|
|
setComponentsBlockStyle((style) => ({
|
|
...style,
|
|
transition: '',
|
|
}));
|
|
});
|
|
}, transitionDuration);
|
|
};
|
|
|
|
const onMouseLeave: React.MouseEventHandler<HTMLDivElement> = () => {
|
|
startTransition(() => {
|
|
setComponentsBlockStyle((style) => ({
|
|
...style,
|
|
transition: `transform ${transitionDuration / 1000}s`,
|
|
transform: '',
|
|
}));
|
|
});
|
|
};
|
|
|
|
return [
|
|
componentsBlockStyle,
|
|
{
|
|
onMouseMove,
|
|
onMouseEnter,
|
|
onMouseLeave,
|
|
},
|
|
] as const;
|
|
};
|
|
|
|
export default useMouseTransform;
|