diff options
author | Hsieh Chin Fan <pham@topo.tw> | 2024-10-31 17:09:51 +0800 |
---|---|---|
committer | Hsieh Chin Fan <pham@topo.tw> | 2024-11-03 14:01:05 +0800 |
commit | 11ff731337c6823e74821d06457972c6d0528c34 (patch) | |
tree | 4733b9b6172fd53f19de9bf454ef7da4e85f8f78 | |
parent | 7ee1ad61627f9a2af04f080cfa95a30f3c8e4525 (diff) |
refactor: getMarkersFromMaps
Make arugments more general, not only GeoLink
-rw-r--r-- | src/Link.mjs | 56 | ||||
-rw-r--r-- | src/MenuItem.mjs | 4 | ||||
-rw-r--r-- | src/dumbymap.mjs | 6 |
3 files changed, 39 insertions, 27 deletions
diff --git a/src/Link.mjs b/src/Link.mjs index 92aaacf..7678f3a 100644 --- a/src/Link.mjs +++ b/src/Link.mjs | |||
@@ -53,7 +53,7 @@ export const GeoLink = (link) => { | |||
53 | link.lines = [] | 53 | link.lines = [] |
54 | 54 | ||
55 | // Hover link for LeaderLine | 55 | // Hover link for LeaderLine |
56 | link.onmouseover = () => getMarkersFromMaps(link) | 56 | link.onmouseover = () => getMarkersByGeoLink(link) |
57 | .filter(isAnchorVisible) | 57 | .filter(isAnchorVisible) |
58 | .forEach(anchor => { | 58 | .forEach(anchor => { |
59 | const labelText = new URL(link).searchParams.get('text') ?? link.textContent | 59 | const labelText = new URL(link).searchParams.get('text') ?? link.textContent |
@@ -78,7 +78,7 @@ export const GeoLink = (link) => { | |||
78 | link.onclick = (event) => { | 78 | link.onclick = (event) => { |
79 | event.preventDefault() | 79 | event.preventDefault() |
80 | removeLeaderLines(link) | 80 | removeLeaderLines(link) |
81 | getMarkersFromMaps(link).forEach(marker => { | 81 | getMarkersByGeoLink(link).forEach(marker => { |
82 | const map = marker.closest('.mapclay') | 82 | const map = marker.closest('.mapclay') |
83 | map.scrollIntoView({ behavior: 'smooth' }) | 83 | map.scrollIntoView({ behavior: 'smooth' }) |
84 | updateMapCameraByMarker([ | 84 | updateMapCameraByMarker([ |
@@ -93,7 +93,7 @@ export const GeoLink = (link) => { | |||
93 | if (e.which !== 2) return | 93 | if (e.which !== 2) return |
94 | e.preventDefault() | 94 | e.preventDefault() |
95 | removeLeaderLines(link) | 95 | removeLeaderLines(link) |
96 | getMarkersFromMaps(link) | 96 | getMarkersByGeoLink(link) |
97 | .forEach(marker => marker.remove()) | 97 | .forEach(marker => marker.remove()) |
98 | } | 98 | } |
99 | 99 | ||
@@ -101,44 +101,56 @@ export const GeoLink = (link) => { | |||
101 | } | 101 | } |
102 | 102 | ||
103 | /** | 103 | /** |
104 | * GeoLink: getMarkersFromMaps. Get marker elements by GeoLink | 104 | * GeoLink: getMarkersFromMaps. Get marker elements from maps |
105 | * | 105 | * |
106 | * @param {GeoLink} link | 106 | * @param {Number[]} xy - xy values of marker |
107 | * @param {string} options.type - type of marker | ||
108 | * @param {string} options.title - title of marker | ||
109 | * @param {Function} options.filter - filter of map elements | ||
107 | * @return {HTMLElement[]} markers | 110 | * @return {HTMLElement[]} markers |
108 | */ | 111 | */ |
109 | export const getMarkersFromMaps = (link) => { | 112 | export const getMarkersFromMaps = (xy, { type = 'pin', title, filter = () => true }) => { |
110 | const params = new URLSearchParams(link.search) | ||
111 | const maps = Array.from( | 113 | const maps = Array.from( |
112 | link.closest('.Dumby') | 114 | document.querySelector('.Dumby') |
113 | .querySelectorAll('.mapclay[data-render="fulfilled"]'), | 115 | .querySelectorAll('.mapclay[data-render="fulfilled"]'), |
114 | ) | 116 | ) |
115 | return maps | 117 | return maps |
116 | .filter(map => link.targets ? link.targets.includes(map.id) : true) | 118 | .filter(filter) |
117 | .map(map => { | 119 | .map(map => { |
118 | const renderer = map.renderer | 120 | const renderer = map.renderer |
119 | const lonLat = [Number(link.dataset.lon), Number(link.dataset.lat)] | ||
120 | const type = params.get('type') ?? 'pin' | ||
121 | const svg = markers[type] | 121 | const svg = markers[type] |
122 | const element = document.createElement('div') | 122 | const element = document.createElement('div') |
123 | element.style.cssText = `width: ${svg.size[0]}px; height: ${svg.size[1]}px;` | 123 | element.style.cssText = `width: ${svg.size[0]}px; height: ${svg.size[1]}px;` |
124 | element.innerHTML = svg.html | 124 | element.innerHTML = svg.html |
125 | 125 | ||
126 | const marker = map.querySelector(`.marker[data-xy="${lonLat}"]`) ?? | 126 | const marker = map.querySelector(`.marker[data-xy="${xy}"]`) ?? |
127 | renderer.addMarker({ | 127 | renderer.addMarker({ xy, element, type, anchor: svg.anchor, size: svg.size }) |
128 | xy: lonLat, | 128 | marker.dataset.xy = xy |
129 | element, | 129 | marker.title = title |
130 | type, | ||
131 | anchor: svg.anchor, | ||
132 | size: svg.size, | ||
133 | }) | ||
134 | marker.dataset.xy = lonLat | ||
135 | marker.title = link.textContent | ||
136 | 130 | ||
137 | return marker | 131 | return marker |
138 | }) | 132 | }) |
139 | } | 133 | } |
140 | 134 | ||
141 | /** | 135 | /** |
136 | * GeoLink: getMarkersByGeoLink. Get marker elements by GeoLink | ||
137 | * | ||
138 | * @param {GeoLink} link | ||
139 | * @return {HTMLElement[]} markers | ||
140 | */ | ||
141 | export const getMarkersByGeoLink = (link) => { | ||
142 | const params = new URLSearchParams(link.search) | ||
143 | const type = params.get('type') ?? 'pin' | ||
144 | const lonLat = [Number(link.dataset.lon), Number(link.dataset.lat)] | ||
145 | |||
146 | return getMarkersFromMaps(lonLat, { | ||
147 | type, | ||
148 | title: link.textContent, | ||
149 | filter: map => !link.targets || link.targets.includes(map.id), | ||
150 | }) | ||
151 | } | ||
152 | |||
153 | /** | ||
142 | * DocLink: append DocLink features onto anchor element | 154 | * DocLink: append DocLink features onto anchor element |
143 | * @param {HTMLAnchorElement} link | 155 | * @param {HTMLAnchorElement} link |
144 | * @return {DocLink} | 156 | * @return {DocLink} |
@@ -213,7 +225,7 @@ const isAnchorVisible = anchor => { | |||
213 | * @param {Number[]} xy | 225 | * @param {Number[]} xy |
214 | * @return {Function} function | 226 | * @return {Function} function |
215 | */ | 227 | */ |
216 | const updateMapCameraByMarker = lonLat => marker => { | 228 | export const updateMapCameraByMarker = lonLat => marker => { |
217 | const renderer = marker.closest('.mapclay')?.renderer | 229 | const renderer = marker.closest('.mapclay')?.renderer |
218 | renderer.updateCamera({ center: lonLat }, true) | 230 | renderer.updateCamera({ center: lonLat }, true) |
219 | } | 231 | } |
diff --git a/src/MenuItem.mjs b/src/MenuItem.mjs index 13dbc44..84a1405 100644 --- a/src/MenuItem.mjs +++ b/src/MenuItem.mjs | |||
@@ -439,9 +439,9 @@ export const setGeoLinkTypeItem = ({ link, type, ...others }) => { | |||
439 | params.set('type', type) | 439 | params.set('type', type) |
440 | link.search = params | 440 | link.search = params |
441 | removeLeaderLines(link) | 441 | removeLeaderLines(link) |
442 | getMarkersFromMaps(link) | 442 | getMarkersByGeoLink(link) |
443 | .forEach(marker => marker.remove()) | 443 | .forEach(marker => marker.remove()) |
444 | getMarkersFromMaps(link) | 444 | getMarkersByGeoLink(link) |
445 | }, | 445 | }, |
446 | }) | 446 | }) |
447 | } | 447 | } |
diff --git a/src/dumbymap.mjs b/src/dumbymap.mjs index 9bc1da7..77f3515 100644 --- a/src/dumbymap.mjs +++ b/src/dumbymap.mjs | |||
@@ -6,7 +6,7 @@ import MarkdownItInjectLinenumbers from 'markdown-it-inject-linenumbers' | |||
6 | import * as mapclay from 'mapclay' | 6 | import * as mapclay from 'mapclay' |
7 | import { onRemove, animateRectTransition, throttle, debounce, shiftByWindow } from './utils' | 7 | import { onRemove, animateRectTransition, throttle, debounce, shiftByWindow } from './utils' |
8 | import { Layout, SideBySide, Overlay, Sticky } from './Layout' | 8 | import { Layout, SideBySide, Overlay, Sticky } from './Layout' |
9 | import { GeoLink, DocLink, getMarkersFromMaps } from './Link.mjs' | 9 | import { GeoLink, DocLink, getMarkersByGeoLink } from './Link.mjs' |
10 | import * as utils from './dumbyUtils' | 10 | import * as utils from './dumbyUtils' |
11 | import * as menuItem from './MenuItem' | 11 | import * as menuItem from './MenuItem' |
12 | import PlainModal from 'plain-modal' | 12 | import PlainModal from 'plain-modal' |
@@ -584,7 +584,7 @@ export const generateMaps = (container, { | |||
584 | menu.appendChild(menuItem.Item({ | 584 | menu.appendChild(menuItem.Item({ |
585 | innerHTML: '<strong style="color: red;">DELETE</strong>', | 585 | innerHTML: '<strong style="color: red;">DELETE</strong>', |
586 | onclick: () => { | 586 | onclick: () => { |
587 | getMarkersFromMaps(geoLink) | 587 | getMarkersByGeoLink(geoLink) |
588 | .forEach(m => m.remove()) | 588 | .forEach(m => m.remove()) |
589 | geoLink.replaceWith( | 589 | geoLink.replaceWith( |
590 | document.createTextNode(geoLink.textContent), | 590 | document.createTextNode(geoLink.textContent), |
@@ -595,7 +595,7 @@ export const generateMaps = (container, { | |||
595 | menu.appendChild(menuItem.Item({ | 595 | menu.appendChild(menuItem.Item({ |
596 | innerHTML: '<strong style="color: red;">DELETE</strong>', | 596 | innerHTML: '<strong style="color: red;">DELETE</strong>', |
597 | onclick: () => { | 597 | onclick: () => { |
598 | getMarkersFromMaps(geoLink) | 598 | getMarkersByGeoLink(geoLink) |
599 | .forEach(m => m.remove()) | 599 | .forEach(m => m.remove()) |
600 | 600 | ||
601 | const sibling = [ | 601 | const sibling = [ |