mirror of
https://github.com/DOI-DO/j40-cejst-2.git
synced 2025-02-22 01:31:25 -08:00
Attempt to add map bounds
- Basic animation (standard ball bounce) was placed on the parent of the map - A state MapBoundReached tracks which bound (N, S, W or E) was reached - This state variable was then used to conditionally apply the CSS animation - How could we detect the end of the animation to remove it from the DOM after the animation played once? - try and add an eventListener on the parent of the map using ref and useEffect ❌ - try and use the onAnimationEnd prop the territory shortcuts seem to trigger this animationEnd event ❌ - try and differentiate between territory shortcut animation and map bound animation using use isPanning ❌ - use isDragging ✅ - Now that the animation end event is being detected properly and its not interfering with the territory shortcuts, moving back to - Getting the bounds to work for all directions (N, S, W, E) - clunky feel and can’t get it to trigger accurately - Making the animation feel real (right not it’s just a random bounce) - Decided to attempt to use the transition built-into the ReactMapGL API, this was also not leading to reliable results.
This commit is contained in:
parent
f5f4330919
commit
38ab640f4e
4 changed files with 168 additions and 10 deletions
|
@ -1,6 +1,16 @@
|
|||
@use '../styles/design-system.scss' as *;
|
||||
@import "./utils.scss";
|
||||
|
||||
.scrollDownBounce {
|
||||
animation: bounce2 2s ease 1;
|
||||
clip-path: inset(30px 0 0 0);
|
||||
|
||||
@keyframes bounce2 {
|
||||
0%, 20%, 50%, 80%, 100% {transform: translateY(0);}
|
||||
40% {transform: translateY(-30px);}
|
||||
60% {transform: translateY(-15px);}
|
||||
}
|
||||
}
|
||||
|
||||
.j40Map {
|
||||
// width < 1024
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
declare namespace J40MapModuleScssNamespace {
|
||||
export interface IJ40MapModuleScss {
|
||||
scrollDownBounce: string;
|
||||
|
||||
// main J40 map style
|
||||
j40Map: string;
|
||||
|
||||
|
|
|
@ -12,7 +12,8 @@ import ReactMapGL, {
|
|||
Popup,
|
||||
FlyToInterpolator,
|
||||
FullscreenControl,
|
||||
MapRef} from 'react-map-gl';
|
||||
MapRef,
|
||||
LinearInterpolator} from 'react-map-gl';
|
||||
import {useIntl} from 'gatsby-plugin-intl';
|
||||
import bbox from '@turf/bbox';
|
||||
import * as d3 from 'd3-ease';
|
||||
|
@ -58,6 +59,8 @@ export interface IDetailViewInterface {
|
|||
properties: constants.J40Properties,
|
||||
};
|
||||
|
||||
type MapBoundaryReached = 'top' | 'right' | 'bottom' | 'left' | '';
|
||||
|
||||
const J40Map = ({location}: IJ40Interface) => {
|
||||
/**
|
||||
* Initializes the zoom, and the map's center point (lat, lng) via the URL hash #{z}/{lat}/{long}
|
||||
|
@ -81,6 +84,10 @@ const J40Map = ({location}: IJ40Interface) => {
|
|||
zoom: zoom && parseFloat(zoom) ? parseFloat(zoom) : constants.GLOBAL_MIN_ZOOM,
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Map selection state variables:
|
||||
*/
|
||||
const [selectedFeature, setSelectedFeature] = useState<MapboxGeoJSONFeature>();
|
||||
const [detailViewData, setDetailViewData] = useState<IDetailViewInterface>();
|
||||
const [transitionInProgress, setTransitionInProgress] = useState<boolean>(false);
|
||||
|
@ -88,6 +95,28 @@ const J40Map = ({location}: IJ40Interface) => {
|
|||
const [isMobileMapState, setIsMobileMapState] = useState<boolean>(false);
|
||||
const [censusSelected, setCensusSelected] = useState<boolean>(true);
|
||||
|
||||
/**
|
||||
* Map Boundary reached state variables:
|
||||
*/
|
||||
// const mapContainerRef = useRef(null);
|
||||
// const [mapBoundaryReached, setMapBoundaryReached] = useState<MapBoundaryReached>('');
|
||||
const [isMapBeingDragged, setIsMapBeingDragged] = useState<boolean>(false);
|
||||
|
||||
// useEffect(() => {
|
||||
// const onAnimationEnd = () => {
|
||||
// setMapBoundaryReached('');
|
||||
// };
|
||||
|
||||
// const mapContainer = mapContainerRef.current;
|
||||
|
||||
// mapContainer.addEventListener('animationend', onAnimationEnd);
|
||||
|
||||
// return () => {
|
||||
// mapContainer.removeEventListener('animationend', onAnimationEnd);
|
||||
// };
|
||||
// }, []);
|
||||
|
||||
|
||||
// In order to detect that the layer has been toggled (between census and tribal),
|
||||
// this state variable will hold that information
|
||||
const [layerToggled, setLayerToggled] = useState<boolean>(false);
|
||||
|
@ -324,11 +353,67 @@ const J40Map = ({location}: IJ40Interface) => {
|
|||
setGeolocationInProgress(true);
|
||||
};
|
||||
|
||||
/**
|
||||
* This function will set the map boundaries during the dragging of the map. If a user attempts to
|
||||
* drag the map past the boundaries, an animation will play to mimic the end of the end has been
|
||||
* reached.
|
||||
*
|
||||
* @param {ViewportProps} viewState
|
||||
* @return {} setViewport
|
||||
*/
|
||||
const onViewportChange = (viewState:ViewportProps) => {
|
||||
// console.log('🚀 ~ file: J40Map.tsx ~ line 355 ~ onViewportChange ~ viewState', viewState);
|
||||
let mapBoundaryReached:MapBoundaryReached = '';
|
||||
|
||||
if (isMapBeingDragged) {
|
||||
if (
|
||||
viewState.longitude &&
|
||||
viewState.longitude > constants.MAP_BOUND_MIN_LONGITUDE &&
|
||||
viewState.longitude < 180 ) {
|
||||
viewState.longitude = constants.MAP_BOUND_MIN_LONGITUDE;
|
||||
mapBoundaryReached= 'left';
|
||||
} else if ( viewState.longitude && viewState.longitude > constants.MAP_BOUND_MAX_LONGITUDE ) {
|
||||
viewState.longitude = constants.MAP_BOUND_MAX_LONGITUDE;
|
||||
mapBoundaryReached= 'right';
|
||||
}
|
||||
|
||||
if ( viewState.latitude && viewState.latitude < constants.MAP_BOUND_MIN_LATITUDE ) {
|
||||
mapBoundaryReached= 'bottom';
|
||||
viewState.latitude = constants.MAP_BOUND_MIN_LATITUDE;
|
||||
}
|
||||
|
||||
if ( viewState.latitude && viewState.latitude > constants.MAP_BOUND_MAX_LATITUDE ) {
|
||||
viewState.latitude = constants.MAP_BOUND_MAX_LATITUDE;
|
||||
mapBoundaryReached= 'bottom';
|
||||
}
|
||||
}
|
||||
|
||||
return mapBoundaryReached ? setViewport({
|
||||
...viewState,
|
||||
transitionDuration: 1000,
|
||||
transitionInterpolator: new LinearInterpolator(),
|
||||
transitionEasing: d3.easeBounce,
|
||||
}) : setViewport(viewState);
|
||||
};
|
||||
|
||||
// Set mapbox base layer:
|
||||
const mapBoxBaseLayer = 'tl' in flags ? `mapbox://styles/justice40/cl2qimpi2000014qeb1egpox8` : `mapbox://styles/justice40/cl5mp95tu000k14lpl21spgny`;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Grid desktop={{col: 9}} className={styles.j40Map}>
|
||||
<Grid
|
||||
desktop={{col: 9}}
|
||||
// className={mapBoundaryReached === 'bottom' ?
|
||||
// `${styles.j40Map} ${styles.scrollDownBounce}` :
|
||||
// styles.j40Map}
|
||||
className={styles.j40Map}
|
||||
// onAnimationEnd={(e) => {
|
||||
// // Todo: Document how both animation types will trigger this callback
|
||||
// // console.log('🚀 ~ file: J40Map.tsx ~ line 394 ~ J40Map ~ e', e);
|
||||
// console.log('animation ended');
|
||||
// setMapBoundaryReached('');
|
||||
// }}
|
||||
>
|
||||
{/**
|
||||
* Note:
|
||||
* The MapSearch component is no longer used in this location. It has been moved inside the
|
||||
|
@ -361,8 +446,10 @@ const J40Map = ({location}: IJ40Interface) => {
|
|||
process.env.MAPBOX_STYLES_READ_TOKEN ?
|
||||
process.env.MAPBOX_STYLES_READ_TOKEN : ''}
|
||||
|
||||
// ****** Map state props: ******
|
||||
// http://visgl.github.io/react-map-gl/docs/api-reference/interactive-map#map-state
|
||||
/**
|
||||
* ****** Map state props: ******
|
||||
* https://github.com/visgl/react-map-gl/blob/6.1-release/docs/api-reference/interactive-map.md#map-state
|
||||
*/
|
||||
{...viewport}
|
||||
mapStyle={process.env.MAPBOX_STYLES_READ_TOKEN ? mapBoxBaseLayer : getOSBaseMap(censusSelected)}
|
||||
width="100%"
|
||||
|
@ -371,9 +458,10 @@ const J40Map = ({location}: IJ40Interface) => {
|
|||
height="100%"
|
||||
mapOptions={{hash: true}}
|
||||
|
||||
|
||||
// ****** Interaction option props: ******
|
||||
// http://visgl.github.io/react-map-gl/docs/api-reference/interactive-map#interaction-options
|
||||
/**
|
||||
* ****** Interaction options: ******
|
||||
* https://github.com/visgl/react-map-gl/blob/6.1-release/docs/api-reference/interactive-map.md#interaction-options
|
||||
*/
|
||||
maxZoom={constants.GLOBAL_MAX_ZOOM}
|
||||
minZoom={constants.GLOBAL_MIN_ZOOM}
|
||||
dragRotate={false}
|
||||
|
@ -389,10 +477,17 @@ const J40Map = ({location}: IJ40Interface) => {
|
|||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* ****** Callback props: ******
|
||||
* https://github.com/visgl/react-map-gl/blob/6.1-release/docs/api-reference/interactive-map.md#callbacks
|
||||
*/
|
||||
// eslint-disable-next-line max-len
|
||||
onViewportChange={(viewState: ViewportProps) => onViewportChange(viewState)}
|
||||
|
||||
// ****** Callback props: ******
|
||||
// http://visgl.github.io/react-map-gl/docs/api-reference/interactive-map#callbacks
|
||||
onViewportChange={setViewport}
|
||||
// Detect and set the state variable is map is dragging
|
||||
onInteractionStateChange={(interactionState: { isDragging: boolean; }) => {
|
||||
interactionState.isDragging ? setIsMapBeingDragged(true) : setIsMapBeingDragged(false);
|
||||
}}
|
||||
onClick={onClick}
|
||||
onLoad={onLoad}
|
||||
onTransitionStart={onTransitionStart}
|
||||
|
|
|
@ -301,6 +301,57 @@ export const SELECTED_FEATURE_BORDER_WIDTH = 5.0;
|
|||
export const ALAKSA_POINTS_STROKE_WIDTH = 1.0;
|
||||
|
||||
// Bounds - these bounds can be obtained by using the getCurrentMapBoundingBox() function in the map
|
||||
|
||||
/**
|
||||
* ### Grab the lat/lon for the bounds of the map ###
|
||||
*
|
||||
* Alaska's coordinates:
|
||||
* - latitude: 63.27827735223102
|
||||
* - longitude: -162.3947525
|
||||
*
|
||||
* Hawaii's coordinates:
|
||||
* - latitude: 20.657020350316177
|
||||
* - longitude: -157.696737
|
||||
*
|
||||
* Mariana Islands coordinates:
|
||||
* - latitude: 16.900917105280538
|
||||
* - longitude: 145.47207349999974
|
||||
*
|
||||
* Guam's coordinates:
|
||||
* - latitude: 14.366555855360668
|
||||
* - longitude: 144.85327381019735
|
||||
*
|
||||
* USVI's coordinates:
|
||||
* - latitude: 18.2017745170224
|
||||
* - longitude: -64.77448172638938
|
||||
*
|
||||
* Maine's coordinates:
|
||||
* - latitude: 42.52750243984539
|
||||
* - longitude: -72.05693075466074
|
||||
*
|
||||
* ### Group the above by Lat/Lon ###
|
||||
*
|
||||
* - latitude: 63.27827735223102
|
||||
* - latitude: 20.657020350316177
|
||||
* - latitude: 16.900917105280538
|
||||
* - latitude: 14.366555855360668
|
||||
* - latitude: 18.2017745170224
|
||||
* - latitude: 42.52750243984539
|
||||
*
|
||||
* - longitude: -162.3947525
|
||||
* - longitude: -157.696737
|
||||
* - longitude: 145.47207349999974
|
||||
* - longitude: 144.85327381019735
|
||||
* - longitude: -64.77448172638938
|
||||
* - longitude: -72.05693075466074
|
||||
*
|
||||
* Set min/max lat/lon:
|
||||
*/
|
||||
export const MAP_BOUND_MIN_LATITUDE = 13;
|
||||
export const MAP_BOUND_MAX_LATITUDE = 65;
|
||||
export const MAP_BOUND_MIN_LONGITUDE = 150;
|
||||
export const MAP_BOUND_MAX_LONGITUDE = -65;
|
||||
|
||||
export const GLOBAL_MAX_BOUNDS: LngLatBoundsLike = [
|
||||
[-180.118306, 5.499550],
|
||||
[-65.0, 83.162102],
|
||||
|
|
Loading…
Add table
Reference in a new issue