From 125f6e3057a16c15c4fe6e379bce601af3cfa0c5 Mon Sep 17 00:00:00 2001 From: Hsieh Chin Fan Date: Thu, 24 Oct 2024 21:41:09 +0800 Subject: feat: patch 14f1398, more marker type * add module 'marker' for svg markers, they are from https://labs.mapbox.com/maki-icons/editor/ * use grid layout and title for menu itmes * update mapclay version to use element for adding marker --- src/Link.mjs | 11 ++++- src/MenuItem.mjs | 25 +++++++---- src/marker.mjs | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 160 insertions(+), 9 deletions(-) create mode 100644 src/marker.mjs (limited to 'src') diff --git a/src/Link.mjs b/src/Link.mjs index 61aa5f8..2ff1123 100644 --- a/src/Link.mjs +++ b/src/Link.mjs @@ -1,5 +1,6 @@ import LeaderLine from 'leader-line' import { insideWindow, insideParent } from './utils' +import * as markers from './marker.mjs' /** VAR: pattern for coodinates */ export const coordPattern = /^geo:([-]?[0-9.]+),([-]?[0-9.]+)/ @@ -106,11 +107,19 @@ export class GeoLink extends window.HTMLAnchorElement { .map(map => { const renderer = map.renderer const lonLat = [Number(this.dataset.lon), Number(this.dataset.lat)] + const type = params.get('type') ?? 'pin' + const svg = markers[type] + const element = document.createElement('div') + element.style.cssText = `width: ${svg.size[0]}px; height: ${svg.size[1]}px;` + element.innerHTML = svg.html const marker = map.querySelector(`.marker[data-xy="${lonLat}"]`) ?? renderer.addMarker({ xy: lonLat, - type: params.get('type') ?? null, + element, + type, + anchor: svg.anchor, + size: svg.size, }) marker.dataset.xy = lonLat marker.title = new URLSearchParams(this.search).get('xy') ?? lonLat diff --git a/src/MenuItem.mjs b/src/MenuItem.mjs index 912080b..64e82d1 100644 --- a/src/MenuItem.mjs +++ b/src/MenuItem.mjs @@ -1,5 +1,6 @@ import { shiftByWindow } from './utils.mjs' import { GeoLink, removeLeaderLines } from './Link.mjs' +import * as markers from './marker.mjs' /** * @typedef {Object} RefLink @@ -59,7 +60,7 @@ export class Folder extends window.HTMLDivElement { * @param {string} [options.innerHTML] - The HTML content of the folder * @param {Item[]} options.items - The submenu items */ - constructor ({ text, innerHTML, items }) { + constructor ({ text, innerHTML, items, style }) { super() this.innerHTML = innerHTML ?? text this.classList.add('folder', 'menu-item') @@ -70,7 +71,7 @@ export class Folder extends window.HTMLDivElement { const submenu = document.createElement('div') submenu.className = 'sub-menu' const offset = this.items.length > 1 ? '-20px' : '0px' - submenu.style.cssText = `position: absolute; left: 105%; top: ${offset};` + submenu.style.cssText = `${style ?? ''}position: absolute; left: 105%; top: ${offset};` this.items.forEach(item => submenu.appendChild(item)) submenu.onmouseleave = () => submenu.remove() @@ -435,10 +436,10 @@ export const addRefLink = (cm, refLinks) => * @param {String} text * @param {String} type */ -export const setGeoLinkTypeItem = ({ link, text, type }) => { +export const setGeoLinkTypeItem = ({ link, type, ...others }) => { const params = new URLSearchParams(link.search) return new Item({ - text, + ...others, className: ['keep-menu'], onclick: () => { params.set('type', type) @@ -458,8 +459,16 @@ export const setGeoLinkTypeItem = ({ link, text, type }) => { */ export const setGeoLinkType = (link) => new Folder({ text: 'Marker Type', - items: [ - setGeoLinkTypeItem({ link, text: 'Pin', type: 'pin' }), - setGeoLinkTypeItem({ link, text: 'Circle', type: 'circle' }), - ], + style: 'min-width: unset; display: grid; grid-template-columns: repeat(5, 1fr);', + items: Object.entries(markers) + .sort(([, a], [, b]) => (a.order ?? 9999) > (b.order ?? 9999)) + .map(([key, value]) => { + return setGeoLinkTypeItem({ + link, + title: key.at(0).toUpperCase() + key.slice(1), + innerHTML: value.html, + type: key, + style: 'min-width: unset; width: fit-content; padding: 10px; margin: auto auto;', + }) + }), }) diff --git a/src/marker.mjs b/src/marker.mjs new file mode 100644 index 0000000..7eb5148 --- /dev/null +++ b/src/marker.mjs @@ -0,0 +1,133 @@ +export const pin = { + order: 1, + html: '', + size: [27, 41], + anchor: [13.5, 35.25], +} + +export const circle = { + order: 2, + html: ' ', + size: [20, 20], + anchor: [10, 10], +} + +export const water = { + html: '', + size: [27, 27], + anchor: [13.5, 13.5], +} + +export const campsite = { + html: '', + size: [27, 27], + anchor: [13.5, 13.5], +} + +export const caution = { + html: '', + size: [27, 27], + anchor: [13.5, 13.5], +} + +export const communication = { + html: '', + size: [27, 27], + anchor: [13.5, 13.5], +} + +export const cross = { + html: '', + size: [27, 27], + anchor: [13.5, 13.5], +} + +export const construction = { + html: '', + size: [27, 27], + anchor: [13.5, 13.5], +} + +export const danger = { + html: ' ', + size: [27, 27], + anchor: [13.5, 13.5], +} + +export const fence = { + html: '', + size: [27, 27], + anchor: [13.5, 13.5], +} + +export const heliport = { + html: '', + size: [27, 27], + anchor: [13.5, 13.5], +} + +export const hot_spring = { + html: '', + size: [27, 27], + anchor: [13.5, 13.5], +} + +export const mountain = { + html: ' ', + size: [27, 27], + anchor: [13.5, 13.5], +} + +export const parking = { + html: '', + size: [27, 27], + anchor: [13.5, 13.5], +} + +export const rail = { + html: '', + size: [27, 27], + anchor: [13.5, 13.5], +} + +export const racetrack = { + html: '', + size: [27, 27], + anchor: [13.5, 13.5], +} + +export const roladblock = { + html: '', + size: [27, 27], + anchor: [13.5, 13.5], +} + +export const star = { + html: '', + size: [27, 27], + anchor: [13.5, 13.5], +} + +export const animal = { + html: '', + size: [27, 27], + anchor: [13.5, 13.5], +} + +export const waterfall = { + html: '', + size: [27, 27], + anchor: [13.5, 13.5], +} + +export const triangle = { + html: '', + size: [27, 27], + anchor: [13.5, 13.5], +} + +export const triangle_white = { + html: '', + size: [27, 27], + anchor: [13.5, 13.5], +} -- cgit v1.2.3-70-g09d2