marks animation fixed

This commit is contained in:
2024-04-11 15:57:48 +05:00
parent 46e02a88b4
commit f2bbe06a89
3 changed files with 67 additions and 49 deletions
+2 -2
View File
@@ -15,9 +15,9 @@ const DistanceCircle = ({ selectedRange }: DistanceCircleProps) => {
}, [setScreenWidth]);
return (
<div className="absolute top-0 left-0 w-full h-full flex justify-center items-center">
<div className="absolute top-0 z-20 left-0 w-full h-full flex justify-center items-center">
<svg
className="transition-all duration-300 ease-in-out"
className="transition-all ease-in-out"
width={
((screenWidth / defaultScreenSize) * (0.8 * 1600 * selectedRange)) /
850
+60 -46
View File
@@ -1,53 +1,92 @@
import { useState } from "react";
import { useEffect, useLayoutEffect, useRef, useState } from "react";
import { Mark as MarkType } from "../types/Mark";
interface MarkProps {
isFiltered: boolean;
setHoveredMark: React.Dispatch<React.SetStateAction<string>>;
hoveredMark: string;
mark: MarkType;
width: number;
height: number;
icon: React.ReactNode;
}
const Mark = ({ isFiltered, width, height, icon, mark }: MarkProps) => {
const [isHovered, setIsHovered] = useState(false);
const Mark = ({
isFiltered,
width,
height,
icon,
mark,
setHoveredMark,
hoveredMark,
}: MarkProps) => {
const [textWidth, setTextWidth] = useState(0);
const textRef = useRef<React.LegacyRef<SVGTextElement> | null>(null);
useLayoutEffect(() => {
if (!textRef.current) return;
const _textWidth = (textRef.current as unknown as SVGSVGElement).getBBox()
.width;
setTextWidth(_textWidth);
}, []);
function handleOnMouseEnter(): void {
setIsHovered(true);
setHoveredMark(mark.id);
}
function handleOnMouseLeave(): void {
setIsHovered(false);
setHoveredMark("");
}
return (
<svg
onMouseEnter={handleOnMouseEnter}
onMouseLeave={handleOnMouseLeave}
className={`transition-all duration-300 ease-in-out relative ${
isFiltered ? "opacity-100" : "opacity-0"
}`}
// x={mark.x - 100 + 82}
x={mark.x - 100 + 32}
className={`transition-all absolute duration-300 ease-in-out cursor-pointer group ${
isFiltered ? "opacity-100" : "opacity-0 pointer-events-none"
} `}
x={mark.x - 150 + 32}
y={mark.y}
width={width + 200}
width={width + 300}
height={height}
// viewBox="0 0 256 64"
viewBox="0 0 128 64"
viewBox={`0 0 ${textWidth + 108} 64`}
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<svg xmlns="http://www.w3.org/2000/svg" x={width / 2}>
<svg xmlns="http://www.w3.org/2000/svg">
<g>
<rect
x="0"
x={width / 2}
y="0"
width="100"
height="100"
width="32"
height="64"
fill="white"
className="transition-all duration-300 ease-in-out"
style={{ width: `${isHovered ? "100%" : 0}` }}
className="transition-all duration-150 ease-in-out w-0 group-hover:w-8"
></rect>
<text x="0" y="50" fontFamily="Inter" fontSize="12" fill="#002347">
<rect
x={width / 2}
y="0"
rx={32}
width="100"
height="64"
fill="white"
className={`transition-all duration-300 ease-in-out w-0 group-hover:w-[${
textWidth + 68
}]`}
style={{
width: `${hoveredMark === mark.id ? `${textWidth + 68}` : 0}`,
}}
></rect>
<text
className={`opacity-0 group-hover:opacity-100
transition-opacity duration-300 ease-in-out`}
ref={textRef}
x="70"
y="38"
fontFamily="Inter"
fontSize="16"
fill={"#002347"}
>
{mark.label}
</text>
</g>
@@ -61,33 +100,8 @@ const Mark = ({ isFiltered, width, height, icon, mark }: MarkProps) => {
rx="28.4444"
fill="#002347"
/>
{icon}
<svg>{icon}</svg>
</svg>
// <svg
// onMouseEnter={handleOnMouseEnter}
// onMouseLeave={handleOnMouseLeave}
// className={`transition-all duration-300 ease-in-out relative ${
// isFiltered ? "opacity-100" : "opacity-0"
// }`}
// x={x}
// y={y}
// width={width}
// height={height}
// viewBox="0 0 64 64"
// fill="none"
// xmlns="http://www.w3.org/2000/svg"
// >
// <rect width="64" height="64" rx="32" fill="white" />
// <rect
// x="3.55566"
// y="3.55566"
// width="56.8889"
// height="56.8889"
// rx="28.4444"
// fill="#002347"
// />
// {icon}
// </svg>
);
};
+5 -1
View File
@@ -1,6 +1,7 @@
import { useState } from "react";
import { isMobile } from "react-device-detect";
import Mark from "./Mark";
import { Mark as MarkType } from "../types/Mark";
import { isMobile } from "react-device-detect";
import MarkEducationIcon from "./icons/marks/MarkEducationIcon";
import MarkFoodIcon from "./icons/marks/MarkFoodIcon";
import MarkHeathyIcon from "./icons/marks/MarkHeathyIcon";
@@ -28,6 +29,7 @@ function MarksContainer({
markWidth = isMobile ? 64 : 48,
markHeigth = isMobile ? 64 : 48,
}: MarksContainerProps) {
const [hoveredMark, setHoveredMark] = useState("");
return (
<svg
width="2160"
@@ -44,6 +46,8 @@ function MarksContainer({
return (
<Mark
setHoveredMark={setHoveredMark}
hoveredMark={hoveredMark}
mark={mark}
key={mark.id}
isFiltered={isFiltered}