diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2020-10-19 10:22:19 +0200 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2020-10-19 10:22:19 +0200 |
| commit | 8ad9aa6fdd743cbcd6ea97d837243cd4d9cb0e46 (patch) | |
| tree | 554ef2c21539b45e3277bf4f751be54e5f86e402 /gui | |
| parent | b0251804f2c7cdeaf3687894282338a32508176b (diff) | |
| parent | 6538458743bd5332006cf740f3f111d52fe3da5d (diff) | |
| download | mullvadvpn-8ad9aa6fdd743cbcd6ea97d837243cd4d9cb0e46.tar.xz mullvadvpn-8ad9aa6fdd743cbcd6ea97d837243cd4d9cb0e46.zip | |
Merge branch 'react-simple-maps-workaround' into master
Diffstat (limited to 'gui')
| -rw-r--r-- | gui/src/renderer/components/SvgMap.tsx | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/gui/src/renderer/components/SvgMap.tsx b/gui/src/renderer/components/SvgMap.tsx index 27bc846d73..93b3b7fdc3 100644 --- a/gui/src/renderer/components/SvgMap.tsx +++ b/gui/src/renderer/components/SvgMap.tsx @@ -1,14 +1,13 @@ import { geoMercator, GeoProjection } from 'd3-geo'; import rbush from 'rbush'; -import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { ComposableMap, Geographies, Geography, Marker, ZoomableGroup } from 'react-simple-maps'; +import React, { useCallback, useEffect, useMemo, useRef } from 'react'; +import { ComposableMap, Geographies, Geography, Marker } from 'react-simple-maps'; import geographyData from '../../../assets/geo/geometry.json'; import statesProvincesLinesData from '../../../assets/geo/states-provinces-lines.json'; import geometryTreeData from '../../../assets/geo/geometry.rbush.json'; import statesProvincesLinesTreeData from '../../../assets/geo/states-provinces-lines.rbush.json'; -import { useScheduler } from '../../shared/scheduler'; interface IGeometryLeaf extends rbush.BBox { id: string; @@ -214,13 +213,6 @@ function SvgMap(props: IProps) { ); const [visibleGeometry, visibleStatesProvincesLines] = useVisibleGeometry(viewportBboxes); - // react-simple-maps renders the map with zoom=1 the first render resulting in a transition from - // 1 to zoomLevel when it immediately renders a second time. This makes sure that transitions are - // disabled until after the second render. - const [enableTransition, setEnableTransition] = useState(false); - const enableTransitionScheduler = useScheduler(); - useEffect(() => enableTransitionScheduler.schedule(() => setEnableTransition(true)), []); - const markerStyle = useMemo( () => mergeRsmStyle({ default: { display: props.showMarker ? undefined : 'none' } }), [props.showMarker], @@ -242,7 +234,10 @@ function SvgMap(props: IProps) { center={zoomCenter} zoom={zoomLevel} onTransitionEnd={removeOldViewportBboxes} - style={enableTransition ? zoomableGroupStyle : undefined}> + style={zoomableGroupStyle} + width={width} + height={height} + projection={projection}> <Geographies geography={geographyData}> {({ geographies }) => { return visibleGeometry.map(({ id }) => ( @@ -274,3 +269,27 @@ function SvgMap(props: IProps) { } export default React.memo(SvgMap, sameProps); + +// Workaround for issue where react-simple-maps does an animated zoom/pan when first loading the +// map. When this issue is resolved it can be removed: +// https://github.com/zcreativelabs/react-simple-maps/issues/228 +interface IZoomableGroupProps extends React.SVGAttributes<SVGGElement> { + center: [number, number]; + zoom: number; + width: number; + height: number; + projection: GeoProjection; +} + +function ZoomableGroup(props: IZoomableGroupProps) { + const { height, width, center, zoom, projection, ...otherProps } = props; + + const transform = useMemo(() => { + const [x, y] = projection(center) ?? [0, 0]; + const translateX = width / 2 - x * zoom; + const translateY = height / 2 - y * zoom; + return `translate(${translateX} ${translateY}) scale(${zoom})`; + }, [projection, center, width, height, zoom]); + + return <g transform={transform} {...otherProps} />; +} |
