1 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
2 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
3 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
4 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
5 | return c > 3 && r && Object.defineProperty(target, key, r), r;
|
6 | };
|
7 | var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
8 | if (kind === "m") throw new TypeError("Private method is not writable");
|
9 | if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
10 | if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
11 | return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
12 | };
|
13 | var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
14 | if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
15 | if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
16 | return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
17 | };
|
18 | var _DuoyunMapElement_projection, _DuoyunMapElement_areas, _DuoyunMapElement_onPan, _DuoyunMapElement_onEnd, _DuoyunMapElement_onLeaveArea, _DuoyunMapElement_onLeaveNode, _DuoyunMapElement_renderArea, _DuoyunMapElement_renderName, _DuoyunMapElement_renderNode;
|
19 | var DuoyunMapElement_1;
|
20 | import { adoptedStyle, customElement, emitter, property, state, part } from '@mantou/gem/lib/decorators';
|
21 | import { html, svg } from '@mantou/gem/lib/element';
|
22 | import { createCSSSheet, css, styleMap, classMap } from '@mantou/gem/lib/utils';
|
23 | import { geoProjection, geoMercatorRaw, geoEquirectangularRaw, geoPath } from 'd3-geo';
|
24 | import { theme } from '../lib/theme';
|
25 | import { DuoyunLoadableBaseElement } from './base/loadable';
|
26 | import './gesture';
|
27 |
|
28 |
|
29 | const customProjectionRaw = (lambda, phi) => {
|
30 | const limit = (Math.PI / 180) * 53;
|
31 | const maxPhi = (Math.PI / 180) * 95;
|
32 | const total = maxPhi - limit;
|
33 | const [, y1] = geoEquirectangularRaw(lambda, phi);
|
34 | const [, y2] = geoMercatorRaw(lambda, phi);
|
35 | const phiAbs = Math.abs(phi);
|
36 | const ratio = phiAbs > limit ? (phiAbs - limit) / total : 0;
|
37 | const y = y1 * ratio + y2 * (1 - ratio);
|
38 | return [lambda, y];
|
39 | };
|
40 |
|
41 | export const geoCommonProjection = () => geoProjection(customProjectionRaw).scale(152.63);
|
42 |
|
43 |
|
44 | export const shapes = [
|
45 |
|
46 | {
|
47 | strokeScale: 1,
|
48 | scale: 2,
|
49 | d: 'M1 .36A.5.5 0 0 1 .64 1 .5.5 0 0 1 0 .64a.42.42 0 0 1 0-.27A.49.49 0 0 1 .63 0 .51.51 0 0 1 1 .29z',
|
50 | },
|
51 |
|
52 | {
|
53 | strokeScale: 0.9,
|
54 | scale: 2,
|
55 | d: 'M.5109 0.01L.0087 .88h1.0046L.5109 .01z',
|
56 | },
|
57 |
|
58 | {
|
59 | strokeScale: 0.8,
|
60 | scale: 2,
|
61 | d: 'M0.00704 0.5071l0.5-0.5 0.5 0.5-0.5 0.5z',
|
62 | },
|
63 |
|
64 | {
|
65 | strokeScale: 0.8,
|
66 | scale: 2,
|
67 | d: 'M0.5030.0062L0.0059 0.3674l0.1899 0.5844h0.6145l0.19-0.5844L0.5030.0062z',
|
68 | },
|
69 |
|
70 | {
|
71 | strokeScale: 0.7,
|
72 | scale: 2.5,
|
73 | d: 'M.73.48L.86.25H.6L.43 0 .3.23H0l.13.25L0 .75h.26L.43 1 .56.77h.3L.73.52V.48z',
|
74 | },
|
75 |
|
76 | {
|
77 | strokeScale: 0.7,
|
78 | scale: 3,
|
79 | d: 'M0.4974 0L0.3709 0.3726 0 0.4988l0.3692 0.1286L0.4974 1l0.1255-0.372L0.9972 0.5 0.6263 0.3744z',
|
80 | },
|
81 |
|
82 | {
|
83 | strokeScale: 0.7,
|
84 | scale: 2.5,
|
85 | d: 'M0.5107 0.8l-0.309 0.1624 0.059-0.344-0.25-0.2437 0.3455-0.0502L0.5107 0.0113l0.1546 0.3131 0.3454 0.0502-0.25 0.2437 0.0591 0.344-0.3091-0.1624z',
|
86 | },
|
87 |
|
88 | {
|
89 | strokeScale: 0.9,
|
90 | scale: 2,
|
91 | d: 'M0 0L0 1L1 1L1 0z',
|
92 | },
|
93 | ];
|
94 | const style = createCSSSheet(css `
|
95 | :host(:where(:not([hidden]))) {
|
96 | display: block;
|
97 | border-radius: ${theme.normalRound};
|
98 | background-color: ${theme.lightBackgroundColor};
|
99 | aspect-ratio: 2 / 1;
|
100 | }
|
101 | svg {
|
102 | overflow: visible;
|
103 | }
|
104 | .area {
|
105 | stroke: ${theme.backgroundColor};
|
106 | transition: opacity 0.3s ${theme.timingFunction};
|
107 | }
|
108 | .area.current:not(.disabled):hover {
|
109 | opacity: 0.8;
|
110 | }
|
111 | .name {
|
112 | fill: ${theme.textColor};
|
113 | stroke: ${theme.backgroundColor};
|
114 | paint-order: stroke;
|
115 | pointer-events: none;
|
116 | text-anchor: middle;
|
117 | }
|
118 | .node {
|
119 | paint-order: stroke;
|
120 | transform-origin: center;
|
121 | transform-box: fill-box;
|
122 | stroke-opacity: 0.4;
|
123 | --translate: calc(-50% + var(--x)), calc(-50% + var(--y));
|
124 | transform: translate(var(--translate)) scale(var(--scale));
|
125 | /* await chrome implement */
|
126 | transition: scale 0.3s ${theme.timingFunction};
|
127 | }
|
128 | .node.current:hover {
|
129 | transform: translate(var(--translate)) scale(calc(var(--scale) * 1.5));
|
130 | }
|
131 | `);
|
132 |
|
133 |
|
134 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 | let DuoyunMapElement = DuoyunMapElement_1 = class DuoyunMapElement extends DuoyunLoadableBaseElement {
|
142 | constructor() {
|
143 | super();
|
144 | this.scale = 1;
|
145 | this.translate2D = [0, 0];
|
146 | this.state = {};
|
147 | _DuoyunMapElement_projection.set(this, void 0);
|
148 | _DuoyunMapElement_areas.set(this, void 0);
|
149 | _DuoyunMapElement_onPan.set(this, ({ detail }) => {
|
150 | this.grabbing = true;
|
151 | this.pan(detail);
|
152 | });
|
153 | _DuoyunMapElement_onEnd.set(this, () => {
|
154 | this.grabbing = false;
|
155 | });
|
156 | _DuoyunMapElement_onLeaveArea.set(this, (detail) => {
|
157 | this.arealeave(detail);
|
158 | this.setState({ currentArea: undefined });
|
159 | });
|
160 | _DuoyunMapElement_onLeaveNode.set(this, (detail) => {
|
161 | this.nodeleave(detail);
|
162 | this.setState({ currentNode: undefined });
|
163 | });
|
164 | this.willMount = () => {
|
165 | this.memo(() => {
|
166 | var _a, _b;
|
167 | __classPrivateFieldSet(this, _DuoyunMapElement_projection, ((_a = this.getProjection) === null || _a === void 0 ? void 0 : _a.call(this, geoCommonProjection)) || geoCommonProjection(), "f");
|
168 | const pathFn = geoPath().projection(__classPrivateFieldGet(this, _DuoyunMapElement_projection, "f"));
|
169 | __classPrivateFieldSet(this, _DuoyunMapElement_areas, (_b = this.geo) === null || _b === void 0 ? void 0 : _b.features.map(({ geometry, properties }) => {
|
170 | return {
|
171 | path: pathFn(geometry),
|
172 | center: pathFn.centroid(geometry),
|
173 | name: (properties && (properties.name || properties.NAME)) || '',
|
174 | };
|
175 | }), "f");
|
176 | }, () => [this.geo, this.getProjection]);
|
177 | };
|
178 | _DuoyunMapElement_renderArea.set(this, (area, isCurrent) => {
|
179 | var _a;
|
180 | const { name, path } = area;
|
181 | const color = (_a = this.getAreaColor) === null || _a === void 0 ? void 0 : _a.call(this, name, isCurrent);
|
182 | const onMouseover = (originEvent) => {
|
183 | if (isCurrent) {
|
184 | this.areahover({ name, originEvent });
|
185 | }
|
186 | else {
|
187 | this.setState({ currentArea: area });
|
188 | }
|
189 | };
|
190 | return svg `
|
191 | <path
|
192 | class=${classMap({ area: true, disabled: !color, current: isCurrent })}
|
193 | d=${path}
|
194 | stroke-width=${0.1 / this.scale}
|
195 | fill=${color || theme.disabledColor}
|
196 | @click=${(originEvent) => this.areaclick({ name, originEvent })}
|
197 | @mouseover=${onMouseover}
|
198 | @mouseout=${(originEvent) => isCurrent && __classPrivateFieldGet(this, _DuoyunMapElement_onLeaveArea, "f").call(this, { name, originEvent })}
|
199 | ></path>
|
200 | `;
|
201 | });
|
202 | _DuoyunMapElement_renderName.set(this, ({ name, center: [x, y] }, isCurrent) => {
|
203 | var _a;
|
204 | return svg `
|
205 | <text
|
206 | class=${classMap({ name: true, current: isCurrent })}
|
207 | x=${x}
|
208 | y=${y}
|
209 | font-size=${2.5 / this.scale}
|
210 | stroke-width=${0.5 / this.scale}>
|
211 | ${(_a = this.getAreaName) === null || _a === void 0 ? void 0 : _a.call(this, name, isCurrent)}
|
212 | </text>
|
213 | `;
|
214 | });
|
215 | _DuoyunMapElement_renderNode.set(this, (node, isCurrent) => {
|
216 | var _a;
|
217 | const { id, type = '0', position: pos } = node;
|
218 | const position = __classPrivateFieldGet(this, _DuoyunMapElement_projection, "f").call(this, pos) || [0, 0];
|
219 | const color = ((_a = this.getNodeColor) === null || _a === void 0 ? void 0 : _a.call(this, id, isCurrent)) || theme.textColor;
|
220 | const shape = shapes[type];
|
221 | const scale = shape.scale / this.scale;
|
222 | const onMouseover = (originEvent) => {
|
223 | if (isCurrent) {
|
224 | this.nodehover({ id, originEvent });
|
225 | }
|
226 | else {
|
227 | this.setState({ currentNode: node });
|
228 | }
|
229 | };
|
230 | return svg `
|
231 | <path
|
232 | class=${classMap({ node: true, current: isCurrent })}
|
233 | style=${`--x: ${position[0]}px; --y: ${position[1]}px; --scale: ${scale}`}
|
234 | d=${shape.d}
|
235 | fill=${color}
|
236 | stroke=${theme.backgroundColor}
|
237 | stroke-width=${(2 / scale) * shape.strokeScale}
|
238 | @click=${(originEvent) => this.nodeclick({ id, originEvent })}
|
239 | @mouseover=${onMouseover}
|
240 | @mouseout=${(originEvent) => isCurrent && __classPrivateFieldGet(this, _DuoyunMapElement_onLeaveNode, "f").call(this, { id, originEvent })}
|
241 | ></path>
|
242 | `;
|
243 | });
|
244 | this.render = () => {
|
245 | var _a, _b, _c;
|
246 | const { currentArea, currentNode } = this.state;
|
247 | return html `
|
248 | <dy-gesture @pan=${__classPrivateFieldGet(this, _DuoyunMapElement_onPan, "f")} @end=${__classPrivateFieldGet(this, _DuoyunMapElement_onEnd, "f")}>
|
249 | ${svg `
|
250 | <svg
|
251 | part=${DuoyunMapElement_1.map}
|
252 | xmlns="http://www.w3.org/2000/svg"
|
253 | viewBox="-180 -90 360 180"
|
254 | aria-hidden="true"
|
255 | style=${styleMap({
|
256 | transform: `scale(${this.scale}) translate(${this.translate2D[0]}px, ${this.translate2D[1]}px)`,
|
257 | })}>
|
258 | ${(_a = __classPrivateFieldGet(this, _DuoyunMapElement_areas, "f")) === null || _a === void 0 ? void 0 : _a.map((area) => (area === currentArea ? '' : __classPrivateFieldGet(this, _DuoyunMapElement_renderArea, "f").call(this, area, false)))}
|
259 | ${currentArea ? __classPrivateFieldGet(this, _DuoyunMapElement_renderArea, "f").call(this, currentArea, true) : ''}
|
260 | ${(_b = __classPrivateFieldGet(this, _DuoyunMapElement_areas, "f")) === null || _b === void 0 ? void 0 : _b.map((area) => __classPrivateFieldGet(this, _DuoyunMapElement_renderName, "f").call(this, area, false))}
|
261 | ${currentArea ? __classPrivateFieldGet(this, _DuoyunMapElement_renderName, "f").call(this, currentArea, true) : ''}
|
262 | ${__classPrivateFieldGet(this, _DuoyunMapElement_areas, "f") && ((_c = this.nodes) === null || _c === void 0 ? void 0 : _c.map((node) => (node === currentNode ? '' : __classPrivateFieldGet(this, _DuoyunMapElement_renderNode, "f").call(this, node, false))))}
|
263 | ${currentNode ? __classPrivateFieldGet(this, _DuoyunMapElement_renderNode, "f").call(this, currentNode, true) : ''}
|
264 | </svg>
|
265 | `}
|
266 | </dy-gesture>
|
267 | `;
|
268 | };
|
269 | this.internals.role = 'img';
|
270 | }
|
271 | };
|
272 | _DuoyunMapElement_projection = new WeakMap(), _DuoyunMapElement_areas = new WeakMap(), _DuoyunMapElement_onPan = new WeakMap(), _DuoyunMapElement_onEnd = new WeakMap(), _DuoyunMapElement_onLeaveArea = new WeakMap(), _DuoyunMapElement_onLeaveNode = new WeakMap(), _DuoyunMapElement_renderArea = new WeakMap(), _DuoyunMapElement_renderName = new WeakMap(), _DuoyunMapElement_renderNode = new WeakMap();
|
273 | __decorate([
|
274 | property
|
275 | ], DuoyunMapElement.prototype, "getProjection", void 0);
|
276 | __decorate([
|
277 | property
|
278 | ], DuoyunMapElement.prototype, "geo", void 0);
|
279 | __decorate([
|
280 | property
|
281 | ], DuoyunMapElement.prototype, "getAreaColor", void 0);
|
282 | __decorate([
|
283 | property
|
284 | ], DuoyunMapElement.prototype, "getAreaName", void 0);
|
285 | __decorate([
|
286 | property
|
287 | ], DuoyunMapElement.prototype, "nodes", void 0);
|
288 | __decorate([
|
289 | property
|
290 | ], DuoyunMapElement.prototype, "getNodeColor", void 0);
|
291 | __decorate([
|
292 | property
|
293 | ], DuoyunMapElement.prototype, "scale", void 0);
|
294 | __decorate([
|
295 | property
|
296 | ], DuoyunMapElement.prototype, "translate2D", void 0);
|
297 | __decorate([
|
298 | state
|
299 | ], DuoyunMapElement.prototype, "grabbing", void 0);
|
300 | __decorate([
|
301 | emitter
|
302 | ], DuoyunMapElement.prototype, "pan", void 0);
|
303 | __decorate([
|
304 | emitter
|
305 | ], DuoyunMapElement.prototype, "nodehover", void 0);
|
306 | __decorate([
|
307 | emitter
|
308 | ], DuoyunMapElement.prototype, "nodeleave", void 0);
|
309 | __decorate([
|
310 | emitter
|
311 | ], DuoyunMapElement.prototype, "nodeclick", void 0);
|
312 | __decorate([
|
313 | emitter
|
314 | ], DuoyunMapElement.prototype, "areahover", void 0);
|
315 | __decorate([
|
316 | emitter
|
317 | ], DuoyunMapElement.prototype, "arealeave", void 0);
|
318 | __decorate([
|
319 | emitter
|
320 | ], DuoyunMapElement.prototype, "areaclick", void 0);
|
321 | __decorate([
|
322 | part
|
323 | ], DuoyunMapElement, "map", void 0);
|
324 | DuoyunMapElement = DuoyunMapElement_1 = __decorate([
|
325 | customElement('dy-map'),
|
326 | adoptedStyle(style)
|
327 | ], DuoyunMapElement);
|
328 | export { DuoyunMapElement };
|
329 | //# sourceMappingURL=map.js.map |
\ | No newline at end of file |