diff --git a/README.md b/README.md index ff79893..23a4cbd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # MesseMap -![](https://badgen.net/badge/version/1.0.3/blue) +![](https://badgen.net/badge/version/1.1.0/blue) [![License](https://img.shields.io/github/license/MesseBasseProduction/MesseMap.svg)](https://github.com/MesseBasseProduction/MesseMap/blob/main/LICENSE) [![Doc](https://badgen.net/badge/documentation/written/green)](https://messebasseproduction.github.io/MesseMap/doc/index.html) @@ -10,7 +10,7 @@ It features 7 poster styles so far, that can all be customized (positioning, col Wanna try it ? We are running a [MesseMap instance](https://messemap.org) just for you! -[![Interface Screenshot](/assets/img/demo.png)](https://messemap.org) +[![Interface Screenshot](/assets/img/demo/demo.png)](https://messemap.org) When exporting the map to disk the user can set the output dimension, the lowest resolution being A7 at 300 dpi (600 x 848) and the highest being A2 at 300 dpi (6500 x 9193). The user can also set the output format, between `.png`, `.jpg`, `.webp` and `.pdf` (exports in PDF are done in the CYMK color space so they're ready to print). @@ -42,4 +42,4 @@ Fonts are taken from DaFont, using [Catamaran](https://www.dafont.com/catamaran. --- -[Messe Basse Production](https://github.com/MesseBasseProduction) --- 2022 / 2023 +[Messe Basse Production](https://github.com/MesseBasseProduction) --- 2022 / 2024 diff --git a/assets/html/index.html b/assets/html/index.html index 2f1cdb2..ed934b1 100644 --- a/assets/html/index.html +++ b/assets/html/index.html @@ -65,14 +65,14 @@

{{TITLE}}

{{HELPER}}

-

{{ORIENTATION}}

-
- {{VERTICAL}} - {{HORIZONTAL}} -

{{STYLE}}

- + +
+ {{VERTICAL}} + {{HORIZONTAL}} +
+
{{STYLE_STD}} {{STYLE_TRAVEL}} @@ -88,7 +88,7 @@

{{STYLE}}{{DARK_THEME}}
- theme-editor-option + theme-editor-option
@@ -116,6 +116,29 @@

{{TEXT}}

+

{{ICON}}

+
+
+ + +
+ + +
+ + +
+ +
+ + + + + + + +
+

{{EXPORT}}

@@ -155,7 +178,7 @@

{{EXPORT}} Messe Basse Production - + @@ -167,6 +190,8 @@

+
+
@@ -188,6 +213,9 @@

MesseMap

- + diff --git a/assets/img/demo.png b/assets/img/demo/demo-1.0.0.png similarity index 100% rename from assets/img/demo.png rename to assets/img/demo/demo-1.0.0.png diff --git a/assets/img/demo/demo.png b/assets/img/demo/demo.png new file mode 100644 index 0000000..ea6c929 Binary files /dev/null and b/assets/img/demo/demo.png differ diff --git a/assets/img/icon/building.svg b/assets/img/icon/building.svg new file mode 100644 index 0000000..7bd4d1f --- /dev/null +++ b/assets/img/icon/building.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/img/icon/case.svg b/assets/img/icon/case.svg new file mode 100644 index 0000000..3adcf36 --- /dev/null +++ b/assets/img/icon/case.svg @@ -0,0 +1,3 @@ + diff --git a/assets/img/icon/heart.svg b/assets/img/icon/heart.svg new file mode 100644 index 0000000..8101018 --- /dev/null +++ b/assets/img/icon/heart.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/img/icon/home.svg b/assets/img/icon/home.svg new file mode 100644 index 0000000..0fd12db --- /dev/null +++ b/assets/img/icon/home.svg @@ -0,0 +1,11 @@ + + + 984 + + + + + + + + diff --git a/assets/img/icon/option.svg b/assets/img/icon/option.svg new file mode 100644 index 0000000..14b3612 --- /dev/null +++ b/assets/img/icon/option.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/img/icon/pin.svg b/assets/img/icon/pin.svg new file mode 100644 index 0000000..fb92ba3 --- /dev/null +++ b/assets/img/icon/pin.svg @@ -0,0 +1,11 @@ + + pin_fill_rounded_circle [#629] + Created with Sketch. + + + + + + + + diff --git a/assets/img/icon/star.svg b/assets/img/icon/star.svg new file mode 100644 index 0000000..c36abc5 --- /dev/null +++ b/assets/img/icon/star.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/img/icon/user.svg b/assets/img/icon/user.svg new file mode 100644 index 0000000..8b2b5bb --- /dev/null +++ b/assets/img/icon/user.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/img/option.svg b/assets/img/option.svg deleted file mode 100644 index 6f6615c..0000000 --- a/assets/img/option.svg +++ /dev/null @@ -1,113 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/nls/ch.json b/assets/nls/ch.json index 174d6f6..f2a67cc 100644 --- a/assets/nls/ch.json +++ b/assets/nls/ch.json @@ -3,14 +3,14 @@ "pageTitle": "MesseMap | 为您选一个特别的地方并下载或打印!", "pageDescription": "制作您自己的原创地图海报的完美网站!浏览世界,调整您的设计、文本和颜色,然后以您想要的分辨率和文件类型下载!", "helper": "欢迎使用 MesseMap!

在地图中导航找到您想要显示的位置(可用搜索栏),然后配置地图基础图层及其属性,使其反映您的海报风格。您可以折叠或展开以下选项类别以便更好地导航。最后,单击导出按钮并享受您新鲜制作的海报!", - "orientation": "方向", - "vertical": "垂直的", - "horizontal": "水平的", "action": { "close": "关闭" }, "style": { "title": "风格", + "orientation": "方向", + "vertical": "垂直的", + "horizontal": "水平的", "mapStyle": "地图布局", "darkTheme": "深色主题", "upText": "向上文字", @@ -33,6 +33,13 @@ "mapComment": "评论", "mapCommentPlaceholder": "关于地图的评论" }, + "icon": { + "title": "图标", + "toggle": "显示图标", + "size": "尺寸", + "color": "图标的颜色", + "image": "图标的形状" + }, "export": { "title": "导出设置", "dimension": "方面", diff --git a/assets/nls/de.json b/assets/nls/de.json index ab85525..6ade16f 100644 --- a/assets/nls/de.json +++ b/assets/nls/de.json @@ -3,14 +3,14 @@ "pageTitle": "MesseMap | Gestalten Sie einen besonderen Ort für Sie und laden Sie ihn herunter oder drucken Sie ihn aus!", "pageDescription": "Die perfekte Seite, um ein originelles Kartenplakat zu erstellen! Navigieren Sie zu dem Ort, den Sie hervorheben möchten, passen Sie Design, Texte und Farben an und laden Sie dann Ihr Poster in der gewünschten Auflösung und im gewünschten Format herunter!", "helper": "Willkommen auf MesseMap!

Navigieren Sie in der Karte, um den Ort zu finden, den Sie anzeigen möchten (Suchleiste verfügbar), und konfigurieren Sie dann die Kartenbasisebene und ihre Attribute so, dass sie den Stil widerspiegeln, den Sie für Ihr Poster anstreben. Sie können die folgenden Optionskategorien für eine bessere Navigation reduzieren oder erweitern. Klicken Sie abschließend auf den Export-Button und genießen Sie Ihr frisch erstelltes Poster!", - "orientation": "Ausrichtung", - "vertical": "Hochformat", - "horizontal": "Querformat", "action": { "close": "Schließen" }, "style": { "title": "Stil", + "orientation": "Ausrichtung", + "vertical": "Hochformat", + "horizontal": "Querformat", "mapStyle": "Kartenlayout", "darkTheme": "Dunkles Thema", "upText": "Text oben", @@ -33,6 +33,13 @@ "mapComment": "Kommentar", "mapCommentPlaceholder": "Ein Kommentar über die Karte" }, + "icon": { + "title": "Symbol", + "toggle": "Bildschirmsymbol", + "size": "Größe", + "color": "Farbe des Symbols", + "image": "Form des Symbols" + }, "export": { "title": "Export Eisntellungen", "dimension": "Größe", diff --git a/assets/nls/en.json b/assets/nls/en.json index 519de84..6fe15da 100644 --- a/assets/nls/en.json +++ b/assets/nls/en.json @@ -3,14 +3,14 @@ "pageTitle": "MesseMap | Frame a special place for you and download it, or make a print of it !", "pageDescription": "The perfect website to craft an original map poster of your own! Browse the world, adjust your design, texts and colors, then download it at the resolution and filetype you want!", "helper": "Welcome on MesseMap!

Navigate in the map to find the place you want to display (search bar available), then configure the map base layer and its attributes so it reflect the style you aim for your poster. You can collapse or expand the following options categories for better navigation. Finally, click on the export button and enjoy your freshly made poster!", - "orientation": "Orientation", - "vertical": "Vertical", - "horizontal": "Horizontal", "action": { "close": "Close" }, "style": { "title": "Style", + "orientation": "Orientation", + "vertical": "Vertical", + "horizontal": "Horizontal", "mapStyle": "Map layout", "darkTheme": "Dark theme", "upText": "Up text", @@ -33,6 +33,13 @@ "mapComment": "Comment", "mapCommentPlaceholder": "A comment about the map" }, + "icon": { + "title": "Icon", + "toggle": "Display icon", + "size": "Size", + "color": "Icon's color", + "image": "Icon's shape" + }, "export": { "title": "Export settings", "dimension": "Dimension", diff --git a/assets/nls/es.json b/assets/nls/es.json index 0b4c003..c5ed0bd 100644 --- a/assets/nls/es.json +++ b/assets/nls/es.json @@ -3,14 +3,14 @@ "pageTitle": "MesseMap | ¡Enmarca un lugar especial para ti y descárgalo, o imprímelo!", "pageDescription": "¡El sitio perfecto para hacer un cartel de tarjeta original! Navegue hasta el lugar que desea resaltar, ajuste su diseño, textos y colores, luego descargue su póster en la resolución y el formato que desee.", "helper": "¡Bienvenido a MesseMap!

Navegue en el mapa para encontrar el lugar que desea mostrar (barra de búsqueda disponible), luego configure la capa base del mapa y sus atributos para que refleje el estilo que desea para su póster. Puede colapsar o expandir las siguientes categorías de opciones para una mejor navegación. Finalmente, haga clic en el botón exportar y disfrute de su póster recién hecho.", - "orientation": "Orientación", - "vertical": "Vertical", - "horizontal": "Horizontal", "action": { "close": "Cerca" }, "style": { "title": "Estilo", + "orientation": "Orientación", + "vertical": "Vertical", + "horizontal": "Horizontal", "mapStyle": "Diseño del mapa", "darkTheme": "Tema oscuro", "upText": "Poner texto encima", @@ -33,6 +33,13 @@ "mapComment": "Comentario", "mapCommentPlaceholder": "Comentar sobre el mapa" }, + "icon": { + "title": "Icono", + "toggle": "Icono de pantalla", + "size": "Tamaño", + "color": "Color del icono", + "image": "La forma del icono" + }, "export": { "title": "Parámetro de exportación", "dimension": "Dimensiones", diff --git a/assets/nls/fr.json b/assets/nls/fr.json index 1d11b85..c1e1ce6 100644 --- a/assets/nls/fr.json +++ b/assets/nls/fr.json @@ -3,14 +3,14 @@ "pageTitle": "MesseMap | Encadrez un endroit qui vous est cher et téléchargez le prêt à tirer !", "pageDescription": "Le site parfait pour réaliser un poster original de carte! Naviguez jusqu'à l'endroit que vous voulez mettre en avant, ajustez votre design, les textes et les couleurs, puis téléchargez votre poster à la résolution et au format que vous souhaitez!", "helper": "Bienvenu sur MesseMap!

Explorez la carte pour trouver votre endroit à cadrer (une barre de recherche est à votre disposition), puis configurez le fond de carte et ses attributs pour qu'il reflète au mieux le style que vous cherchez à appliquer. Vous pouvez étendre ou réduire les catégories suivantes pour facilité la navigation. Finallement, clickez sur exporter pour télécharger votre poster, prêt à l'impression!", - "orientation": "Orientation", - "vertical": "Vertical", - "horizontal": "Horizontal", "action": { "close": "Fermer" }, "style": { "title": "Style", + "orientation": "Orientation", + "vertical": "Vertical", + "horizontal": "Horizontal", "mapStyle": "Format des éléments", "darkTheme": "Thème sombre", "upText": "Texte en haut", @@ -33,6 +33,13 @@ "mapComment": "Commentaire", "mapCommentPlaceholder": "Commentaire à propos de la carte" }, + "icon": { + "title": "Icone", + "toggle": "Afficher une icone", + "size": "Taille", + "color": "Couleur de l'icone", + "image": "Forme de l'icone" + }, "export": { "title": "Paramètre d'export", "dimension": "Dimension", diff --git a/assets/nls/it.json b/assets/nls/it.json index 4a90bf6..1289668 100644 --- a/assets/nls/it.json +++ b/assets/nls/it.json @@ -3,14 +3,14 @@ "pageTitle": "MesseMap | Inquadra un luogo speciale per te e scaricalo, oppure stampalo!", "pageDescription": "Il sito perfetto per realizzare un poster di carta originale! Naviga fino al luogo che desideri evidenziare, modifica il design, i testi e i colori, quindi scarica il tuo poster nella risoluzione e nel formato che desideri!", "helper": "Benvenuto su MesseMap!

Naviga nella mappa per trovare il luogo che desideri visualizzare (barra di ricerca disponibile), quindi configura il livello di base della mappa e i suoi attributi in modo che riflettano lo stile che desideri per il tuo poster. Puoi comprimere o espandere le seguenti categorie di opzioni per una migliore navigazione. Infine, fai clic sul pulsante Esporta e goditi il tuo poster appena creato!", - "orientation": "Orientamento", - "vertical": "Verticale", - "horizontal": "Orizzontale", "action": { "close": "Vicino" }, "style": { "title": "Stile", + "orientation": "Orientamento", + "vertical": "Verticale", + "horizontal": "Orizzontale", "mapStyle": "Disposizione della mappa", "darkTheme": "Tema scuro", "upText": "Testo in alto", @@ -33,6 +33,13 @@ "mapComment": "Commento", "mapCommentPlaceholder": "Un commento sulla mappa" }, + "icon": { + "title": "Icona", + "toggle": "Visualizza l'icona", + "size": "Misurare", + "color": "Colore dell'icona", + "image": "La forma dell'icona" + }, "export": { "title": "Impostazioni di esportazione", "dimension": "Dimensione", diff --git a/assets/nls/ja.json b/assets/nls/ja.json index 9ccc1a6..d2a0b23 100644 --- a/assets/nls/ja.json +++ b/assets/nls/ja.json @@ -3,14 +3,14 @@ "pageTitle": "MesseMap | あなたのための特別な場所をフレームに入れてダウンロードするか、印刷してください。", "pageDescription": "自分だけのオリジナル地図ポスターを作るのに最適なサイトです。世界を閲覧し、デザイン、テキスト、色を調整して、希望の解像度とファイルタイプでダウンロードしてください。", "helper": "MesseMap へようこそ!

マップ内を移動して表示したい場所を見つけて (検索バーが利用可能)、ポスターの目的のスタイルを反映するようにマップのベース レイヤーとその属性を構成します。ナビゲーションを改善するために、次のオプション カテゴリを折りたたんだり展開したりできます。最後に、エクスポート ボタンをクリックして、作成したばかりのポスターをお楽しみください。", - "orientation": "オリエンテーション", - "vertical": "垂直", - "horizontal": "水平", "action": { "close": "近い" }, "style": { "title": "スタイル", + "orientation": "オリエンテーション", + "vertical": "垂直", + "horizontal": "水平", "mapStyle": "マップレイアウト", "darkTheme": "暗いテーマ", "upText": "上のテキスト", @@ -33,6 +33,13 @@ "mapComment": "コメント", "mapCommentPlaceholder": "地図についてのコメント" }, + "icon": { + "title": "アイコン", + "toggle": "表示アイコン", + "size": "サイズ", + "color": "アイコンの色", + "image": "アイコンの形状" + }, "export": { "title": "設定のエクスポート", "dimension": "寸法", diff --git a/assets/nls/pl.json b/assets/nls/pl.json index 7f15af0..bd36dc6 100644 --- a/assets/nls/pl.json +++ b/assets/nls/pl.json @@ -3,14 +3,14 @@ "pageTitle": "MesseMap | Wykadruj bliskie Ci miejsce i pobierz gotowe do zdjęcia!", "pageDescription": "Idealne miejsce do stworzenia oryginalnego plakatu z mapą! Przejdź do miejsca, które chcesz wyróżnić, dostosuj projekt, teksty i kolory, a następnie pobierz plakat w wybranej rozdzielczości i formacie!", "helper": "Witamy w MesseMap!

Przejrzyj mapę, aby znaleźć miejsce do wykadrowania (pasek wyszukiwania jest do Twojej dyspozycji), a następnie skonfiguruj mapę bazową i jej atrybuty, aby jak najlepiej odzwierciedlały styl, który chcesz zastosować. Możesz rozwinąć lub zwinąć następujące kategorie, aby ułatwić nawigację. Na koniec kliknij eksport, aby pobrać plakat gotowy do druku!", - "orientation": "Orientacja", - "vertical": "Pionowy", - "horizontal": "Poziomy", "action": { "close": "Zamknąć" }, "style": { "title": "Styl", + "orientation": "Orientacja", + "vertical": "Pionowy", + "horizontal": "Poziomy", "mapStyle": "Format elementów", "darkTheme": "Ciemny schemat", "upText": "Tekst na górze", @@ -33,6 +33,13 @@ "mapComment": "Komentarz", "mapCommentPlaceholder": "Komentarz do mapy" }, + "icon": { + "title": "Ikona", + "toggle": "Wyświetl ikonę", + "size": "Rozmiar", + "color": "Kolor ikony", + "image": "Kształt ikony" + }, "export": { "title": "Eksportuj parametr", "dimension": "Wymiar", diff --git a/assets/nls/pt.json b/assets/nls/pt.json index 6c099a4..3a4142d 100644 --- a/assets/nls/pt.json +++ b/assets/nls/pt.json @@ -3,14 +3,14 @@ "pageTitle": "MesseMap | Enquadre um local especial para você e faça o download ou imprima!", "pageDescription": "O site perfeito para fazer um pôster de cartão original! Navegue até o local que deseja destacar, ajuste seu design, textos e cores e baixe seu pôster na resolução e formato que desejar!", "helper": "Bem-vindo ao MesseMap!

Navegue no mapa para encontrar o local que deseja exibir (barra de pesquisa disponível) e configure a camada base do mapa e seus atributos para que reflitam o estilo que você deseja para o seu pôster. Você pode recolher ou expandir as seguintes categorias de opções para uma melhor navegação. Por fim, clique no botão de exportação e aproveite seu pôster recém-criado!", - "orientation": "Orientação", - "vertical": "Vertical", - "horizontal": "Horizontal", "action": { "close": "Fechar" }, "style": { "title": "Estilo", + "orientation": "Orientação", + "vertical": "Vertical", + "horizontal": "Horizontal", "mapStyle": "Layout do mapa", "darkTheme": "Tema escuro", "upText": "Texto para cima", @@ -33,6 +33,13 @@ "mapComment": "Comentário", "mapCommentPlaceholder": "Um comentário sobre o mapa" }, + "icon": { + "title": "Ícone", + "toggle": "Ícone de exibição", + "size": "Tamanho", + "color": "Cor do ícone", + "image": "Forma do ícone" + }, "export": { "title": "Exportar configurações", "dimension": "Dimensão", diff --git a/assets/nls/ru.json b/assets/nls/ru.json index 6c0aa79..8e25557 100644 --- a/assets/nls/ru.json +++ b/assets/nls/ru.json @@ -3,14 +3,14 @@ "pageTitle": "MesseMap | Выделите для себя особое место и скачайте его или распечатайте!", "pageDescription": "Идеальный веб-сайт для создания собственного оригинального плаката с картой! Просмотрите мир, настройте свой дизайн, тексты и цвета, а затем загрузите его в нужном разрешении и типе файла!", "helper": "Добро пожаловать на MesseMap!

Перейдите по карте, чтобы найти место, которое вы хотите отобразить (доступна панель поиска), затем настройте базовый слой карты и его атрибуты, чтобы они отражали стиль, который вы хотите использовать для своего плаката. Вы можете свернуть или развернуть следующие категории параметров для лучшей навигации. Наконец, нажмите кнопку экспорта и наслаждайтесь свежеиспеченным плакатом!", - "orientation": "Ориентация", - "vertical": "Вертикальный", - "horizontal": "Горизонтальный", "action": { "close": "Закрывать" }, "style": { "title": "Стиль", + "orientation": "Ориентация", + "vertical": "Вертикальный", + "horizontal": "Горизонтальный", "mapStyle": "Макет карты", "darkTheme": "Темная тема", "upText": "Текст вверху", @@ -33,6 +33,13 @@ "mapComment": "Комментарий", "mapCommentPlaceholder": "Комментарий к карте" }, + "icon": { + "title": "Икона", + "toggle": "Значок иконки", + "size": "Размер", + "color": "Цвет иконки", + "image": "Форма иконки" + }, "export": { "title": "Экспорт настроек", "dimension": "Измерение", diff --git a/doc/MesseMap.html b/doc/MesseMap.html index 3f91178..8564f5d 100644 --- a/doc/MesseMap.html +++ b/doc/MesseMap.html @@ -820,7 +820,7 @@

Methods

-

(private, static) _applyTexts()

+

(private, static) _applyTexts(e)

@@ -841,6 +841,55 @@

(private, static +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
e + + +Event + + + +

The text input

+ + @@ -884,7 +933,7 @@

(private, static
Source:
@@ -1057,7 +1106,7 @@
Parameters:
Source:
@@ -1206,7 +1255,7 @@
Parameters:
Source:
@@ -1379,7 +1428,7 @@
Parameters:
Source:
@@ -1530,7 +1579,7 @@
Parameters:
Source:
@@ -1729,7 +1778,7 @@
Parameters:
Source:
@@ -1879,7 +1928,7 @@
Parameters:
Source:
@@ -1983,7 +2032,7 @@

(private, static)
Source:
@@ -2084,7 +2133,7 @@

(private, static
Source:
@@ -2234,7 +2283,7 @@
Parameters:
Source:
@@ -2286,6 +2335,106 @@
Returns:
+ + + + + + +

(private, static) _handleIconDrag()

+ + + + + + +
+
+Handle the icon dragging in the map output +
+
+ + + + + + + + + + + + + +
+ + + + +
Since:
+
  • January 2024
+ + + + + + + + + + + + + + + +
Author:
+
+
    +
  • Arthur Beaulieu
  • +
+
+ + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + @@ -2357,7 +2506,7 @@

(priva
Source:
@@ -2481,7 +2630,7 @@

(private, static
Source:
@@ -2603,7 +2752,7 @@

(private, sta
Source:
@@ -2729,7 +2878,727 @@

(private, static) <
Source:
+ + + + + + + + + + + + + + + + + + + + + + + +
Returns:
+ + +
+

A resolved or rejected Promise

+
+ + + +
+
+ Type +
+
+ +Promise + + +
+
+ + + + + + + + + + + + + +

(private, static) _prepareIconForPrinting(scale)

+ + + + + + +
+
+Apply svg image with color to properly render icon ou output map +
+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
scale + + +Number + + + +

The output map scale

+ + + + + + +
+ + + + +
Since:
+
  • January 2024
+ + + + + + + + + + + + + + + +
Author:
+
+
    +
  • Arthur Beaulieu
  • +
+
+ + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(private, static) _searchMatch(data)

+ + + + + + +
+
+Set map view depending on search result +
+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
data + + +Object + + + +

The search data result to set view from

+ + + + + + +
+ + + + +
Since:
+
  • November 2022
+ + + + + + + + + + + + + + + +
Author:
+
+
    +
  • Arthur Beaulieu
  • +
+
+ + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(private, static) _sendImageParameters()

+ + + + + + +
+
+Perform a POST call to the server to save map parameters as JSON +
+
+ + + + + + + + + + + + + +
+ + + + +
Since:
+
  • April 2023
+ + + + + + + + + + + + + + + +
Author:
+
+
    +
  • Arthur Beaulieu
  • +
+
+ + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(private, static) _setPosterConfigurationFromData(data)

+ + + + + + +
+
+From a JSON input, apply any transformation to the map or the poster, updates +colors, texts, map style, map orientation, dark theme, text position and position +map at lat/lng and zoom level described in saved file. +
+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
data + + +Object + + + +

A JSON map object, described in /saved/README.md

+ + + + + + +
+ + + + +
Since:
+
  • November 2023
+ + + + + + + + + + + + + + + +
Author:
+
+
    +
  • Arthur Beaulieu
  • +
+
+ + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(private, static) _textColorEdit(e)

+ + + + + + +
+
+Modify the text on map color. Overrides the default theme color +
+
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
e + + +Event + + + +

The input color change

+ + + + + + +
+ + + + +
Since:
+
  • October 2022
+ + + + + + + + + + + + + + + +
Author:
+
+
    +
  • Arthur Beaulieu
  • +
+
+ + + + + + + + + +
Source:
+
@@ -2754,28 +3623,6 @@

(private, static) < -
Returns:
- - -
-

A resolved or rejected Promise

-
- - - -
-
- Type -
-
- -Promise - - -
-
- - @@ -2787,7 +3634,7 @@
Returns:
-

(private, static) _searchMatch(data)

+

(private, static) _themeEditModal(e)

@@ -2796,7 +3643,7 @@

(private, stati
-Set map view depending on search result +This method will build th theme edit modal into the user interface.
@@ -2833,13 +3680,13 @@
Parameters:
- data + e -Object +Event @@ -2849,7 +3696,7 @@
Parameters:
-

The search data result to set view from

+

The click event that triggered the modal

@@ -2867,7 +3714,7 @@
Parameters:
Since:
-
  • November 2022
+
  • October 2022
@@ -2900,7 +3747,7 @@
Parameters:
Source:
@@ -2936,7 +3783,7 @@
Parameters:
-

(private, static) _sendImageParameters()

+

(private, static) _toggleCategory(e)

@@ -2945,7 +3792,7 @@

(privat
-Perform a POST call to the server to save map parameters as JSON +Expand or colapse a given map modifiers category
@@ -2957,6 +3804,55 @@

(privat +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
e + + +Event + + + +

The click event on the category expander/collapser

+ + @@ -3000,7 +3896,7 @@

(privat
Source:
@@ -3036,7 +3932,7 @@

(privat -

(private, static) _setPosterConfigurationFromData(data)

+

(private, static) _toggleIcon(e)

@@ -3045,9 +3941,7 @@

-From a JSON input, apply any transformation to the map or the poster, updates -colors, texts, map style, map orientation, dark theme, text position and position -map at lat/lng and zoom level described in saved file. +Display or hide the icon on the output map
@@ -3084,13 +3978,13 @@
Parameters:
- data + e -Object +Event @@ -3100,7 +3994,7 @@
Parameters:
-

A JSON map object, described in /saved/README.md

+

The check input

@@ -3118,7 +4012,7 @@
Parameters:
Since:
-
  • November 2023
+
  • January 2024
@@ -3151,7 +4045,7 @@
Parameters:
Source:
@@ -3187,7 +4081,7 @@
Parameters:
-

(private, static) _textColorEdit(e)

+

(private, static) _updateCommentLabel()

@@ -3196,7 +4090,7 @@

(private, sta
-Modify the text on map color. Overrides the default theme color +Update the comment with map center coordinates, only if user didn't set a text in comment
@@ -3208,55 +4102,6 @@

(private, sta -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
e - - -Event - - - -

The input color change

- - @@ -3300,7 +4145,7 @@
Parameters:
Source:
@@ -3336,7 +4181,7 @@
Parameters:
-

(private, static) _themeEditModal(e)

+

(private, static) _updateDarkTheme(e)

@@ -3345,7 +4190,8 @@

(private, st
-This method will build th theme edit modal into the user interface. +Will update the poster with dark or light css theme colors. If colors have been overiden +by user, they will properly applied to the poster.
@@ -3398,7 +4244,7 @@
Parameters:
-

The click event that triggered the modal

+

The change event on the theme checkbox

@@ -3449,7 +4295,7 @@
Parameters:
Source:
@@ -3485,7 +4331,7 @@
Parameters:
-

(private, static) _toggleCategory(e)

+

(private, static) _updateDimensionClicked(e)

@@ -3494,7 +4340,7 @@

(private, st
-Expand or colapse a given map modifiers category +Update the export resolution slider label and buttons according to a click on a button
@@ -3547,7 +4393,7 @@
Parameters:
-

The click event on the category expander/collapser

+

The input event on the size span

@@ -3598,7 +4444,7 @@
Parameters:
Source:
@@ -3634,7 +4480,7 @@
Parameters:
-

(private, static) _updateCommentLabel()

+

(private, static) _updateDimensionLabel(e)

@@ -3643,7 +4489,8 @@

(private
-Update the comment with map center coordinates, only if user didn't set a text in comment +Update the export resolution slider label to notify the user the size of the generated +poster, at 300 DPI.
@@ -3655,6 +4502,55 @@

(private +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
e + + +Event + + + +

The input event on the resolution slider

+ + @@ -3698,7 +4594,7 @@

(private
Source:
@@ -3734,7 +4630,7 @@

(private -

(private, static) _updateDarkTheme(e)

+

(private, static) _updateIconColor(e)

@@ -3743,8 +4639,7 @@

(private, s
-Will update the poster with dark or light css theme colors. If colors have been overiden -by user, they will properly applied to the poster. +Update the icon color
@@ -3797,7 +4692,7 @@
Parameters:
-

The change event on the theme checkbox

+

The color input

@@ -3815,7 +4710,7 @@
Parameters:
Since:
-
  • October 2022
+
  • January 2024
@@ -3848,7 +4743,7 @@
Parameters:
Source:
@@ -3884,7 +4779,7 @@
Parameters:
-

(private, static) _updateDimensionClicked(e)

+

(private, static) _updateIconImage(e)

@@ -3893,7 +4788,7 @@

(pri
-Update the export resolution slider label and buttons according to a click on a button +Update the icon source image
@@ -3946,7 +4841,7 @@
Parameters:
-

The input event on the size span

+

The clicked image

@@ -3964,7 +4859,7 @@
Parameters:
Since:
-
  • April 2023
+
  • January 2024
@@ -3997,7 +4892,7 @@
Parameters:
Source:
@@ -4033,7 +4928,7 @@
Parameters:
-

(private, static) _updateDimensionLabel(e)

+

(private, static) _updateIconSize(e)

@@ -4042,8 +4937,7 @@

(priva
-Update the export resolution slider label to notify the user the size of the generated -poster, at 300 DPI. +Update the icon size in output map
@@ -4096,7 +4990,7 @@
Parameters:
-

The input event on the resolution slider

+

The range input

@@ -4114,7 +5008,7 @@
Parameters:
Since:
-
  • October 2022
+
  • January 2024
@@ -4147,7 +5041,7 @@
Parameters:
Source:
@@ -4296,7 +5190,7 @@
Parameters:
Source:
@@ -4445,7 +5339,7 @@
Parameters:
Source:
@@ -4595,7 +5489,7 @@
Parameters:
Source:
@@ -4744,7 +5638,7 @@
Parameters:
Source:
@@ -4844,7 +5738,7 @@

(static) Source:
@@ -4944,7 +5838,7 @@

(static) Source:
@@ -5068,7 +5962,7 @@

(stati
Source:
@@ -5193,7 +6087,7 @@

(static) <
Source:
@@ -5387,7 +6281,7 @@
Parameters:
Source:
@@ -5606,7 +6500,7 @@
Parameters:
Source:
@@ -5706,7 +6600,7 @@

(static) Source:
@@ -5830,7 +6724,7 @@

(st
Source:
@@ -5882,7 +6776,7 @@

Home

Classes

  • diff --git a/doc/MesseMap.js.html b/doc/MesseMap.js.html index 82b3e97..65b0b07 100644 --- a/doc/MesseMap.js.html +++ b/doc/MesseMap.js.html @@ -88,7 +88,7 @@

    Source: MesseMap.js

    * @type {Boolean} * @private **/ - this._commentEdited = false; + this._commentEdited = false; /** * setInterval ID used to frequently ask for printing (only if tiles are loaded) * @type {Number} @@ -106,7 +106,7 @@

    Source: MesseMap.js

    lcom: '#999998', dbg: '#000001', dtxt: '#FFFFFE', - dcom: '#999998' + dcom: '#999998' }; /** * The currently applied language @@ -132,7 +132,15 @@

    Source: MesseMap.js

    style: 'standard', darkTheme: false, upText: false, - layer: 'Imagery (E)' + layer: 'Imagery (E)', + hasIcon: false, + icon: { + color: '#FFFFFF', + image: '/assets/img/icon/home.svg', + size: 2, // Size in rem + x: 48.33, // Size in % + y: 48.33 // Size in % + } }; // Begin the initialization sequence (interface and events) @@ -183,11 +191,12 @@

    Source: MesseMap.js

    // Update page content with translations this.replaceString(document.body, '{{TITLE}}', this._nls.title); this.replaceString(document.body, '{{HELPER}}', this._nls.helper); - this.replaceString(document.body, '{{ORIENTATION}}', this._nls.orientation); - this.replaceString(document.body, '{{VERTICAL}}', this._nls.vertical); - this.replaceString(document.body, '{{HORIZONTAL}}', this._nls.horizontal); this.replaceString(document.body, '{{STYLE}}', this._nls.style.title); + this.replaceString(document.body, '{{MAP_ORIENTATION}}', this._nls.style.orientation); + this.replaceString(document.body, '{{VERTICAL}}', this._nls.style.vertical); + this.replaceString(document.body, '{{HORIZONTAL}}', this._nls.style.horizontal); + this.replaceString(document.body, '{{MAP_STYLE}}', this._nls.style.mapStyle); this.replaceString(document.body, '{{STYLE_STD}}', this._nls.style.std); this.replaceString(document.body, '{{STYLE_TRAVEL}}', this._nls.style.travel); @@ -208,6 +217,13 @@

    Source: MesseMap.js

    this.replaceString(document.body, '{{MAP_SUBTITLE_PLACEHOLDER}}', this._nls.text.mapSubtitlePlaceholder); this.replaceString(document.body, '{{MAP_COMMENT}}', this._nls.text.mapComment); this.replaceString(document.body, '{{MAP_COMMENT_PLACEHOLDER}}', this._nls.text.mapCommentPlaceholder); + + this.replaceString(document.body, '{{ICON}}', this._nls.icon.title); + this.replaceString(document.body, '{{TOGGLE_ICON}}', this._nls.icon.toggle); + this.replaceString(document.body, '{{ICON_SIZE}}', this._nls.icon.size); + this.replaceString(document.body, '{{ICON_COLOR}}', this._nls.icon.color); + this.replaceString(document.body, '{{ICON_IMAGE}}', this._nls.icon.image); + this.replaceString(document.body, '{{EXPORT}}', this._nls.export.title); this.replaceString(document.body, '{{EXPORT_DIMENSION}}', this._nls.export.dimension); this.replaceString(document.body, '{{EXPORT_AT}}', this._nls.export.at); @@ -256,7 +272,7 @@

    Source: MesseMap.js

    url: 'https://nominatim.openstreetmap.org/search?format=json&q={s}', jsonpParam: 'json_callback', propertyName: 'display_name', - propertyLoc: ['lat','lon'], + propertyLoc: ['lat', 'lon'], marker: false, autoCollapse: true, firstTipSubmit: true, @@ -324,14 +340,12 @@

    Source: MesseMap.js

    _initEvents() { if (CONST.DEBUG) { console.log('MesseMap._initEvents() called'); } return new Promise(resolve => { - // Orientation - document.getElementById('toggle-orientation').addEventListener('click', this._toggleCategory.bind(this)); + // Style + document.getElementById('toggle-style').addEventListener('click', this._toggleCategory.bind(this)); const orientations = document.getElementById('toggle-orientation-container'); for (let i = 0; i < orientations.children.length; ++i) { orientations.children[i].addEventListener('click', this._updateMapOrientation.bind(this)); } - // Style - document.getElementById('toggle-style').addEventListener('click', this._toggleCategory.bind(this)); const styles = document.getElementById('map-style'); for (let i = 0; i < styles.children.length; ++i) { styles.children[i].addEventListener('click', this._updateMapStyle.bind(this)); @@ -347,6 +361,16 @@

    Source: MesseMap.js

    document.getElementById('user-title').addEventListener('input', this._applyTexts.bind(this)); document.getElementById('user-subtitle').addEventListener('input', this._applyTexts.bind(this)); document.getElementById('user-comment').addEventListener('input', this._applyTexts.bind(this)); + // Icon + document.getElementById('toggle-icon').addEventListener('click', this._toggleCategory.bind(this)); + document.getElementById('activate-icon').addEventListener('change', this._toggleIcon.bind(this)); + document.getElementById('icon-size').addEventListener('input', this._updateIconSize.bind(this)); + this._handleIconDrag(); + document.getElementById('icon-color').addEventListener('input', this._updateIconColor.bind(this)); + const icons = document.getElementById('icon-images'); + for (let i = 0; i < icons.children.length; ++i) { + icons.children[i].addEventListener('click', this._updateIconImage.bind(this)); + } // Export settings document.getElementById('toggle-export').addEventListener('click', this._toggleCategory.bind(this)); document.getElementById('image-width').addEventListener('input', this._updateDimensionLabel.bind(this)); @@ -391,7 +415,7 @@

    Source: MesseMap.js

    * @returns {Promise} A resolved Promise **/ _initAdvancedFeatures() { - if (CONST.DEBUG) { console.log('MesseMap._initAdvancedFeatures called'); } + if (CONST.DEBUG) { console.log('MesseMap._initAdvancedFeatures called'); } return new Promise(resolve => { if (window.location.href.indexOf('?callmeroot') > -1) { const reader = new FileReader(); @@ -431,7 +455,7 @@

    Source: MesseMap.js

    * </blockquote> **/ _endStartup() { - if (CONST.DEBUG) { console.log('MesseMap._endStartup called'); } + if (CONST.DEBUG) { console.log('MesseMap._endStartup called'); } return new Promise(resolve => { this.unblockInterface().then(resolve); }); @@ -496,11 +520,33 @@

    Source: MesseMap.js

    break; } } + + if (data.icon && data.icon.displayed === true) { + document.getElementById('activate-icon').click(); + document.getElementById('icon-size').value = data.icon.size; + this._updateIconSize({ + target: document.getElementById('icon-size') + }); + const icons = document.getElementById('icon-images'); + for (let i = 0; i < icons.children.length; ++i) { + if (icons.children[i].dataset.url === data.icon.image) { + icons.children[i].click(); + break; + } + } + document.getElementById('icon-color').value = data.icon.color; + this._updateIconColor({ + target: document.getElementById('icon-color') + }); + document.getElementById('map-icon').style.left = `${data.icon.x}%`; + document.getElementById('map-icon').style.top = `${data.icon.y}%`; + } + // Update map position this._map.setView(new window.L.LatLng(data.map.center.lat, data.map.center.lng), data.map.zoom); // Switch map base layer this._map.removeLayer(MapProviders.layers[this._data.layer]); - this._map.addLayer(MapProviders.layers[data.map.layer]); + this._map.addLayer(MapProviders.layers[data.map.layer]); } @@ -674,6 +720,7 @@

    Source: MesseMap.js

    * <blockquote> * Simply apply the input text to the poster (for title, subtitle and comment) * </blockquote> + * @param {Event} e - The text input **/ _applyTexts(e) { if (CONST.DEBUG) { console.log('MesseMap._applyTexts() called with ', e); } @@ -726,6 +773,236 @@

    Source: MesseMap.js

    } + /** + * @method + * @name _toggleIcon + * @private + * @memberof MesseMap + * @author Arthur Beaulieu + * @since January 2024 + * @description + * <blockquote> + * Display or hide the icon on the output map + * </blockquote> + * @param {Event} e - The check input + **/ + _toggleIcon(e) { + if (CONST.DEBUG) { console.log('MesseMap._toggleIcon() called with ', e); } + const icon = document.getElementById('map-icon'); + if (e.target.checked) { + // Init icon position + icon.style.left = `${this._data.icon.x}%`; + icon.style.top = `${this._data.icon.y}%`; + icon.classList.add('visible'); + icon.style.backgroundColor = this._data.icon.color; + icon.style.mask = `url(${this._data.icon.image}) no-repeat center / contain`; + this._data.hasIcon = true; + } else { + icon.classList.remove('visible'); + this._data.hasIcon = false; + } + } + + + /** + * @method + * @name _updateIconSize + * @private + * @memberof MesseMap + * @author Arthur Beaulieu + * @since January 2024 + * @description + * <blockquote> + * Update the icon size in output map + * </blockquote> + * @param {Event} e - The range input + **/ + _updateIconSize(e) { + if (CONST.DEBUG) { console.log('MesseMap._updateIconSize() called with ', e); } + document.getElementById('map-icon').style.height = `${e.target.value}rem`; + document.getElementById('map-icon').style.width = `${e.target.value}rem`; + const label = e.target.previousElementSibling; + this._data.icon.size = parseInt(e.target.value); + // Update position with new size + e.target.dataset.size = e.target.value; + label.innerHTML = `${this._nls.icon.size} : ${e.target.value}`; + } + + + /** + * @method + * @name _handleIconDrag + * @private + * @memberof MesseMap + * @author Arthur Beaulieu + * @since January 2024 + * @description + * <blockquote> + * Handle the icon dragging in the map output + * </blockquote> + **/ + _handleIconDrag() { + if (CONST.DEBUG) { console.log('MesseMap._handleIconDrag() called'); } + let dragging = false; + const map = document.getElementById('map-output'); + const mapRect = map.getBoundingClientRect(); + const element = document.getElementById('map-icon'); + let rect = element.getBoundingClientRect(); + // Map paddings + let paddingLeft = parseInt(window.getComputedStyle(map).getPropertyValue('padding-left').slice(0, -2)); + let paddingTop = parseInt(window.getComputedStyle(map).getPropertyValue('padding-top').slice(0, -2)); + // User pointer position + let clickX = 0; + let clickY = 0; + // Variation between place clicked and icon X,Y absolute origin + let dX = 0; + let dY = 0; + // Current position + let positionX = 0; + let positionY = 0; + + const mouseDown = e => { + e.preventDefault(); + dragging = true; + // Update icon bounding rect in case its sized was updated + rect = element.getBoundingClientRect(); + // Update map paddings if style has been updated + paddingLeft = parseInt(window.getComputedStyle(map).getPropertyValue('padding-left').slice(0, -2)); + paddingTop = parseInt(window.getComputedStyle(map).getPropertyValue('padding-top').slice(0, -2)); + // Store initial position + positionX = e.clientX; + positionY = e.clientY; + // Get dif between click and icon x pos + dX = e.clientX - rect.x; + dY = e.clientY - rect.y; + }; + + const mouseMove = e => { + const xAxis = (e.pageX > (mapRect.x + paddingLeft - dX) && e.pageX < (mapRect.x + mapRect.width - paddingLeft + dX)); + const yAxis = (e.pageY > (mapRect.y + paddingTop - dY) && e.pageY < (mapRect.y + mapRect.height - paddingTop + dY)); + if (dragging && xAxis && yAxis) { + e.preventDefault(); + // Update pointer position with differential + clickX = positionX - e.clientX; + clickY = positionY - e.clientY; + // Store current pointer position + positionX = e.clientX; + positionY = e.clientY; + // Determine icon new top and left position + const newTop = element.offsetTop - clickY; + const newLeft = element.offsetLeft - clickX; + // Only update Y if in bounds + if (newTop > paddingTop && newTop + rect.width < mapRect.height - paddingTop) { + element.style.top = `${newTop}px`; + element.dataset.top = `${newTop}px`; + this._data.icon.y = newTop * 100 / mapRect.height; + } + // Only update X if in bounds + if (newLeft > paddingLeft && newLeft + rect.width < mapRect.width - paddingLeft) { + element.style.left = `${newLeft}px`; + element.dataset.left = `${newLeft}px`; + this._data.icon.x = newLeft * 100 / mapRect.width; + } + } + }; + + const mouseUp = () => { + dragging = false; + }; + + element.addEventListener('mousedown', mouseDown); + map.addEventListener('mousemove', mouseMove); + window.addEventListener('mouseup', mouseUp); + } + + + /** + * @method + * @name _updateIconImage + * @private + * @memberof MesseMap + * @author Arthur Beaulieu + * @since January 2024 + * @description + * <blockquote> + * Update the icon source image + * </blockquote> + * @param {Event} e - The clicked image + **/ + _updateIconImage(e) { + if (CONST.DEBUG) { console.log('MesseMap._updateIconImage() called with ', e); } + const icons = document.getElementById('icon-images'); + for (let i = 0; i < icons.children.length; ++i) { + if (icons.children[i].classList.contains('selected')) { + icons.children[i].classList.remove('selected'); + break; + } + } + // Update icon src and store it + e.target.classList.add('selected'); + this._data.icon.image = e.target.dataset.url; // Update internal data + document.getElementById('map-icon').style.mask = `url(${e.target.dataset.url}) no-repeat center / contain`; + } + + + /** + * @method + * @name _updateIconColor + * @private + * @memberof MesseMap + * @author Arthur Beaulieu + * @since January 2024 + * @description + * <blockquote> + * Update the icon color + * </blockquote> + * @param {Event} e - The color input + **/ + _updateIconColor(e) { + document.getElementById('map-icon').style.backgroundColor = e.target.value; + document.getElementById('map-icon').style.mask = `url(${this._data.icon.image}) no-repeat center / contain`; + this._data.icon.color = e.target.value; + document.documentElement.style.setProperty('--fillColor', this._data.icon.color); + } + + + /** + * @method + * @name _prepareIconForPrinting + * @private + * @memberof MesseMap + * @author Arthur Beaulieu + * @since January 2024 + * @description + * <blockquote> + * Apply svg image with color to properly render icon ou output map + * </blockquote> + * @param {Number} scale - The output map scale + **/ + _prepareIconForPrinting(scale) { + return new Promise(resolve => { + fetch(this._data.icon.image) + .then(response => response.text()) + .then((data) => { + var parser = new DOMParser(); + var svg = parser.parseFromString(data, 'image/svg+xml').lastChild; + svg.style.width = '100%'; + svg.style.height = '100%'; + const wrapper = document.createElement('DIV'); + wrapper.style.position = 'absolute'; + wrapper.style.zIndex = '999'; + wrapper.style.width = `${this._data.icon.size * scale}rem`; + wrapper.style.height = `${this._data.icon.size * scale}rem`; + wrapper.style.left = `calc(${this._data.icon.x}% - ${this._data.icon.size}px)`; + wrapper.style.top = `calc(${this._data.icon.y}% - ${this._data.icon.size}px`; + wrapper.appendChild(svg); + document.getElementById('map-output').appendChild(wrapper); + requestAnimationFrame(resolve); + }).catch(resolve); + }); + } + + /** * @method * @name _updateDimensionClicked @@ -941,6 +1218,11 @@

    Source: MesseMap.js

    } else { document.getElementById('map-output').style.width = `${size}px`; } + // Update icon position + if (this._data.hasIcon === true) { + document.getElementById('map-icon').style.display = 'none'; + } + // Mobile specific if (document.body.clientWidth < 1150) { document.querySelector('.user-text-wrapper').style.fontSize = 'inherit'; } @@ -955,7 +1237,12 @@

    Source: MesseMap.js

    document.getElementById('print-status').innerHTML = this._nls.download.tileLoad; document.getElementById('print-progress').style.width = '25%'; this._tilesLoaded = false; - resolve(); + // Need to create svg if an icon is requested + if (this._data.hasIcon === true) { + this._prepareIconForPrinting(scale).then(resolve); + } else { + resolve(); + } }); }); } @@ -1074,6 +1361,12 @@

    Source: MesseMap.js

    if (document.body.clientWidth < 1150) { document.querySelector('.user-text-wrapper').style.fontSize = '50%'; } + // Restore icon position + if (this._data.hasIcon === true) { + document.getElementById('map-icon').style.display = 'block'; + document.getElementById('map-output').removeChild(document.getElementById('map-output').lastElementChild); + } + // Clear map temporary styles and remove temporary document.getElementById('map-output').style = ''; // Restore map container box shadow document.getElementById('map-output').classList.add('shadow'); @@ -1187,7 +1480,7 @@

    Source: MesseMap.js

    this._cssTheme.dcom = '#999998'; this.applyThemeColor(); _updateInputs(); - }); + }); }); _updateInputs(); @@ -1456,6 +1749,14 @@

    Source: MesseMap.js

    subtitle: document.getElementById('user-subtitle').value, comment: document.getElementById('user-comment').value }, + icon: { + displayed: this._data.hasIcon, + color: this._data.icon.color, + image: this._data.icon.image, + size: this._data.icon.size, + x: this._data.icon.x, + y: this._data.icon.y + }, map: { layer: this._data.layer, center: this._map.getCenter(), @@ -1484,7 +1785,7 @@

    Source: MesseMap.js

    * @return {Promise} - A promise resolved when UI is blocked **/ blockInterface() { - if (CONST.DEBUG) { console.log('MesseMap.blockInterface called'); } + if (CONST.DEBUG) { console.log('MesseMap.blockInterface called'); } return new Promise(resolve => { document.getElementById('print-overlay').style.zIndex = 99; document.getElementById('print-overlay').style.opacity = 1; @@ -1508,10 +1809,10 @@

    Source: MesseMap.js

    * @return {Promise} - A promise resolved when UI is unblocked **/ unblockInterface() { - if (CONST.DEBUG) { console.log('MesseMap.unblockInterface called'); } + if (CONST.DEBUG) { console.log('MesseMap.unblockInterface called'); } return new Promise(resolve => { document.getElementById('print-overlay').style.opacity = 0; - setTimeout(() => { + setTimeout(() => { document.getElementById('print-overlay').style.zIndex = -1; document.getElementById('print-overlay').children[0].innerHTML = this._nls.download.title; document.getElementById('print-overlay').children[1].innerHTML = this._nls.download.subtitle; @@ -1541,7 +1842,7 @@

    Home

    Classes

    • diff --git a/doc/ScrollBar.html b/doc/ScrollBar.html index cb17cdc..7f568bc 100644 --- a/doc/ScrollBar.html +++ b/doc/ScrollBar.html @@ -2284,7 +2284,7 @@

      Home

      Classes

      • diff --git a/doc/index.html b/doc/index.html index dd7a3de..0be19f4 100644 --- a/doc/index.html +++ b/doc/index.html @@ -44,13 +44,13 @@

        MesseMap

        -

        +

        License Doc

        A website that helps you to create a map poster, so it can be exported ready to print, with the ability to scale the map to a given size. Different map layers available to create your unique wall-memory touch!

        It features 7 poster styles so far, that can all be customized (positioning, colors). It allows user to define a title, a subtitle and a comment for their map. Each of these text's color can also be modified. Available in 7 languages, translations welcome.

        Wanna try it ? We are running a MesseMap instance just for you!

        -

        Interface Screenshot

        +

        Interface Screenshot

        When exporting the map to disk the user can set the output dimension, the lowest resolution being A7 at 300 dpi (600 x 848) and the highest being A2 at 300 dpi (6500 x 9193). The user can also set the output format, between .png, .jpg, .webp and .pdf (exports in PDF are done in the CYMK color space so they're ready to print).

        On Google Chrome, exporting large maps may lead to grey tiles. Unfortunatly this is a known ressource issue with Chrome ; please try with Firefox or non-webkit based browsers in the meantime.

        Get started

        @@ -69,7 +69,7 @@

        Libraries and credits

        The map handling is done using Leaflet.js (BSD-2-Clause license), a Leaflet plugin to enable a smooth zooming, SmoothWheelZoom (MIT license), another Leaflet plugin Leaflet Control Search (MIT license) to perform searches on the map, it uses html2canvas (MIT license), html2canvas-proxy-nodejs (MIT license) and jsPDF (MIT license) to allow the exporting in all supported formats.

        Fonts are taken from DaFont, using Catamaran from Vladimir Nikolic, Sublima from Ruls Do Paolo and Louis George Café from Chen Yining.


        -

        Messe Basse Production --- 2022 / 2023

        +

        Messe Basse Production --- 2022 / 2024

        @@ -86,7 +86,7 @@

        Home

        Classes

        • diff --git a/doc/utils_ScrollBar.js.html b/doc/utils_ScrollBar.js.html index 11124c0..4d9d42d 100644 --- a/doc/utils_ScrollBar.js.html +++ b/doc/utils_ScrollBar.js.html @@ -430,7 +430,7 @@

          Home

          Classes

          • diff --git a/package.json b/package.json index dd63439..a2d1376 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "messemap", - "version": "1.0.3", + "version": "1.1.0", "keywords": [], "main": "src/js/MesseMap.js", "scripts": { diff --git a/src/js/MesseMap.js b/src/js/MesseMap.js index 8e2dd10..6aac182 100644 --- a/src/js/MesseMap.js +++ b/src/js/MesseMap.js @@ -60,7 +60,7 @@ class MesseMap { * @type {Boolean} * @private **/ - this._commentEdited = false; + this._commentEdited = false; /** * setInterval ID used to frequently ask for printing (only if tiles are loaded) * @type {Number} @@ -78,7 +78,7 @@ class MesseMap { lcom: '#999998', dbg: '#000001', dtxt: '#FFFFFE', - dcom: '#999998' + dcom: '#999998' }; /** * The currently applied language @@ -104,7 +104,15 @@ class MesseMap { style: 'standard', darkTheme: false, upText: false, - layer: 'Imagery (E)' + layer: 'Imagery (E)', + hasIcon: false, + icon: { + color: '#FFFFFF', + image: '/assets/img/icon/home.svg', + size: 2, // Size in rem + x: 48.33, // Size in % + y: 48.33 // Size in % + } }; // Begin the initialization sequence (interface and events) @@ -155,11 +163,12 @@ class MesseMap { // Update page content with translations this.replaceString(document.body, '{{TITLE}}', this._nls.title); this.replaceString(document.body, '{{HELPER}}', this._nls.helper); - this.replaceString(document.body, '{{ORIENTATION}}', this._nls.orientation); - this.replaceString(document.body, '{{VERTICAL}}', this._nls.vertical); - this.replaceString(document.body, '{{HORIZONTAL}}', this._nls.horizontal); this.replaceString(document.body, '{{STYLE}}', this._nls.style.title); + this.replaceString(document.body, '{{MAP_ORIENTATION}}', this._nls.style.orientation); + this.replaceString(document.body, '{{VERTICAL}}', this._nls.style.vertical); + this.replaceString(document.body, '{{HORIZONTAL}}', this._nls.style.horizontal); + this.replaceString(document.body, '{{MAP_STYLE}}', this._nls.style.mapStyle); this.replaceString(document.body, '{{STYLE_STD}}', this._nls.style.std); this.replaceString(document.body, '{{STYLE_TRAVEL}}', this._nls.style.travel); @@ -180,6 +189,13 @@ class MesseMap { this.replaceString(document.body, '{{MAP_SUBTITLE_PLACEHOLDER}}', this._nls.text.mapSubtitlePlaceholder); this.replaceString(document.body, '{{MAP_COMMENT}}', this._nls.text.mapComment); this.replaceString(document.body, '{{MAP_COMMENT_PLACEHOLDER}}', this._nls.text.mapCommentPlaceholder); + + this.replaceString(document.body, '{{ICON}}', this._nls.icon.title); + this.replaceString(document.body, '{{TOGGLE_ICON}}', this._nls.icon.toggle); + this.replaceString(document.body, '{{ICON_SIZE}}', this._nls.icon.size); + this.replaceString(document.body, '{{ICON_COLOR}}', this._nls.icon.color); + this.replaceString(document.body, '{{ICON_IMAGE}}', this._nls.icon.image); + this.replaceString(document.body, '{{EXPORT}}', this._nls.export.title); this.replaceString(document.body, '{{EXPORT_DIMENSION}}', this._nls.export.dimension); this.replaceString(document.body, '{{EXPORT_AT}}', this._nls.export.at); @@ -228,7 +244,7 @@ class MesseMap { url: 'https://nominatim.openstreetmap.org/search?format=json&q={s}', jsonpParam: 'json_callback', propertyName: 'display_name', - propertyLoc: ['lat','lon'], + propertyLoc: ['lat', 'lon'], marker: false, autoCollapse: true, firstTipSubmit: true, @@ -296,14 +312,12 @@ class MesseMap { _initEvents() { if (CONST.DEBUG) { console.log('MesseMap._initEvents() called'); } return new Promise(resolve => { - // Orientation - document.getElementById('toggle-orientation').addEventListener('click', this._toggleCategory.bind(this)); + // Style + document.getElementById('toggle-style').addEventListener('click', this._toggleCategory.bind(this)); const orientations = document.getElementById('toggle-orientation-container'); for (let i = 0; i < orientations.children.length; ++i) { orientations.children[i].addEventListener('click', this._updateMapOrientation.bind(this)); } - // Style - document.getElementById('toggle-style').addEventListener('click', this._toggleCategory.bind(this)); const styles = document.getElementById('map-style'); for (let i = 0; i < styles.children.length; ++i) { styles.children[i].addEventListener('click', this._updateMapStyle.bind(this)); @@ -319,6 +333,16 @@ class MesseMap { document.getElementById('user-title').addEventListener('input', this._applyTexts.bind(this)); document.getElementById('user-subtitle').addEventListener('input', this._applyTexts.bind(this)); document.getElementById('user-comment').addEventListener('input', this._applyTexts.bind(this)); + // Icon + document.getElementById('toggle-icon').addEventListener('click', this._toggleCategory.bind(this)); + document.getElementById('activate-icon').addEventListener('change', this._toggleIcon.bind(this)); + document.getElementById('icon-size').addEventListener('input', this._updateIconSize.bind(this)); + this._handleIconDrag(); + document.getElementById('icon-color').addEventListener('input', this._updateIconColor.bind(this)); + const icons = document.getElementById('icon-images'); + for (let i = 0; i < icons.children.length; ++i) { + icons.children[i].addEventListener('click', this._updateIconImage.bind(this)); + } // Export settings document.getElementById('toggle-export').addEventListener('click', this._toggleCategory.bind(this)); document.getElementById('image-width').addEventListener('input', this._updateDimensionLabel.bind(this)); @@ -363,7 +387,7 @@ class MesseMap { * @returns {Promise} A resolved Promise **/ _initAdvancedFeatures() { - if (CONST.DEBUG) { console.log('MesseMap._initAdvancedFeatures called'); } + if (CONST.DEBUG) { console.log('MesseMap._initAdvancedFeatures called'); } return new Promise(resolve => { if (window.location.href.indexOf('?callmeroot') > -1) { const reader = new FileReader(); @@ -403,7 +427,7 @@ class MesseMap { * **/ _endStartup() { - if (CONST.DEBUG) { console.log('MesseMap._endStartup called'); } + if (CONST.DEBUG) { console.log('MesseMap._endStartup called'); } return new Promise(resolve => { this.unblockInterface().then(resolve); }); @@ -468,11 +492,33 @@ class MesseMap { break; } } + + if (data.icon && data.icon.displayed === true) { + document.getElementById('activate-icon').click(); + document.getElementById('icon-size').value = data.icon.size; + this._updateIconSize({ + target: document.getElementById('icon-size') + }); + const icons = document.getElementById('icon-images'); + for (let i = 0; i < icons.children.length; ++i) { + if (icons.children[i].dataset.url === data.icon.image) { + icons.children[i].click(); + break; + } + } + document.getElementById('icon-color').value = data.icon.color; + this._updateIconColor({ + target: document.getElementById('icon-color') + }); + document.getElementById('map-icon').style.left = `${data.icon.x}%`; + document.getElementById('map-icon').style.top = `${data.icon.y}%`; + } + // Update map position this._map.setView(new window.L.LatLng(data.map.center.lat, data.map.center.lng), data.map.zoom); // Switch map base layer this._map.removeLayer(MapProviders.layers[this._data.layer]); - this._map.addLayer(MapProviders.layers[data.map.layer]); + this._map.addLayer(MapProviders.layers[data.map.layer]); } @@ -646,6 +692,7 @@ class MesseMap { *
            * Simply apply the input text to the poster (for title, subtitle and comment) *
            + * @param {Event} e - The text input **/ _applyTexts(e) { if (CONST.DEBUG) { console.log('MesseMap._applyTexts() called with ', e); } @@ -698,6 +745,236 @@ class MesseMap { } + /** + * @method + * @name _toggleIcon + * @private + * @memberof MesseMap + * @author Arthur Beaulieu + * @since January 2024 + * @description + *
            + * Display or hide the icon on the output map + *
            + * @param {Event} e - The check input + **/ + _toggleIcon(e) { + if (CONST.DEBUG) { console.log('MesseMap._toggleIcon() called with ', e); } + const icon = document.getElementById('map-icon'); + if (e.target.checked) { + // Init icon position + icon.style.left = `${this._data.icon.x}%`; + icon.style.top = `${this._data.icon.y}%`; + icon.classList.add('visible'); + icon.style.backgroundColor = this._data.icon.color; + icon.style.mask = `url(${this._data.icon.image}) no-repeat center / contain`; + this._data.hasIcon = true; + } else { + icon.classList.remove('visible'); + this._data.hasIcon = false; + } + } + + + /** + * @method + * @name _updateIconSize + * @private + * @memberof MesseMap + * @author Arthur Beaulieu + * @since January 2024 + * @description + *
            + * Update the icon size in output map + *
            + * @param {Event} e - The range input + **/ + _updateIconSize(e) { + if (CONST.DEBUG) { console.log('MesseMap._updateIconSize() called with ', e); } + document.getElementById('map-icon').style.height = `${e.target.value}rem`; + document.getElementById('map-icon').style.width = `${e.target.value}rem`; + const label = e.target.previousElementSibling; + this._data.icon.size = parseInt(e.target.value); + // Update position with new size + e.target.dataset.size = e.target.value; + label.innerHTML = `${this._nls.icon.size} : ${e.target.value}`; + } + + + /** + * @method + * @name _handleIconDrag + * @private + * @memberof MesseMap + * @author Arthur Beaulieu + * @since January 2024 + * @description + *
            + * Handle the icon dragging in the map output + *
            + **/ + _handleIconDrag() { + if (CONST.DEBUG) { console.log('MesseMap._handleIconDrag() called'); } + let dragging = false; + const map = document.getElementById('map-output'); + const mapRect = map.getBoundingClientRect(); + const element = document.getElementById('map-icon'); + let rect = element.getBoundingClientRect(); + // Map paddings + let paddingLeft = parseInt(window.getComputedStyle(map).getPropertyValue('padding-left').slice(0, -2)); + let paddingTop = parseInt(window.getComputedStyle(map).getPropertyValue('padding-top').slice(0, -2)); + // User pointer position + let clickX = 0; + let clickY = 0; + // Variation between place clicked and icon X,Y absolute origin + let dX = 0; + let dY = 0; + // Current position + let positionX = 0; + let positionY = 0; + + const mouseDown = e => { + e.preventDefault(); + dragging = true; + // Update icon bounding rect in case its sized was updated + rect = element.getBoundingClientRect(); + // Update map paddings if style has been updated + paddingLeft = parseInt(window.getComputedStyle(map).getPropertyValue('padding-left').slice(0, -2)); + paddingTop = parseInt(window.getComputedStyle(map).getPropertyValue('padding-top').slice(0, -2)); + // Store initial position + positionX = e.clientX; + positionY = e.clientY; + // Get dif between click and icon x pos + dX = e.clientX - rect.x; + dY = e.clientY - rect.y; + }; + + const mouseMove = e => { + const xAxis = (e.pageX > (mapRect.x + paddingLeft - dX) && e.pageX < (mapRect.x + mapRect.width - paddingLeft + dX)); + const yAxis = (e.pageY > (mapRect.y + paddingTop - dY) && e.pageY < (mapRect.y + mapRect.height - paddingTop + dY)); + if (dragging && xAxis && yAxis) { + e.preventDefault(); + // Update pointer position with differential + clickX = positionX - e.clientX; + clickY = positionY - e.clientY; + // Store current pointer position + positionX = e.clientX; + positionY = e.clientY; + // Determine icon new top and left position + const newTop = element.offsetTop - clickY; + const newLeft = element.offsetLeft - clickX; + // Only update Y if in bounds + if (newTop > paddingTop && newTop + rect.width < mapRect.height - paddingTop) { + element.style.top = `${newTop}px`; + element.dataset.top = `${newTop}px`; + this._data.icon.y = newTop * 100 / mapRect.height; + } + // Only update X if in bounds + if (newLeft > paddingLeft && newLeft + rect.width < mapRect.width - paddingLeft) { + element.style.left = `${newLeft}px`; + element.dataset.left = `${newLeft}px`; + this._data.icon.x = newLeft * 100 / mapRect.width; + } + } + }; + + const mouseUp = () => { + dragging = false; + }; + + element.addEventListener('mousedown', mouseDown); + map.addEventListener('mousemove', mouseMove); + window.addEventListener('mouseup', mouseUp); + } + + + /** + * @method + * @name _updateIconImage + * @private + * @memberof MesseMap + * @author Arthur Beaulieu + * @since January 2024 + * @description + *
            + * Update the icon source image + *
            + * @param {Event} e - The clicked image + **/ + _updateIconImage(e) { + if (CONST.DEBUG) { console.log('MesseMap._updateIconImage() called with ', e); } + const icons = document.getElementById('icon-images'); + for (let i = 0; i < icons.children.length; ++i) { + if (icons.children[i].classList.contains('selected')) { + icons.children[i].classList.remove('selected'); + break; + } + } + // Update icon src and store it + e.target.classList.add('selected'); + this._data.icon.image = e.target.dataset.url; // Update internal data + document.getElementById('map-icon').style.mask = `url(${e.target.dataset.url}) no-repeat center / contain`; + } + + + /** + * @method + * @name _updateIconColor + * @private + * @memberof MesseMap + * @author Arthur Beaulieu + * @since January 2024 + * @description + *
            + * Update the icon color + *
            + * @param {Event} e - The color input + **/ + _updateIconColor(e) { + document.getElementById('map-icon').style.backgroundColor = e.target.value; + document.getElementById('map-icon').style.mask = `url(${this._data.icon.image}) no-repeat center / contain`; + this._data.icon.color = e.target.value; + document.documentElement.style.setProperty('--fillColor', this._data.icon.color); + } + + + /** + * @method + * @name _prepareIconForPrinting + * @private + * @memberof MesseMap + * @author Arthur Beaulieu + * @since January 2024 + * @description + *
            + * Apply svg image with color to properly render icon ou output map + *
            + * @param {Number} scale - The output map scale + **/ + _prepareIconForPrinting(scale) { + return new Promise(resolve => { + fetch(this._data.icon.image) + .then(response => response.text()) + .then((data) => { + var parser = new DOMParser(); + var svg = parser.parseFromString(data, 'image/svg+xml').lastChild; + svg.style.width = '100%'; + svg.style.height = '100%'; + const wrapper = document.createElement('DIV'); + wrapper.style.position = 'absolute'; + wrapper.style.zIndex = '999'; + wrapper.style.width = `${this._data.icon.size * scale}rem`; + wrapper.style.height = `${this._data.icon.size * scale}rem`; + wrapper.style.left = `calc(${this._data.icon.x}% - ${this._data.icon.size}px)`; + wrapper.style.top = `calc(${this._data.icon.y}% - ${this._data.icon.size}px`; + wrapper.appendChild(svg); + document.getElementById('map-output').appendChild(wrapper); + requestAnimationFrame(resolve); + }).catch(resolve); + }); + } + + /** * @method * @name _updateDimensionClicked @@ -913,6 +1190,11 @@ class MesseMap { } else { document.getElementById('map-output').style.width = `${size}px`; } + // Update icon position + if (this._data.hasIcon === true) { + document.getElementById('map-icon').style.display = 'none'; + } + // Mobile specific if (document.body.clientWidth < 1150) { document.querySelector('.user-text-wrapper').style.fontSize = 'inherit'; } @@ -927,7 +1209,12 @@ class MesseMap { document.getElementById('print-status').innerHTML = this._nls.download.tileLoad; document.getElementById('print-progress').style.width = '25%'; this._tilesLoaded = false; - resolve(); + // Need to create svg if an icon is requested + if (this._data.hasIcon === true) { + this._prepareIconForPrinting(scale).then(resolve); + } else { + resolve(); + } }); }); } @@ -1046,6 +1333,12 @@ class MesseMap { if (document.body.clientWidth < 1150) { document.querySelector('.user-text-wrapper').style.fontSize = '50%'; } + // Restore icon position + if (this._data.hasIcon === true) { + document.getElementById('map-icon').style.display = 'block'; + document.getElementById('map-output').removeChild(document.getElementById('map-output').lastElementChild); + } + // Clear map temporary styles and remove temporary document.getElementById('map-output').style = ''; // Restore map container box shadow document.getElementById('map-output').classList.add('shadow'); @@ -1159,7 +1452,7 @@ class MesseMap { this._cssTheme.dcom = '#999998'; this.applyThemeColor(); _updateInputs(); - }); + }); }); _updateInputs(); @@ -1428,6 +1721,14 @@ class MesseMap { subtitle: document.getElementById('user-subtitle').value, comment: document.getElementById('user-comment').value }, + icon: { + displayed: this._data.hasIcon, + color: this._data.icon.color, + image: this._data.icon.image, + size: this._data.icon.size, + x: this._data.icon.x, + y: this._data.icon.y + }, map: { layer: this._data.layer, center: this._map.getCenter(), @@ -1456,7 +1757,7 @@ class MesseMap { * @return {Promise} - A promise resolved when UI is blocked **/ blockInterface() { - if (CONST.DEBUG) { console.log('MesseMap.blockInterface called'); } + if (CONST.DEBUG) { console.log('MesseMap.blockInterface called'); } return new Promise(resolve => { document.getElementById('print-overlay').style.zIndex = 99; document.getElementById('print-overlay').style.opacity = 1; @@ -1480,10 +1781,10 @@ class MesseMap { * @return {Promise} - A promise resolved when UI is unblocked **/ unblockInterface() { - if (CONST.DEBUG) { console.log('MesseMap.unblockInterface called'); } + if (CONST.DEBUG) { console.log('MesseMap.unblockInterface called'); } return new Promise(resolve => { document.getElementById('print-overlay').style.opacity = 0; - setTimeout(() => { + setTimeout(() => { document.getElementById('print-overlay').style.zIndex = -1; document.getElementById('print-overlay').children[0].innerHTML = this._nls.download.title; document.getElementById('print-overlay').children[1].innerHTML = this._nls.download.subtitle; diff --git a/src/js/Server.js b/src/js/Server.js index 2e1e68c..3cb6262 100644 --- a/src/js/Server.js +++ b/src/js/Server.js @@ -7,7 +7,7 @@ const request = require('request'); const compression = require('compression'); const zlib = require('node:zlib'); // App and preferences -const version = '1.0.3'; +const version = '1.1.0'; const port = 8010; const exportPath = path.join(__dirname, '../../saved'); // Must match Dockerfile value const app = express(); diff --git a/src/py/MapDownloader.py b/src/py/MapDownloader.py index 869479d..92f5ede 100644 --- a/src/py/MapDownloader.py +++ b/src/py/MapDownloader.py @@ -15,7 +15,7 @@ global mapInfo global savedPath global scriptVersion -scriptVersion = '1.0.3' +scriptVersion = '0' def main(): global mapInfo diff --git a/src/scss/app/_layout.scss b/src/scss/app/_layout.scss index e3ed5a0..a91bd52 100644 --- a/src/scss/app/_layout.scss +++ b/src/scss/app/_layout.scss @@ -1,3 +1,7 @@ +:root { + --fillColor: #FFFFFF; +} + .app-wrapper { align-items: center; background: linear-gradient(126deg, rgba(251, 255, 144, 0.1), rgba(255, 107, 103, 0.2)), linear-gradient(204deg, rgba(255, 255, 255, .3), rgba(86, 212, 91, .2)); @@ -19,7 +23,7 @@ aside { left: 0; position: absolute; top: 0; - width: 36rem; + width: 42rem; hr { border-top: transparent; @@ -56,7 +60,7 @@ aside { width: 100%; .aside-content-wrapper { - padding-right: calc((2 * var(--default-scroll-size)) - 1px); + padding-right: calc((2 * var(--scroll-size))); width: 100%; } @@ -91,11 +95,11 @@ aside { &.expanded { height: auto; - &.orientation-container span, .txt-position-wrapper, + .icon-images-container, .input-with-color:last-of-type, fieldset { - margin-bottom: 4rem; + margin-bottom: 3rem; } } @@ -122,28 +126,23 @@ aside { } } - /* Specific to orientation category */ - .orientation-container { - display: flex; - flex-wrap: wrap; - grid-gap: .5rem; - justify-content: flex-start; - margin: 0; - padding: 0 1rem; - - span { - margin-bottom: 2rem; - } - } - /* Specific to style category */ .style-container { + .orientation-container { + display: flex; + flex-wrap: wrap; + grid-gap: .5rem; + justify-content: flex-start; + margin: .5rem 0 1rem; + padding: 0 1rem; + } + .map-style { display: flex; flex-wrap: wrap; grid-gap: .5rem; justify-content: flex-start; - margin: .2rem 0 1rem; + margin: .5rem 0 1rem; padding: 0 1rem; } @@ -183,7 +182,7 @@ aside { align-items: center; display: flex; height: 2.5rem; - margin: .2rem 0; + margin: .5rem 0; margin-bottom: 1rem; padding: 0 1rem; width: 100%; @@ -220,6 +219,79 @@ aside { } } + .icon-container { + .toggle-icon-wrapper { + display: flex; + justify-content: space-between; + margin: 0 0 1rem; + padding: 0 1rem; + + label { + margin: 0; + } + + div.theme-input-holder { + display: flex; + + input { + margin-left: 1rem; + } + + div { + cursor: pointer; + width: calc(1.2rem + 2px); + } + } + } + + input[type="range"] { + margin: 0 1rem; + margin-bottom: 1rem; + width: calc(100% - 2rem); + } + + .icon-color-container { + align-items: center; + display: flex; + justify-content: space-between; + margin: 0 1rem; + + label { + margin-left: 0; + } + + input { + aspect-ratio: 2/1; + background-color: transparent; + border: 1px solid #a1a1a1; + border-radius: .5rem; + cursor: pointer; + height: 2.5rem; + padding: .2rem; + } + } + + .icon-images-container { + align-items: center; + display: flex; + justify-content: space-evenly; + margin: .5rem 0 1rem; + + img { + cursor: pointer; + border: solid 1px #a1a1a1; + border-radius: .5rem; + height: 3rem; + padding: .7rem; + transition: all .2s; + + &.selected { + filter: invert(63%) sepia(60%) saturate(507%) hue-rotate(73deg) brightness(172%) contrast(98%); + } + } + } + } + /* Specific to export category */ .export-container { input[type="range"] { @@ -230,7 +302,7 @@ aside { .size-container { display: flex; - justify-content: space-between; + justify-content: space-evenly; padding: 0 1rem; span { @@ -285,10 +357,10 @@ main { flex-direction: column; height: 100%; justify-content: center; - left: 36rem; + left: 42rem; position: absolute; top: 0; - width: calc(100% - 36rem); + width: calc(100% - 42rem); } .map-container { @@ -321,9 +393,29 @@ main { width: 100%; } + .map-icon { + cursor: grab; + display: none; + position: absolute; + left: 50%; + height: 2rem; + opacity: 0; + width: 2rem; + z-index: 999; + + &.visible { + display: block; + opacity: 1; + } + } + &.horizontal { aspect-ratio: 29.7 / 21; height: 600px; width: auto; } + + svg, path, circle { + fill: var(--fillColor) !important; + } }