From 0a9c6ce16ae78e89d8853fc1bb07549494592158 Mon Sep 17 00:00:00 2001 From: Jakub Hampl Date: Tue, 19 Jun 2018 16:39:32 +0100 Subject: Adds a custom element for mapbox integration --- src/Mapbox/Element.elm | 106 +++++++++++++++++++++++++++++++++++++++++++++++++ src/Mapbox/Layer.elm | 2 +- src/js/main.js | 92 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 src/Mapbox/Element.elm create mode 100644 src/js/main.js (limited to 'src') diff --git a/src/Mapbox/Element.elm b/src/Mapbox/Element.elm new file mode 100644 index 0000000..4ca28cc --- /dev/null +++ b/src/Mapbox/Element.elm @@ -0,0 +1,106 @@ +module Mapbox.Element exposing (..) + +import Html exposing (Attribute, Html, node) +import Html.Attributes exposing (property, attribute) +import Json.Encode as Encode +import Mapbox.Style exposing (Style) + + +type MapboxAttr msg + = MapboxAttr (Attribute msg) + + +type Control msg + = Control (Html msg) + + +type Position + = TopLeft + | BottomLeft + | TopRight + | BottomRight + + +map : List (MapboxAttr msg) -> List (Control msg) -> Html msg +map attrs children = + let + props = + (List.map (\(MapboxAttr attr) -> attr) attrs) + in + node "elm-mapbox-map" props [] + + +css : Html msg +css = + node "link" [ attribute "href" "https://api.tiles.mapbox.com/mapbox-gl-js/v0.45.0/mapbox-gl.css", attribute "rel" "stylesheet" ] [] + + +style : Style -> MapboxAttr msg +style = + Mapbox.Style.encode >> property "mapboxStyle" >> MapboxAttr + + +minZoom : Float -> MapboxAttr msg +minZoom = + Encode.float >> property "minZoom" >> MapboxAttr + + +maxZoom : Float -> MapboxAttr msg +maxZoom = + Encode.float >> property "maxZoom" >> MapboxAttr + + +token : String -> MapboxAttr msg +token = + Encode.string >> property "token" >> MapboxAttr + + +id : String -> MapboxAttr msg +id = + attribute "id" >> MapboxAttr + + +type alias LngLat = + ( Float, Float ) + + +{-| sw: lnglat, ne: lnglat +-} +maxBounds : ( LngLat, LngLat ) -> MapboxAttr msg +maxBounds = + encodePair (encodePair Encode.float) >> property "maxBounds" >> MapboxAttr + + +renderWorldCopies : Bool -> MapboxAttr msg +renderWorldCopies = + Encode.bool >> property "renderWorldCopies" >> MapboxAttr + + +encodePair encoder ( a, b ) = + Encode.list [ encoder a, encoder b ] + + +encodePosition pos = + case pos of + TopLeft -> + Encode.string "top-left" + + BottomLeft -> + Encode.string "bottom-left" + + TopRight -> + Encode.string "top-right" + + BottomRight -> + Encode.string "bottom-right" + + + +--- Controlled mode + + +{-| Note: this property will only take effect when the map is created. +-} +controlled : MapboxAttr msg +controlled = + property "interactive" (Encode.bool False) |> MapboxAttr diff --git a/src/Mapbox/Layer.elm b/src/Mapbox/Layer.elm index 8d97965..ad60292 100644 --- a/src/Mapbox/Layer.elm +++ b/src/Mapbox/Layer.elm @@ -285,7 +285,7 @@ encode (Layer value) = value -layerImpl tipe source id attrs = +layerImpl tipe id source attrs = [ ( "type", Encode.string tipe ) , ( "id", Encode.string id ) , ( "source", Encode.string source ) diff --git a/src/js/main.js b/src/js/main.js new file mode 100644 index 0000000..c2b3120 --- /dev/null +++ b/src/js/main.js @@ -0,0 +1,92 @@ +import mapboxgl from "mapbox-gl"; + +function wrapElmApplication(elmApp) { + window.customElements.define( + "elm-mapbox-map", + class MapboxMap extends window.HTMLElement { + constructor() { + super(); + this._refreshExpiredTiles = true; + this._renderWorldCopies = true; + this.interactive = true; + } + + get mapboxStyle() { + return this._style; + } + set mapboxStyle(value) { + if (this._map) this._map.setStyle(value); + this._style = value; + } + + get minZoom() { + return this._minZoom; + } + set minZoom(value) { + if (this._map) this._map.setMinZoom(value); + this._minZoom = value; + } + + get maxZoom() { + return this._maxZoom; + } + set maxZoom(value) { + if (this._map) this._map.setMaxZoom(value); + this._maxZoom = value; + } + + get map() { + return this._map; + } + + get maxBounds() { + return this._maxBounds; + } + set maxBounds(value) { + if (this._map) this._map.setBounds(value); + this._maxBounds = value; + } + + get renderWorldCopies() { + return this._renderWorldCopies; + } + set renderWorldCopies(value) { + if (this._map) this._map.setRenderWorldCopies(value); + this._renderWorldCopies = value; + } + + connectedCallback() { + mapboxgl.accessToken = this.token; + this.style.display = "block"; + this.style.width = "100%"; + this.style.height = "100%"; + this._map = new mapboxgl.Map({ + container: this, + style: this._style, + minZoom: this._minZoom || 0, + maxZoom: this._maxZoom || 22, + interactive: this.interactive, + attributionControl: false, + logoPosition: this.logoPosition || "bottom-left", + refreshExpiredTiles: this._refreshExpiredTiles, + maxBounds: this._maxBounds, + center: this.center, + // zoom: this.zoom, + // bearing: this.bearing, + // pitch: this.pitch, + renderWorldCopies: this._renderWorldCopies + // maxTileCacheSize: this._maxTileCacheSize, + // localIdeographFamily: this._localIdeographFamily + }); + } + + disconnectedCallback() { + this._map.remove(); + delete this._map; + } + } + ); + return elmApp; +} + +export default wrapElmApplication; -- cgit v1.2.3