This commit is contained in:
2025-11-10 16:49:38 +05:00
parent ce5718f30e
commit c0d6641eee
5 changed files with 222 additions and 1 deletions
+3
View File
@@ -4,6 +4,7 @@
"": {
"name": "baraha-town",
"dependencies": {
"clsx": "^2.1.1",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"react-router": "^7.9.5",
@@ -243,6 +244,8 @@
"chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="],
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
+1
View File
@@ -10,6 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
"clsx": "^2.1.1",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"react-router": "^7.9.5"
+24 -1
View File
@@ -1,5 +1,28 @@
import { useState } from "react";
import Compass from "./components/Compass";
function App() {
return <div></div>;
const [degrees, setDegrees] = useState<number>(0);
return (
<div className="h-dvh w-screen p-10 bg-[#f0f0f0]">
<Compass degrees={degrees} />
<div className="flex gap-20">
<button
onClick={() => setDegrees(degrees - 90)}
className="select-none"
>
{"<"}
</button>
<button
onClick={() => setDegrees(degrees + 90)}
className="select-none"
>
{">"}
</button>
</div>
</div>
);
}
export default App;
+191
View File
@@ -0,0 +1,191 @@
function Compass({ degrees }: { degrees: number }) {
const normalized = ((degrees % 360) + 360) % 360;
const letter =
normalized === 0
? "N"
: normalized === 90
? "W"
: normalized === 180
? "S"
: normalized === 270
? "E"
: "";
return (
<div className="select-none 2xl:p-[0.556vw] relative 2xl:size-[5.556vw] size-10 aspect-square ring-1a">
<div
style={{ rotate: `${degrees}deg` }}
className="transition-[rotate] duration-300"
>
<svg
viewBox="0 0 83 83"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="max-2xl:hidden"
>
<g filter="url(#a)">
<circle
cx={41.359}
cy={41.359}
r={27}
fill="#363636"
fillOpacity={0.15}
/>
</g>
<path
d="M49.442 11.192a31.23 31.23 0 1 1-16.166 0"
stroke="#fff"
strokeWidth={"0.107vw"}
strokeLinecap="round"
strokeLinejoin="round"
/>
<defs>
<filter
id="a"
x={0}
y={0}
width={"5.744vw"}
height={"5.744vw"}
filterUnits="userSpaceOnUse"
colorInterpolationFilters="sRGB"
>
<feFlood floodOpacity={0} result="BackgroundImageFix" />
<feBlend
in="SourceGraphic"
in2="BackgroundImageFix"
result="shape"
/>
<feGaussianBlur
stdDeviation={7.179}
result="effect1_foregroundBlur_490_31649"
/>
</filter>
</defs>
</svg>
<svg
className="2xl:hidden"
width={40}
height={40}
viewBox="0 0 40 40"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M14.953 1.164a19.5 19.5 0 1 1 10.094 37.672A19.5 19.5 0 0 1 14.953 1.164"
stroke="#fff"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
</div>
<div className="2xl:hidden absolute inset-0 -translate-x-[13px] -translate-y-[13px]">
<svg
width={63}
height={63}
viewBox="0 0 63 63"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g filter="url(#a)">
<circle
cx={31.359}
cy={31.359}
r={17}
fill="#363636"
fillOpacity={0.15}
/>
</g>
<defs>
<filter
id="a"
x={0}
y={0}
width={62.718}
height={62.718}
filterUnits="userSpaceOnUse"
colorInterpolationFilters="sRGB"
>
<feFlood floodOpacity={0} result="BackgroundImageFix" />
<feBlend
in="SourceGraphic"
in2="BackgroundImageFix"
result="shape"
/>
<feGaussianBlur
stdDeviation={7.179}
result="effect1_foregroundBlur_11187_57936"
/>
</filter>
</defs>
</svg>
</div>
<p className="absolute font-medium 2xl:text-[0.833vw] text-[10px] leading-none text-white left-1/2 -translate-x-1/2 top-1/2 -translate-y-1/2 2xl:blur-[0.142vw]">
{letter}
</p>
<p className="absolute font-medium 2xl:text-[0.833vw] text-[10px] leading-none text-white left-1/2 -translate-x-1/2 top-1/2 -translate-y-1/2">
{letter}
</p>
<div
style={{
transform: `translateX(-50%) rotate(${degrees}deg)`,
}}
className="absolute left-1/2 h-full top-0 transition-[transform] duration-300 2xl:pt-[0.139vw] pt-1.5"
>
<div className="flex flex-col items-center 2xl:gap-[0.208vw]">
<p
style={{ rotate: `${-degrees}deg` }}
className="font-medium text-[0.833vw] leading-none text-white text-center transition-[rotate] duration-300 max-2xl:hidden"
>
N
</p>
<div className="2xl:size-[0.556vw] size-1.5 relative">
<div className="absolute inset-0">
<svg
viewBox="0 0 7 6"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M5.666 4.974H.513L3.09.512z"
fill="#fff"
stroke="#fff"
strokeWidth={"0.071vw"}
/>
</svg>
</div>
<div className="absolute inset-0 2xl:blur-[0.142vw] blur-[2.05px]">
<svg
viewBox="0 0 7 6"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M5.666 4.974H.513L3.09.512z"
fill="#fff"
stroke="#fff"
strokeWidth={"0.071vw"}
/>
</svg>
</div>
<div className="absolute inset-0 2xl:blur-[0.142vw] blur-[2.05px]">
<svg
viewBox="0 0 7 6"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M5.666 4.974H.513L3.09.512z"
fill="#fff"
stroke="#fff"
strokeWidth={"0.071vw"}
/>
</svg>
</div>
</div>
</div>
</div>
</div>
);
}
export default Compass;
+3
View File
@@ -3,6 +3,9 @@ export default {
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
theme: {
extend: {},
screens: {
"2xl": "1440px",
},
},
plugins: [],
};