Bensstats
Bensstats

Reputation: 1056

Putting a leaflet map in a "Picture Frame" in R

I am presently in the process of building an R package that allows users to make custom souvenir maps of their flights, road trips and the cities they visit.

I am in the process of trying to figure out how to add a custom title and frame to a leaflet map.

What I have so far

library(leaflet)
library(htmltools)
library(htmlwidgets)

# Custom CSS
tag.map.title <-  tags$style(HTML("
  .leaflet-control.map-title { 
    transform: translate(-30%,850%);
    position: fixed !important;
    left: 50%;
    text-align: center;
    font-weight: bold;
    font-size: 60px;
    font-family: 'Brush Script MT'
  }
"))

# Adding a title
title <- tags$div(
  tag.map.title, HTML("New York, New York!")
)  

# Using my custom package
# devtools::install_github("benyamindsmith/mapBliss")
mapBliss::plot_city_view("New York City",
                         #mapBoxTemplate ="mapbox-template-link",
                         zoomControl = c(0.15, 0.05, 0.04, -0.003)) %>% 
  addControl(title, position = "topright", className="map-title")

enter image description here

What I want

I am wondering what is the CSS required if I want to have frames like these? Ideally they would maintain their position when resized also.

(For now, ignore the MapBox theme)

enter image description here

enter image description here

Upvotes: 2

Views: 377

Answers (1)

I_O
I_O

Reputation: 6921

If map and title share a common parent container (e.g. <div>), you can position both relative to their parent container. Remember to set position:relative in the children's CSS. Example:

library(shiny)
library(leaflet)
ui <- fluidPage(
    ## see various ways of including CSS: https://shiny.rstudio.com/articles/css.html
    tags$head(
             tags$style(HTML("
                  #greetings{top:-8rem;
                   position:relative;
                   z-index:1000;
                   background-color:#f0f0f099;
                   }

                  .fancy_border{border:dotted 5em green}           
                  
      ")
      )
      ),

    div(class = 'fancy_border', ## set CSS class to style border
        div(leafletOutput('map')),
        div(id = 'greetings', uiOutput('message'))
        )
)
                                        
server <- function(input, output) {
    output$map <- renderLeaflet({
        leaflet() %>%
            addProviderTiles(providers$Stamen.TonerLite,
                             options = providerTileOptions(noWrap = TRUE)
                             ) %>%
            addMarkers(data = cbind(c(16, 17), c(46, 48)))
    })
    ## note that you can also add CSS classes here:
    output$message <- renderUI(h1('Hello from here', class='text-success'))

}
shinyApp(ui, server)

edit: you can style the "picture frame" by setting a class for the parent DIV of both leaflet map and title. Or by having the user choose one of several CSS classes. Alternatively, you can compose a CSS style string (style="...") from user input (colour, width etc.) and re-renderUI this part. Aside: if UI rendering is expensive, you can alternatively set CSS classes/styles client-side.

enter image description here

Upvotes: 1

Related Questions