maparea 0.1.24 → 0.1.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- const{PI:e}=Math,t=e/180,n=180/e,r={spherical:0,ellipsoidal:.0818191908426},i=-85.05,a=85.05,o=-180,s=180,{PI:c,sin:l,tan:u,atan:d,pow:f,exp:p,log:m,abs:h}=Math;var g=class{_p;_c;_cc;_r=new Set;constructor(e){this._p=e,this.container.style=`position: relative; overflow: hidden; touch-action: none;`,this.container.dataset.role=`maparea`}render(){for(let e of this._r)e(this)}onRender(e,t=!1){return this._r.add(e),t||e(this),()=>{this._r.delete(e)}}getOptions(){return{...this._p,center:this.center,bounds:this.bounds}}setOptions(e){this._p={...this._p,...e},`container`in e&&delete this._c,delete this._cc,this.render()}get container(){if(!this._c){let e=document.querySelector(this._p.container);if(!e)throw Error(`missing container element`);this._c=e}return this._c}get box(){let e=this.container.getBoundingClientRect();return{x:e.left,y:e.top,w:e.width,h:e.height}}get bounds(){let e=this._p.bounds;return e?{...e}:{}}set bounds(e){this._p.bounds=e}get center(){let e=this._p.center;return e?e.slice():[0,0]}set center(e){this._p.center=e,delete this._cc,this.render()}get centerCoords(){if(!this._cc){let[e,t]=this.center;this._cc=this.toPixelCoords(e,t)}return this._cc}get zoom(){return this._p.zoom??this._p.minZoom??0}set zoom(e){let{minZoom:t,maxZoom:n}=this,r=e;e<t&&(r=t),e>n&&(r=n),this._p.zoom=r,delete this._cc,this.render()}get minZoom(){return this._p.minZoom??-1/0}set minZoom(e){this._p.minZoom=e,this.zoom<this.minZoom&&(this.zoom=this.minZoom)}get maxZoom(){return this._p.maxZoom??1/0}set maxZoom(e){this._p.maxZoom=e,this.zoom>this.maxZoom&&(this.zoom=this.maxZoom)}get projection(){return this._p.projection??`spherical`}set projection(e){this._p.projection=e,this.render()}get lang(){return this._p.lang??``}set lang(e){this._p.lang=e,this.render()}inPixelBounds(e,t){let[n,r]=this.toGeoCoords(e,t);return this.inBounds(n,r)}inBounds(e,t){let{minLat:n=i,maxLat:r=a,minLon:s=o,maxLon:c=180}=this.bounds;return e>=n&&e<=r&&t>=s&&t<=c}canMoveTo(e,t){if(!this.inBounds(e,t))return!1;let{w:n,h:r}=this.box;if(n===0||r===0)return!1;let[i,a]=this.toPixelCoords(e,t);return this.inPixelBounds(i-n/2,a-r/2)&&this.inPixelBounds(i+n/2,a+r/2)}toPixelCoords(e,n){let i=r[this.projection],a=f(2,this.zoom+7)/c,o=e*t,s=i===0?1:f((1-i*l(o))/(1+i*l(o)),i/2);return[a*(c+n*t),a*(c-m(s*u(c/4+o/2)))]}toGeoCoords(e,t){let o=r[this.projection],s=f(2,this.zoom+7)/c,l=(e/s-c)*n,u;if(o===0)u=2*(d(p(c-t/s))-c/4)*n;else{u=i;let e=a-i,n=NaN,r=0;for(;(Number.isNaN(n)||h(n-t)>.1)&&r++<30;)e/=2,n=this.toPixelCoords(u+e,l)[1],n>t&&(u+=e)}return(l<-180||l>=180)&&(l=(l+180)%360-180),(u<-90||u>=90)&&(u=(u+90)%180-90),[u,l]}};function _(){return Math.random().toString(36).slice(2)}function v(e,{id:t,className:n,inset:r=`0`}={}){let i=`${n?`.${n}`:``}${t?`[data-id="${t}"]`:``}`,a=e.container.querySelector(i);return a||(a=document.createElement(`div`),a.className=`${n?`${n} `:``}layer`,a.dataset.id=t??_(),a.style=`position: absolute; inset: ${r};`,e.container.append(a)),a}function y(e,t){return t===void 0?t:t instanceof Function?t(e):t}function b(e,t){return e.toFixed(t).replace(/\.(\d*[^0])0+$/,`.$1`).replace(/\.0+$/,``)}function x(e,t,{className:n,coords:r,inset:i,layer:a,content:o}){let s=a??v(e,{className:`elements`});n&&t.setAttribute(`class`,n),t.style.position=`absolute`,s.append(t),e.onRender(()=>{if(i)t.style.inset=y(e,i)??``;else if(r){let{centerCoords:[n,i],box:{w:a,h:o}}=e,[s,c]=e.toPixelCoords(...r),l=b(s-n+a/2,2),u=b(c-i+o/2,2);t.style.transform=`translate3d(${l}px, ${u}px, 0)`}if(o){let n=y(e,o)??``;t.innerHTML!==n&&(t.innerHTML=n)}})}function S(e,t){return t===void 0||!(e instanceof HTMLElement)?!1:typeof t==`function`&&t(e)||typeof t==`string`&&e.closest(t)!==null}function C(e,{onStart:t,onMove:n,onEnd:r,wheel:i,ignore:a}={}){let o=null,s=null,c=Date.now(),l=null,u=null,d=!1,f=!1,p=0,m=0,h=0;function g(t,r){m+=t,h+=r,o!==null&&(o-=t),s!==null&&(s-=r),!f&&!e.dataset.dragged&&(e.dataset.dragged=`true`);let i=Date.now(),a=f?10:100;(m!==0||h!==0)&&i-c>=a&&(l&&cancelAnimationFrame(l),l=requestAnimationFrame(()=>{n?.(m,h),m=0,h=0,c=i,l=null}))}function _(e,t){o!==null&&s!==null&&g(o-e,s-t)}function v(e,n){u!==null&&(clearTimeout(u),f=!1,u=null),d=!0,t?.(),e!==void 0&&(o=e),n!==void 0&&(s=n),c=Date.now(),m=0,h=0}function y(t,n){d=!1,t!==void 0&&n!==void 0&&_(t,n),delete e.dataset.dragged,o=null,s=null,r?.()}e.dataset.draggable=`true`;function b(e){return!S(e.target,a)&&p===1}function x(e){p++,b(e)&&(e.preventDefault(),v(e.pageX,e.pageY))}function C(e){b(e)&&(e.preventDefault(),_(e.pageX,e.pageY))}function w(e){b(e)&&(e.preventDefault(),y(e.pageX,e.pageY)),p=0}function T(e){S(e.target,a)||(e.preventDefault(),d||(v(),f=!0),e.shiftKey?g(e.deltaY,e.deltaX):g(e.deltaX,e.deltaY),u!==null&&clearTimeout(u),u=setTimeout(()=>{y(),f=!1,u=null},200))}return e.addEventListener(`pointerdown`,x),e.addEventListener(`pointermove`,C),e.addEventListener(`pointerup`,w),e.addEventListener(`pointercancel`,w),i&&e.addEventListener(`wheel`,T),()=>{e.removeEventListener(`pointerdown`,x),e.removeEventListener(`pointermove`,C),e.removeEventListener(`pointerup`,w),e.removeEventListener(`pointercancel`,w),i&&e.removeEventListener(`wheel`,T)}}function w(e,{wheel:t=!0,ignore:n}={}){let r=0,i=0;C(e.container,{onStart(){[r,i]=e.centerCoords},onMove(t,n){let a=r+t,o=i+n,s=e.toGeoCoords(a,o);e.canMoveTo(...s)&&(e.center=s,r=a,i=o)},wheel:t,ignore:n})}function T(e,{storageKey:t,session:n=!1}={}){let r=n?window.sessionStorage:window.localStorage,i=t??[`maparea`,e.container.id].filter(Boolean).join(`#`),a=e.getOptions(),o=!1,s=()=>{try{r.setItem(i,JSON.stringify(e.getOptions()))}catch{}},c=()=>{try{let t=r.getItem(i);t===null?s():e.setOptions(JSON.parse(t))}catch{}},l=e=>{o=e===void 0?!o:e},u=()=>{e.setOptions(a)};c();let d=null;return e.onRender(()=>{o||(d&&=(clearTimeout(d),null),d=setTimeout(()=>{d=null,s()},350))}),{sync:c,write:s,toggle:l,reset:u}}const{hypot:ee,log2:E,abs:D,trunc:O}=Math;function k({clientX:e,clientY:t},{clientX:n,clientY:r}){return ee(n-e,r-t)}function A({clientX:e,clientY:t},{clientX:n,clientY:r}){return[(e+n)/2,(t+r)/2]}const te=1.2;function ne(e,{pace:t=1.2}={}){let{container:n}=e,r=null,i=null,a=0;function o(e){return e.touches.length===2}function s(t){o(t)&&(t.preventDefault(),r=k(t.touches[0],t.touches[1]),i=e.zoom,a=0)}let c=null;function l(n){if(o(n)&&r!==null&&r!==0&&i!==null){n.preventDefault();let i=E(k(n.touches[0],n.touches[1])/r)/E(t)-a;if(D(i)>=1){let{box:{x:t,y:r,w:o,h:s},centerCoords:[l,u]}=e,[d,f]=A(n.touches[0],n.touches[1]),p=d-o/2-t,m=f-s/2-r,[h,g]=e.toGeoCoords(l+p,u+m),_=O(i);c&&cancelAnimationFrame(c),c=requestAnimationFrame(()=>{e.zoom+=_,a+=_;let[t,n]=e.toPixelCoords(h,g),[r,i]=e.centerCoords;t-=r,n-=i;let o=t-p,s=n-m;e.center=e.toGeoCoords(r+o,i+s)})}}}return n.addEventListener(`touchstart`,s),n.addEventListener(`touchmove`,l),()=>{n.removeEventListener(`touchstart`,s),n.removeEventListener(`touchmove`,l)}}function j(e,t,{ignore:n}={}){let r=null,i=null,a=Date.now(),o=e=>{r=e.clientX,i=e.clientY,a=Date.now()},s=o=>{if(S(o.target,n)||r===null||i===null||Date.now()-a>150)return;let{box:s,centerCoords:[c,l]}=e,u=r-s.x,d=i-s.y,[f,p]=e.toGeoCoords(u-.5*s.w+c,d-.5*s.h+l);t({x:u,y:d,lat:f,lon:p,originalEvent:o}),r=null,i=null};return e.container.addEventListener(`pointerdown`,o),e.container.addEventListener(`pointerup`,s),e.container.addEventListener(`pointercancel`,s),()=>{e.container.removeEventListener(`pointerdown`,o),e.container.removeEventListener(`pointerup`,s),e.container.removeEventListener(`pointercancel`,s)}}function M(e,t){let n=new ResizeObserver(n=>{for(let r of n)if(r.contentBoxSize){if(t)if(r.contentBoxSize){let{inlineSize:e,blockSize:n}=r.contentBoxSize[0]??r.contentBoxSize;t({inlineSize:e,blockSize:n})}else{let{width:e,height:n}=r.contentRect;t({width:e,height:n})}e.render()}});return n.observe(e.container),()=>{n.unobserve(e.container)}}const N=`http://www.w3.org/2000/svg`;function P(e){return parseFloat(window.getComputedStyle(e).strokeWidth||e.getAttribute(`stroke-width`)||`1`)}function F(e,t,n){if(t.length===0){e.innerHTML=``;return}let r=e.querySelector(`path`);r||(r=document.createElementNS(N,`path`),e.append(r));let i=t[0].coords[0],a=i,o=t[0].coords[1],s=o,c=``;for(let{coords:[e,n]}of t)i>e&&(i=e),a<e&&(a=e),o>n&&(o=n),s<n&&(s=n);i-=10,a+=10,o-=10,s+=10;let l=Array.from(e.querySelectorAll(`.marker`)),u=0;for(let{id:a,coords:[s,d]}of t){let t=b(s-i,3),f=b(d-o,3);if(c+=`${c?` L`:`M`} ${t} ${f}`,n?.markers){let n=l[u++];n||(n=document.createElementNS(N,`circle`),n.setAttribute(`class`,`marker`),n.setAttribute(`r`,String(1.5*P(r))),e.append(n)),n.setAttribute(`cx`,t),n.setAttribute(`cy`,f),n.dataset.id=a}}for(let e=u;e<l.length;e++)l[e].remove();return r.setAttribute(`d`,c),{xMin:i,xMax:a,yMin:o,yMax:s}}function I(e,t,n){let r=n?.layer??v(e,{className:`shape`});r.toggleAttribute(`hidden`,t.length===0);let i=r.querySelector(`svg`);i||(i=document.createElementNS(N,`svg`),i.setAttribute(`xmlns`,N),r.append(i));let a=F(i,t.map(({id:t,coords:[n,r]})=>({id:t,coords:e.toPixelCoords(n,r)})),n);if(a){let{xMin:t,xMax:n,yMin:r,yMax:o}=a,{centerCoords:[s,c],box:l}=e,u=b(n-t,3),d=b(o-r,3),f=b(.5*l.w+t-s,2),p=b(.5*l.h+r-c,2);i.setAttribute(`viewBox`,`0 0 ${u} ${d}`),i.setAttribute(`width`,u),i.setAttribute(`height`,d),i.setAttribute(`style`,`position: absolute; transform: translate3d(${f}px, ${p}px, 0);`)}return r}function re(e,t,n){let r=t.map(e=>({id:_(),coords:e}));return e.onRender(()=>{I(e,r,n)}),{remove:()=>{r=[],I(e,r,n)}}}function ie(e,t){let n=[],r=null,i={layer:v(e,{className:`shape-editor`}),markers:!0},a=()=>{I(e,n,i),t?.onUpdate?.(n)};return j(e,({lat:e,lon:t,originalEvent:i})=>{let o=(i.target?.closest(`.marker`))?.dataset.id;if(o&&r){clearTimeout(r),r=null,n=n.filter(({id:e})=>e!==o),a();return}let s=()=>{n.push({id:_(),coords:[e,t]}),a(),r=null};o?r=setTimeout(s,250):s()},{ignore:t?.ignore}),e.onRender(a),{reset:()=>{n=[],a()}}}const{floor:L,ceil:R,random:z}=Math,ae=256;function B(e,t,n){return`${t},${n},${e.zoom},${e.lang}`}function V(e){let t=e.target;t instanceof HTMLImageElement&&(t.style.opacity=``)}function H(e,t,n,{size:r,url:i,subdomains:a,retries:o=0,error:s}){let c=new Image,l=y(e,r)??256,u=0,d=(r,o)=>{if(!i)return``;if(typeof i==`function`)return i(e,t,n);let s=i.replaceAll(`{x}`,String(r)).replaceAll(`{y}`,String(o)).replaceAll(`{z}`,String(e.zoom)).replaceAll(`{lang}`,e.lang);return a&&s.includes(`{s}`)&&(s=s.replaceAll(`{s}`,a[L(a.length*z())])),s},f=t=>{let n=t.target;if(n instanceof HTMLImageElement){if(u++<o){let e=new URL(n.src);e.searchParams.set(`_t`,String(Date.now())),n.src=e.href;return}let t=y(e,s);t&&(n.dataset.src=n.src,n.src=t),c.removeEventListener(`error`,f)}};return c.width=l,c.height=l,c.src=d(t,n),c.dataset.id=B(e,t,n),c.style.position=`absolute`,c.addEventListener(`load`,V),c.addEventListener(`error`,f),c.complete||(c.style.opacity=`0`),c}function U(e){return e.querySelectorAll(`img[data-id]`)}function W(e,t){return e.querySelector(`img[data-id="${t}"]`)}function G(e,t={}){let{attribution:n,attributionInset:r=`auto 0 0 auto`}=t,i=t.layer??v(e,{className:`tiles`}),a=v(e,{id:i.dataset.id,className:`tiles-attribution`,inset:r}),o=()=>{let{box:{w:r,h:o},centerCoords:[s,c]}=e,{size:l,margin:u=0}=t,d=y(e,l)??256,f=Array.isArray(u)?u[0]:u,p=Array.isArray(u)?u[1]:u,m=R((r+2*f)/d),h=R((o+2*p)/d),g=L(s/d),_=L(c/d),v=null,x=new Set,S=``;for(let n=0;n<=m;n++){let a=g+(n%2==0?-1:1)*L(n/2);for(let n=0;n<=h;n++){let l=_+(n%2==0?-1:1)*L(n/2);S=B(e,a,l),v=W(i,S),v||(v=H(e,a,l,t),i.append(v));let u=b(.5*r+a*d-s,2),f=b(.5*o+l*d-c,2);v.style.transform=`translate3d(${u}px, ${f}px, 0)`,x.add(S)}}for(let e of U(i)){let{id:t}=e.dataset;t&&!x.has(t)&&e.remove()}let C=y(e,n)??``;a.toggleAttribute(`hidden`,!C),a.innerHTML!==C&&(a.innerHTML=C)},s=e.zoom,c=null;return e.onRender(()=>{c!==null&&(clearTimeout(c),c=null),e.zoom===s?(i.style.opacity&&(i.style.opacity=``),o()):(i.style.opacity=`0`,c=setTimeout(()=>{c=null,i.style.opacity&&(i.style.opacity=``),o()},300)),s=e.zoom}),i}function K(e,t={}){let{zoomIn:n=`➕`,zoomOut:r=`➖`}=t,i=document.createElement(`fieldset`);i.dataset.role=`zoom`;let a=document.createElement(`button`);a.dataset.role=`zoomin`,a.innerHTML=n;let o=document.createElement(`button`);o.dataset.role=`zoomout`,o.innerHTML=r;let s=()=>{a.toggleAttribute(`disabled`,e.zoom+1>e.maxZoom),o.toggleAttribute(`disabled`,e.zoom-1<e.minZoom)};return j(e,({originalEvent:t})=>{let n=t.target;n instanceof HTMLButtonElement&&i.contains(n)&&(e.zoom+=n.dataset.role===`zoomout`?-1:1,s())}),e.onRender(s),i.append(a,o),i}function q(e,t={}){let n=K(e,t),r=v(e,{className:`controls`,inset:t.inset??`0 0 auto auto`});return r.append(n),r}function J(e){if(e.length===0)return{};let t=e[0][0],n=t,r=e[0][1],i=r;for(let[a,o]of e)t>a&&(t=a),n<a&&(n=a),r>o&&(r=o),i<o&&(i=o);return{minLat:t,maxLat:n,minLon:r,maxLon:i}}function Y(e){return Array.isArray(e)&&e.length===2&&typeof e[0]==`number`&&typeof e[1]==`number`}function X(e){return Y(e)?{minLat:e[0],maxLat:e[0],minLon:e[1],maxLon:e[1]}:Array.isArray(e)?J(e):e}function Z(e){let{minLat:t,maxLat:n,minLon:r,maxLon:i}=X(e);return[t===void 0||n===void 0?0:(n+t)/2,r===void 0||i===void 0?0:(i+r)/2]}const{abs:Q,log2:$,min:oe,floor:se}=Math;function ce(e,t){let{box:{w:n,h:r},center:[i,a],zoom:o}=e,{minLat:s,maxLat:c,minLon:l,maxLon:u}=t,d=0,f=0;if(l!==void 0&&u!==void 0){let t=Q(e.toPixelCoords(i,u)[0]-e.toPixelCoords(i,l)[0]);t!==0&&(d=$(n/t))}if(s!==void 0&&c!==void 0){let t=Q(e.toPixelCoords(s,a)[1]-e.toPixelCoords(c,a)[1]);t!==0&&(f=$(r/t))}let p=se(oe(o+d,o+f)),m={center:Z(t)};p!==o&&(m.zoom=p),e.setOptions(m)}const le=[.005,.018];function ue(e,t=le){let{minLat:n=0,maxLat:r=0,minLon:i=0,maxLon:a=0}=X(e),[o,s]=t;return{minLat:n-o,maxLat:r+o,minLon:i-s,maxLon:a+s}}exports.DEG=n,exports.MAX_LAT=a,exports.MAX_LON=180,exports.MIN_LAT=i,exports.MIN_LON=o,exports.MapArea=g,exports.RAD=t,exports.addElement=x,exports.addMovableViewport=w,exports.addPersistence=T,exports.addPinchToZoom=ne,exports.addPointerListener=j,exports.addResizeObserver=M,exports.addShape=re,exports.addShapeEditor=ie,exports.addTiles=G,exports.addZoomControl=q,exports.eccentricityMap=r,exports.fitGeoBounds=ce,exports.getCenter=Z,exports.getGeoBounds=J,exports.getId=_,exports.getLayer=v,exports.getVicinity=ue,exports.getZoomControl=K,exports.isCoordsArray=Y,exports.resolveDynamic=y,exports.toGeoBounds=X,exports.toPrecision=b;
1
+ const{PI:e}=Math,t=e/180,n=180/e,r={spherical:0,ellipsoidal:.0818191908426},i=-85.05,a=85.05,o=-180,s=180,{PI:c,sin:l,tan:u,atan:d,pow:f,exp:p,log:m,abs:h}=Math;var g=class{_p;_c;_cc;_r=new Set;constructor(e){this._p=e,this.container.style=`position: relative; overflow: hidden; touch-action: none;`,this.container.dataset.role=`maparea`}render(){for(let e of this._r)e(this)}onRender(e,t=!1){return this._r.add(e),t||e(this),()=>{this._r.delete(e)}}getOptions(){return{...this._p,center:this.center,bounds:this.bounds}}setOptions(e){this._p={...this._p,...e},`container`in e&&delete this._c,delete this._cc,this.render()}get container(){if(!this._c){let e=document.querySelector(this._p.container);if(!e)throw Error(`missing container element`);this._c=e}return this._c}get box(){let e=this.container.getBoundingClientRect();return{x:e.left,y:e.top,w:e.width,h:e.height}}get bounds(){let e=this._p.bounds;return e?{...e}:{}}set bounds(e){this._p.bounds=e}get center(){let e=this._p.center;return e?e.slice():[0,0]}set center(e){this._p.center=e,delete this._cc,this.render()}get centerCoords(){if(!this._cc){let[e,t]=this.center;this._cc=this.toPixelCoords(e,t)}return this._cc}get zoom(){return this._p.zoom??this.minZoom}set zoom(e){let{minZoom:t,maxZoom:n}=this,r=e;e<t&&(r=t),e>n&&(r=n),this._p.zoom=r,delete this._cc,this.render()}get minZoom(){return this._p.minZoom??0}set minZoom(e){this._p.minZoom=e,this.zoom<this.minZoom&&(this.zoom=this.minZoom)}get maxZoom(){return this._p.maxZoom??20}set maxZoom(e){this._p.maxZoom=e,this.zoom>this.maxZoom&&(this.zoom=this.maxZoom)}get projection(){return this._p.projection??`spherical`}set projection(e){this._p.projection=e,this.render()}get lang(){return this._p.lang??``}set lang(e){this._p.lang=e,this.render()}inPixelBounds(e,t){let[n,r]=this.toGeoCoords(e,t);return this.inBounds(n,r)}inBounds(e,t){let{minLat:n=i,maxLat:r=a,minLon:s=o,maxLon:c=180}=this.bounds;return e>=n&&e<=r&&t>=s&&t<=c}canMoveTo(e,t){if(!this.inBounds(e,t))return!1;let{w:n,h:r}=this.box;if(n===0||r===0)return!1;let[i,a]=this.toPixelCoords(e,t);return this.inPixelBounds(i-n/2,a-r/2)&&this.inPixelBounds(i+n/2,a+r/2)}toPixelCoords(e,n){let i=r[this.projection],a=f(2,this.zoom+7)/c,o=e*t,s=i===0?1:f((1-i*l(o))/(1+i*l(o)),i/2);return[a*(c+n*t),a*(c-m(s*u(c/4+o/2)))]}toGeoCoords(e,t){let o=r[this.projection],s=f(2,this.zoom+7)/c,l=(e/s-c)*n,u;if(o===0)u=2*(d(p(c-t/s))-c/4)*n;else{u=i;let e=a-i,n=NaN,r=0;for(;(Number.isNaN(n)||h(n-t)>.1)&&r++<30;)e/=2,n=this.toPixelCoords(u+e,l)[1],n>t&&(u+=e)}return(l<-180||l>=180)&&(l=(l+180)%360-180),(u<-90||u>=90)&&(u=(u+90)%180-90),[u,l]}};function _(){return Math.random().toString(36).slice(2)}function v(e,{id:t,className:n,inset:r=`0`}={}){let i=`${n?`.${n}`:``}${t?`[data-id="${t}"]`:``}`,a=e.container.querySelector(i);return a||(a=document.createElement(`div`),a.className=`${n?`${n} `:``}layer`,a.dataset.id=t??_(),a.style=`position: absolute; inset: ${r};`,e.container.append(a)),a}function y(e,t){return t===void 0?t:t instanceof Function?t(e):t}function b(e,t){return e.toFixed(t).replace(/\.(\d*[^0])0+$/,`.$1`).replace(/\.0+$/,``)}function x(e,t,{className:n,coords:r,inset:i,layer:a,content:o}){let s=a??v(e,{className:`elements`});n&&t.setAttribute(`class`,n),t.style.position=`absolute`,s.append(t),e.onRender(()=>{if(i)t.style.inset=y(e,i)??``;else if(r){let{centerCoords:[n,i],box:{w:a,h:o}}=e,[s,c]=e.toPixelCoords(...r),l=b(s-n+a/2,2),u=b(c-i+o/2,2);t.style.transform=`translate3d(${l}px, ${u}px, 0)`}if(o){let n=y(e,o)??``;t.innerHTML!==n&&(t.innerHTML=n)}})}function S(e,t){return t===void 0||!(e instanceof HTMLElement)?!1:typeof t==`function`&&t(e)||typeof t==`string`&&e.closest(t)!==null}function C(e,{onStart:t,onMove:n,onEnd:r,wheel:i,ignore:a}={}){let o=null,s=null,c=Date.now(),l=null,u=null,d=!1,f=!1,p=0,m=0,h=0;function g(t,r){m+=t,h+=r,o!==null&&(o-=t),s!==null&&(s-=r),!f&&!e.dataset.dragged&&(e.dataset.dragged=`true`);let i=Date.now(),a=f?10:100;(m!==0||h!==0)&&i-c>=a&&(l&&cancelAnimationFrame(l),l=requestAnimationFrame(()=>{n?.(m,h),m=0,h=0,c=i,l=null}))}function _(e,t){o!==null&&s!==null&&g(o-e,s-t)}function v(e,n){u!==null&&(clearTimeout(u),f=!1,u=null),d=!0,t?.(),e!==void 0&&(o=e),n!==void 0&&(s=n),c=Date.now(),m=0,h=0}function y(t,n){d=!1,t!==void 0&&n!==void 0&&_(t,n),delete e.dataset.dragged,o=null,s=null,r?.()}e.dataset.draggable=`true`;function b(e){return!S(e.target,a)&&p===1}function x(e){p++,b(e)&&(e.preventDefault(),v(e.pageX,e.pageY))}function C(e){b(e)&&(e.preventDefault(),_(e.pageX,e.pageY))}function w(e){b(e)&&(e.preventDefault(),y(e.pageX,e.pageY)),p=0}function T(e){S(e.target,a)||(e.preventDefault(),d||(v(),f=!0),e.shiftKey?g(e.deltaY,e.deltaX):g(e.deltaX,e.deltaY),u!==null&&clearTimeout(u),u=setTimeout(()=>{y(),f=!1,u=null},200))}return e.addEventListener(`pointerdown`,x),e.addEventListener(`pointermove`,C),e.addEventListener(`pointerup`,w),e.addEventListener(`pointercancel`,w),i&&e.addEventListener(`wheel`,T),()=>{e.removeEventListener(`pointerdown`,x),e.removeEventListener(`pointermove`,C),e.removeEventListener(`pointerup`,w),e.removeEventListener(`pointercancel`,w),i&&e.removeEventListener(`wheel`,T)}}function w(e,{wheel:t=!0,ignore:n}={}){let r=0,i=0;C(e.container,{onStart(){[r,i]=e.centerCoords},onMove(t,n){let a=r+t,o=i+n,s=e.toGeoCoords(a,o);e.canMoveTo(...s)&&(e.center=s,r=a,i=o)},wheel:t,ignore:n})}function T(e,{storageKey:t,session:n=!1}={}){let r=n?window.sessionStorage:window.localStorage,i=t??[`maparea`,e.container.id].filter(Boolean).join(`#`),a=e.getOptions(),o=!1,s=()=>{try{r.setItem(i,JSON.stringify(e.getOptions()))}catch{}},c=()=>{try{let t=r.getItem(i);t===null?s():e.setOptions(JSON.parse(t))}catch{}},l=e=>{o=e===void 0?!o:e},u=()=>{e.setOptions(a)};c();let d=null;return e.onRender(()=>{o||(d&&=(clearTimeout(d),null),d=setTimeout(()=>{d=null,s()},350))}),{sync:c,write:s,toggle:l,reset:u}}const{hypot:ee,log2:E,abs:D,trunc:O}=Math;function k({clientX:e,clientY:t},{clientX:n,clientY:r}){return ee(n-e,r-t)}function A({clientX:e,clientY:t},{clientX:n,clientY:r}){return[(e+n)/2,(t+r)/2]}const te=1.2;function ne(e,{pace:t=1.2}={}){let{container:n}=e,r=null,i=null,a=0;function o(e){return e.touches.length===2}function s(t){o(t)&&(t.preventDefault(),r=k(t.touches[0],t.touches[1]),i=e.zoom,a=0)}let c=null;function l(n){if(o(n)&&r!==null&&r!==0&&i!==null){n.preventDefault();let i=E(k(n.touches[0],n.touches[1])/r)/E(t)-a;if(D(i)>=1){let{box:{x:t,y:r,w:o,h:s},centerCoords:[l,u]}=e,[d,f]=A(n.touches[0],n.touches[1]),p=d-o/2-t,m=f-s/2-r,[h,g]=e.toGeoCoords(l+p,u+m),_=O(i);c&&cancelAnimationFrame(c),c=requestAnimationFrame(()=>{e.zoom+=_,a+=_;let[t,n]=e.toPixelCoords(h,g),[r,i]=e.centerCoords;t-=r,n-=i;let o=t-p,s=n-m;e.center=e.toGeoCoords(r+o,i+s)})}}}return n.addEventListener(`touchstart`,s),n.addEventListener(`touchmove`,l),()=>{n.removeEventListener(`touchstart`,s),n.removeEventListener(`touchmove`,l)}}function j(e,t,{ignore:n}={}){let r=null,i=null,a=Date.now(),o=e=>{r=e.clientX,i=e.clientY,a=Date.now()},s=o=>{if(S(o.target,n)||r===null||i===null||Date.now()-a>150)return;let{box:s,centerCoords:[c,l]}=e,u=r-s.x,d=i-s.y,[f,p]=e.toGeoCoords(u-.5*s.w+c,d-.5*s.h+l);t({x:u,y:d,lat:f,lon:p,originalEvent:o}),r=null,i=null};return e.container.addEventListener(`pointerdown`,o),e.container.addEventListener(`pointerup`,s),e.container.addEventListener(`pointercancel`,s),()=>{e.container.removeEventListener(`pointerdown`,o),e.container.removeEventListener(`pointerup`,s),e.container.removeEventListener(`pointercancel`,s)}}function M(e,t){let n=new ResizeObserver(n=>{for(let r of n)if(r.contentBoxSize){if(t)if(r.contentBoxSize){let{inlineSize:e,blockSize:n}=r.contentBoxSize[0]??r.contentBoxSize;t({inlineSize:e,blockSize:n})}else{let{width:e,height:n}=r.contentRect;t({width:e,height:n})}e.render()}});return n.observe(e.container),()=>{n.unobserve(e.container)}}const N=`http://www.w3.org/2000/svg`;function P(e){return parseFloat(window.getComputedStyle(e).strokeWidth||e.getAttribute(`stroke-width`)||`1`)}function F(e,t,n){if(t.length===0){e.innerHTML=``;return}let r=e.querySelector(`path`);r||(r=document.createElementNS(N,`path`),e.append(r));let i=t[0].coords[0],a=i,o=t[0].coords[1],s=o,c=``;for(let{coords:[e,n]}of t)i>e&&(i=e),a<e&&(a=e),o>n&&(o=n),s<n&&(s=n);i-=10,a+=10,o-=10,s+=10;let l=Array.from(e.querySelectorAll(`.marker`)),u=0;for(let{id:a,coords:[s,d]}of t){let t=b(s-i,3),f=b(d-o,3);if(c+=`${c?` L`:`M`} ${t} ${f}`,n?.markers){let n=l[u++];n||(n=document.createElementNS(N,`circle`),n.setAttribute(`class`,`marker`),n.setAttribute(`r`,String(1.5*P(r))),e.append(n)),n.setAttribute(`cx`,t),n.setAttribute(`cy`,f),n.dataset.id=a}}for(let e=u;e<l.length;e++)l[e].remove();return r.setAttribute(`d`,c),{xMin:i,xMax:a,yMin:o,yMax:s}}function I(e,t,n){let r=n?.layer??v(e,{className:`shape`});r.toggleAttribute(`hidden`,t.length===0);let i=r.querySelector(`svg`);i||(i=document.createElementNS(N,`svg`),i.setAttribute(`xmlns`,N),r.append(i));let a=F(i,t.map(({id:t,coords:[n,r]})=>({id:t,coords:e.toPixelCoords(n,r)})),n);if(a){let{xMin:t,xMax:n,yMin:r,yMax:o}=a,{centerCoords:[s,c],box:l}=e,u=b(n-t,3),d=b(o-r,3),f=b(.5*l.w+t-s,2),p=b(.5*l.h+r-c,2);i.setAttribute(`viewBox`,`0 0 ${u} ${d}`),i.setAttribute(`width`,u),i.setAttribute(`height`,d),i.setAttribute(`style`,`position: absolute; transform: translate3d(${f}px, ${p}px, 0);`)}return r}function re(e,t,n){let r=t.map(e=>({id:_(),coords:e}));return e.onRender(()=>{I(e,r,n)}),{remove:()=>{r=[],I(e,r,n)}}}function ie(e,t){let n=[],r=null,i={layer:v(e,{className:`shape-editor`}),markers:!0},a=()=>{I(e,n,i),t?.onUpdate?.(n)};return j(e,({lat:e,lon:t,originalEvent:i})=>{let o=(i.target?.closest(`.marker`))?.dataset.id;if(o&&r){clearTimeout(r),r=null,n=n.filter(({id:e})=>e!==o),a();return}let s=()=>{n.push({id:_(),coords:[e,t]}),a(),r=null};o?r=setTimeout(s,250):s()},{ignore:t?.ignore}),e.onRender(a),{reset:()=>{n=[],a()}}}const{floor:L,ceil:R,random:z}=Math,ae=256;function B(e,t,n){return`${t},${n},${e.zoom},${e.lang}`}function V(e){let t=e.target;t instanceof HTMLImageElement&&(t.style.opacity=``)}function H(e,t,n,{size:r,url:i,subdomains:a,retries:o=0,error:s}){let c=new Image,l=y(e,r)??256,u=0,d=(r,o)=>{if(!i)return``;if(typeof i==`function`)return i(e,t,n);let s=i.replaceAll(`{x}`,String(r)).replaceAll(`{y}`,String(o)).replaceAll(`{z}`,String(e.zoom)).replaceAll(`{lang}`,e.lang);return a&&s.includes(`{s}`)&&(s=s.replaceAll(`{s}`,a[L(a.length*z())])),s},f=t=>{let n=t.target;if(n instanceof HTMLImageElement){if(u++<o){let e=new URL(n.src);e.searchParams.set(`_t`,String(Date.now())),n.src=e.href;return}let t=y(e,s);t&&(n.dataset.src=n.src,n.src=t),c.removeEventListener(`error`,f)}};return c.width=l,c.height=l,c.src=d(t,n),c.dataset.id=B(e,t,n),c.style.position=`absolute`,c.addEventListener(`load`,V),c.addEventListener(`error`,f),c.complete||(c.style.opacity=`0`),c}function U(e){return e.querySelectorAll(`img[data-id]`)}function W(e,t){return e.querySelector(`img[data-id="${t}"]`)}function G(e,t={}){let{attribution:n,attributionInset:r=`auto 0 0 auto`}=t,i=t.layer??v(e,{className:`tiles`}),a=v(e,{id:i.dataset.id,className:`tiles-attribution`,inset:r}),o=()=>{let{box:{w:r,h:o},centerCoords:[s,c]}=e,{size:l,margin:u=0}=t,d=y(e,l)??256,f=Array.isArray(u)?u[0]:u,p=Array.isArray(u)?u[1]:u,m=R((r+2*f)/d),h=R((o+2*p)/d),g=L(s/d),_=L(c/d),v=null,x=new Set,S=``;for(let n=0;n<=m;n++){let a=g+(n%2==0?-1:1)*L(n/2);for(let n=0;n<=h;n++){let l=_+(n%2==0?-1:1)*L(n/2);S=B(e,a,l),v=W(i,S),v||(v=H(e,a,l,t),i.append(v));let u=b(.5*r+a*d-s,2),f=b(.5*o+l*d-c,2);v.style.transform=`translate3d(${u}px, ${f}px, 0)`,x.add(S)}}for(let e of U(i)){let{id:t}=e.dataset;t&&!x.has(t)&&e.remove()}let C=y(e,n)??``;a.toggleAttribute(`hidden`,!C),a.innerHTML!==C&&(a.innerHTML=C)},s=e.zoom,c=null;return e.onRender(()=>{c!==null&&(clearTimeout(c),c=null),e.zoom===s?(i.style.opacity&&(i.style.opacity=``),o()):(i.style.opacity=`0`,c=setTimeout(()=>{c=null,i.style.opacity&&(i.style.opacity=``),o()},300)),s=e.zoom}),i}function K(e,t={}){let{zoomIn:n=`➕`,zoomOut:r=`➖`}=t,i=document.createElement(`fieldset`);i.dataset.role=`zoom`;let a=document.createElement(`button`);a.dataset.role=`zoomin`,a.innerHTML=n;let o=document.createElement(`button`);o.dataset.role=`zoomout`,o.innerHTML=r;let s=()=>{a.toggleAttribute(`disabled`,e.zoom+1>e.maxZoom),o.toggleAttribute(`disabled`,e.zoom-1<e.minZoom)};return j(e,({originalEvent:t})=>{let n=t.target;n instanceof HTMLButtonElement&&i.contains(n)&&(e.zoom+=n.dataset.role===`zoomout`?-1:1,s())}),e.onRender(s),i.append(a,o),i}function q(e,t={}){let n=v(e,{className:`controls`,inset:t.inset??`0 0 auto auto`});return n.append(K(e,t)),n}function J(e){if(e.length===0)return{};let t=e[0][0],n=t,r=e[0][1],i=r;for(let[a,o]of e)t>a&&(t=a),n<a&&(n=a),r>o&&(r=o),i<o&&(i=o);return{minLat:t,maxLat:n,minLon:r,maxLon:i}}function Y(e){return Array.isArray(e)&&e.length===2&&typeof e[0]==`number`&&typeof e[1]==`number`}function X(e){return Y(e)?{minLat:e[0],maxLat:e[0],minLon:e[1],maxLon:e[1]}:Array.isArray(e)?J(e):e}function Z(e){let{minLat:t,maxLat:n,minLon:r,maxLon:i}=X(e);return[t===void 0||n===void 0?0:(n+t)/2,r===void 0||i===void 0?0:(i+r)/2]}const{abs:Q,log2:$,min:oe,floor:se}=Math;function ce(e,t){let{box:{w:n,h:r},center:[i,a],zoom:o}=e,{minLat:s,maxLat:c,minLon:l,maxLon:u}=t,d=0,f=0;if(l!==void 0&&u!==void 0){let t=Q(e.toPixelCoords(i,u)[0]-e.toPixelCoords(i,l)[0]);t!==0&&(d=$(n/t))}if(s!==void 0&&c!==void 0){let t=Q(e.toPixelCoords(s,a)[1]-e.toPixelCoords(c,a)[1]);t!==0&&(f=$(r/t))}let p=se(oe(o+d,o+f)),m={center:Z(t)};p!==o&&(m.zoom=p),e.setOptions(m)}const le=[.005,.018];function ue(e,t=le){let{minLat:n=0,maxLat:r=0,minLon:i=0,maxLon:a=0}=X(e),[o,s]=t;return{minLat:n-o,maxLat:r+o,minLon:i-s,maxLon:a+s}}exports.DEG=n,exports.MAX_LAT=a,exports.MAX_LON=180,exports.MIN_LAT=i,exports.MIN_LON=o,exports.MapArea=g,exports.RAD=t,exports.addElement=x,exports.addMovableViewport=w,exports.addPersistence=T,exports.addPinchToZoom=ne,exports.addPointerListener=j,exports.addResizeObserver=M,exports.addShape=re,exports.addShapeEditor=ie,exports.addTiles=G,exports.addZoomControl=q,exports.eccentricityMap=r,exports.fitGeoBounds=ce,exports.getCenter=Z,exports.getGeoBounds=J,exports.getId=_,exports.getLayer=v,exports.getVicinity=ue,exports.getZoomControl=K,exports.isCoordsArray=Y,exports.resolveDynamic=y,exports.toGeoBounds=X,exports.toPrecision=b;
package/dist/index.d.ts CHANGED
@@ -29,9 +29,9 @@ type PixelCoords = [number, number];
29
29
 
