MapboxGL Marker Leaving Map Container in React
Asked Answered
O

0

6

I'm working on a React/MapboxGL app and I'm having some issue with my marker leaving the bounds of designated map area whenever i move the map around. I feel there may be some other larger underlying React rendering principals that I don't fully understand that is causing this problem for me. Any help would be much appreciated. Thanks!

Additionally I've noticed a blue highlightable border on the map whenever I click on the map which is not present in any of the tutorials/examples I've seen. Which leads me to further believe that it's how I am integrating mapbox-gl with React.

Here are the components I'm using-

Main Component

import React from 'react';
import ReactDOM from 'react-dom';
import List from './List.jsx';
import MapComponent from './Map.jsx';
import Header from './Header.jsx';

const appConstants = require('../constants/appConstants');
const host = 'http://localhost:8020';
const socket = io(host);

let key = 0;

class MainComponent extends React.Component {

  constructor() {
     super();
     this.state = {
        events: []
    };
  }

componentWillMount() {
    socket.on('new event', (event) => this._handleStateChange(event));
}

render() {
    return (
        <div>
            <div className="headerContainer">
                <Header name={appConstants.appHeader}></Header>
            </div>
            <div className="flexContainer">
                <div className="tabContainer">Tabs on Tabs</div>
                <div className="mapContainer">
                    <MapComponent events={this.state.events} heading={appConstants.mapHeader}></MapComponent>
                </div>
                <div className="eventContainer">
                    <List events={this.state.events}></List>
                </div>
            </div>
        </div>
    );
}

    _handleStateChange(event) {
        let newEvent = {
            browserName: event.new_val.browserName,
            location: event.new_val.location,
            osName: event.new_val.osName,
            key: key,
            eventName: event.new_val.event,
            interval: event.new_val.interval
        };

        key++;

        this.state.events.unshift(newEvent);
        let events = this.state.events.slice(0, 10);

        this.setState({events});
    }
}

ReactDOM.render(<MainComponent />, document.getElementById('main'));

Map Component

class MapComponent extends React.Component {

    constructor() {
        super();
    };

    componentDidMount() {
        /* On first load - center */
        map = new mapboxgl.Map({
            container: 'map',
            style: mapConstants.style,
            center: mapConstants.hqCoordinates,
            zoom: 11
        });

        /* on initial load setup the location + icon */
        map.on('load', function () {

            const el = document.createElement('img');
            el.className = 'marker';
            el.style.backgroundImage = 'url(./assets/images/banana.png)';
            el.style.width = mapConstants.markerWidth;
            el.style.height = mapConstants.markerHeight;

            new mapboxgl.Marker(el)
               .setLngLat(mapConstants.hqCoordinates)
               .addTo(map);
        });

   }

    /* called when the props are updated */
    componentWillUpdate() {
       this._handleEventChange(this.props.events)
    }


    /* helper functions */
    _handleEventChange(events) {
        /* get most recent event and fly there */
        const mostRecentEvent = events[0];

        /* map box coordinates: [lng, lat ] */
        const mostRecentLocation = mostRecentEvent.location.split(',').reverse();

        map.flyTo({
           center: mostRecentLocation,
           zoom: 11
        });

        /* check if data source has been added */
        const existingEvent = map.getSource('mostRecentEvent');

        /* if data source exists, update the data */
        if (existingEvent) {
            existingEvent.setData({
                "type": "Feature",
                "geometry": {
                   "type": 'Point',
                   "coordinates": mostRecentLocation
               },
               "properties": {
                   "title":helperService.getShortEventName(mostRecentEvent.eventName),
                   "icon": mostRecentEvent.browserName.toLowerCase()
                }
            })
        } else {
            /* otherwise this is the first event and we need to add a source & layer */
            map.addSource('mostRecentEvent', {
                "type": "geojson",
                "data": {
                    "type": "Feature",
                    "geometry": {
                         "type": 'Point',
                         "coordinates": mostRecentLocation
                     },
                    "properties": {
                       "title": helperService.getShortEventName(mostRecentEvent.eventName),
                        "icon": mostRecentEvent.browserName.toLowerCase()
                    }
                }
            });

            map.addLayer({
                "id": "mostRecentEvent",
                "type": "symbol",
                "source": "mostRecentEvent",
                "layout": {
                    "icon-image": "{icon}",
                    "text-field": "{title}",
                    "text-font": ["Open Sans Semibold", "Arial Unicode MS Bold"],
                    "text-offset": [0, 0.6],
                    "text-anchor": "top",
                    "text-allow-overlap": true,
                    "text-size": 20
                },
                "paint": {
                    "text-color": '#FF0080'
                }
             });
        }
    }

    render() {
        return (<div>
             <div className="mapHeader">{this.props.heading}</div>
            <div id="map" style={styles.map}></div>
        </div>);
     }

}

   let styles = {
         map: {
           height: '500',
           width: '100%',
           zIndex: 0
  }
};

module.exports = MapComponent;

And a couple images of the issue

centered

after moving the map

Ocker answered 20/1, 2017 at 18:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.