tooltip overflow wrapping
This commit is contained in:
@@ -1,11 +1,11 @@
|
|||||||
const CapitalIcon = () => (
|
const CapitalIcon = () => (
|
||||||
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<g id="SVGRepo_bgCarrier" stroke-width="0"></g>
|
<g id="SVGRepo_bgCarrier" strokeWidth="0"></g>
|
||||||
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g>
|
<g id="SVGRepo_tracerCarrier" strokeLinecap="round" strokeLinejoin="round"></g>
|
||||||
<g id="SVGRepo_iconCarrier">
|
<g id="SVGRepo_iconCarrier">
|
||||||
<path
|
<path
|
||||||
d="M4.5 14L3 15V21H7M7 21H10M7 21V13L9.5 11V6L12 3L14.5 6V11L17 13V21M10 21H14M10 21V17C10 15.8954 10.8954 15 12 15C13.1046 15 14 15.8954 14 17V21M14 21H17M17 21H21V15L19.5 14"
|
d="M4.5 14L3 15V21H7M7 21H10M7 21V13L9.5 11V6L12 3L14.5 6V11L17 13V21M10 21H14M10 21V17C10 15.8954 10.8954 15 12 15C13.1046 15 14 15.8954 14 17V21M14 21H17M17 21H21V15L19.5 14"
|
||||||
stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
stroke="#ffffff" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"></path>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
const DescriptionIcon = () => (
|
const DescriptionIcon = () => (
|
||||||
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<g id="SVGRepo_bgCarrier" stroke-width="0"></g>
|
<g id="SVGRepo_bgCarrier" strokeWidth="0"></g>
|
||||||
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g>
|
<g id="SVGRepo_tracerCarrier" strokeLinecap="round" strokeLinejoin="round"></g>
|
||||||
<g id="SVGRepo_iconCarrier">
|
<g id="SVGRepo_iconCarrier">
|
||||||
<path d="M3 10H16M3 14H21M3 18H16M3 6H21" stroke="#ffffff" stroke-width="2" stroke-linecap="round"
|
<path d="M3 10H16M3 14H21M3 18H16M3 6H21" stroke="#ffffff" strokeWidth="2" strokeLinecap="round"
|
||||||
stroke-linejoin="round"></path>
|
strokeLinejoin="round"></path>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
const PopulationIcon = () => (
|
const PopulationIcon = () => (
|
||||||
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<g id="SVGRepo_bgCarrier" stroke-width="0"></g>
|
<g id="SVGRepo_bgCarrier" strokeWidth="0"></g>
|
||||||
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g>
|
<g id="SVGRepo_tracerCarrier" strokeLinecap="round" strokeLinejoin="round"></g>
|
||||||
<g id="SVGRepo_iconCarrier">
|
<g id="SVGRepo_iconCarrier">
|
||||||
<path
|
<path
|
||||||
d="M13 20V18C13 15.2386 10.7614 13 8 13C5.23858 13 3 15.2386 3 18V20H13ZM13 20H21V19C21 16.0545 18.7614 14 16 14C14.5867 14 13.3103 14.6255 12.4009 15.6311M11 7C11 8.65685 9.65685 10 8 10C6.34315 10 5 8.65685 5 7C5 5.34315 6.34315 4 8 4C9.65685 4 11 5.34315 11 7ZM18 9C18 10.1046 17.1046 11 16 11C14.8954 11 14 10.1046 14 9C14 7.89543 14.8954 7 16 7C17.1046 7 18 7.89543 18 9Z"
|
d="M13 20V18C13 15.2386 10.7614 13 8 13C5.23858 13 3 15.2386 3 18V20H13ZM13 20H21V19C21 16.0545 18.7614 14 16 14C14.5867 14 13.3103 14.6255 12.4009 15.6311M11 7C11 8.65685 9.65685 10 8 10C6.34315 10 5 8.65685 5 7C5 5.34315 6.34315 4 8 4C9.65685 4 11 5.34315 11 7ZM18 9C18 10.1046 17.1046 11 16 11C14.8954 11 14 10.1046 14 9C14 7.89543 14.8954 7 16 7C17.1046 7 18 7.89543 18 9Z"
|
||||||
stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
stroke="#ffffff" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"></path>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
const RulerIcon = () => (
|
const RulerIcon = () => (
|
||||||
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<g id="SVGRepo_bgCarrier" stroke-width="0"></g>
|
<g id="SVGRepo_bgCarrier" strokeWidth="0"></g>
|
||||||
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g>
|
<g id="SVGRepo_tracerCarrier" strokeLinecap="round" strokeLinejoin="round"></g>
|
||||||
<g id="SVGRepo_iconCarrier">
|
<g id="SVGRepo_iconCarrier">
|
||||||
<path
|
<path
|
||||||
d="M4 8L6 20H18L20 8M4 8L5.71624 9.37299C6.83218 10.2657 7.39014 10.7121 7.95256 10.7814C8.4453 10.8421 8.94299 10.7173 9.34885 10.4314C9.81211 10.1051 10.0936 9.4483 10.6565 8.13476L12 5M4 8C4.55228 8 5 7.55228 5 7C5 6.44772 4.55228 6 4 6C3.44772 6 3 6.44772 3 7C3 7.55228 3.44772 8 4 8ZM20 8L18.2838 9.373C17.1678 10.2657 16.6099 10.7121 16.0474 10.7814C15.5547 10.8421 15.057 10.7173 14.6511 10.4314C14.1879 10.1051 13.9064 9.4483 13.3435 8.13476L12 5M20 8C20.5523 8 21 7.55228 21 7C21 6.44772 20.5523 6 20 6C19.4477 6 19 6.44772 19 7C19 7.55228 19.4477 8 20 8ZM12 5C12.5523 5 13 4.55228 13 4C13 3.44772 12.5523 3 12 3C11.4477 3 11 3.44772 11 4C11 4.55228 11.4477 5 12 5ZM12 4H12.01M20 7H20.01M4 7H4.01"
|
d="M4 8L6 20H18L20 8M4 8L5.71624 9.37299C6.83218 10.2657 7.39014 10.7121 7.95256 10.7814C8.4453 10.8421 8.94299 10.7173 9.34885 10.4314C9.81211 10.1051 10.0936 9.4483 10.6565 8.13476L12 5M4 8C4.55228 8 5 7.55228 5 7C5 6.44772 4.55228 6 4 6C3.44772 6 3 6.44772 3 7C3 7.55228 3.44772 8 4 8ZM20 8L18.2838 9.373C17.1678 10.2657 16.6099 10.7121 16.0474 10.7814C15.5547 10.8421 15.057 10.7173 14.6511 10.4314C14.1879 10.1051 13.9064 9.4483 13.3435 8.13476L12 5M20 8C20.5523 8 21 7.55228 21 7C21 6.44772 20.5523 6 20 6C19.4477 6 19 6.44772 19 7C19 7.55228 19.4477 8 20 8ZM12 5C12.5523 5 13 4.55228 13 4C13 3.44772 12.5523 3 12 3C11.4477 3 11 3.44772 11 4C11 4.55228 11.4477 5 12 5ZM12 4H12.01M20 7H20.01M4 7H4.01"
|
||||||
stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
|
stroke="#ffffff" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"></path>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
|||||||
+35
-15
@@ -18,6 +18,7 @@ interface MapProps {
|
|||||||
const Map: React.FC<MapProps> = ({ imageUrl, regions = [], cities = [], pois = [], capitals = [] }) => {
|
const Map: React.FC<MapProps> = ({ imageUrl, regions = [], cities = [], pois = [], capitals = [] }) => {
|
||||||
const svgRef = useRef<SVGSVGElement | null>(null);
|
const svgRef = useRef<SVGSVGElement | null>(null);
|
||||||
const gRef = useRef<SVGGElement | null>(null);
|
const gRef = useRef<SVGGElement | null>(null);
|
||||||
|
const tooltipRef = useRef<HTMLDivElement | null>(null); // Ref for the tooltip
|
||||||
const [tooltip, setTooltip] = useState<{ visible: boolean; x: number; y: number; content: JSX.Element | null }>({
|
const [tooltip, setTooltip] = useState<{ visible: boolean; x: number; y: number; content: JSX.Element | null }>({
|
||||||
visible: false,
|
visible: false,
|
||||||
x: 0,
|
x: 0,
|
||||||
@@ -45,9 +46,8 @@ const Map: React.FC<MapProps> = ({ imageUrl, regions = [], cities = [], pois = [
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleMouseMove = (e: MouseEvent) => {
|
const handleMouseMove = (e: MouseEvent) => {
|
||||||
if (!isDragging) return;
|
if (!isDragging || scale <= 1) return;
|
||||||
|
|
||||||
// Increase deltaX and deltaY by the drag sensitivity factor
|
|
||||||
const deltaX = (e.clientX - startX) * dragSensitivity;
|
const deltaX = (e.clientX - startX) * dragSensitivity;
|
||||||
const deltaY = (e.clientY - startY) * dragSensitivity;
|
const deltaY = (e.clientY - startY) * dragSensitivity;
|
||||||
setTranslate(prev => ({
|
setTranslate(prev => ({
|
||||||
@@ -59,13 +59,10 @@ const Map: React.FC<MapProps> = ({ imageUrl, regions = [], cities = [], pois = [
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleMouseUp = () => setIsDragging(false);
|
const handleMouseUp = () => setIsDragging(false);
|
||||||
|
|
||||||
const handleWheel = (e: WheelEvent) => {
|
const handleWheel = (e: WheelEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const zoomFactor = e.deltaY > 0 ? 0.9 : 1.1;
|
const zoomFactor = e.deltaY > 0 ? 0.9 : 1.1;
|
||||||
const newScale = Math.min(Math.max(scale * zoomFactor, 1), 6);
|
const newScale = Math.min(Math.max(scale * zoomFactor, 1), 6);
|
||||||
|
|
||||||
// If zooming out to the minimum scale, reset translation
|
|
||||||
if (newScale === 1) {
|
if (newScale === 1) {
|
||||||
setTranslate({ x: 0, y: 0 });
|
setTranslate({ x: 0, y: 0 });
|
||||||
} else {
|
} else {
|
||||||
@@ -73,7 +70,6 @@ const Map: React.FC<MapProps> = ({ imageUrl, regions = [], cities = [], pois = [
|
|||||||
svgPoint.x = e.clientX;
|
svgPoint.x = e.clientX;
|
||||||
svgPoint.y = e.clientY;
|
svgPoint.y = e.clientY;
|
||||||
const mousePoint = svgPoint.matrixTransform(svgElement.getScreenCTM()?.inverse());
|
const mousePoint = svgPoint.matrixTransform(svgElement.getScreenCTM()?.inverse());
|
||||||
|
|
||||||
const newTranslateX = translate.x - (mousePoint.x - translate.x) * (newScale / scale - 1);
|
const newTranslateX = translate.x - (mousePoint.x - translate.x) * (newScale / scale - 1);
|
||||||
const newTranslateY = translate.y - (mousePoint.y - translate.y) * (newScale / scale - 1);
|
const newTranslateY = translate.y - (mousePoint.y - translate.y) * (newScale / scale - 1);
|
||||||
setTranslate({ x: newTranslateX, y: newTranslateY });
|
setTranslate({ x: newTranslateX, y: newTranslateY });
|
||||||
@@ -97,30 +93,54 @@ const Map: React.FC<MapProps> = ({ imageUrl, regions = [], cities = [], pois = [
|
|||||||
}
|
}
|
||||||
}, [isDragging, startX, startY, scale]);
|
}, [isDragging, startX, startY, scale]);
|
||||||
|
|
||||||
// Tooltip handling remains unchanged
|
const setDynamicTooltipPosition = (clientX: number, clientY: number) => {
|
||||||
|
if (tooltipRef.current) {
|
||||||
|
const { width, height } = tooltipRef.current.getBoundingClientRect();
|
||||||
|
// console.log("Width:", width, "Height:", height);
|
||||||
|
let tooltipX = clientX + 10;
|
||||||
|
let tooltipY = clientY + 10;
|
||||||
|
|
||||||
|
if (tooltipX + width > window.innerWidth) {
|
||||||
|
// console.log("Horizontal overflow");
|
||||||
|
tooltipX = clientX - width - 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tooltipY + height > window.innerHeight) {
|
||||||
|
// console.log("Vertical overflow");
|
||||||
|
tooltipY = clientY - height - 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { tooltipX, tooltipY };
|
||||||
|
}
|
||||||
|
return { tooltipX: clientX, tooltipY: clientY };
|
||||||
|
};
|
||||||
|
|
||||||
const handleMouseEnterRegion = (event: React.MouseEvent<SVGPolygonElement>, region: MapRegion) => {
|
const handleMouseEnterRegion = (event: React.MouseEvent<SVGPolygonElement>, region: MapRegion) => {
|
||||||
|
const { tooltipX, tooltipY } = setDynamicTooltipPosition(event.pageX, event.pageY);
|
||||||
setTooltip({
|
setTooltip({
|
||||||
visible: true,
|
visible: true,
|
||||||
x: event.clientX + 10,
|
x: tooltipX,
|
||||||
y: event.clientY + 10,
|
y: tooltipY,
|
||||||
content: <MapRegionTooltip region={region} />,
|
content: <MapRegionTooltip region={region} />,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMouseEnterLocation = (event: React.MouseEvent<SVGGElement>, location: MapLocation) => {
|
const handleMouseEnterLocation = (event: React.MouseEvent<SVGGElement>, location: MapLocation) => {
|
||||||
|
const { tooltipX, tooltipY } = setDynamicTooltipPosition(event.clientX, event.clientY);
|
||||||
setTooltip({
|
setTooltip({
|
||||||
visible: true,
|
visible: true,
|
||||||
x: event.clientX + 10,
|
x: tooltipX,
|
||||||
y: event.clientY + 10,
|
y: tooltipY,
|
||||||
content: <MapLocationTooltip location={location} />,
|
content: <MapLocationTooltip location={location} />,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMouseMove = (event: React.MouseEvent) => {
|
const handleMouseMove = (event: React.MouseEvent) => {
|
||||||
|
const { tooltipX, tooltipY } = setDynamicTooltipPosition(event.clientX, event.clientY);
|
||||||
setTooltip(prev => ({
|
setTooltip(prev => ({
|
||||||
...prev,
|
...prev,
|
||||||
x: event.clientX + 10,
|
x: tooltipX,
|
||||||
y: event.clientY + 10,
|
y: tooltipY,
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -130,7 +150,7 @@ const Map: React.FC<MapProps> = ({ imageUrl, regions = [], cities = [], pois = [
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<svg ref={svgRef} id="map" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2641 2035">
|
<svg ref={svgRef} id="map" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2641 2035" onMouseMove={handleMouseMove}>
|
||||||
<g ref={gRef} transform={`translate(${translate.x}, ${translate.y}) scale(${scale})`}>
|
<g ref={gRef} transform={`translate(${translate.x}, ${translate.y}) scale(${scale})`}>
|
||||||
<image href={imageUrl} width="100%" />
|
<image href={imageUrl} width="100%" />
|
||||||
{regions.map((region, index) => (
|
{regions.map((region, index) => (
|
||||||
@@ -142,7 +162,6 @@ const Map: React.FC<MapProps> = ({ imageUrl, regions = [], cities = [], pois = [
|
|||||||
stroke="transparent"
|
stroke="transparent"
|
||||||
strokeWidth={4}
|
strokeWidth={4}
|
||||||
onMouseEnter={(e) => handleMouseEnterRegion(e, region)}
|
onMouseEnter={(e) => handleMouseEnterRegion(e, region)}
|
||||||
onMouseMove={handleMouseMove}
|
|
||||||
onMouseLeave={handleMouseLeave}
|
onMouseLeave={handleMouseLeave}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
@@ -177,6 +196,7 @@ const Map: React.FC<MapProps> = ({ imageUrl, regions = [], cities = [], pois = [
|
|||||||
</svg>
|
</svg>
|
||||||
{tooltip.visible && !isDragging && (
|
{tooltip.visible && !isDragging && (
|
||||||
<div
|
<div
|
||||||
|
ref={tooltipRef} // Attach the ref here
|
||||||
id={"tooltip"}
|
id={"tooltip"}
|
||||||
className={"tooltip"}
|
className={"tooltip"}
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
Reference in New Issue
Block a user