mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-25 04:46:40 +07:00
added motion to login scene
This commit is contained in:
parent
d4e8b59eea
commit
8a5270921d
9 changed files with 10795 additions and 624 deletions
|
@ -1,14 +1,87 @@
|
|||
import React, { FC, useState } from "react";
|
||||
import React, {
|
||||
FC,
|
||||
memo,
|
||||
MouseEventHandler,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
|
||||
import styles from "./styles.module.scss";
|
||||
|
||||
interface LoginSceneProps {}
|
||||
|
||||
const LoginScene: FC<LoginSceneProps> = () => {
|
||||
interface Layer {
|
||||
src: string;
|
||||
velocity: number;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
const layers: Layer[] = [
|
||||
{
|
||||
src: "/images/clouds__bg.svg",
|
||||
velocity: -0.3,
|
||||
width: 3840,
|
||||
height: 1080,
|
||||
},
|
||||
{
|
||||
src: "/images/clouds__cube.svg",
|
||||
velocity: -0.1,
|
||||
width: 3840,
|
||||
height: 1080,
|
||||
},
|
||||
{
|
||||
src: "/images/clouds__cloud.svg",
|
||||
velocity: 0.2,
|
||||
width: 3840,
|
||||
height: 1080,
|
||||
},
|
||||
{
|
||||
src: "/images/clouds__dudes.svg",
|
||||
velocity: 0.5,
|
||||
width: 3840,
|
||||
height: 1080,
|
||||
},
|
||||
{
|
||||
src: "/images/clouds__trash.svg",
|
||||
velocity: 0.8,
|
||||
width: 3840,
|
||||
height: 1080,
|
||||
},
|
||||
];
|
||||
|
||||
const LoginScene: FC<LoginSceneProps> = memo(() => {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const [loaded, setLoaded] = useState(false);
|
||||
|
||||
const onMouseMove = useCallback(
|
||||
(event: MouseEvent): any => {
|
||||
if (!ref.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { x, width } = ref.current.getBoundingClientRect();
|
||||
const middle = (width - x) / 2;
|
||||
const shift = event.pageX / middle / 2 - 0.5;
|
||||
|
||||
layers.map((it, index) => {
|
||||
document.getElementById(
|
||||
`LoginScene__${index}`,
|
||||
)?.style.transform = `translate(${shift * it.velocity * 200}px, 0)`;
|
||||
});
|
||||
},
|
||||
[ref],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
document.addEventListener("mousemove", onMouseMove);
|
||||
return () => document.removeEventListener("mousemove", onMouseMove);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className={styles.scene}>
|
||||
<div className={styles.scene} ref={ref}>
|
||||
<svg
|
||||
width="100%"
|
||||
height="100%"
|
||||
|
@ -39,19 +112,23 @@ const LoginScene: FC<LoginSceneProps> = () => {
|
|||
fill="url(#fallbackGradient)"
|
||||
/>
|
||||
|
||||
<image
|
||||
href="/images/clouds.svg"
|
||||
width={1920}
|
||||
height={1080}
|
||||
x={0}
|
||||
y={0}
|
||||
opacity={loaded ? 1 : 0}
|
||||
onLoad={() => setLoaded(true)}
|
||||
className={styles.image}
|
||||
/>
|
||||
{layers.map((it, index) => (
|
||||
<image
|
||||
id={`LoginScene__${index}`}
|
||||
key={it.src}
|
||||
href={it.src}
|
||||
width={it.width}
|
||||
height={it.height}
|
||||
x={1920 / 2 - it.width / 2}
|
||||
y={0}
|
||||
opacity={loaded ? 1 : 0}
|
||||
onLoad={() => setLoaded(true)}
|
||||
className={styles.image}
|
||||
/>
|
||||
))}
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
export { LoginScene };
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
.image {
|
||||
transition: opacity 1s;
|
||||
will-change: opacity, transform;
|
||||
|
||||
@include tablet {
|
||||
display: none;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue