Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Trying out 6.0.0: fade in animation on symbols #10916

Closed
palto-blubek opened this issue Jan 12, 2018 · 5 comments
Closed

Trying out 6.0.0: fade in animation on symbols #10916

palto-blubek opened this issue Jan 12, 2018 · 5 comments
Labels
Android Mapbox Maps SDK for Android Core The cross-platform C++ core, aka mbgl

Comments

@palto-blubek
Copy link

Platform: Android
Mapbox SDK version: 6.0.0 (snapshot)

Steps to trigger behavior

  1. Add a symbol layer, or update the source of an already existing symbol layer

Expected behavior

The symbol should be shown immediately (same behavior seen in pre 6.0.0)

Actual behavior

The symbol is appearing progressively (fade-in effect)

I'm not sure if it's a feature (if so, can it be disabled?) or a bug?

@tobrun
Copy link
Member

tobrun commented Jan 12, 2018

Thank you for reaching out. The fix for this was merged 17 hours ago here. You can retest this with the latest 6.0.0-SNAPSHOT build.

@tobrun tobrun closed this as completed Jan 12, 2018
@tobrun tobrun added the Android Mapbox Maps SDK for Android label Jan 12, 2018
@LukasPaczos
Copy link
Member

I was able to reproduce the issue on v6.0.1.

source_fade

The example code:

mapView.getMapAsync(new OnMapReadyCallback() {
  @Override
  public void onMapReady(MapboxMap mapboxMap) {
    List<Feature> features1 = new ArrayList<>();
    features1.add(Feature.fromGeometry(Point.fromLngLat(-77.036461, 38.898679)));

    List<Feature> features2 = new ArrayList<>();
    features2.add(Feature.fromGeometry(Point.fromLngLat(21.032070, 52.240291)));

    FeatureCollection featureCollection1 = FeatureCollection.fromFeatures(features1);
    FeatureCollection featureCollection2 = FeatureCollection.fromFeatures(features2);

    GeoJsonSource source1 = new GeoJsonSource("source1", featureCollection1);
    GeoJsonSource source2 = new GeoJsonSource("source2", featureCollection2);
    mapboxMap.addSource(source1);
    mapboxMap.addSource(source2);

    Layer layer1 = new SymbolLayer("layer1", "source1").withProperties(PropertyFactory.iconImage("restaurant-15"));
    Layer layer2 = new SymbolLayer("layer2", "source2").withProperties(PropertyFactory.iconImage("restaurant-15"));
    mapboxMap.addLayer(layer1);
    mapboxMap.addLayer(layer2);

    new Handler().postDelayed(new Runnable() {
      @Override
      public void run() {
        featureCollection2.features().addAll(featureCollection1.features());
        featureCollection1.features().clear();
        source1.setGeoJson(featureCollection1);
        source2.setGeoJson(featureCollection2);
      }
    }, 2500);
  }
});

/cc @ansis @ChrisLoer

@LukasPaczos LukasPaczos reopened this Apr 27, 2018
@LukasPaczos LukasPaczos added the Core The cross-platform C++ core, aka mbgl label Apr 27, 2018
@ChrisLoer
Copy link
Contributor

With global/viewport collision detection (PR #10436), the fade-in for new symbols is currently unavoidable for symbol layers that require collision detection. If you don't need collision detection, you can disable it for that layer with [text|icon]-allow-overlap: true, and the symbol will show immediately.

Your example of updating an existing symbol is triggering a fade-in/fade-out because the symbol is "moving" to a new layer (from the point of view of all the symbol code, that basically makes it a completely new symbol).

It's possible for us to add functionality for controlling the fade duration of collision animations, but we don't have a good way to distinguish "just added" from "just stopped colliding", so if you shortened/eliminated the fade animation it would affect both.

@LukasPaczos
Copy link
Member

Noting, that disabling symbol collision detection with PropertyFactory.iconAllowOverlap(true) in the above use-case still results in a symbol flash (without the fade in/out), which is to be expected as we are refreshing the layers twice - once without the symbol, and then with the symbol re-added.

ezgif com-video-to-gif

@LukasPaczos
Copy link
Member

LukasPaczos commented May 17, 2018

Also wanted to add that a solution for the above use-case would be using a single source which refreshes both layers at the same time, for example:

    mapView.getMapAsync(mapboxMap -> {
      List<Feature> features = new ArrayList<>();
      Feature feature1 = Feature.fromGeometry(Point.fromLngLat(21.032070, 52.2401));
      feature1.addBooleanProperty("selected", false);
      Feature feature2 = Feature.fromGeometry(Point.fromLngLat(21.032070, 52.2402));
      feature2.addBooleanProperty("selected", false);
      Feature feature3 = Feature.fromGeometry(Point.fromLngLat(21.032070, 52.2403));
      feature3.addBooleanProperty("selected", false);

      features.add(feature1);
      features.add(feature2);
      features.add(feature3);

      FeatureCollection featureCollection = FeatureCollection.fromFeatures(features);

      GeoJsonSource source = new GeoJsonSource("source", featureCollection);
      mapboxMap.addSource(source);

      Layer layer = new SymbolLayer("layer", "source")
        .withProperties(PropertyFactory.iconImage(
          Expression.switchCase(
            Expression.get("selected"), Expression.literal(""),
            Expression.literal("cafe-15")
          )),
          PropertyFactory.iconSize(2f),
          PropertyFactory.iconAllowOverlap(true));
      mapboxMap.addLayer(layer);

      Layer layerSelected = new SymbolLayer("layerSelected", "source")
        .withProperties(PropertyFactory.iconImage(
          Expression.switchCase(
            Expression.get("selected"), Expression.literal("restaurant-15"),
            Expression.literal("")
          )),
          PropertyFactory.iconSize(2f),
          PropertyFactory.iconAllowOverlap(true));
      mapboxMap.addLayerAbove(layerSelected, "layer");

      mapboxMap.addOnMapClickListener(point -> {
        if (selected) {
          feature3.addBooleanProperty("selected", false);
        } else {
          feature3.addBooleanProperty("selected", true);
        }
        source.setGeoJson(featureCollection);
        selected = !selected;
      });

      mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
        new LatLng(52.2401, 21.032070),
        15.5
      ));
    });

Closing as not actionable/resolved.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Android Mapbox Maps SDK for Android Core The cross-platform C++ core, aka mbgl
Projects
None yet
Development

No branches or pull requests

4 participants