From e02c08e19fe32c7d2a2955d2f07783f2812e0fc9 Mon Sep 17 00:00:00 2001 From: KartoffelChips Date: Sat, 26 Oct 2024 21:24:38 +0200 Subject: [PATCH] bigger map, legend floating --- public/robots.txt | 0 src/{_fonts.css => _fonts.scss} | 0 src/_variables.scss | 2 +- src/components/icons/DiscordIcon.tsx | 17 +++++++++ src/components/icons/GitHubIcon.tsx | 24 ++++++++++++ src/components/icons/index.ts | 3 ++ src/components/layout/Legend.scss | 57 +++++++++++++++++++++++++--- src/components/layout/Legend.tsx | 55 +++++++++++++++++++++++++-- src/components/map/Map.tsx | 30 ++++++++++++--- src/index.scss | 30 ++++++++++----- src/pages/Main.tsx | 10 ++++- 11 files changed, 201 insertions(+), 27 deletions(-) create mode 100644 public/robots.txt rename src/{_fonts.css => _fonts.scss} (100%) create mode 100644 src/components/icons/DiscordIcon.tsx create mode 100644 src/components/icons/GitHubIcon.tsx create mode 100644 src/components/icons/index.ts diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/_fonts.css b/src/_fonts.scss similarity index 100% rename from src/_fonts.css rename to src/_fonts.scss diff --git a/src/_variables.scss b/src/_variables.scss index 17d2616..ed986c7 100644 --- a/src/_variables.scss +++ b/src/_variables.scss @@ -1,4 +1,4 @@ -@import "_fonts.css"; +@use "fonts"; $header-font: "Cormorant Garamond", sans-serif; $font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; \ No newline at end of file diff --git a/src/components/icons/DiscordIcon.tsx b/src/components/icons/DiscordIcon.tsx new file mode 100644 index 0000000..e3e70fa --- /dev/null +++ b/src/components/icons/DiscordIcon.tsx @@ -0,0 +1,17 @@ +import React from "react"; +import {IconProps} from "./index.ts"; + +const DiscordIcon: React.FC = ({ color = "#ffffff" }) => ( + + + + + + + +); + +export default DiscordIcon; \ No newline at end of file diff --git a/src/components/icons/GitHubIcon.tsx b/src/components/icons/GitHubIcon.tsx new file mode 100644 index 0000000..080cfeb --- /dev/null +++ b/src/components/icons/GitHubIcon.tsx @@ -0,0 +1,24 @@ +import React from "react"; +import {IconProps} from "./index.ts"; + +const GitHubIcon: React.FC = ({ color = "#ffffff"} ) => ( + + + + + + + + + + + + + + +); + +export default GitHubIcon; \ No newline at end of file diff --git a/src/components/icons/index.ts b/src/components/icons/index.ts new file mode 100644 index 0000000..fc4d2fb --- /dev/null +++ b/src/components/icons/index.ts @@ -0,0 +1,3 @@ +export interface IconProps { + color?: string; +} \ No newline at end of file diff --git a/src/components/layout/Legend.scss b/src/components/layout/Legend.scss index f10c374..da7af60 100644 --- a/src/components/layout/Legend.scss +++ b/src/components/layout/Legend.scss @@ -1,18 +1,31 @@ .legend { + position: fixed; display: flex; flex-direction: column; - padding: 0 15px; + padding: 0 25px 25px; flex-grow: 1; + max-width: 500px; + + background-color: rgba(0, 0, 0, 0.8); + border-bottom-right-radius: 12px; + z-index: 1000; + + @media (max-width: 1200px) { + position: relative; + max-width: 100%; + margin-top: 20px; + background-color: transparent; + } h1 { font-size: 3rem; - font-weight: 700; + font-weight: 800; width: fit-content; margin-bottom: 12px; margin-top: 20px; @media (max-width: 768px) { - font-size: 1rem; + font-size: 2.5rem; } } @@ -26,9 +39,9 @@ border-bottom: 1px solid #a8a8a8; - @media (max-width: 768px) { - font-size: 1rem; - } + //@media (max-width: 768px) { + // font-size: 1rem; + //} } .border { @@ -45,4 +58,36 @@ padding-left: 7px; } + + .platform-tooltip-info { + color: white; + z-index: 1; + + .key { + background-color: rgba(255, 255, 255, 0.07); + padding: 7px 12px; + border-radius: 7px; + margin: 0 3px; + z-index: 0; + } + } + + .links { + display: flex; + align-items: center; + gap: 15px; + + a.link { + display: flex; + align-items: center; + gap: 7px; + + img, svg { + --hw: 23px; + height: var(--hw); + width: var(--hw); + min-width: var(--hw); + } + } + } } \ No newline at end of file diff --git a/src/components/layout/Legend.tsx b/src/components/layout/Legend.tsx index 360688f..c7deb46 100644 --- a/src/components/layout/Legend.tsx +++ b/src/components/layout/Legend.tsx @@ -1,18 +1,31 @@ -import React from "react"; +import React, {useEffect, useState} from "react"; import "./Legend.scss"; import CityIcon from "../icons/CityIcon.tsx"; import StarIcon from "../icons/StarIcon.tsx"; import LegendCheckbox from "../common/LegendCheckbox.tsx"; import CapitalIcon from "../icons/CapitalIcon.tsx"; +import GitHubIcon from "../icons/GitHubIcon.tsx"; +import DiscordIcon from "../icons/DiscordIcon.tsx"; +import {Link} from "react-router-dom"; interface LegendProps { + hidden?: boolean; showCapitals: boolean; showSettlements: boolean; showPOIs: boolean; onUpdated: (showCapitals: boolean, showSettlements: boolean, showPOIs: boolean) => void; } -const Legend: React.FC = ({ showCapitals, showSettlements, showPOIs, onUpdated }) => { +const Legend: React.FC = ({ showCapitals, showSettlements, showPOIs, onUpdated, hidden = false }) => { + const [platformText, setPlatformText] = useState(<>); + + useEffect(() => { + const isMac = navigator.platform.toUpperCase().indexOf("MAC") >= 0; + const isWin = navigator.platform.toUpperCase().indexOf("WIN") >= 0; + if (isMac) setPlatformText(

Hold the ⌘ Command key to keep the tooltip from moving.

); + else if (isWin) setPlatformText(

Hold the Ctrl key to keep the tooltip from moving.

); + }, []); + const onCheckboxUpdate = (type: "capitals" | "settlements" | "pois", checked: boolean) => { onUpdated( type === "capitals" ? checked : showCapitals, @@ -21,13 +34,16 @@ const Legend: React.FC = ({ showCapitals, showSettlements, showPOIs ); }; + if (hidden) return null; + return (

Interactive Map of the Magic Continent

-

Filters

+

This is an interactive map of the world of Tensei Shitara Slime Datta Ken (That Time I Got Reincarnated as a Slime)

+

Filters

= ({ showCapitals, showSettlements, showPOIs onUpdated={(checked) => onCheckboxUpdate("pois", checked)} />
+ + {platformText && ( +

+ {platformText} +

+ )} + +
+ + + GitHub + + + + Discord + + + Legal Notice + +
); } diff --git a/src/components/map/Map.tsx b/src/components/map/Map.tsx index 7873b74..f1638b8 100644 --- a/src/components/map/Map.tsx +++ b/src/components/map/Map.tsx @@ -13,9 +13,21 @@ interface MapProps { capitals?: MapLocation[]; cities?: MapLocation[]; pois?: MapLocation[]; + onStartDragging?: () => void; + onStopDragging?: () => void; + onZoom?: (scale: number) => void; } -const Map: React.FC = ({ imageUrl, regions = [], cities = [], pois = [], capitals = [] }) => { +const Map: React.FC = ({ + imageUrl, + regions = [], + cities = [], + pois = [], + capitals = [], + onStartDragging = (() => {}), + onStopDragging = (() => {}), + onZoom = (() => {}), +}) => { const svgRef = useRef(null); const gRef = useRef(null); const tooltipRef = useRef(null); // Ref for the tooltip @@ -32,7 +44,7 @@ const Map: React.FC = ({ imageUrl, regions = [], cities = [], pois = [ const [translate, setTranslate] = useState({ x: 0, y: 0 }); const [scale, setScale] = useState(1); - const dragSensitivity = 2; + const DRAG_SENSITIVITY = 2; useEffect(() => { const svgElement = svgRef.current; @@ -43,13 +55,14 @@ const Map: React.FC = ({ imageUrl, regions = [], cities = [], pois = [ setIsDragging(true); setStartX(e.clientX); setStartY(e.clientY); + onStartDragging(); }; const handleMouseMove = (e: MouseEvent) => { if (!isDragging || scale <= 1) return; - const deltaX = (e.clientX - startX) * dragSensitivity; - const deltaY = (e.clientY - startY) * dragSensitivity; + const deltaX = (e.clientX - startX) * DRAG_SENSITIVITY; + const deltaY = (e.clientY - startY) * DRAG_SENSITIVITY; setTranslate(prev => ({ x: prev.x + deltaX, y: prev.y + deltaY, @@ -58,7 +71,11 @@ const Map: React.FC = ({ imageUrl, regions = [], cities = [], pois = [ setStartY(e.clientY); }; - const handleMouseUp = () => setIsDragging(false); + const handleMouseUp = () => { + setIsDragging(false); + onStopDragging(); + }; + const handleWheel = (e: WheelEvent) => { e.preventDefault(); const zoomFactor = e.deltaY > 0 ? 0.9 : 1.1; @@ -75,6 +92,7 @@ const Map: React.FC = ({ imageUrl, regions = [], cities = [], pois = [ setTranslate({ x: newTranslateX, y: newTranslateY }); } setScale(newScale); + onZoom(newScale); }; svgElement.addEventListener("mousedown", handleMouseDown); @@ -200,7 +218,7 @@ const Map: React.FC = ({ imageUrl, regions = [], cities = [], pois = [ {tooltip.visible && !isDragging && (
{ const [showCapitals, setShowCapitals] = useState(true); const [showSettlements, setShowSettlements] = useState(true); const [showPOIs, setShowPOIs] = useState(true); + const [isDragging, setIsDragging] = useState(false); + const [isZoomedIn, setIsZoomedIn] = useState(false); const onUpdated = (showCapitals: boolean, showSettlements: boolean, showPOIs: boolean) => { setShowCapitals(showCapitals); @@ -25,8 +27,12 @@ const Main = () => { capitals={showCapitals ? capitals : []} cities={showSettlements ? cities : []} pois={showPOIs ? pois : []} + onStartDragging={() => setIsDragging(true)} + onStopDragging={() => setIsDragging(false)} + onZoom={(scale) => setIsZoomedIn(scale > 1)} />