30
30
  type MapAreaOptions = {
31
31
  container: string;
32
- center?: GeoCoords;
33
- zoom?: number;
34
- minZoom?: number;
32
+ center?: GeoCoords; /** Initial map zoom level (default: `minZoom`) */
33
+ zoom?: number; /** Minimal map zoom level (default: `0`) */
34
+ minZoom?: number; /** Maximal map zoom level (default: `20`) */
35
35
  maxZoom?: number; /** Minimal and maximal latitudes and longitudes */
36
36
  bounds?: GeoBounds; /** Map projection (default: `"spherical"`) */
37
37
  projection?: Projection;
@@ -80,7 +80,7 @@ declare class MapArea {
80
80
 
81
81
  type Dynamic<T> = T | ((map: MapArea) => T);
82
82
 
83
- type MapAreaElementOptions = {
83
+ type AddElementOptions = {
84
84
  className?: string; /** Geographical position (`[lat, lon]`) of the element's top left corner. */
85
85
  coords?: GeoCoords; /** CSS `inset` (disregarding `coords`). */
86
86
  inset?: Dynamic<string>; /** Target layer. */
@@ -100,11 +100,11 @@ declare function addElement(map: MapArea, element: HTMLElement | SVGSVGElement,
100
100
  inset,
101
101
  layer,
102
102
  content
103
- }: MapAreaElementOptions): void;
103
+ }: AddElementOptions): void;
104
104
 
105
105
  type IgnoredElement = string | ((element: HTMLElement) => boolean);
106
106
 
107
- type MapAreaNavigationOptions = {
107
+ type AddMovableViewportOptions = {
108
108
  wheel?: boolean;
109
109
  ignore?: IgnoredElement;
110
110
  };
@@ -116,9 +116,9 @@ type MapAreaNavigationOptions = {
116
116
  declare function addMovableViewport(map: MapArea, {
117
117
  wheel,
118
118
  ignore
119
- }?: MapAreaNavigationOptions): void;
119
+ }?: AddMovableViewportOptions): void;
120
120
 
121
- type PersistenceOptions = {
121
+ type AddPersistenceOptions = {
122
122
  storageKey?: string;
123
123
  session?: boolean;
124
124
  };
@@ -130,7 +130,7 @@ type PersistenceOptions = {
130
130
  declare function addPersistence(map: MapArea, {
131
131
  storageKey,
132
132
  session
133
- }?: PersistenceOptions): {
133
+ }?: AddPersistenceOptions): {
134
134
  /**
135
135
  * Restores map options from the browser storage, or saves the
136
136
  * current map options to the storage if the storage entry is empty.
@@ -141,7 +141,7 @@ declare function addPersistence(map: MapArea, {
141
141
  reset: () => void;
142
142
  };
143
143
 
144
- type MapAreaPinchToZoomOptions = {
144
+ type AddPinchToZoomOptions = {
145
145
  /**
146
146
  * Defines how much the distance between the pinch touches should change
147
147
  * in order to change the map zoom by 1.
@@ -150,26 +150,26 @@ type MapAreaPinchToZoomOptions = {
150
150
  };
151
151
  declare function addPinchToZoom(map: MapArea, {
152
152
  pace
153
- }?: MapAreaPinchToZoomOptions): () => void;
153
+ }?: AddPinchToZoomOptions): () => void;
154
154
 
155
- type MapAreaClickEvent = {
155
+ type MapAreaPointerEvent = {
156
156
  x: number;
157
157
  y: number;
158
158
  lat: number;
159
159
  lon: number;
160
- originalEvent: MouseEvent | TouchEvent;
160
+ originalEvent: PointerEvent;
161
161
  };
162
- type MapAreaClickCallback = (event: MapAreaClickEvent) => void;
163
- type MapAreaClickOptions = {
162
+ type MapAreaPointerEventCallback = (event: MapAreaPointerEvent) => void;
163
+ type AddPointerListenerOptions = {
164
164
  ignore?: IgnoredElement;
165
165
  };
166
166
  /**
167
167
  * Adds a pointer event listener to the map and returns a function that
168
168
  * removes the added listener.
169
169
  */
170
- declare function addPointerListener(map: MapArea, callback: MapAreaClickCallback, {
170
+ declare function addPointerListener(map: MapArea, callback: MapAreaPointerEventCallback, {
171
171
  ignore
172
- }?: MapAreaClickOptions): () => void;
172
+ }?: AddPointerListenerOptions): () => void;
173
173
 
174
174
  type MapAreaResizeEvent = {
175
175
  inlineSize?: number;
@@ -188,11 +188,12 @@ type ShapeOptions = {
188
188
  markers?: boolean;
189
189
  };
190
190
 
191
+ type AddShapeOptions = ShapeOptions;
191
192
  /**
192
193
  * Adds a shape based on the given array of geographic coordinates to
193
194
  * the specified map layer.
194
195
  */
195
- declare function addShape(map: MapArea, coords: GeoCoords[], options?: ShapeOptions): {
196
+ declare function addShape(map: MapArea, coords: GeoCoords[], options?: AddShapeOptions): {
196
197
  remove: () => void;
197
198
  };
198
199
 
@@ -203,18 +204,18 @@ type Vertex<T> = {
203
204
 
204
205
  type GeoVertex = Vertex<GeoCoords>;
205
206
 
206
- type ShapeEditorOptions = {
207
+ type AddShapeEditorOptions = {
207
208
  /** Adds a shape update callback. */onUpdate?: (shape: GeoVertex[]) => void; /** Map elements to be ignored in the shape editor when clicked. */
208
209
  ignore?: IgnoredElement;
209
210
  };
210
211
  /**
211
212
  * Adds a shape editor to the given map container.
212
213
  */
213
- declare function addShapeEditor(map: MapArea, options?: ShapeEditorOptions): {
214
+ declare function addShapeEditor(map: MapArea, options?: AddShapeEditorOptions): {
214
215
  reset: () => void;
215
216
  };
216
217
 
217
- type MapAreaTileOptions = {
218
+ type AddTilesOptions = {
218
219
  /**
219
220
  * Tile URL, either a string with placeholders (`{x}` and `{y}` for the
220
221
  * tile indices, `{z}` for the zoom level, `{lang}` for the map language)
@@ -239,7 +240,7 @@ type MapAreaTileOptions = {
239
240
  * which is a string URL with placeholders or a function of
240
241
  * `(map, xIndex, yIndex) => string`.
241
242
  */
242
- declare function addTiles(map: MapArea, options?: MapAreaTileOptions): HTMLElement;
243
+ declare function addTiles(map: MapArea, options?: AddTilesOptions): HTMLElement;
243
244
 
244
245
  type ZoomControlOptions = {
245
246
  /** HTML content of the zoom-in button */zoomIn?: string; /** HTML content of the zoom-out button */
@@ -318,4 +319,4 @@ declare function toGeoBounds(x: GeoCoords | GeoCoords[] | GeoBounds): GeoBounds;
318
319
 
319
320
  declare function toPrecision(x: number, n: number): string;
320
321
 
321
- export { AddZoomControlOptions, BoxDimensions, DEG, Dynamic, GeoBounds, GeoCoords, GeoVertex, IgnoredElement, LayerOptions, MAX_LAT, MAX_LON, MIN_LAT, MIN_LON, MapArea, MapAreaClickCallback, MapAreaClickEvent, MapAreaClickOptions, MapAreaElementOptions, MapAreaNavigationOptions, MapAreaOptions, MapAreaPinchToZoomOptions, MapAreaResizeCallback, MapAreaResizeEvent, MapAreaTileOptions, PersistenceOptions, PixelCoords, PixelVertex, Projection, RAD, RenderCallback, ShapeEditorOptions, ShapeOptions, ZoomControlOptions, addElement, addMovableViewport, addPersistence, addPinchToZoom, addPointerListener, addResizeObserver, addShape, addShapeEditor, addTiles, addZoomControl, eccentricityMap, fitGeoBounds, getCenter, getGeoBounds, getId, getLayer, getVicinity, getZoomControl, isCoordsArray, resolveDynamic, toGeoBounds, toPrecision };
322
+ export { AddElementOptions, AddMovableViewportOptions, AddPersistenceOptions, AddPinchToZoomOptions, AddPointerListenerOptions, AddShapeEditorOptions, AddShapeOptions, AddTilesOptions, AddZoomControlOptions, BoxDimensions, DEG, Dynamic, GeoBounds, GeoCoords, GeoVertex, IgnoredElement, LayerOptions, MAX_LAT, MAX_LON, MIN_LAT, MIN_LON, MapArea, MapAreaOptions, MapAreaPointerEvent, MapAreaPointerEventCallback, MapAreaResizeCallback, MapAreaResizeEvent, PixelCoords, PixelVertex, Projection, RAD, RenderCallback, ShapeOptions, ZoomControlOptions, addElement, addMovableViewport, addPersistence, addPinchToZoom, addPointerListener, addResizeObserver, addShape, addShapeEditor, addTiles, addZoomControl, eccentricityMap, fitGeoBounds, getCenter, getGeoBounds, getId, getLayer, getVicinity, getZoomControl, isCoordsArray, resolveDynamic, toGeoBounds, toPrecision };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- const{PI:e}=Math,t=e/180,n=180/e,r={spherical:0,ellipsoidal:.0818191908426},i=-85.05,a=85.05,o=-180,s=180,{PI:c,sin:l,tan:u,atan:d,pow:f,exp:p,log:m,abs:h}=Math;var g=class{_p;_c;_cc;_r=new Set;constructor(e){this._p=e,this.container.style=`position: relative; overflow: hidden; touch-action: none;`,this.container.dataset.role=`maparea`}render(){for(let e of this._r)e(this)}onRender(e,t=!1){return this._r.add(e),t||e(this),()=>{this._r.delete(e)}}getOptions(){return{...this._p,center:this.center,bounds:this.bounds}}setOptions(e){this._p={...this._p,...e},`container`in e&&delete this._c,delete this._cc,this.render()}get container(){if(!this._c){let e=document.querySelector(this._p.container);if(!e)throw Error(`missing container element`);this._c=e}return this._c}get box(){let e=this.container.getBoundingClientRect();return{x:e.left,y:e.top,w:e.width,h:e.height}}get bounds(){let e=this._p.bounds;return e?{...e}:{}}set bounds(e){this._p.bounds=e}get center(){let e=this._p.center;return e?e.slice():[0,0]}set center(e){this._p.center=e,delete this._cc,this.render()}get centerCoords(){if(!this._cc){let[e,t]=this.center;this._cc=this.toPixelCoords(e,t)}return this._cc}get zoom(){return this._p.zoom??this._p.minZoom??0}set zoom(e){let{minZoom:t,maxZoom:n}=this,r=e;e<t&&(r=t),e>n&&(r=n),this._p.zoom=r,delete this._cc,this.render()}get minZoom(){return this._p.minZoom??-1/0}set minZoom(e){this._p.minZoom=e,this.zoom<this.minZoom&&(this.zoom=this.minZoom)}get maxZoom(){return this._p.maxZoom??1/0}set maxZoom(e){this._p.maxZoom=e,this.zoom>this.maxZoom&&(this.zoom=this.maxZoom)}get projection(){return this._p.projection??`spherical`}set projection(e){this._p.projection=e,this.render()}get lang(){return this._p.lang??``}set lang(e){this._p.lang=e,this.render()}inPixelBounds(e,t){let[n,r]=this.toGeoCoords(e,t);return this.inBounds(n,r)}inBounds(e,t){let{minLat:n=i,maxLat:r=a,minLon:s=o,maxLon:c=180}=this.bounds;return e>=n&&e<=r&&t>=s&&t<=c}canMoveTo(e,t){if(!this.inBounds(e,t))return!1;let{w:n,h:r}=this.box;if(n===0||r===0)return!1;let[i,a]=this.toPixelCoords(e,t);return this.inPixelBounds(i-n/2,a-r/2)&&this.inPixelBounds(i+n/2,a+r/2)}toPixelCoords(e,n){let i=r[this.projection],a=f(2,this.zoom+7)/c,o=e*t,s=i===0?1:f((1-i*l(o))/(1+i*l(o)),i/2);return[a*(c+n*t),a*(c-m(s*u(c/4+o/2)))]}toGeoCoords(e,t){let o=r[this.projection],s=f(2,this.zoom+7)/c,l=(e/s-c)*n,u;if(o===0)u=2*(d(p(c-t/s))-c/4)*n;else{u=i;let e=a-i,n=NaN,r=0;for(;(Number.isNaN(n)||h(n-t)>.1)&&r++<30;)e/=2,n=this.toPixelCoords(u+e,l)[1],n>t&&(u+=e)}return(l<-180||l>=180)&&(l=(l+180)%360-180),(u<-90||u>=90)&&(u=(u+90)%180-90),[u,l]}};function _(){return Math.random().toString(36).slice(2)}function v(e,{id:t,className:n,inset:r=`0`}={}){let i=`${n?`.${n}`:``}${t?`[data-id="${t}"]`:``}`,a=e.container.querySelector(i);return a||(a=document.createElement(`div`),a.className=`${n?`${n} `:``}layer`,a.dataset.id=t??_(),a.style=`position: absolute; inset: ${r};`,e.container.append(a)),a}function y(e,t){return t===void 0?t:t instanceof Function?t(e):t}function b(e,t){return e.toFixed(t).replace(/\.(\d*[^0])0+$/,`.$1`).replace(/\.0+$/,``)}function x(e,t,{className:n,coords:r,inset:i,layer:a,content:o}){let s=a??v(e,{className:`elements`});n&&t.setAttribute(`class`,n),t.style.position=`absolute`,s.append(t),e.onRender(()=>{if(i)t.style.inset=y(e,i)??``;else if(r){let{centerCoords:[n,i],box:{w:a,h:o}}=e,[s,c]=e.toPixelCoords(...r),l=b(s-n+a/2,2),u=b(c-i+o/2,2);t.style.transform=`translate3d(${l}px, ${u}px, 0)`}if(o){let n=y(e,o)??``;t.innerHTML!==n&&(t.innerHTML=n)}})}function S(e,t){return t===void 0||!(e instanceof HTMLElement)?!1:typeof t==`function`&&t(e)||typeof t==`string`&&e.closest(t)!==null}function C(e,{onStart:t,onMove:n,onEnd:r,wheel:i,ignore:a}={}){let o=null,s=null,c=Date.now(),l=null,u=null,d=!1,f=!1,p=0,m=0,h=0;function g(t,r){m+=t,h+=r,o!==null&&(o-=t),s!==null&&(s-=r),!f&&!e.dataset.dragged&&(e.dataset.dragged=`true`);let i=Date.now(),a=f?10:100;(m!==0||h!==0)&&i-c>=a&&(l&&cancelAnimationFrame(l),l=requestAnimationFrame(()=>{n?.(m,h),m=0,h=0,c=i,l=null}))}function _(e,t){o!==null&&s!==null&&g(o-e,s-t)}function v(e,n){u!==null&&(clearTimeout(u),f=!1,u=null),d=!0,t?.(),e!==void 0&&(o=e),n!==void 0&&(s=n),c=Date.now(),m=0,h=0}function y(t,n){d=!1,t!==void 0&&n!==void 0&&_(t,n),delete e.dataset.dragged,o=null,s=null,r?.()}e.dataset.draggable=`true`;function b(e){return!S(e.target,a)&&p===1}function x(e){p++,b(e)&&(e.preventDefault(),v(e.pageX,e.pageY))}function C(e){b(e)&&(e.preventDefault(),_(e.pageX,e.pageY))}function w(e){b(e)&&(e.preventDefault(),y(e.pageX,e.pageY)),p=0}function T(e){S(e.target,a)||(e.preventDefault(),d||(v(),f=!0),e.shiftKey?g(e.deltaY,e.deltaX):g(e.deltaX,e.deltaY),u!==null&&clearTimeout(u),u=setTimeout(()=>{y(),f=!1,u=null},200))}return e.addEventListener(`pointerdown`,x),e.addEventListener(`pointermove`,C),e.addEventListener(`pointerup`,w),e.addEventListener(`pointercancel`,w),i&&e.addEventListener(`wheel`,T),()=>{e.removeEventListener(`pointerdown`,x),e.removeEventListener(`pointermove`,C),e.removeEventListener(`pointerup`,w),e.removeEventListener(`pointercancel`,w),i&&e.removeEventListener(`wheel`,T)}}function w(e,{wheel:t=!0,ignore:n}={}){let r=0,i=0;C(e.container,{onStart(){[r,i]=e.centerCoords},onMove(t,n){let a=r+t,o=i+n,s=e.toGeoCoords(a,o);e.canMoveTo(...s)&&(e.center=s,r=a,i=o)},wheel:t,ignore:n})}function T(e,{storageKey:t,session:n=!1}={}){let r=n?window.sessionStorage:window.localStorage,i=t??[`maparea`,e.container.id].filter(Boolean).join(`#`),a=e.getOptions(),o=!1,s=()=>{try{r.setItem(i,JSON.stringify(e.getOptions()))}catch{}},c=()=>{try{let t=r.getItem(i);t===null?s():e.setOptions(JSON.parse(t))}catch{}},l=e=>{o=e===void 0?!o:e},u=()=>{e.setOptions(a)};c();let d=null;return e.onRender(()=>{o||(d&&=(clearTimeout(d),null),d=setTimeout(()=>{d=null,s()},350))}),{sync:c,write:s,toggle:l,reset:u}}const{hypot:ee,log2:E,abs:D,trunc:O}=Math;function k({clientX:e,clientY:t},{clientX:n,clientY:r}){return ee(n-e,r-t)}function te({clientX:e,clientY:t},{clientX:n,clientY:r}){return[(e+n)/2,(t+r)/2]}function A(e,{pace:t=1.2}={}){let{container:n}=e,r=null,i=null,a=0;function o(e){return e.touches.length===2}function s(t){o(t)&&(t.preventDefault(),r=k(t.touches[0],t.touches[1]),i=e.zoom,a=0)}let c=null;function l(n){if(o(n)&&r!==null&&r!==0&&i!==null){n.preventDefault();let i=E(k(n.touches[0],n.touches[1])/r)/E(t)-a;if(D(i)>=1){let{box:{x:t,y:r,w:o,h:s},centerCoords:[l,u]}=e,[d,f]=te(n.touches[0],n.touches[1]),p=d-o/2-t,m=f-s/2-r,[h,g]=e.toGeoCoords(l+p,u+m),_=O(i);c&&cancelAnimationFrame(c),c=requestAnimationFrame(()=>{e.zoom+=_,a+=_;let[t,n]=e.toPixelCoords(h,g),[r,i]=e.centerCoords;t-=r,n-=i;let o=t-p,s=n-m;e.center=e.toGeoCoords(r+o,i+s)})}}}return n.addEventListener(`touchstart`,s),n.addEventListener(`touchmove`,l),()=>{n.removeEventListener(`touchstart`,s),n.removeEventListener(`touchmove`,l)}}function j(e,t,{ignore:n}={}){let r=null,i=null,a=Date.now(),o=e=>{r=e.clientX,i=e.clientY,a=Date.now()},s=o=>{if(S(o.target,n)||r===null||i===null||Date.now()-a>150)return;let{box:s,centerCoords:[c,l]}=e,u=r-s.x,d=i-s.y,[f,p]=e.toGeoCoords(u-.5*s.w+c,d-.5*s.h+l);t({x:u,y:d,lat:f,lon:p,originalEvent:o}),r=null,i=null};return e.container.addEventListener(`pointerdown`,o),e.container.addEventListener(`pointerup`,s),e.container.addEventListener(`pointercancel`,s),()=>{e.container.removeEventListener(`pointerdown`,o),e.container.removeEventListener(`pointerup`,s),e.container.removeEventListener(`pointercancel`,s)}}function M(e,t){let n=new ResizeObserver(n=>{for(let r of n)if(r.contentBoxSize){if(t)if(r.contentBoxSize){let{inlineSize:e,blockSize:n}=r.contentBoxSize[0]??r.contentBoxSize;t({inlineSize:e,blockSize:n})}else{let{width:e,height:n}=r.contentRect;t({width:e,height:n})}e.render()}});return n.observe(e.container),()=>{n.unobserve(e.container)}}const N=`http://www.w3.org/2000/svg`;function P(e){return parseFloat(window.getComputedStyle(e).strokeWidth||e.getAttribute(`stroke-width`)||`1`)}function F(e,t,n){if(t.length===0){e.innerHTML=``;return}let r=e.querySelector(`path`);r||(r=document.createElementNS(N,`path`),e.append(r));let i=t[0].coords[0],a=i,o=t[0].coords[1],s=o,c=``;for(let{coords:[e,n]}of t)i>e&&(i=e),a<e&&(a=e),o>n&&(o=n),s<n&&(s=n);i-=10,a+=10,o-=10,s+=10;let l=Array.from(e.querySelectorAll(`.marker`)),u=0;for(let{id:a,coords:[s,d]}of t){let t=b(s-i,3),f=b(d-o,3);if(c+=`${c?` L`:`M`} ${t} ${f}`,n?.markers){let n=l[u++];n||(n=document.createElementNS(N,`circle`),n.setAttribute(`class`,`marker`),n.setAttribute(`r`,String(1.5*P(r))),e.append(n)),n.setAttribute(`cx`,t),n.setAttribute(`cy`,f),n.dataset.id=a}}for(let e=u;e<l.length;e++)l[e].remove();return r.setAttribute(`d`,c),{xMin:i,xMax:a,yMin:o,yMax:s}}function I(e,t,n){let r=n?.layer??v(e,{className:`shape`});r.toggleAttribute(`hidden`,t.length===0);let i=r.querySelector(`svg`);i||(i=document.createElementNS(N,`svg`),i.setAttribute(`xmlns`,N),r.append(i));let a=F(i,t.map(({id:t,coords:[n,r]})=>({id:t,coords:e.toPixelCoords(n,r)})),n);if(a){let{xMin:t,xMax:n,yMin:r,yMax:o}=a,{centerCoords:[s,c],box:l}=e,u=b(n-t,3),d=b(o-r,3),f=b(.5*l.w+t-s,2),p=b(.5*l.h+r-c,2);i.setAttribute(`viewBox`,`0 0 ${u} ${d}`),i.setAttribute(`width`,u),i.setAttribute(`height`,d),i.setAttribute(`style`,`position: absolute; transform: translate3d(${f}px, ${p}px, 0);`)}return r}function ne(e,t,n){let r=t.map(e=>({id:_(),coords:e}));return e.onRender(()=>{I(e,r,n)}),{remove:()=>{r=[],I(e,r,n)}}}function re(e,t){let n=[],r=null,i={layer:v(e,{className:`shape-editor`}),markers:!0},a=()=>{I(e,n,i),t?.onUpdate?.(n)};return j(e,({lat:e,lon:t,originalEvent:i})=>{let o=(i.target?.closest(`.marker`))?.dataset.id;if(o&&r){clearTimeout(r),r=null,n=n.filter(({id:e})=>e!==o),a();return}let s=()=>{n.push({id:_(),coords:[e,t]}),a(),r=null};o?r=setTimeout(s,250):s()},{ignore:t?.ignore}),e.onRender(a),{reset:()=>{n=[],a()}}}const{floor:L,ceil:R,random:z}=Math;function B(e,t,n){return`${t},${n},${e.zoom},${e.lang}`}function V(e){let t=e.target;t instanceof HTMLImageElement&&(t.style.opacity=``)}function H(e,t,n,{size:r,url:i,subdomains:a,retries:o=0,error:s}){let c=new Image,l=y(e,r)??256,u=0,d=(r,o)=>{if(!i)return``;if(typeof i==`function`)return i(e,t,n);let s=i.replaceAll(`{x}`,String(r)).replaceAll(`{y}`,String(o)).replaceAll(`{z}`,String(e.zoom)).replaceAll(`{lang}`,e.lang);return a&&s.includes(`{s}`)&&(s=s.replaceAll(`{s}`,a[L(a.length*z())])),s},f=t=>{let n=t.target;if(n instanceof HTMLImageElement){if(u++<o){let e=new URL(n.src);e.searchParams.set(`_t`,String(Date.now())),n.src=e.href;return}let t=y(e,s);t&&(n.dataset.src=n.src,n.src=t),c.removeEventListener(`error`,f)}};return c.width=l,c.height=l,c.src=d(t,n),c.dataset.id=B(e,t,n),c.style.position=`absolute`,c.addEventListener(`load`,V),c.addEventListener(`error`,f),c.complete||(c.style.opacity=`0`),c}function U(e){return e.querySelectorAll(`img[data-id]`)}function W(e,t){return e.querySelector(`img[data-id="${t}"]`)}function G(e,t={}){let{attribution:n,attributionInset:r=`auto 0 0 auto`}=t,i=t.layer??v(e,{className:`tiles`}),a=v(e,{id:i.dataset.id,className:`tiles-attribution`,inset:r}),o=()=>{let{box:{w:r,h:o},centerCoords:[s,c]}=e,{size:l,margin:u=0}=t,d=y(e,l)??256,f=Array.isArray(u)?u[0]:u,p=Array.isArray(u)?u[1]:u,m=R((r+2*f)/d),h=R((o+2*p)/d),g=L(s/d),_=L(c/d),v=null,x=new Set,S=``;for(let n=0;n<=m;n++){let a=g+(n%2==0?-1:1)*L(n/2);for(let n=0;n<=h;n++){let l=_+(n%2==0?-1:1)*L(n/2);S=B(e,a,l),v=W(i,S),v||(v=H(e,a,l,t),i.append(v));let u=b(.5*r+a*d-s,2),f=b(.5*o+l*d-c,2);v.style.transform=`translate3d(${u}px, ${f}px, 0)`,x.add(S)}}for(let e of U(i)){let{id:t}=e.dataset;t&&!x.has(t)&&e.remove()}let C=y(e,n)??``;a.toggleAttribute(`hidden`,!C),a.innerHTML!==C&&(a.innerHTML=C)},s=e.zoom,c=null;return e.onRender(()=>{c!==null&&(clearTimeout(c),c=null),e.zoom===s?(i.style.opacity&&(i.style.opacity=``),o()):(i.style.opacity=`0`,c=setTimeout(()=>{c=null,i.style.opacity&&(i.style.opacity=``),o()},300)),s=e.zoom}),i}function K(e,t={}){let{zoomIn:n=`➕`,zoomOut:r=`➖`}=t,i=document.createElement(`fieldset`);i.dataset.role=`zoom`;let a=document.createElement(`button`);a.dataset.role=`zoomin`,a.innerHTML=n;let o=document.createElement(`button`);o.dataset.role=`zoomout`,o.innerHTML=r;let s=()=>{a.toggleAttribute(`disabled`,e.zoom+1>e.maxZoom),o.toggleAttribute(`disabled`,e.zoom-1<e.minZoom)};return j(e,({originalEvent:t})=>{let n=t.target;n instanceof HTMLButtonElement&&i.contains(n)&&(e.zoom+=n.dataset.role===`zoomout`?-1:1,s())}),e.onRender(s),i.append(a,o),i}function q(e,t={}){let n=K(e,t),r=v(e,{className:`controls`,inset:t.inset??`0 0 auto auto`});return r.append(n),r}function J(e){if(e.length===0)return{};let t=e[0][0],n=t,r=e[0][1],i=r;for(let[a,o]of e)t>a&&(t=a),n<a&&(n=a),r>o&&(r=o),i<o&&(i=o);return{minLat:t,maxLat:n,minLon:r,maxLon:i}}function Y(e){return Array.isArray(e)&&e.length===2&&typeof e[0]==`number`&&typeof e[1]==`number`}function X(e){return Y(e)?{minLat:e[0],maxLat:e[0],minLon:e[1],maxLon:e[1]}:Array.isArray(e)?J(e):e}function Z(e){let{minLat:t,maxLat:n,minLon:r,maxLon:i}=X(e);return[t===void 0||n===void 0?0:(n+t)/2,r===void 0||i===void 0?0:(i+r)/2]}const{abs:Q,log2:$,min:ie,floor:ae}=Math;function oe(e,t){let{box:{w:n,h:r},center:[i,a],zoom:o}=e,{minLat:s,maxLat:c,minLon:l,maxLon:u}=t,d=0,f=0;if(l!==void 0&&u!==void 0){let t=Q(e.toPixelCoords(i,u)[0]-e.toPixelCoords(i,l)[0]);t!==0&&(d=$(n/t))}if(s!==void 0&&c!==void 0){let t=Q(e.toPixelCoords(s,a)[1]-e.toPixelCoords(c,a)[1]);t!==0&&(f=$(r/t))}let p=ae(ie(o+d,o+f)),m={center:Z(t)};p!==o&&(m.zoom=p),e.setOptions(m)}const se=[.005,.018];function ce(e,t=se){let{minLat:n=0,maxLat:r=0,minLon:i=0,maxLon:a=0}=X(e),[o,s]=t;return{minLat:n-o,maxLat:r+o,minLon:i-s,maxLon:a+s}}export{n as DEG,a as MAX_LAT,s as MAX_LON,i as MIN_LAT,o as MIN_LON,g as MapArea,t as RAD,x as addElement,w as addMovableViewport,T as addPersistence,A as addPinchToZoom,j as addPointerListener,M as addResizeObserver,ne as addShape,re as addShapeEditor,G as addTiles,q as addZoomControl,r as eccentricityMap,oe as fitGeoBounds,Z as getCenter,J as getGeoBounds,_ as getId,v as getLayer,ce as getVicinity,K as getZoomControl,Y as isCoordsArray,y as resolveDynamic,X as toGeoBounds,b as toPrecision};
1
+ const{PI:e}=Math,t=e/180,n=180/e,r={spherical:0,ellipsoidal:.0818191908426},i=-85.05,a=85.05,o=-180,s=180,{PI:c,sin:l,tan:u,atan:d,pow:f,exp:p,log:m,abs:h}=Math;var g=class{_p;_c;_cc;_r=new Set;constructor(e){this._p=e,this.container.style=`position: relative; overflow: hidden; touch-action: none;`,this.container.dataset.role=`maparea`}render(){for(let e of this._r)e(this)}onRender(e,t=!1){return this._r.add(e),t||e(this),()=>{this._r.delete(e)}}getOptions(){return{...this._p,center:this.center,bounds:this.bounds}}setOptions(e){this._p={...this._p,...e},`container`in e&&delete this._c,delete this._cc,this.render()}get container(){if(!this._c){let e=document.querySelector(this._p.container);if(!e)throw Error(`missing container element`);this._c=e}return this._c}get box(){let e=this.container.getBoundingClientRect();return{x:e.left,y:e.top,w:e.width,h:e.height}}get bounds(){let e=this._p.bounds;return e?{...e}:{}}set bounds(e){this._p.bounds=e}get center(){let e=this._p.center;return e?e.slice():[0,0]}set center(e){this._p.center=e,delete this._cc,this.render()}get centerCoords(){if(!this._cc){let[e,t]=this.center;this._cc=this.toPixelCoords(e,t)}return this._cc}get zoom(){return this._p.zoom??this.minZoom}set zoom(e){let{minZoom:t,maxZoom:n}=this,r=e;e<t&&(r=t),e>n&&(r=n),this._p.zoom=r,delete this._cc,this.render()}get minZoom(){return this._p.minZoom??0}set minZoom(e){this._p.minZoom=e,this.zoom<this.minZoom&&(this.zoom=this.minZoom)}get maxZoom(){return this._p.maxZoom??20}set maxZoom(e){this._p.maxZoom=e,this.zoom>this.maxZoom&&(this.zoom=this.maxZoom)}get projection(){return this._p.projection??`spherical`}set projection(e){this._p.projection=e,this.render()}get lang(){return this._p.lang??``}set lang(e){this._p.lang=e,this.render()}inPixelBounds(e,t){let[n,r]=this.toGeoCoords(e,t);return this.inBounds(n,r)}inBounds(e,t){let{minLat:n=i,maxLat:r=a,minLon:s=o,maxLon:c=180}=this.bounds;return e>=n&&e<=r&&t>=s&&t<=c}canMoveTo(e,t){if(!this.inBounds(e,t))return!1;let{w:n,h:r}=this.box;if(n===0||r===0)return!1;let[i,a]=this.toPixelCoords(e,t);return this.inPixelBounds(i-n/2,a-r/2)&&this.inPixelBounds(i+n/2,a+r/2)}toPixelCoords(e,n){let i=r[this.projection],a=f(2,this.zoom+7)/c,o=e*t,s=i===0?1:f((1-i*l(o))/(1+i*l(o)),i/2);return[a*(c+n*t),a*(c-m(s*u(c/4+o/2)))]}toGeoCoords(e,t){let o=r[this.projection],s=f(2,this.zoom+7)/c,l=(e/s-c)*n,u;if(o===0)u=2*(d(p(c-t/s))-c/4)*n;else{u=i;let e=a-i,n=NaN,r=0;for(;(Number.isNaN(n)||h(n-t)>.1)&&r++<30;)e/=2,n=this.toPixelCoords(u+e,l)[1],n>t&&(u+=e)}return(l<-180||l>=180)&&(l=(l+180)%360-180),(u<-90||u>=90)&&(u=(u+90)%180-90),[u,l]}};function _(){return Math.random().toString(36).slice(2)}function v(e,{id:t,className:n,inset:r=`0`}={}){let i=`${n?`.${n}`:``}${t?`[data-id="${t}"]`:``}`,a=e.container.querySelector(i);return a||(a=document.createElement(`div`),a.className=`${n?`${n} `:``}layer`,a.dataset.id=t??_(),a.style=`position: absolute; inset: ${r};`,e.container.append(a)),a}function y(e,t){return t===void 0?t:t instanceof Function?t(e):t}function b(e,t){return e.toFixed(t).replace(/\.(\d*[^0])0+$/,`.$1`).replace(/\.0+$/,``)}function x(e,t,{className:n,coords:r,inset:i,layer:a,content:o}){let s=a??v(e,{className:`elements`});n&&t.setAttribute(`class`,n),t.style.position=`absolute`,s.append(t),e.onRender(()=>{if(i)t.style.inset=y(e,i)??``;else if(r){let{centerCoords:[n,i],box:{w:a,h:o}}=e,[s,c]=e.toPixelCoords(...r),l=b(s-n+a/2,2),u=b(c-i+o/2,2);t.style.transform=`translate3d(${l}px, ${u}px, 0)`}if(o){let n=y(e,o)??``;t.innerHTML!==n&&(t.innerHTML=n)}})}function S(e,t){return t===void 0||!(e instanceof HTMLElement)?!1:typeof t==`function`&&t(e)||typeof t==`string`&&e.closest(t)!==null}function C(e,{onStart:t,onMove:n,onEnd:r,wheel:i,ignore:a}={}){let o=null,s=null,c=Date.now(),l=null,u=null,d=!1,f=!1,p=0,m=0,h=0;function g(t,r){m+=t,h+=r,o!==null&&(o-=t),s!==null&&(s-=r),!f&&!e.dataset.dragged&&(e.dataset.dragged=`true`);let i=Date.now(),a=f?10:100;(m!==0||h!==0)&&i-c>=a&&(l&&cancelAnimationFrame(l),l=requestAnimationFrame(()=>{n?.(m,h),m=0,h=0,c=i,l=null}))}function _(e,t){o!==null&&s!==null&&g(o-e,s-t)}function v(e,n){u!==null&&(clearTimeout(u),f=!1,u=null),d=!0,t?.(),e!==void 0&&(o=e),n!==void 0&&(s=n),c=Date.now(),m=0,h=0}function y(t,n){d=!1,t!==void 0&&n!==void 0&&_(t,n),delete e.dataset.dragged,o=null,s=null,r?.()}e.dataset.draggable=`true`;function b(e){return!S(e.target,a)&&p===1}function x(e){p++,b(e)&&(e.preventDefault(),v(e.pageX,e.pageY))}function C(e){b(e)&&(e.preventDefault(),_(e.pageX,e.pageY))}function w(e){b(e)&&(e.preventDefault(),y(e.pageX,e.pageY)),p=0}function T(e){S(e.target,a)||(e.preventDefault(),d||(v(),f=!0),e.shiftKey?g(e.deltaY,e.deltaX):g(e.deltaX,e.deltaY),u!==null&&clearTimeout(u),u=setTimeout(()=>{y(),f=!1,u=null},200))}return e.addEventListener(`pointerdown`,x),e.addEventListener(`pointermove`,C),e.addEventListener(`pointerup`,w),e.addEventListener(`pointercancel`,w),i&&e.addEventListener(`wheel`,T),()=>{e.removeEventListener(`pointerdown`,x),e.removeEventListener(`pointermove`,C),e.removeEventListener(`pointerup`,w),e.removeEventListener(`pointercancel`,w),i&&e.removeEventListener(`wheel`,T)}}function w(e,{wheel:t=!0,ignore:n}={}){let r=0,i=0;C(e.container,{onStart(){[r,i]=e.centerCoords},onMove(t,n){let a=r+t,o=i+n,s=e.toGeoCoords(a,o);e.canMoveTo(...s)&&(e.center=s,r=a,i=o)},wheel:t,ignore:n})}function T(e,{storageKey:t,session:n=!1}={}){let r=n?window.sessionStorage:window.localStorage,i=t??[`maparea`,e.container.id].filter(Boolean).join(`#`),a=e.getOptions(),o=!1,s=()=>{try{r.setItem(i,JSON.stringify(e.getOptions()))}catch{}},c=()=>{try{let t=r.getItem(i);t===null?s():e.setOptions(JSON.parse(t))}catch{}},l=e=>{o=e===void 0?!o:e},u=()=>{e.setOptions(a)};c();let d=null;return e.onRender(()=>{o||(d&&=(clearTimeout(d),null),d=setTimeout(()=>{d=null,s()},350))}),{sync:c,write:s,toggle:l,reset:u}}const{hypot:ee,log2:E,abs:D,trunc:O}=Math;function k({clientX:e,clientY:t},{clientX:n,clientY:r}){return ee(n-e,r-t)}function te({clientX:e,clientY:t},{clientX:n,clientY:r}){return[(e+n)/2,(t+r)/2]}function A(e,{pace:t=1.2}={}){let{container:n}=e,r=null,i=null,a=0;function o(e){return e.touches.length===2}function s(t){o(t)&&(t.preventDefault(),r=k(t.touches[0],t.touches[1]),i=e.zoom,a=0)}let c=null;function l(n){if(o(n)&&r!==null&&r!==0&&i!==null){n.preventDefault();let i=E(k(n.touches[0],n.touches[1])/r)/E(t)-a;if(D(i)>=1){let{box:{x:t,y:r,w:o,h:s},centerCoords:[l,u]}=e,[d,f]=te(n.touches[0],n.touches[1]),p=d-o/2-t,m=f-s/2-r,[h,g]=e.toGeoCoords(l+p,u+m),_=O(i);c&&cancelAnimationFrame(c),c=requestAnimationFrame(()=>{e.zoom+=_,a+=_;let[t,n]=e.toPixelCoords(h,g),[r,i]=e.centerCoords;t-=r,n-=i;let o=t-p,s=n-m;e.center=e.toGeoCoords(r+o,i+s)})}}}return n.addEventListener(`touchstart`,s),n.addEventListener(`touchmove`,l),()=>{n.removeEventListener(`touchstart`,s),n.removeEventListener(`touchmove`,l)}}function j(e,t,{ignore:n}={}){let r=null,i=null,a=Date.now(),o=e=>{r=e.clientX,i=e.clientY,a=Date.now()},s=o=>{if(S(o.target,n)||r===null||i===null||Date.now()-a>150)return;let{box:s,centerCoords:[c,l]}=e,u=r-s.x,d=i-s.y,[f,p]=e.toGeoCoords(u-.5*s.w+c,d-.5*s.h+l);t({x:u,y:d,lat:f,lon:p,originalEvent:o}),r=null,i=null};return e.container.addEventListener(`pointerdown`,o),e.container.addEventListener(`pointerup`,s),e.container.addEventListener(`pointercancel`,s),()=>{e.container.removeEventListener(`pointerdown`,o),e.container.removeEventListener(`pointerup`,s),e.container.removeEventListener(`pointercancel`,s)}}function M(e,t){let n=new ResizeObserver(n=>{for(let r of n)if(r.contentBoxSize){if(t)if(r.contentBoxSize){let{inlineSize:e,blockSize:n}=r.contentBoxSize[0]??r.contentBoxSize;t({inlineSize:e,blockSize:n})}else{let{width:e,height:n}=r.contentRect;t({width:e,height:n})}e.render()}});return n.observe(e.container),()=>{n.unobserve(e.container)}}const N=`http://www.w3.org/2000/svg`;function P(e){return parseFloat(window.getComputedStyle(e).strokeWidth||e.getAttribute(`stroke-width`)||`1`)}function F(e,t,n){if(t.length===0){e.innerHTML=``;return}let r=e.querySelector(`path`);r||(r=document.createElementNS(N,`path`),e.append(r));let i=t[0].coords[0],a=i,o=t[0].coords[1],s=o,c=``;for(let{coords:[e,n]}of t)i>e&&(i=e),a<e&&(a=e),o>n&&(o=n),s<n&&(s=n);i-=10,a+=10,o-=10,s+=10;let l=Array.from(e.querySelectorAll(`.marker`)),u=0;for(let{id:a,coords:[s,d]}of t){let t=b(s-i,3),f=b(d-o,3);if(c+=`${c?` L`:`M`} ${t} ${f}`,n?.markers){let n=l[u++];n||(n=document.createElementNS(N,`circle`),n.setAttribute(`class`,`marker`),n.setAttribute(`r`,String(1.5*P(r))),e.append(n)),n.setAttribute(`cx`,t),n.setAttribute(`cy`,f),n.dataset.id=a}}for(let e=u;e<l.length;e++)l[e].remove();return r.setAttribute(`d`,c),{xMin:i,xMax:a,yMin:o,yMax:s}}function I(e,t,n){let r=n?.layer??v(e,{className:`shape`});r.toggleAttribute(`hidden`,t.length===0);let i=r.querySelector(`svg`);i||(i=document.createElementNS(N,`svg`),i.setAttribute(`xmlns`,N),r.append(i));let a=F(i,t.map(({id:t,coords:[n,r]})=>({id:t,coords:e.toPixelCoords(n,r)})),n);if(a){let{xMin:t,xMax:n,yMin:r,yMax:o}=a,{centerCoords:[s,c],box:l}=e,u=b(n-t,3),d=b(o-r,3),f=b(.5*l.w+t-s,2),p=b(.5*l.h+r-c,2);i.setAttribute(`viewBox`,`0 0 ${u} ${d}`),i.setAttribute(`width`,u),i.setAttribute(`height`,d),i.setAttribute(`style`,`position: absolute; transform: translate3d(${f}px, ${p}px, 0);`)}return r}function ne(e,t,n){let r=t.map(e=>({id:_(),coords:e}));return e.onRender(()=>{I(e,r,n)}),{remove:()=>{r=[],I(e,r,n)}}}function re(e,t){let n=[],r=null,i={layer:v(e,{className:`shape-editor`}),markers:!0},a=()=>{I(e,n,i),t?.onUpdate?.(n)};return j(e,({lat:e,lon:t,originalEvent:i})=>{let o=(i.target?.closest(`.marker`))?.dataset.id;if(o&&r){clearTimeout(r),r=null,n=n.filter(({id:e})=>e!==o),a();return}let s=()=>{n.push({id:_(),coords:[e,t]}),a(),r=null};o?r=setTimeout(s,250):s()},{ignore:t?.ignore}),e.onRender(a),{reset:()=>{n=[],a()}}}const{floor:L,ceil:R,random:z}=Math;function B(e,t,n){return`${t},${n},${e.zoom},${e.lang}`}function V(e){let t=e.target;t instanceof HTMLImageElement&&(t.style.opacity=``)}function H(e,t,n,{size:r,url:i,subdomains:a,retries:o=0,error:s}){let c=new Image,l=y(e,r)??256,u=0,d=(r,o)=>{if(!i)return``;if(typeof i==`function`)return i(e,t,n);let s=i.replaceAll(`{x}`,String(r)).replaceAll(`{y}`,String(o)).replaceAll(`{z}`,String(e.zoom)).replaceAll(`{lang}`,e.lang);return a&&s.includes(`{s}`)&&(s=s.replaceAll(`{s}`,a[L(a.length*z())])),s},f=t=>{let n=t.target;if(n instanceof HTMLImageElement){if(u++<o){let e=new URL(n.src);e.searchParams.set(`_t`,String(Date.now())),n.src=e.href;return}let t=y(e,s);t&&(n.dataset.src=n.src,n.src=t),c.removeEventListener(`error`,f)}};return c.width=l,c.height=l,c.src=d(t,n),c.dataset.id=B(e,t,n),c.style.position=`absolute`,c.addEventListener(`load`,V),c.addEventListener(`error`,f),c.complete||(c.style.opacity=`0`),c}function U(e){return e.querySelectorAll(`img[data-id]`)}function W(e,t){return e.querySelector(`img[data-id="${t}"]`)}function G(e,t={}){let{attribution:n,attributionInset:r=`auto 0 0 auto`}=t,i=t.layer??v(e,{className:`tiles`}),a=v(e,{id:i.dataset.id,className:`tiles-attribution`,inset:r}),o=()=>{let{box:{w:r,h:o},centerCoords:[s,c]}=e,{size:l,margin:u=0}=t,d=y(e,l)??256,f=Array.isArray(u)?u[0]:u,p=Array.isArray(u)?u[1]:u,m=R((r+2*f)/d),h=R((o+2*p)/d),g=L(s/d),_=L(c/d),v=null,x=new Set,S=``;for(let n=0;n<=m;n++){let a=g+(n%2==0?-1:1)*L(n/2);for(let n=0;n<=h;n++){let l=_+(n%2==0?-1:1)*L(n/2);S=B(e,a,l),v=W(i,S),v||(v=H(e,a,l,t),i.append(v));let u=b(.5*r+a*d-s,2),f=b(.5*o+l*d-c,2);v.style.transform=`translate3d(${u}px, ${f}px, 0)`,x.add(S)}}for(let e of U(i)){let{id:t}=e.dataset;t&&!x.has(t)&&e.remove()}let C=y(e,n)??``;a.toggleAttribute(`hidden`,!C),a.innerHTML!==C&&(a.innerHTML=C)},s=e.zoom,c=null;return e.onRender(()=>{c!==null&&(clearTimeout(c),c=null),e.zoom===s?(i.style.opacity&&(i.style.opacity=``),o()):(i.style.opacity=`0`,c=setTimeout(()=>{c=null,i.style.opacity&&(i.style.opacity=``),o()},300)),s=e.zoom}),i}function K(e,t={}){let{zoomIn:n=`➕`,zoomOut:r=`➖`}=t,i=document.createElement(`fieldset`);i.dataset.role=`zoom`;let a=document.createElement(`button`);a.dataset.role=`zoomin`,a.innerHTML=n;let o=document.createElement(`button`);o.dataset.role=`zoomout`,o.innerHTML=r;let s=()=>{a.toggleAttribute(`disabled`,e.zoom+1>e.maxZoom),o.toggleAttribute(`disabled`,e.zoom-1<e.minZoom)};return j(e,({originalEvent:t})=>{let n=t.target;n instanceof HTMLButtonElement&&i.contains(n)&&(e.zoom+=n.dataset.role===`zoomout`?-1:1,s())}),e.onRender(s),i.append(a,o),i}function q(e,t={}){let n=v(e,{className:`controls`,inset:t.inset??`0 0 auto auto`});return n.append(K(e,t)),n}function J(e){if(e.length===0)return{};let t=e[0][0],n=t,r=e[0][1],i=r;for(let[a,o]of e)t>a&&(t=a),n<a&&(n=a),r>o&&(r=o),i<o&&(i=o);return{minLat:t,maxLat:n,minLon:r,maxLon:i}}function Y(e){return Array.isArray(e)&&e.length===2&&typeof e[0]==`number`&&typeof e[1]==`number`}function X(e){return Y(e)?{minLat:e[0],maxLat:e[0],minLon:e[1],maxLon:e[1]}:Array.isArray(e)?J(e):e}function Z(e){let{minLat:t,maxLat:n,minLon:r,maxLon:i}=X(e);return[t===void 0||n===void 0?0:(n+t)/2,r===void 0||i===void 0?0:(i+r)/2]}const{abs:Q,log2:$,min:ie,floor:ae}=Math;function oe(e,t){let{box:{w:n,h:r},center:[i,a],zoom:o}=e,{minLat:s,maxLat:c,minLon:l,maxLon:u}=t,d=0,f=0;if(l!==void 0&&u!==void 0){let t=Q(e.toPixelCoords(i,u)[0]-e.toPixelCoords(i,l)[0]);t!==0&&(d=$(n/t))}if(s!==void 0&&c!==void 0){let t=Q(e.toPixelCoords(s,a)[1]-e.toPixelCoords(c,a)[1]);t!==0&&(f=$(r/t))}let p=ae(ie(o+d,o+f)),m={center:Z(t)};p!==o&&(m.zoom=p),e.setOptions(m)}const se=[.005,.018];function ce(e,t=se){let{minLat:n=0,maxLat:r=0,minLon:i=0,maxLon:a=0}=X(e),[o,s]=t;return{minLat:n-o,maxLat:r+o,minLon:i-s,maxLon:a+s}}export{n as DEG,a as MAX_LAT,s as MAX_LON,i as MIN_LAT,o as MIN_LON,g as MapArea,t as RAD,x as addElement,w as addMovableViewport,T as addPersistence,A as addPinchToZoom,j as addPointerListener,M as addResizeObserver,ne as addShape,re as addShapeEditor,G as addTiles,q as addZoomControl,r as eccentricityMap,oe as fitGeoBounds,Z as getCenter,J as getGeoBounds,_ as getId,v as getLayer,ce as getVicinity,K as getZoomControl,Y as isCoordsArray,y as resolveDynamic,X as toGeoBounds,b as toPrecision};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "maparea",
3
- "version": "0.1.24",
3
+ "version": "0.1.26",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",