Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conditional SymbolLayer overlaps rather than replaces #1335

Open
isabelle-butterfield opened this issue Aug 15, 2018 · 7 comments
Open

Conditional SymbolLayer overlaps rather than replaces #1335

isabelle-butterfield opened this issue Aug 15, 2018 · 7 comments

Comments

@isabelle-butterfield
Copy link

isabelle-butterfield commented Aug 15, 2018

My ShapeSource has a FillLayer and a SymbolLayer which changes depending on state. The initial rendering is correct; however, once I toggle state, the new SymbolLayer overlaps the old one rather than replacing it. Below is sample code as well as screenshots to help describe the issue.

export default class App extends Component{
  constructor(props) {
    super(props);

    this.state= {
      showTesting: false
    }
  }

  onButton = () => {
    this.setState({showTesting: !this.state.showTesting})
  }
render() {
    return (
      <View style={styles.container}>
        <Mapbox.MapView
            styleURL={Mapbox.StyleURL.Street}
            zoomLevel={13}
            centerCoordinate={[-116.17117573543476, 45.91943632276249]}
            style={styles.container}>
              <TouchableHighlight style={{backgroundColor: 'red', height: 40, width: 80}} onPress={this.onButton}>
                <Text>Press</Text>
              </TouchableHighlight>

              <Mapbox.ShapeSource 
                key={'hi'} 
                id={'shape'} 
                shape={{
                  "type":"FeatureCollection",
                  "features":[
                    {
                      "type":"Feature",
                      "properties":{

                      },
                      "geometry":{
                        "type":"Polygon",
                        "coordinates":[
                          [
                            [-116.17117573543476, 45.91943632276249],
                            [-116.17598225394266, 45.914241330348744],
                            [-116.16413761904698, 45.91331573468162],
                            [-116.17117573543476, 45.91943632276249]
                          ]
                        ]
                      }
                    }
                  ]}} 
                hitbox={{ width: 5, height: 5 }} >

                <Mapbox.FillLayer 
                      id={'layer'} 
                      style={{fillColor: 'rgba(0, 0, 0, .4)'}}/>

                { this.state.showTesting ? 
                  <Mapbox.SymbolLayer 
                          id={'name'} 
                          style={{
                            textField: "Testing",
                            textSize: 14, 
                            textMaxWidth: 50, 
                            textColor: '#FFFFFF', 
                            textAnchor: 'center'
                          }}
                        />
                  :
                  <Mapbox.SymbolLayer 
                        id={'name'} 
                        style={{
                          iconSize: .5,
                          iconAnchor: 'center',
                          iconImage: info
                        }}
                      />
                }
              </Mapbox.ShapeSource>
        </Mapbox.MapView>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
});

BEFORE BUTTON PRESS:
screen shot 2018-08-15 at 3 58 00 pm

AFTER BUTTON PRESS:
screen shot 2018-08-15 at 3 58 15 pm

@kristfal
Copy link
Collaborator

Please see aboveLayerID and belowLayerID in the documentation.

Also, please refrain from using Github for questions. Github is intended for posting bugs, issues and feature requests. Use the gitter channel (https://gitter.im/react-native-mapbox-gl/Lobby) or stack overflow for code questions.

@isabelle-butterfield
Copy link
Author

isabelle-butterfield commented Aug 20, 2018

Thank you for the response; however, I'm not sure that it implies an obvious solution. It seems like aboveLayerID and belowLayerID may be useful especially when the overlap of SymbolLayers is intended, yet this is not the case here.

From my understanding, it does seem like this could be a bug; apologies for the location of the comment if it in fact is not a bug.

It looks like when the state of showTesting changes, the SymbolLayer containing the icon should disappear, and the SymbolLayer containing the text should appear instead. This is not the current behavior. Could you be willing to give me any more insight into how this might be resolved if it is not a Mapbox bug? Thank you!

@kristfal
Copy link
Collaborator

Sorry, that was a misunderstanding on my side.

Have you tried defining non-identical IDs for the layers? If this doesn't work, can you try keeping the same SymbolLayer component, and only conditionally return a different style object?

It seems like the diffing algo may have issues interpreting the proper layer changes when two components with the same ID is replaced.

@kristfal kristfal reopened this Aug 20, 2018
@isabelle-butterfield
Copy link
Author

isabelle-butterfield commented Aug 20, 2018

No worries, thanks for the help. I've tried both of these as follows:

<Mapbox.SymbolLayer
        id={'name'} 
        style= {this.state.showTesting ? 
                {
	                iconSize: .5,
		        iconAnchor: 'center',
		        iconImage: info

		}
		:
		{
			textField: "Testing",
			textSize: 14, 
			textMaxWidth: 50, 
			textColor: '#FFFFFF', 
			textPadding: 0,
			textAnchor: 'center'
		}
	}
/>

and

{ this.state.showTesting ? 
        <Mapbox.SymbolLayer 
                id={'text'} 
                style={{
                        textField: "Testing",
                        textSize: 14, 
                        textMaxWidth: 50, 
                        textColor: '#FFFFFF', 
                        textAnchor: 'center'
                }}
          />
          :
          <Mapbox.SymbolLayer 
                  id={'icon'} 
                  style={{
                          iconSize: .5,
                          iconAnchor: 'center',
                          iconImage: info
                  }}
           />
}

The behavior unfortunately remains the same.

@kristfal
Copy link
Collaborator

Ok, thanks for testing. Can you try passing a null value or an empty string for textField symbol layer where you don't want it to render? I'm looking at the native code and I can't find any place where a set style prop is "deallocated" once set. Will dig into it more.

@isabelle-butterfield
Copy link
Author

isabelle-butterfield commented Aug 20, 2018

Do you mean something like this?

{ this.state.showTesting ? 
        <Mapbox.SymbolLayer 
                id={'text'} 
                style={{
                        textField: this.state.showTesting ? "Testing" : null,
                        textSize: 14, 
                        textMaxWidth: 50, 
                        textColor: '#FFFFFF', 
                        textAnchor: 'center'
                }}
          />
          :
          <Mapbox.SymbolLayer 
                  id={'icon'} 
                  style={{
                          iconSize: .5,
                          iconAnchor: 'center',
                          iconImage: info
                  }}
           />
}

This still doesn't change the result. Same with an empty string. However, it's interesting that it never complains about the null value. It looks like if I were to make the textField always null, it would not be acceptable.

screen shot 2018-08-20 at 8 37 16 am

This issue does not arise when null is only conditional as in the example above.

@arnaudambro
Copy link

@kristfal @isabelle-butterfield did you find a solution ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants