Skip to content

Commit d9ad673

Browse files
committed
0.2.2
1. Improved Documentation 2. Added ability to display real-world maps 3. Added ability to specify default latitude and longitude 4. Added ability to specify zoom deltas 5. Improved error handling 6. Added tooltips on markers that link to notes (closes #8) 7. Fixed issue related to creating multiple additional markers in settings (closes #12) 8. General code cleanup
1 parent 1355327 commit d9ad673

File tree

9 files changed

+292
-158
lines changed

9 files changed

+292
-158
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ main.js
1111
*.js.map
1212
.DS_Store
1313
*build.js
14+
rollup.config-dev.js

README.md

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,40 @@ A map can be created with a `leaflet` code block. For example:
1212
```leaflet
1313
image: https://i.imgur.com/jH8j3mJ.jpg
1414
height: 500px
15+
lat: 50
16+
long: 50
17+
height: 500px
18+
minZoom: 1
19+
maxZoom: 10
20+
defaultZoom: 5
1521
```
1622
````
1723

18-
### API
24+
### Options
25+
26+
| Option | Description | Default |
27+
| ----------- | ----------------------------------------------------------------- | --------------------------------- |
28+
| image* | Direct URL/file path to an image file to be used as the map layer | OpenStreetMap map |
29+
| lat* | Default latitude to display when rendering | 50% (image) / 0 (open street map) |
30+
| long* | Default longitude to display when rendering | 50% (image) / 0 (open street map) |
31+
| height | Height in pixels of the map element | 500px |
32+
| minZoom | Minimum allowable zoom level of the map | 1 |
33+
| maxZoom | Maximum allowable zoom level of the map | 10 |
34+
| defaultZoom | Map will load zoomed to this level | 5 |
35+
| zoomDelta | Zoom level will change by this amount when zooming | 1 |
36+
37+
#### Image Map URL / file path
38+
39+
Image maps can be loaded one of three ways:
40+
41+
1. Direct URL (e.g., https://i.imgur.com/jH8j3mJ.jpg)
42+
2. Obsidian URL (e.g., obsidian://open?vault=VaultName&file=Path/To/Image.jpg)
43+
3. Direct path to image (e.g., Path/To/Image.jpg)
44+
45+
#### Latitude and Longtitude of Image Maps
46+
47+
Because an image map does not have a true coordinate system, the latitude and longitude provided must be given as a percentage from the **top left corner of the image**.
1948

20-
```
21-
image: Direct URL to an image file to be used as the map layer. **Required**
22-
height: Height in pixels of the map element. Defaults to 500px.
23-
minZoom: Minimum allowable zoom level (optional, default = 1).
24-
maxZoom: Maximum allowable zoom level (optional, default = 10).
25-
defaultZoom: Map will load zoomed to this level (optional, default = 5).
26-
```
2749

2850
### Markers
2951

@@ -32,13 +54,31 @@ New markers can be added to the map by right clicking.
3254
If any additional marker types have been created in the settings, a list will appear to choose from.
3355

3456
Once a marker has been created, it can be dragged to a different location. A marker can also point to a note; right-click on it, and a popup will appear. Enter the note as:
35-
`Path/To/Note.md`. Once linked, a click will open the note (<kbd>Ctrl</kbd>/<kbd>Cmd</kbd>-click to open in new window).
57+
`Path/To/Note.md` (case-sensitive). Once linked, a click will open the note (<kbd>Ctrl</kbd>/<kbd>Cmd</kbd>-click to open in new window).
3658

3759
Additionally, markers can be created by dragging a note from the file tree and dropping it on the map.
3860

3961
## Installation
4062

41-
The plugin is not currently part of the community plugin list. To install, copy the files from the lastest release to your plugins folder.
63+
### From within Obsidian
64+
From Obsidian v0.9.8, you can activate this plugin within Obsidian by doing the following:
65+
- Open Settings > Third-party plugin
66+
- Make sure Safe mode is **off**
67+
- Click Browse community plugins
68+
- Search for this plugin
69+
- Click Install
70+
- Once installed, close the community plugins window and activate the newly installed plugin
71+
#### Updates
72+
You can follow the same procedure to update the plugin
73+
74+
### From GitHub
75+
- Download the Latest Release from the Releases section of the GitHub Repository
76+
- Extract the plugin folder from the zip to your vault's plugins folder: `<vault>/.obsidian/plugins/`
77+
Note: On some machines the `.obsidian` folder may be hidden. On MacOS you should be able to press `Command+Shift+Dot` to show the folder in Finder.
78+
- Reload Obsidian
79+
- If prompted about Safe Mode, you can disable safe mode and enable the plugin.
80+
Otherwise head to Settings, third-party plugins, make sure safe mode is off and
81+
enable the plugin from there.
4282

4383
## Configuration
4484

manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"id": "obsidian-leaflet-plugin",
33
"name": "Obsidian Leaflet",
44
"description": "Leaflet integration for Obsidian.md",
5-
"version": "0.2.1",
5+
"version": "0.2.2",
66
"minAppVersion": "0.11.0",
77
"author": "Jeremy Valentine",
88
"repo": "valentine195/obsidian-leaflet-plugin",

package.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
{
22
"name": "obsidian-leaflet-plugin",
3-
"version": "0.2.1",
3+
"version": "0.2.2",
44
"description": "Leaflet integration for Obsidian.md",
55
"main": "main.js",
66
"scripts": {
7-
"dev": "rollup --config rollup.config.js -w",
8-
"build": "rollup --config rollup.config.js",
9-
"build-copy": "rollup --config rollup.config-build.js"
7+
"dev": "rollup --config rollup.config-dev.js -w",
8+
"build": "rollup --config rollup.config.js"
109
},
1110
"keywords": [],
1211
"author": "",

src/leaflet.ts

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import * as L from "leaflet";
33
import 'leaflet/dist/leaflet.css';
44

55
import { Events, Menu, Point } from "obsidian";
6-
/* import { EventEmitter } from "events"; */
76
import { v4 as uuidv4 } from "uuid";
87

98
/**
@@ -54,7 +53,7 @@ export default class LeafletMap extends Events {
5453
}
5554

5655

57-
loadData(data: any/* : MarkerData[] */): Promise<void> {
56+
loadData(data: any): Promise<void> {
5857
return new Promise(resolve => {
5958
data?.markers.forEach((marker: MarkerData) => {
6059
this.createMarker(
@@ -68,11 +67,13 @@ export default class LeafletMap extends Events {
6867
});
6968
}
7069

71-
async render(image: string) {
70+
async renderImage(image: string, coords?: [number, number]) {
7271
this.map = L.map(this.contentEl, {
7372
crs: L.CRS.Simple,
7473
maxZoom: this.zoom.max,
75-
minZoom: this.zoom.min
74+
minZoom: this.zoom.min,
75+
zoomDelta: this.zoom.delta,
76+
zoomSnap: this.zoom.delta
7677
});
7778
this.markers.forEach(marker => {
7879
marker.leafletInstance.addTo(this.map);
@@ -90,22 +91,46 @@ export default class LeafletMap extends Events {
9091
L.imageOverlay(image, this.bounds).addTo(this.map);
9192
this.map.fitBounds(this.bounds);
9293
this.map.panTo(this.bounds.getCenter());
94+
9395
// tell leaflet that the map is exactly as big as the image
9496
this.map.setMaxBounds(this.bounds);
95-
this.map.invalidateSize();
96-
this.map.setZoom(this.zoom.default, { animate: false })
97-
/* this.map.setMaxZoom(this.zoom.max);
98-
this.map.setMinZoom(this.zoom.min); */
97+
this.map.setZoom(this.zoom.default, { animate: false });
98+
99+
if (coords) {
100+
this.map.panTo([coords[0] * this.bounds.getSouthEast().lat / 100, coords[1] * this.bounds.getSouthEast().lng / 100]);
101+
}
99102

100103
this.map.on("contextmenu", this.contextMenu.bind(this));
101-
104+
102105
this.rendered = true;
103106

104107
}
105108

106-
contextMenu(evt: L.LeafletMouseEvent): void {
107-
/** Create Context Menu */
109+
async renderReal(coords: [number, number] = [0, 0]) {
110+
111+
this.map = L.map(this.contentEl, {
112+
maxZoom: this.zoom.max,
113+
minZoom: this.zoom.min,
114+
worldCopyJump: true,
115+
zoomDelta: this.zoom.delta,
116+
zoomSnap: this.zoom.delta
117+
}).setView(coords, this.zoom.default);
118+
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
119+
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
120+
}).addTo(this.map);
121+
122+
this.markers.forEach(marker => {
123+
marker.leafletInstance.addTo(this.map);
124+
})
125+
this.map.setZoom(this.zoom.default, { animate: false });
126+
127+
this.map.on("contextmenu", this.contextMenu.bind(this));
108128

129+
this.rendered = true;
130+
131+
}
132+
133+
contextMenu(evt: L.LeafletMouseEvent): void {
109134
if (this.markerIcons.length <= 1) {
110135
this.createMarker(this.markerIcons[0], evt.latlng);
111136
return;
@@ -168,18 +193,33 @@ export default class LeafletMap extends Events {
168193
.on("dragend", evt => {
169194
marker.loc = marker.leafletInstance.getLatLng();
170195
this.trigger("marker-added", marker);
171-
});
196+
})
197+
.on('mouseover', (evt: L.LeafletMouseEvent) => {
198+
199+
if (marker.link) {
200+
let el = evt.originalEvent.target as SVGElement;
201+
marker.leafletInstance.bindTooltip(
202+
marker.link.split('/').pop(),
203+
{
204+
className: 'leaflet-marker-link-tooltip',
205+
direction: 'top',
206+
offset: new L.Point(0, -1 * el.getBoundingClientRect().height)
207+
}
208+
).openTooltip();
209+
}
210+
211+
})
172212

173213
if (this.rendered) {
174214

175215
marker.leafletInstance.addTo(this.map);
176216

177217
}
178218

179-
180219
this.markers.push(marker);
181220

182221
this.trigger("marker-added", marker);
222+
183223
}
184224
setMarkerIcons(markerIcons: MarkerIcon[]) {
185225

src/main.css

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,28 @@
11
/* Settings */
2-
.additional-markers-container > .setting-item:not(.setting-item-heading) {
2+
3+
.additional-markers-container>.setting-item:not(.setting-item-heading) {
34
border: 0px;
45
}
6+
57
/* .additional-markers-container > .setting-item-heading:first-of-type {
68
border-bottom: 1px solid var(--background-modifier-border);
79
} */
10+
811
.additional-markers-container {
912
border-bottom: 1px solid var(--background-modifier-border);
1013
border-top: 1px solid var(--background-modifier-border);
1114
padding: 18px 0 0 0;
1215
}
1316

14-
.additional-markers-container > .setting-item-heading:only-child {
17+
.additional-markers-container>.setting-item-heading:only-child {
1518
padding-bottom: 18px;
1619
}
1720

18-
.additional-markers-control > input:first-of-type {
21+
.additional-markers-control>input:first-of-type {
1922
margin-right: auto !important;
2023
}
21-
.setting-item-control.marker-icon-display,
22-
.setting-item-control > .marker-icon-display {
24+
25+
.setting-item-control.marker-icon-display, .setting-item-control>.marker-icon-display {
2326
margin-left: 0.5rem;
2427
margin-right: 12px;
2528
position: relative;
@@ -58,47 +61,73 @@
5861
margin-right: 12px;
5962
}
6063

61-
.full-width-height,
62-
.full-width-height > * {
64+
.full-width-height, .full-width-height>* {
6365
height: 100% !important;
6466
width: 100% !important;
6567
}
6668

67-
.full-width,
68-
.full-width > * {
69+
.full-width, .full-width>* {
6970
width: 100% !important;
7071
}
7172

7273
/** Invalid Setting */
74+
7375
.unset-align-items {
7476
align-items: unset;
7577
}
78+
7679
.has-invalid-message {
7780
flex-grow: unset;
7881
flex-flow: column nowrap;
7982
}
83+
8084
input.is-invalid {
8185
border-color: #dc3545 !important;
8286
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");
8387
background-repeat: no-repeat;
8488
background-position: right calc(0.375em + 0.1875rem) center;
8589
background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
8690
}
91+
8792
.invalid-feedback {
8893
display: block;
8994
width: 100%;
9095
margin-top: 0.25rem;
9196
font-size: 0.875em;
9297
color: #dc3545;
9398
}
99+
94100
/* div icon override */
95101

96102
.leaflet-div-icon {
97-
98103
background: transparent !important;
99104
border: none !important;
100105
width: 25px !important;
101106
height: 25px !important;
102107
margin-left: -12.5px !important;
103108
margin-top: -25px !important;
109+
}
110+
111+
.leaflet-marker-link-tooltip {
112+
box-shadow: 0 2px 8px var(--background-modifier-box-shadow) !important;
113+
background-color: rgba(0, 0, 0, 0.9) !important;
114+
border: 1px solid rgba(0, 0, 0, 0.9) !important;
115+
border-radius: 6px !important;
116+
color: #dcddde !important;
117+
font-size: 14px !important;
118+
left: 50% !important;
119+
line-height: 20px !important;
120+
width: auto !important;
121+
/* max-width: 300px !important; */
122+
padding: 5px 14px !important;
123+
/* position: fixed !important;
124+
text-align: center !important;
125+
transform: translateX(-50%) !important;
126+
z-index: var(--layer-tooltip) !important; */
127+
pointer-events: none !important;
128+
/* white-space: pre-wrap !important; */
129+
}
130+
131+
.leaflet-marker-link-tooltip::before {
132+
border-top-color: rgba(0, 0, 0, 0.9) !important;
104133
}

0 commit comments

Comments
 (0)