Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:location/location.dart';
import 'package:mapbox_gl/mapbox_gl.dart';
import 'package:mapbox_gl_example/popup.dart';

import 'animate_camera.dart';
import 'annotation_order_maps.dart';
Expand Down Expand Up @@ -50,7 +51,8 @@ final List<ExamplePage> _allPages = <ExamplePage>[
BatchAddPage(),
TakeSnapPage(),
ClickAnnotationPage(),
Sources()
Sources(),
PopupPage(),
];

class MapsDemo extends StatefulWidget {
Expand Down
117 changes: 117 additions & 0 deletions example/lib/popup.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import 'package:flutter/material.dart';
import 'package:mapbox_gl_example/main.dart';
import 'package:mapbox_gl_example/page.dart';
import 'package:mapbox_gl/mapbox_gl.dart';

class PopupPage extends ExamplePage {
PopupPage() : super(const Icon(Icons.mouse), "Popup");

@override
Widget build(BuildContext context) {
return PopupBody();
}
}

class PopupBody extends StatefulWidget {
const PopupBody({Key? key}) : super(key: key);

@override
State<PopupBody> createState() => _PopupBodyState();
}

class _PopupBodyState extends State<PopupBody> {
static final LatLng center = const LatLng(-33.86711, 151.1947171);

late final MapboxMapController controller;

void _onMapCreated(MapboxMapController controller) {
this.controller = controller;
}

void _onStyleLoadedCallback() async {
await controller.addGeoJsonSource("points", _points);

await controller.addSymbolLayer(
"points",
"symbols",
SymbolLayerProperties(
iconImage: "{type}-15",
iconSize: 2,
iconAllowOverlap: true,
),
);

controller.showPopupOnFeatureHover(
layerId: "symbols",
closeButton: false,
loseButton: false,
closeOnClick: false);
}

@override
Widget build(BuildContext context) {
return MapboxMap(
accessToken: MapsDemo.ACCESS_TOKEN,
onMapCreated: _onMapCreated,
onStyleLoadedCallback: _onStyleLoadedCallback,
initialCameraPosition: CameraPosition(
target: center,
zoom: 11.0,
),
);
}
}

const _points = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": 2,
"properties": {
"description": "a good restaurant",
"type": "restaurant",
},
"geometry": {
"type": "Point",
"coordinates": [151.184913929732943, -33.874874486427181]
}
},
{
"type": "Feature",
"id": 3,
"properties": {
"description": "<i>Sydney airport</i>",
"type": "airport",
},
"geometry": {
"type": "Point",
"coordinates": [151.215730044667879, -33.874616048776858]
}
},
{
"type": "Feature",
"id": 4,
"properties": {
"description": "<h3>Go get croissants!</h3>",
"type": "bakery",
},
"geometry": {
"type": "Point",
"coordinates": [151.228803547973598, -33.892188026142584]
}
},
{
"type": "Feature",
"id": 5,
"properties": {
"description": "The city college",
"type": "college",
},
"geometry": {
"type": "Point",
"coordinates": [151.186470299174118, -33.902781145804774]
}
}
]
};
3 changes: 2 additions & 1 deletion lib/mapbox_gl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ library mapbox_gl;
import 'dart:async';
import 'dart:convert';
import 'dart:math';
import 'dart:typed_data';

import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:mapbox_gl_platform_interface/mapbox_gl_platform_interface.dart';
import 'package:mapbox_gl_web/mapbox_gl_web.dart';
import 'package:mapbox_gl_dart/mapbox_gl_dart.dart' show Popup, PopupOptions;

export 'package:mapbox_gl_platform_interface/mapbox_gl_platform_interface.dart'
show
Expand Down
36 changes: 36 additions & 0 deletions lib/src/controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1333,6 +1333,42 @@ class MapboxMapController extends ChangeNotifier {
}
}

/// show popup when a feature of a given layer is hovered, remove the popup when the mouse leaves the feature
///
/// You can configure how the popup will appear by setting [loseButton], [closeButton], [offset], [anchor] and [textSize].
///
/// *This only works on web*
void showPopupOnFeatureHover({
required String layerId,
bool? loseButton,
bool? closeButton,
bool? closeOnClick,
String? anchor,
String? className,
String? maxWidth,
dynamic offset,
}) {
if (_mapboxGlPlatform is MapboxWebGlPlatform) {
final mapboxWebPlatform = _mapboxGlPlatform as MapboxWebGlPlatform;
final popup = Popup();
// Passing the option directly in constructor does not work
popup.options.loseButton = loseButton;
popup.options.closeButton = closeButton;
popup.options.closeOnClick = closeOnClick;
popup.options.anchor = anchor;
popup.options.className = className;
popup.options.maxWidth = maxWidth;

// We also don't pass the offset if it's null because it will put
// the popup at the top left corner of the screen
if (offset != null) {
popup.options.offset = offset;
}

mapboxWebPlatform.showPopupOnFeatureHover(layerId: layerId, popup: popup);
}
}

/// Generates static raster images of the map. Each snapshot image depicts a portion of a map defined by an [SnapshotOptions] object you provide
/// Android/iOS: Return snapshot uri in app specific cache storage or base64 string
/// Web: Return base64 string with current camera posision of [MapboxMap]
Expand Down
24 changes: 24 additions & 0 deletions mapbox_gl_web/lib/src/mapbox_web_gl_platform.dart
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,30 @@ class MapboxWebGlPlatform extends MapboxGlPlatform
_map.getCanvas().style.cursor = '';
}

/// show a given popup when a feature of a given layer is hovered, remove the popup when the mouse leaves the feature
void showPopupOnFeatureHover(
{required String layerId, required Popup popup}) {
_map.on('mouseenter', layerId, (Event e) {
final feature = e.features.first;
final lngLat = e.lngLat;

final coordinates = <num>[...feature.geometry.coordinates];
final description = feature.properties["description"] as String?;

while ((lngLat.lng - coordinates.first).abs() > 180) {
coordinates.first += lngLat.lng > coordinates.first ? 360 : -360;
}

popup
.setLngLat(LngLat(coordinates.first, coordinates.last))
.setHTML(description)
.addTo(_map);
});
_map.on('mouseleave', layerId, (Event e) {
popup.remove();
});
}

@override
void setGestures(
{required bool rotateGesturesEnabled,
Expand Down
6 changes: 3 additions & 3 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ packages:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
version: "1.2.1"
collection:
dependency: "direct main"
description:
Expand Down Expand Up @@ -80,14 +80,14 @@ packages:
name: material_color_utilities
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.4"
version: "0.1.5"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
version: "1.8.0"
path:
dependency: transitive
description:
Expand Down