mirror of https://gitee.com/antv-l7/antv-l7
feat(component): add scale ,zoom, popup, marker map method
This commit is contained in:
parent
2cffc58813
commit
f55429d018
|
@ -2,7 +2,6 @@ import { configure, addParameters } from '@storybook/react';
|
|||
import '@storybook/addon-console';
|
||||
import { create } from '@storybook/theming';
|
||||
import '!style-loader!css-loader!sass-loader!./iframe.scss';
|
||||
|
||||
addParameters({
|
||||
options: {
|
||||
isFullscreen: false,
|
||||
|
|
|
@ -0,0 +1,397 @@
|
|||
.l7-marker {
|
||||
position: absolute !important;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 5;
|
||||
}
|
||||
.l7-popup-anchor-top,
|
||||
.l7-popup-anchor-top-left,
|
||||
.l7-popup-anchor-top-right {
|
||||
-webkit-flex-direction: column;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-bottom,
|
||||
.l7-popup-anchor-bottom-left,
|
||||
.l7-popup-anchor-bottom-right {
|
||||
-webkit-flex-direction: column-reverse;
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-left {
|
||||
-webkit-flex-direction: row;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-right {
|
||||
-webkit-flex-direction: row-reverse;
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
.l7-popup {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
will-change: transform;
|
||||
pointer-events: none;
|
||||
z-index: 5;
|
||||
}
|
||||
.l7-popup-tip {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: 10px solid transparent;
|
||||
z-index: 1;
|
||||
}
|
||||
.l7-popup-anchor-top .l7-popup-tip {
|
||||
-webkit-align-self: center;
|
||||
align-self: center;
|
||||
border-top: none;
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-top-left .l7-popup-tip {
|
||||
-webkit-align-self: flex-start;
|
||||
align-self: flex-start;
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-top-right .l7-popup-tip {
|
||||
-webkit-align-self: flex-end;
|
||||
align-self: flex-end;
|
||||
border-top: none;
|
||||
border-right: none;
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-bottom .l7-popup-tip {
|
||||
-webkit-align-self: center;
|
||||
align-self: center;
|
||||
border-bottom: none;
|
||||
border-top-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-bottom-left .l7-popup-tip {
|
||||
-webkit-align-self: flex-start;
|
||||
align-self: flex-start;
|
||||
border-bottom: none;
|
||||
border-left: none;
|
||||
border-top-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-bottom-right .l7-popup-tip {
|
||||
-webkit-align-self: flex-end;
|
||||
align-self: flex-end;
|
||||
border-bottom: none;
|
||||
border-right: none;
|
||||
border-top-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-left .l7-popup-tip {
|
||||
-webkit-align-self: center;
|
||||
align-self: center;
|
||||
border-left: none;
|
||||
border-right-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-right .l7-popup-tip {
|
||||
-webkit-align-self: center;
|
||||
align-self: center;
|
||||
border-right: none;
|
||||
border-left-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-close-button {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
font-size: 25px;
|
||||
line-height: 20px;
|
||||
border-radius: 0 3px 0 0;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.l7-popup-close-button:hover {
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.l7-popup-content {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
padding: 10px 10px 15px;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-top-left .l7-popup-content {
|
||||
border-top-left-radius: 0;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-top-right .l7-popup-content {
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-bottom-left .l7-popup-content {
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-bottom-right .l7-popup-content {
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
.l7-popup-track-pointer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.l7-popup-track-pointer * {
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.l7-map:hover .l7-popup-track-pointer {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.l7-map:active .l7-popup-track-pointer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.l7-popup-close-button {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
border: 0;
|
||||
border-radius: 0 3px 0 0;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.l7-popup-close-button:hover {
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.l7-popup-content {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
padding: 10px 10px 15px;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* general toolbar styles */
|
||||
|
||||
.l7-bar {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.l7-bar a,
|
||||
.l7-bar a:hover {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #ccc;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
.l7-bar a,
|
||||
.l7-control-layers-toggle {
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
display: block;
|
||||
}
|
||||
.l7-bar a:hover {
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
.l7-bar a:first-child {
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
.l7-bar a:last-child {
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom: none;
|
||||
}
|
||||
.l7-bar a.l7-disabled {
|
||||
cursor: default;
|
||||
background-color: #f4f4f4;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
|
||||
/* control positioning */
|
||||
|
||||
.l7-control-container {
|
||||
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
}
|
||||
.l7-control-hide {
|
||||
display: none;
|
||||
}
|
||||
.l7-control {
|
||||
position: relative;
|
||||
z-index: 800;
|
||||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
|
||||
pointer-events: auto;
|
||||
}
|
||||
.l7-top,
|
||||
.l7-bottom {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
}
|
||||
.l7-top {
|
||||
top: 0;
|
||||
}
|
||||
.l7-right {
|
||||
right: 0;
|
||||
}
|
||||
.l7-bottom {
|
||||
bottom: 0;
|
||||
}
|
||||
.l7-left {
|
||||
left: 0;
|
||||
}
|
||||
.l7-control {
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
.l7-right .l7-control {
|
||||
float: right;
|
||||
}
|
||||
.l7-top .l7-control {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.l7-bottom .l7-control {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.l7-left .l7-control {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.l7-right .l7-control {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
/* attribution and scale controls */
|
||||
|
||||
.l7-control-container .l7-control-attribution {
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
margin: 0;
|
||||
}
|
||||
.l7-control-attribution,
|
||||
.l7-control-scale-line {
|
||||
padding: 0 5px;
|
||||
color: #333;
|
||||
}
|
||||
.l7-control-attribution a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.l7-control-attribution a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.l7-container .l7-control-attribution,
|
||||
.l7-container .l7-control-scale {
|
||||
font-size: 11px;
|
||||
}
|
||||
.l7-left .l7-control-scale {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.l7-bottom .l7-control-scale {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.l7-control-scale-line {
|
||||
border: 2px solid #777;
|
||||
border-top: none;
|
||||
line-height: 1.1;
|
||||
padding: 2px 5px 1px;
|
||||
font-size: 11px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.l7-control-scale-line:not(:first-child) {
|
||||
border-top: 2px solid #777;
|
||||
border-bottom: none;
|
||||
margin-top: -2px;
|
||||
}
|
||||
.l7-control-scale-line:not(:first-child):not(:last-child) {
|
||||
border-bottom: 2px solid #777;
|
||||
}
|
||||
|
||||
.l7-touch .l7-control-attribution,
|
||||
.l7-touch .l7-control-layers,
|
||||
.l7-touch .l7-bar {
|
||||
box-shadow: none;
|
||||
}
|
||||
.l7-touch .l7-control-layers,
|
||||
.l7-touch .l7-bar {
|
||||
border: 2px solid rgba(0,0,0,0.2);
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
|
||||
/* layers control */
|
||||
|
||||
.l7-control-layers {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.l7-control-layers-toggle {
|
||||
background-image: url(../images/layers.svg);
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
.l7-retina .l7-control-layers-toggle {
|
||||
background-image: url(../images/layers.svg);
|
||||
background-size: 26px 26px;
|
||||
}
|
||||
.l7-touch .l7-control-layers-toggle {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
}
|
||||
.l7-control-layers .l7-control-layers-list,
|
||||
.l7-control-layers-expanded .l7-control-layers-toggle {
|
||||
display: none;
|
||||
}
|
||||
.l7-control-layers-expanded .l7-control-layers-list {
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.l7-control-layers-expanded {
|
||||
padding: 6px 10px 6px 6px;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
}
|
||||
.l7-control-layers-scrollbar {
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
padding-right: 5px;
|
||||
}
|
||||
.l7-control-layers-selector {
|
||||
margin-top: 2px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
.l7-control-layers label {
|
||||
display: block;
|
||||
}
|
||||
.l7-control-layers-separator {
|
||||
height: 0;
|
||||
border-top: 1px solid #ddd;
|
||||
margin: 5px -10px 5px -6px;
|
||||
}
|
||||
|
|
@ -27,9 +27,13 @@ module.exports = ({ config }) => {
|
|||
},
|
||||
],
|
||||
enforce: 'pre',
|
||||
});
|
||||
},{
|
||||
test: /\.stories\.css?$/,
|
||||
use: ['style-loader', 'css-loader'],
|
||||
},
|
||||
);
|
||||
|
||||
config.resolve.extensions.push('.ts', '.tsx', '.js', '.glsl');
|
||||
|
||||
return config;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -77,4 +77,4 @@ module.exports = (api) => {
|
|||
},
|
||||
ignore: ['node_modules'],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5524,6 +5524,16 @@
|
|||
"@babel/plugin-syntax-typescript": "^7.3.3"
|
||||
}
|
||||
},
|
||||
"babel-plugin-css-modules-transform": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-css-modules-transform/-/babel-plugin-css-modules-transform-1.6.2.tgz",
|
||||
"integrity": "sha512-zBsI54N5n979vfYpqFzQ6oRwEiVcmLH5REyaincNW+Ecl52nvRsQPYIbDcJzHePrXI20YSRUw6G/qbPwZZDgfg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"css-modules-require-hook": "^4.0.6",
|
||||
"mkdirp": "^0.5.1"
|
||||
}
|
||||
},
|
||||
"babel-plugin-dynamic-import-node": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz",
|
||||
|
@ -8289,6 +8299,84 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"css-modules-require-hook": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/css-modules-require-hook/-/css-modules-require-hook-4.2.3.tgz",
|
||||
"integrity": "sha1-Z5LKQSsV4j5vm+agfc739Xf/kE0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "^2.2.0",
|
||||
"generic-names": "^1.0.1",
|
||||
"glob-to-regexp": "^0.3.0",
|
||||
"icss-replace-symbols": "^1.0.2",
|
||||
"lodash": "^4.3.0",
|
||||
"postcss": "^6.0.1",
|
||||
"postcss-modules-extract-imports": "^1.0.0",
|
||||
"postcss-modules-local-by-default": "^1.0.1",
|
||||
"postcss-modules-resolve-imports": "^1.3.0",
|
||||
"postcss-modules-scope": "^1.0.0",
|
||||
"postcss-modules-values": "^1.1.1",
|
||||
"seekout": "^1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"postcss": {
|
||||
"version": "6.0.23",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
|
||||
"integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^2.4.1",
|
||||
"source-map": "^0.6.1",
|
||||
"supports-color": "^5.4.0"
|
||||
}
|
||||
},
|
||||
"postcss-modules-extract-imports": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.1.tgz",
|
||||
"integrity": "sha512-6jt9XZwUhwmRUhb/CkyJY020PYaPJsCyt3UjbaWo6XEbH/94Hmv6MP7fG2C5NDU/BcHzyGYxNtHvM+LTf9HrYw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"postcss": "^6.0.1"
|
||||
}
|
||||
},
|
||||
"postcss-modules-local-by-default": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz",
|
||||
"integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"css-selector-tokenizer": "^0.7.0",
|
||||
"postcss": "^6.0.1"
|
||||
}
|
||||
},
|
||||
"postcss-modules-scope": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz",
|
||||
"integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"css-selector-tokenizer": "^0.7.0",
|
||||
"postcss": "^6.0.1"
|
||||
}
|
||||
},
|
||||
"postcss-modules-values": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz",
|
||||
"integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"icss-replace-symbols": "^1.1.0",
|
||||
"postcss": "^6.0.1"
|
||||
}
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"css-select": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
|
||||
|
@ -8307,6 +8395,57 @@
|
|||
"integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==",
|
||||
"dev": true
|
||||
},
|
||||
"css-selector-tokenizer": {
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz",
|
||||
"integrity": "sha512-xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cssesc": "^0.1.0",
|
||||
"fastparse": "^1.1.1",
|
||||
"regexpu-core": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"cssesc": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz",
|
||||
"integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=",
|
||||
"dev": true
|
||||
},
|
||||
"jsesc": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
|
||||
"integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
|
||||
"dev": true
|
||||
},
|
||||
"regexpu-core": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
|
||||
"integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"regenerate": "^1.2.1",
|
||||
"regjsgen": "^0.2.0",
|
||||
"regjsparser": "^0.1.4"
|
||||
}
|
||||
},
|
||||
"regjsgen": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
|
||||
"integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=",
|
||||
"dev": true
|
||||
},
|
||||
"regjsparser": {
|
||||
"version": "0.1.5",
|
||||
"resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
|
||||
"integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"jsesc": "~0.5.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"css-to-react-native": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-2.3.2.tgz",
|
||||
|
@ -9927,6 +10066,12 @@
|
|||
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
|
||||
"dev": true
|
||||
},
|
||||
"fastparse": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz",
|
||||
"integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==",
|
||||
"dev": true
|
||||
},
|
||||
"fastq": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz",
|
||||
|
@ -11038,6 +11183,41 @@
|
|||
"globule": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"generic-names": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/generic-names/-/generic-names-1.0.3.tgz",
|
||||
"integrity": "sha1-LXhqEhruUIh2eWk56OO/+DbCCRc=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"loader-utils": "^0.2.16"
|
||||
},
|
||||
"dependencies": {
|
||||
"big.js": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz",
|
||||
"integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==",
|
||||
"dev": true
|
||||
},
|
||||
"json5": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
|
||||
"integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
|
||||
"dev": true
|
||||
},
|
||||
"loader-utils": {
|
||||
"version": "0.2.17",
|
||||
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz",
|
||||
"integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"big.js": "^3.1.3",
|
||||
"emojis-list": "^2.0.0",
|
||||
"json5": "^0.5.0",
|
||||
"object-assign": "^4.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"genfun": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/genfun/-/genfun-5.0.0.tgz",
|
||||
|
@ -16836,6 +17016,51 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"postcss-modules-resolve-imports": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-modules-resolve-imports/-/postcss-modules-resolve-imports-1.3.0.tgz",
|
||||
"integrity": "sha1-OY0wALla6WlCDN9M2D+oBn8cXq4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"css-selector-tokenizer": "^0.7.0",
|
||||
"icss-utils": "^3.0.1",
|
||||
"minimist": "^1.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"icss-utils": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-3.0.1.tgz",
|
||||
"integrity": "sha1-7nDTroysOMa+XtkehRsn7tNDrQ8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"postcss": "^6.0.2"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"dev": true
|
||||
},
|
||||
"postcss": {
|
||||
"version": "6.0.23",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
|
||||
"integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^2.4.1",
|
||||
"source-map": "^0.6.1",
|
||||
"supports-color": "^5.4.0"
|
||||
}
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"postcss-modules-scope": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.1.0.tgz",
|
||||
|
@ -18969,6 +19194,12 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"seekout": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/seekout/-/seekout-1.0.2.tgz",
|
||||
"integrity": "sha1-CbqfG9W0b7sTRxjrGaaDgsuxuck=",
|
||||
"dev": true
|
||||
},
|
||||
"select": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
|
||||
|
|
|
@ -27,11 +27,13 @@
|
|||
"babel-jest": "^24.8.0",
|
||||
"babel-loader": "^8.0.6",
|
||||
"babel-plugin-const-enum": "^0.0.2",
|
||||
"babel-plugin-css-modules-transform": "^1.6.2",
|
||||
"babel-plugin-inline-import": "^3.0.0",
|
||||
"babel-plugin-transform-postcss": "^0.3.0",
|
||||
"clean-webpack-plugin": "^0.1.19",
|
||||
"commitizen": "^4.0.3",
|
||||
"copy-webpack-plugin": "^4.5.2",
|
||||
"css-loader": "^3.0.0",
|
||||
"css-loader": "^3.2.0",
|
||||
"cz-conventional-changelog": "^3.0.2",
|
||||
"dat.gui": "^0.7.2",
|
||||
"enzyme": "^3.6.0",
|
||||
|
@ -45,6 +47,8 @@
|
|||
"lint-staged": "^9.2.4",
|
||||
"node-sass": "^4.12.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss": "^7.0.18",
|
||||
"postcss-plugin": "^1.0.0",
|
||||
"prettier": "^1.14.2",
|
||||
"raw-loader": "^1.0.0",
|
||||
"react": "^16.8.6",
|
||||
|
@ -52,7 +56,7 @@
|
|||
"react-dom": "^16.8.6",
|
||||
"rimraf": "^2.6.2",
|
||||
"sass-loader": "^7.1.0",
|
||||
"style-loader": "^0.23.1",
|
||||
"style-loader": "^1.0.0",
|
||||
"styled-components": "^3.4.6",
|
||||
"stylelint": "^9.5.0",
|
||||
"stylelint-config-recommended": "^2.1.0",
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
lib
|
||||
esm
|
||||
dist
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"name": "@l7/component",
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"main": "/dist/index.js",
|
||||
"module": "esm/index.js",
|
||||
"types": "esm/index.d.ts",
|
||||
"sideEffects": true,
|
||||
"files": [
|
||||
"lib",
|
||||
"esm",
|
||||
"README.md"
|
||||
],
|
||||
"scripts": {
|
||||
"tsc": "tsc --project tsconfig.build.json",
|
||||
"build": "BABEL_ENV=build babel src --root-mode upward --out-dir dist --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
|
||||
"watch": "BABEL_ENV=build babel src --watch --root-mode upward --out-dir dist --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
|
||||
"lint:ts": "run-p -c lint:ts-*",
|
||||
"test": "jest"
|
||||
},
|
||||
"author": "lzxue",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@l7/core": "0.0.1",
|
||||
"@l7/utils": "0.0.1",
|
||||
"@turf/distance": "^6.0.1",
|
||||
"eventemitter3": "^3.1.0",
|
||||
"inversify": "^5.0.1",
|
||||
"inversify-inject-decorators": "^3.1.0",
|
||||
"inversify-logging": "^0.2.1"
|
||||
},
|
||||
"devDependencies": {}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
import { IControlService, IMapService, lazyInject, TYPES } from '@l7/core';
|
||||
import { DOM } from '@l7/utils';
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
|
||||
export enum PositionType {
|
||||
'TOPRIGHT' = 'topright',
|
||||
'TOPLEFT' = 'topleft',
|
||||
'BOTTOMRIGHT' = 'bottomright',
|
||||
'BOTTOMLEFT' = 'bottomleft',
|
||||
}
|
||||
export type PositionName =
|
||||
| 'topright'
|
||||
| 'topleft'
|
||||
| 'bottomright'
|
||||
| 'bottomleft';
|
||||
export interface IControlOption {
|
||||
position: PositionName;
|
||||
[key: string]: any;
|
||||
}
|
||||
export default class Control extends EventEmitter {
|
||||
public controlOption: IControlOption;
|
||||
protected mapsService: IMapService;
|
||||
@lazyInject(TYPES.IControlService)
|
||||
private readonly controlService: IControlService;
|
||||
private container: HTMLElement;
|
||||
private isShow: boolean;
|
||||
|
||||
constructor(cfg?: Partial<IControlOption>) {
|
||||
super();
|
||||
this.controlOption = {
|
||||
...this.getDefault(),
|
||||
...(cfg || {}),
|
||||
};
|
||||
}
|
||||
public getDefault() {
|
||||
return {
|
||||
position: PositionType.TOPRIGHT,
|
||||
};
|
||||
}
|
||||
public setPosition(position: PositionName) {
|
||||
const controlService = this.controlService;
|
||||
if (controlService) {
|
||||
controlService.removeControl(this);
|
||||
}
|
||||
this.controlOption.position = position;
|
||||
if (controlService) {
|
||||
controlService.addControl(this, this.mapsService);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public addTo(mapService: IMapService) {
|
||||
this.remove();
|
||||
this.isShow = true;
|
||||
this.mapsService = mapService;
|
||||
this.container = this.onAdd(mapService);
|
||||
const container = this.container;
|
||||
const pos = this.controlOption.position;
|
||||
const corner = this.controlService.controlCorners[pos];
|
||||
DOM.addClass(container, 'l7-control');
|
||||
|
||||
if (pos.indexOf('bottom') !== -1) {
|
||||
corner.insertBefore(container, corner.firstChild);
|
||||
} else {
|
||||
corner.appendChild(container);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public onAdd(Map: IMapService): HTMLElement {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
public hide() {
|
||||
const container = this.container;
|
||||
DOM.addClass(container, 'l7-control-hide');
|
||||
this.isShow = false;
|
||||
}
|
||||
public show() {
|
||||
const container = this.container;
|
||||
DOM.removeClass(container, 'l7-control-hide');
|
||||
this.isShow = true;
|
||||
}
|
||||
public remove() {
|
||||
if (!this.mapsService) {
|
||||
return this;
|
||||
}
|
||||
DOM.remove(this.container);
|
||||
}
|
||||
public _refocusOnMap(e: MouseEvent) {
|
||||
// if map exists and event is not a keyboard event
|
||||
if (this.mapsService && e && e.screenX > 0 && e.screenY > 0) {
|
||||
const container = this.mapsService.getContainer();
|
||||
if (container !== null) {
|
||||
container.focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
import { IMapService } from '@l7/core';
|
||||
import { bindAll, DOM, lnglatDistance } from '@l7/utils';
|
||||
import Control, {
|
||||
IControlOption,
|
||||
PositionName,
|
||||
PositionType,
|
||||
} from './BaseControl';
|
||||
export interface ILayerControlOption extends IControlOption {
|
||||
collapsed: boolean;
|
||||
autoZIndex: boolean;
|
||||
hideSingleBase: boolean;
|
||||
sortLayers: boolean;
|
||||
}
|
||||
export default class Layers extends Control {
|
||||
private layerControlInputs: any[];
|
||||
private layers: any[];
|
||||
private lastZIndex: number;
|
||||
private handlingClick: boolean;
|
||||
|
||||
constructor(cfg: Partial<ILayerControlOption>) {
|
||||
super(cfg);
|
||||
this.layerControlInputs = [];
|
||||
this.layers = [];
|
||||
this.lastZIndex = 0;
|
||||
this.handlingClick = false;
|
||||
// const baseLayers = this.get('baseLayers');
|
||||
// const overlays = this.get('overlayers');
|
||||
// for (const i in baseLayers) {
|
||||
// this._addLayer(baseLayers[i], i);
|
||||
// }
|
||||
|
||||
// for (const i in overlays) {
|
||||
// this._addLayer(overlays[i], i, true);
|
||||
// }
|
||||
// bindAll([ '_checkDisabledLayers', '_onLayerChange', 'collapse', 'extend', 'expand', '_onInputClick' ], this);
|
||||
}
|
||||
|
||||
public getDefault() {
|
||||
return {
|
||||
collapsed: true,
|
||||
position: PositionType.TOPRIGHT,
|
||||
autoZIndex: true,
|
||||
hideSingleBase: false,
|
||||
sortLayers: false,
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
import { IMapService } from '@l7/core';
|
||||
import { bindAll, DOM, lnglatDistance } from '@l7/utils';
|
||||
import Control, { IControlOption, PositionType } from './BaseControl';
|
||||
export interface IScaleControlOption extends IControlOption {
|
||||
maxWidth: number;
|
||||
metric: boolean;
|
||||
updateWhenIdle: boolean;
|
||||
imperial: boolean;
|
||||
}
|
||||
export default class Scale extends Control {
|
||||
private mScale: HTMLElement;
|
||||
private iScale: HTMLElement;
|
||||
constructor(cfg?: Partial<IScaleControlOption>) {
|
||||
super(cfg);
|
||||
bindAll(['update'], this);
|
||||
}
|
||||
|
||||
public getDefault() {
|
||||
return {
|
||||
position: PositionType.BOTTOMLEFT,
|
||||
maxWidth: 100,
|
||||
metric: true,
|
||||
updateWhenIdle: false,
|
||||
imperial: false,
|
||||
};
|
||||
}
|
||||
|
||||
public onAdd(MapService: IMapService) {
|
||||
const className = 'l7-control-scale';
|
||||
const container = DOM.create('div', className);
|
||||
this.addScales(className + '-line', container);
|
||||
const { updateWhenIdle } = this.controlOption;
|
||||
// TODO: 高德地图和MapBox地图事件不一致问题
|
||||
this.mapsService.on(updateWhenIdle ? 'moveend' : 'mapmove', this.update);
|
||||
this.update();
|
||||
|
||||
return container;
|
||||
}
|
||||
public onRemove(MapService: IMapService) {
|
||||
const { updateWhenIdle } = this.controlOption;
|
||||
this.mapsService.off(updateWhenIdle ? 'moveend' : 'mapmove', this.update);
|
||||
}
|
||||
public update() {
|
||||
const mapsService = this.mapsService;
|
||||
const { maxWidth } = this.controlOption;
|
||||
const y = mapsService.getSize()[1] / 2;
|
||||
|
||||
const p1 = mapsService.containerToLngLat([0, y]);
|
||||
const p2 = mapsService.containerToLngLat([maxWidth, y]);
|
||||
const maxMeters = lnglatDistance([p1.lng, p1.lat], [p2.lng, p2.lat]);
|
||||
this.updateScales(maxMeters);
|
||||
}
|
||||
public updateScales(maxMeters: number) {
|
||||
const { metric, imperial } = this.controlOption;
|
||||
if (metric && maxMeters) {
|
||||
this.updateMetric(maxMeters);
|
||||
}
|
||||
if (imperial && maxMeters) {
|
||||
this.updateImperial(maxMeters);
|
||||
}
|
||||
}
|
||||
private updateMetric(maxMeters: number) {
|
||||
const meters = this.getRoundNum(maxMeters);
|
||||
const label = meters < 1000 ? meters + ' m' : meters / 1000 + ' km';
|
||||
this.updateScale(this.mScale, label, meters / maxMeters);
|
||||
}
|
||||
private updateImperial(maxMeters: number) {
|
||||
const maxFeet = maxMeters * 3.2808399;
|
||||
let maxMiles: number;
|
||||
let miles: number;
|
||||
let feet: number;
|
||||
|
||||
if (maxFeet > 5280) {
|
||||
maxMiles = maxFeet / 5280;
|
||||
miles = this.getRoundNum(maxMiles);
|
||||
this.updateScale(this.iScale, miles + ' mi', miles / maxMiles);
|
||||
} else {
|
||||
feet = this.getRoundNum(maxFeet);
|
||||
this.updateScale(this.iScale, feet + ' ft', feet / maxFeet);
|
||||
}
|
||||
}
|
||||
private updateScale(scale: HTMLElement, text: string, ratio: number) {
|
||||
const { maxWidth } = this.controlOption;
|
||||
scale.style.width = Math.round(maxWidth * ratio) + 'px';
|
||||
scale.innerHTML = text;
|
||||
}
|
||||
private getRoundNum(num: number) {
|
||||
const pow10 = Math.pow(10, (Math.floor(num) + '').length - 1);
|
||||
let d = num / pow10;
|
||||
|
||||
d = d >= 10 ? 10 : d >= 5 ? 5 : d >= 3 ? 3 : d >= 2 ? 2 : 1;
|
||||
|
||||
return pow10 * d;
|
||||
}
|
||||
private addScales(className: string, container: HTMLElement) {
|
||||
const { metric, imperial } = this.controlOption;
|
||||
if (metric) {
|
||||
this.mScale = DOM.create('div', className, container);
|
||||
}
|
||||
if (imperial) {
|
||||
this.iScale = DOM.create('div', className, container);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
import { IMapService } from '@l7/core';
|
||||
import { bindAll, DOM } from '@l7/utils';
|
||||
import Control, { IControlOption, PositionType } from './BaseControl';
|
||||
export interface IZoomControlOption extends IControlOption {
|
||||
zoomInText: string;
|
||||
zoomInTitle: string;
|
||||
zoomOutText: string;
|
||||
zoomOutTitle: string;
|
||||
}
|
||||
export default class Zoom extends Control {
|
||||
private disabled: boolean;
|
||||
private zoomInButton: HTMLElement;
|
||||
private zoomOutButton: HTMLElement;
|
||||
|
||||
constructor(cfg?: Partial<IZoomControlOption>) {
|
||||
super(cfg);
|
||||
bindAll(['updateDisabled', 'zoomIn', 'zoomOut'], this);
|
||||
}
|
||||
public getDefault() {
|
||||
return {
|
||||
position: PositionType.TOPLEFT,
|
||||
zoomInText: '+',
|
||||
zoomInTitle: 'Zoom in',
|
||||
zoomOutText: '−',
|
||||
zoomOutTitle: 'Zoom out',
|
||||
};
|
||||
}
|
||||
|
||||
public onAdd(MapService: IMapService) {
|
||||
const zoomName = 'l7-control-zoom';
|
||||
const container = DOM.create('div', zoomName + ' l7-bar');
|
||||
|
||||
this.zoomInButton = this.createButton(
|
||||
this.controlOption.zoomInText,
|
||||
this.controlOption.zoomInTitle,
|
||||
zoomName + '-in',
|
||||
container,
|
||||
this.zoomIn,
|
||||
);
|
||||
this.zoomOutButton = this.createButton(
|
||||
this.controlOption.zoomOutText,
|
||||
this.controlOption.zoomOutTitle,
|
||||
zoomName + '-out',
|
||||
container,
|
||||
this.zoomOut,
|
||||
);
|
||||
this.mapsService.on('zoomend', this.updateDisabled);
|
||||
this.mapsService.on('zoomchange', this.updateDisabled);
|
||||
this.updateDisabled();
|
||||
return container;
|
||||
}
|
||||
|
||||
public onRemove() {
|
||||
this.mapsService.off('zoomend', this.updateDisabled);
|
||||
this.mapsService.off('zoomchange', this.updateDisabled);
|
||||
}
|
||||
|
||||
public disable() {
|
||||
this.disabled = true;
|
||||
this.updateDisabled();
|
||||
return this;
|
||||
}
|
||||
|
||||
public enable() {
|
||||
this.disabled = false;
|
||||
this.updateDisabled();
|
||||
return this;
|
||||
}
|
||||
|
||||
private zoomIn() {
|
||||
if (
|
||||
!this.disabled &&
|
||||
this.mapsService.getZoom() < this.mapsService.getMaxZoom()
|
||||
) {
|
||||
this.mapsService.zoomIn();
|
||||
}
|
||||
}
|
||||
private zoomOut() {
|
||||
if (
|
||||
!this.disabled &&
|
||||
this.mapsService.getZoom() > this.mapsService.getMinZoom()
|
||||
) {
|
||||
this.mapsService.zoomOut();
|
||||
}
|
||||
}
|
||||
private createButton(
|
||||
html: string,
|
||||
tile: string,
|
||||
className: string,
|
||||
container: HTMLElement,
|
||||
fn: (...arg: any[]) => any,
|
||||
) {
|
||||
const link = DOM.create('a', className, container) as HTMLLinkElement;
|
||||
link.innerHTML = html;
|
||||
link.href = '#';
|
||||
link.addEventListener('click', fn);
|
||||
return link;
|
||||
}
|
||||
private updateDisabled() {
|
||||
const mapsService = this.mapsService;
|
||||
const className = 'l7-disabled';
|
||||
DOM.removeClass(this.zoomInButton, className);
|
||||
DOM.removeClass(this.zoomOutButton, className);
|
||||
if (this.disabled || mapsService.getZoom() <= mapsService.getMinZoom()) {
|
||||
DOM.addClass(this.zoomOutButton, className);
|
||||
}
|
||||
if (this.disabled || mapsService.getZoom() >= mapsService.getMaxZoom()) {
|
||||
DOM.addClass(this.zoomInButton, className);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,397 @@
|
|||
.l7-marker {
|
||||
position: absolute !important;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 5;
|
||||
}
|
||||
.l7-popup-anchor-top,
|
||||
.l7-popup-anchor-top-left,
|
||||
.l7-popup-anchor-top-right {
|
||||
-webkit-flex-direction: column;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-bottom,
|
||||
.l7-popup-anchor-bottom-left,
|
||||
.l7-popup-anchor-bottom-right {
|
||||
-webkit-flex-direction: column-reverse;
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-left {
|
||||
-webkit-flex-direction: row;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-right {
|
||||
-webkit-flex-direction: row-reverse;
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
.l7-popup {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
will-change: transform;
|
||||
pointer-events: none;
|
||||
z-index: 5;
|
||||
}
|
||||
.l7-popup-tip {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: 10px solid transparent;
|
||||
z-index: 1;
|
||||
}
|
||||
.l7-popup-anchor-top .l7-popup-tip {
|
||||
-webkit-align-self: center;
|
||||
align-self: center;
|
||||
border-top: none;
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-top-left .l7-popup-tip {
|
||||
-webkit-align-self: flex-start;
|
||||
align-self: flex-start;
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-top-right .l7-popup-tip {
|
||||
-webkit-align-self: flex-end;
|
||||
align-self: flex-end;
|
||||
border-top: none;
|
||||
border-right: none;
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-bottom .l7-popup-tip {
|
||||
-webkit-align-self: center;
|
||||
align-self: center;
|
||||
border-bottom: none;
|
||||
border-top-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-bottom-left .l7-popup-tip {
|
||||
-webkit-align-self: flex-start;
|
||||
align-self: flex-start;
|
||||
border-bottom: none;
|
||||
border-left: none;
|
||||
border-top-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-bottom-right .l7-popup-tip {
|
||||
-webkit-align-self: flex-end;
|
||||
align-self: flex-end;
|
||||
border-bottom: none;
|
||||
border-right: none;
|
||||
border-top-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-left .l7-popup-tip {
|
||||
-webkit-align-self: center;
|
||||
align-self: center;
|
||||
border-left: none;
|
||||
border-right-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-right .l7-popup-tip {
|
||||
-webkit-align-self: center;
|
||||
align-self: center;
|
||||
border-right: none;
|
||||
border-left-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-close-button {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
font-size: 25px;
|
||||
line-height: 20px;
|
||||
border-radius: 0 3px 0 0;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.l7-popup-close-button:hover {
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.l7-popup-content {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
padding: 10px 10px 15px;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-top-left .l7-popup-content {
|
||||
border-top-left-radius: 0;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-top-right .l7-popup-content {
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-bottom-left .l7-popup-content {
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-bottom-right .l7-popup-content {
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
.l7-popup-track-pointer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.l7-popup-track-pointer * {
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.l7-map:hover .l7-popup-track-pointer {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.l7-map:active .l7-popup-track-pointer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.l7-popup-close-button {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
border: 0;
|
||||
border-radius: 0 3px 0 0;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.l7-popup-close-button:hover {
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.l7-popup-content {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
padding: 10px 10px 15px;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* general toolbar styles */
|
||||
|
||||
.l7-bar {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.l7-bar a,
|
||||
.l7-bar a:hover {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #ccc;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
.l7-bar a,
|
||||
.l7-control-layers-toggle {
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
display: block;
|
||||
}
|
||||
.l7-bar a:hover {
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
.l7-bar a:first-child {
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
.l7-bar a:last-child {
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom: none;
|
||||
}
|
||||
.l7-bar a.l7-disabled {
|
||||
cursor: default;
|
||||
background-color: #f4f4f4;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
|
||||
/* control positioning */
|
||||
|
||||
.l7-control-container {
|
||||
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
}
|
||||
.l7-control-hide {
|
||||
display: none;
|
||||
}
|
||||
.l7-control {
|
||||
position: relative;
|
||||
z-index: 800;
|
||||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
|
||||
pointer-events: auto;
|
||||
}
|
||||
.l7-top,
|
||||
.l7-bottom {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
}
|
||||
.l7-top {
|
||||
top: 0;
|
||||
}
|
||||
.l7-right {
|
||||
right: 0;
|
||||
}
|
||||
.l7-bottom {
|
||||
bottom: 0;
|
||||
}
|
||||
.l7-left {
|
||||
left: 0;
|
||||
}
|
||||
.l7-control {
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
.l7-right .l7-control {
|
||||
float: right;
|
||||
}
|
||||
.l7-top .l7-control {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.l7-bottom .l7-control {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.l7-left .l7-control {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.l7-right .l7-control {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
/* attribution and scale controls */
|
||||
|
||||
.l7-control-container .l7-control-attribution {
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
margin: 0;
|
||||
}
|
||||
.l7-control-attribution,
|
||||
.l7-control-scale-line {
|
||||
padding: 0 5px;
|
||||
color: #333;
|
||||
}
|
||||
.l7-control-attribution a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.l7-control-attribution a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.l7-container .l7-control-attribution,
|
||||
.l7-container .l7-control-scale {
|
||||
font-size: 11px;
|
||||
}
|
||||
.l7-left .l7-control-scale {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.l7-bottom .l7-control-scale {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.l7-control-scale-line {
|
||||
border: 2px solid #777;
|
||||
border-top: none;
|
||||
line-height: 1.1;
|
||||
padding: 2px 5px 1px;
|
||||
font-size: 11px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.l7-control-scale-line:not(:first-child) {
|
||||
border-top: 2px solid #777;
|
||||
border-bottom: none;
|
||||
margin-top: -2px;
|
||||
}
|
||||
.l7-control-scale-line:not(:first-child):not(:last-child) {
|
||||
border-bottom: 2px solid #777;
|
||||
}
|
||||
|
||||
.l7-touch .l7-control-attribution,
|
||||
.l7-touch .l7-control-layers,
|
||||
.l7-touch .l7-bar {
|
||||
box-shadow: none;
|
||||
}
|
||||
.l7-touch .l7-control-layers,
|
||||
.l7-touch .l7-bar {
|
||||
border: 2px solid rgba(0,0,0,0.2);
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
|
||||
/* layers control */
|
||||
|
||||
.l7-control-layers {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.l7-control-layers-toggle {
|
||||
background-image: url(../images/layers.svg);
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
.l7-retina .l7-control-layers-toggle {
|
||||
background-image: url(../images/layers.svg);
|
||||
background-size: 26px 26px;
|
||||
}
|
||||
.l7-touch .l7-control-layers-toggle {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
}
|
||||
.l7-control-layers .l7-control-layers-list,
|
||||
.l7-control-layers-expanded .l7-control-layers-toggle {
|
||||
display: none;
|
||||
}
|
||||
.l7-control-layers-expanded .l7-control-layers-list {
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.l7-control-layers-expanded {
|
||||
padding: 6px 10px 6px 6px;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
}
|
||||
.l7-control-layers-scrollbar {
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
padding-right: 5px;
|
||||
}
|
||||
.l7-control-layers-selector {
|
||||
margin-top: 2px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
.l7-control-layers label {
|
||||
display: block;
|
||||
}
|
||||
.l7-control-layers-separator {
|
||||
height: 0;
|
||||
border-top: 1px solid #ddd;
|
||||
margin: 5px -10px 5px -6px;
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
import Control from './control/BaseControl';
|
||||
import Scale from './control/scale';
|
||||
import Zoom from './control/zoom';
|
||||
import Marker from './marker';
|
||||
import Popup from './popup';
|
||||
export { Control, Scale, Zoom, Marker, Popup };
|
|
@ -0,0 +1,186 @@
|
|||
import { ILngLat, IMapService, IMarkerScene, IPopup } from '@l7/core';
|
||||
import { bindAll, DOM } from '@l7/utils';
|
||||
import { anchorTranslate, anchorType, applyAnchorClass } from './utils/anchor';
|
||||
// marker 支持 dragger 未完成
|
||||
|
||||
export interface IMarkerOption {
|
||||
element: HTMLElement | undefined;
|
||||
anchor: anchorType;
|
||||
color: string;
|
||||
offset: number[];
|
||||
draggable: boolean;
|
||||
}
|
||||
export default class Marker {
|
||||
private markerOption: IMarkerOption;
|
||||
private defaultMarker: boolean;
|
||||
private popup: IPopup; // TODO: POPup
|
||||
private mapservice: IMapService;
|
||||
private lngLat: ILngLat;
|
||||
private scene: IMarkerScene;
|
||||
constructor(option?: Partial<IMarkerOption>) {
|
||||
this.markerOption = {
|
||||
...this.getDefault(),
|
||||
...option,
|
||||
};
|
||||
bindAll(['update', 'onMove', 'onUp', 'addDragHandler', 'onMapClick'], this);
|
||||
this.init();
|
||||
}
|
||||
|
||||
public getDefault() {
|
||||
return {
|
||||
element: undefined, // DOM element
|
||||
anchor: anchorType.BOTTOM,
|
||||
offset: [0, 0],
|
||||
color: '#5B8FF9',
|
||||
draggable: false,
|
||||
};
|
||||
}
|
||||
|
||||
public addTo(scene: IMarkerScene) {
|
||||
this.scene = scene;
|
||||
const mapService = scene.getMapService();
|
||||
const { element, draggable } = this.markerOption;
|
||||
this.remove();
|
||||
this.mapservice = mapService;
|
||||
mapService.getMarkerContainer().appendChild(element as HTMLElement);
|
||||
mapService.on('camerachange', this.update);
|
||||
this.setDraggable(draggable);
|
||||
this.update();
|
||||
return this;
|
||||
}
|
||||
|
||||
public remove() {
|
||||
if (this.mapservice) {
|
||||
this.mapservice.off('click', this.onMapClick);
|
||||
this.mapservice.off('move', this.update);
|
||||
this.mapservice.off('moveend', this.update);
|
||||
this.mapservice.off('mousedown', this.addDragHandler);
|
||||
this.mapservice.off('touchstart', this.addDragHandler);
|
||||
this.mapservice.off('mouseup', this.onUp);
|
||||
this.mapservice.off('touchend', this.onUp);
|
||||
delete this.mapservice;
|
||||
}
|
||||
const { element } = this.markerOption;
|
||||
if (element) {
|
||||
DOM.remove(element);
|
||||
}
|
||||
if (this.popup) {
|
||||
this.popup.remove();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public setLnglat(lngLat: ILngLat) {
|
||||
this.lngLat = lngLat;
|
||||
if (this.popup) {
|
||||
this.popup.setLnglat(this.lngLat);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public getLnglat(): ILngLat {
|
||||
return this.lngLat;
|
||||
}
|
||||
|
||||
public getElement(): HTMLElement {
|
||||
return this.markerOption.element as HTMLElement;
|
||||
}
|
||||
|
||||
public togglePopup() {
|
||||
const popup = this.popup;
|
||||
if (!popup) {
|
||||
return this;
|
||||
} else if (popup.isOpen()) {
|
||||
popup.remove();
|
||||
} else {
|
||||
popup.addTo(this.scene);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public getPopup() {
|
||||
return this.popup;
|
||||
}
|
||||
|
||||
public getOffset(): number[] {
|
||||
return this.markerOption.offset;
|
||||
}
|
||||
|
||||
public setDraggable(draggable: boolean) {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
public isDraggable() {
|
||||
return this.markerOption.draggable;
|
||||
}
|
||||
|
||||
private update() {
|
||||
if (!this.mapservice) {
|
||||
return;
|
||||
}
|
||||
const { element, anchor } = this.markerOption;
|
||||
this.updatePosition();
|
||||
DOM.setTransform(element as HTMLElement, `${anchorTranslate[anchor]}`);
|
||||
}
|
||||
|
||||
private onMapClick(e: MouseEvent) {
|
||||
const { element } = this.markerOption;
|
||||
if (this.popup && element) {
|
||||
this.togglePopup();
|
||||
}
|
||||
}
|
||||
|
||||
private updatePosition() {
|
||||
if (!this.mapservice) {
|
||||
return;
|
||||
}
|
||||
const { element } = this.markerOption;
|
||||
const { lng, lat } = this.lngLat;
|
||||
const pos = this.mapservice.lngLatToContainer([lng, lat]);
|
||||
if (element) {
|
||||
element.style.left = pos.x + 'px';
|
||||
element.style.top = pos.y + 'px';
|
||||
}
|
||||
}
|
||||
|
||||
private init() {
|
||||
let { element } = this.markerOption;
|
||||
const { color, anchor } = this.markerOption;
|
||||
if (!element) {
|
||||
this.defaultMarker = true;
|
||||
element = DOM.create('div');
|
||||
this.markerOption.element = element;
|
||||
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||
svg.setAttributeNS(null, 'display', 'block');
|
||||
svg.setAttributeNS(null, 'height', '48px');
|
||||
svg.setAttributeNS(null, 'width', '48px');
|
||||
svg.setAttributeNS(null, 'viewBox', '0 0 1024 1024');
|
||||
|
||||
const path = document.createElementNS(
|
||||
'http://www.w3.org/2000/svg',
|
||||
'path',
|
||||
);
|
||||
path.setAttributeNS(
|
||||
null,
|
||||
'd',
|
||||
'M512 490.666667C453.12 490.666667 405.333333 442.88 405.333333 384 405.333333 325.12 453.12 277.333333 512 277.333333 570.88 277.333333 618.666667 325.12 618.666667 384 618.666667 442.88 570.88 490.666667 512 490.666667M512 85.333333C346.88 85.333333 213.333333 218.88 213.333333 384 213.333333 608 512 938.666667 512 938.666667 512 938.666667 810.666667 608 810.666667 384 810.666667 218.88 677.12 85.333333 512 85.333333Z',
|
||||
);
|
||||
path.setAttributeNS(null, 'fill', color);
|
||||
svg.appendChild(path);
|
||||
element.appendChild(svg);
|
||||
}
|
||||
DOM.addClass(element, 'l7-marker');
|
||||
element.addEventListener('click', (e: MouseEvent) => {
|
||||
this.onMapClick(e);
|
||||
});
|
||||
applyAnchorClass(element, anchor, 'marker');
|
||||
}
|
||||
|
||||
private addDragHandler(e: MouseEvent) {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
private onUp(e: MouseEvent) {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,210 @@
|
|||
import { ILngLat, IMapService, IMarkerScene, IPopup } from '@l7/core';
|
||||
import { bindAll, DOM } from '@l7/utils';
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import { anchorTranslate, anchorType, applyAnchorClass } from './utils/anchor';
|
||||
|
||||
/** colse event */
|
||||
|
||||
export interface IPopupOption {
|
||||
closeButton: boolean;
|
||||
closeOnClick: boolean;
|
||||
maxWidth: string;
|
||||
anchor: anchorType;
|
||||
className: string;
|
||||
offsets: number[];
|
||||
}
|
||||
export default class Popup extends EventEmitter implements IPopup {
|
||||
private popupOption: IPopupOption;
|
||||
private mapservice: IMapService;
|
||||
private lngLat: ILngLat;
|
||||
private content: HTMLElement;
|
||||
private closeButton: HTMLElement;
|
||||
private timeoutInstance: any;
|
||||
private container: HTMLElement;
|
||||
private tip: HTMLElement;
|
||||
|
||||
constructor(cfg?: Partial<IPopupOption>) {
|
||||
super();
|
||||
this.popupOption = {
|
||||
...this.getdefault(),
|
||||
...cfg,
|
||||
};
|
||||
bindAll(['update', 'onClickClose', 'remove'], this);
|
||||
}
|
||||
|
||||
public addTo(scene: IMarkerScene) {
|
||||
const mapService = scene.getMapService();
|
||||
this.mapservice = mapService;
|
||||
this.mapservice.on('camerachange', this.update);
|
||||
this.update();
|
||||
if (this.popupOption.closeOnClick) {
|
||||
this.timeoutInstance = setTimeout(() => {
|
||||
this.mapservice.on('click', this.onClickClose);
|
||||
}, 30);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public setHTML(html: string) {
|
||||
const frag = window.document.createDocumentFragment();
|
||||
const temp = window.document.createElement('body');
|
||||
let child: ChildNode | null;
|
||||
temp.innerHTML = html;
|
||||
while (true) {
|
||||
child = temp.firstChild;
|
||||
if (!child) {
|
||||
break;
|
||||
}
|
||||
frag.appendChild(child);
|
||||
}
|
||||
|
||||
return this.setDOMContent(frag);
|
||||
}
|
||||
|
||||
public setLnglat(lngLat: ILngLat): this {
|
||||
this.lngLat = lngLat;
|
||||
if (this.mapservice) {
|
||||
this.mapservice.on('camerachange', this.update);
|
||||
}
|
||||
this.update();
|
||||
return this;
|
||||
}
|
||||
public getLnglat(): ILngLat {
|
||||
return this.lngLat;
|
||||
}
|
||||
public setText(text: string) {
|
||||
return this.setDOMContent(window.document.createTextNode(text));
|
||||
}
|
||||
|
||||
public setMaxWidth(maxWidth: string): this {
|
||||
this.popupOption.maxWidth = maxWidth;
|
||||
this.update();
|
||||
return this;
|
||||
}
|
||||
|
||||
public setDOMContent(htmlNode: ChildNode | DocumentFragment) {
|
||||
this.createContent();
|
||||
this.content.appendChild(htmlNode);
|
||||
this.update();
|
||||
return this;
|
||||
}
|
||||
|
||||
// 移除popup
|
||||
public remove() {
|
||||
if (this.content) {
|
||||
this.removeDom(this.content);
|
||||
}
|
||||
|
||||
if (this.container) {
|
||||
this.removeDom(this.container);
|
||||
delete this.container;
|
||||
}
|
||||
if (this.mapservice) {
|
||||
// TODO: mapbox AMap 事件同步
|
||||
this.mapservice.off('camerachange', this.update);
|
||||
this.mapservice.off('click', this.onClickClose);
|
||||
delete this.mapservice;
|
||||
}
|
||||
clearTimeout(this.timeoutInstance);
|
||||
this.emit('close');
|
||||
return this;
|
||||
}
|
||||
public isOpen() {
|
||||
return !!this.mapservice;
|
||||
}
|
||||
|
||||
private createContent() {
|
||||
if (this.content) {
|
||||
DOM.remove(this.content);
|
||||
}
|
||||
this.content = DOM.create('div', 'l7-popup-content', this.container);
|
||||
if (this.popupOption.closeButton) {
|
||||
this.closeButton = DOM.create(
|
||||
'button',
|
||||
'l7-popup-close-button',
|
||||
this.content,
|
||||
);
|
||||
// this.closeButton.type = 'button';
|
||||
this.closeButton.setAttribute('aria-label', 'Close popup');
|
||||
this.closeButton.innerHTML = '×';
|
||||
this.closeButton.addEventListener('click', this.onClickClose);
|
||||
}
|
||||
}
|
||||
|
||||
private creatDom(tagName: string, className: string, container: HTMLElement) {
|
||||
const el = window.document.createElement(tagName);
|
||||
if (className !== undefined) {
|
||||
el.className = className;
|
||||
}
|
||||
if (container) {
|
||||
container.appendChild(el);
|
||||
}
|
||||
return el;
|
||||
}
|
||||
|
||||
private removeDom(node: ChildNode) {
|
||||
if (node.parentNode) {
|
||||
node.parentNode.removeChild(node);
|
||||
}
|
||||
}
|
||||
|
||||
private getdefault() {
|
||||
return {
|
||||
closeButton: true,
|
||||
closeOnClick: true,
|
||||
maxWidth: '240px',
|
||||
offsets: [0, 0],
|
||||
anchor: anchorType.BOTTOM,
|
||||
className: '',
|
||||
};
|
||||
}
|
||||
|
||||
private onClickClose() {
|
||||
this.remove();
|
||||
}
|
||||
|
||||
private update() {
|
||||
const hasPosition = this.lngLat;
|
||||
const { className, maxWidth, anchor } = this.popupOption;
|
||||
if (!this.mapservice || !hasPosition || !this.content) {
|
||||
return;
|
||||
}
|
||||
const markerContainer = this.mapservice.getMarkerContainer();
|
||||
if (!this.container && markerContainer) {
|
||||
this.container = this.creatDom(
|
||||
'div',
|
||||
'l7-popup',
|
||||
markerContainer.parentNode as HTMLElement,
|
||||
);
|
||||
|
||||
this.tip = this.creatDom('div', 'l7-popup-tip', this.container);
|
||||
this.container.appendChild(this.content);
|
||||
if (className) {
|
||||
className
|
||||
.split(' ')
|
||||
.forEach((name) => this.container.classList.add(name));
|
||||
}
|
||||
this.container.addEventListener('mousedown', (e) => {
|
||||
e.stopPropagation();
|
||||
});
|
||||
}
|
||||
if (maxWidth && this.container.style.maxWidth !== maxWidth) {
|
||||
this.container.style.maxWidth = maxWidth;
|
||||
}
|
||||
|
||||
this.updatePosition();
|
||||
DOM.setTransform(this.container, `${anchorTranslate[anchor]}`);
|
||||
applyAnchorClass(this.container, anchor, 'popup');
|
||||
}
|
||||
|
||||
private updatePosition() {
|
||||
if (!this.mapservice) {
|
||||
return;
|
||||
}
|
||||
const { lng, lat } = this.lngLat;
|
||||
const { offsets } = this.popupOption;
|
||||
const pos = this.mapservice.lngLatToContainer([lng, lat]);
|
||||
this.container.style.left = pos.x + offsets[0] + 'px';
|
||||
this.container.style.top = pos.y - offsets[1] + 'px';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
export enum anchorType {
|
||||
'CENTER' = 'center',
|
||||
'TOP' = 'top',
|
||||
'TOP-LEFT' = 'top-left',
|
||||
'TOP-RIGHT' = 'top-right',
|
||||
'BOTTOM' = 'bottom',
|
||||
'BOTTOM-LEFT' = 'bottom-left',
|
||||
'LEFT' = 'left',
|
||||
'RIGHT' = 'right',
|
||||
}
|
||||
|
||||
export const anchorTranslate = {
|
||||
center: 'translate(-50%,-50%)',
|
||||
top: 'translate(-50%,0)',
|
||||
'top-left': 'translate(0,0)',
|
||||
'top-right': 'translate(-100%,0)',
|
||||
bottom: 'translate(-50%,-100%)',
|
||||
'bottom-left': 'translate(0,-100%)',
|
||||
'bottom-right': 'translate(-100%,-100%)',
|
||||
left: 'translate(0,-50%)',
|
||||
right: 'translate(-100%,-50%)',
|
||||
};
|
||||
|
||||
export function applyAnchorClass(
|
||||
element: HTMLElement,
|
||||
anchor: string,
|
||||
prefix: string,
|
||||
) {
|
||||
const classList = element.classList;
|
||||
for (const key in anchorTranslate) {
|
||||
if (anchorTranslate.hasOwnProperty(key)) {
|
||||
classList.remove(`l7-${prefix}-anchor-${key}`);
|
||||
}
|
||||
}
|
||||
classList.add(`l7-${prefix}-anchor-${anchor}`);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"extends": "../../tsconfig.build.json",
|
||||
"compilerOptions": {
|
||||
"declarationDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"baseUrl": "./"
|
||||
},
|
||||
"include": ["./src"]
|
||||
}
|
|
@ -19,8 +19,9 @@
|
|||
"author": "xiaoiver",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@l7/source": "0.0.1",
|
||||
"@mapbox/tiny-sdf": "^1.1.1",
|
||||
"eventemitter3": "^3.1.0",
|
||||
"@l7/utils": "0.0.1",
|
||||
"gl-matrix": "^3.1.0",
|
||||
"hammerjs": "^2.0.8",
|
||||
"inversify": "^5.0.1",
|
||||
|
@ -29,6 +30,7 @@
|
|||
"probe.gl": "^3.1.1",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"tapable": "^2.0.0-beta.8",
|
||||
"mapbox-gl": "^1.2.1",
|
||||
"viewport-mercator-project": "^6.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -52,6 +52,10 @@ export * from './services/config/IConfigService';
|
|||
export * from './services/scene/ISceneService';
|
||||
export * from './services/shader/IShaderModuleService';
|
||||
export * from './services/asset/IIconService';
|
||||
export * from './services/asset/IFontService';
|
||||
export * from './services/component/IControlService';
|
||||
export * from './services/component/IMarkerService';
|
||||
export * from './services/component/IPopUpService';
|
||||
|
||||
/** 全部渲染服务接口 */
|
||||
export * from './services/renderer/IAttribute';
|
||||
|
|
|
@ -6,8 +6,10 @@ import getDecorators from 'inversify-inject-decorators';
|
|||
import { TYPES } from './types';
|
||||
|
||||
/** Service interfaces */
|
||||
import { IFontService } from './services/asset/IFontService';
|
||||
import { IIconService } from './services/asset/IIconService';
|
||||
import { ICameraService } from './services/camera/ICameraService';
|
||||
import { IControlService } from './services/component/IControlService';
|
||||
import { IGlobalConfigService } from './services/config/IConfigService';
|
||||
import { ICoordinateSystemService } from './services/coordinate/ICoordinateSystemService';
|
||||
import { IInteractionService } from './services/interaction/IInteractionService';
|
||||
|
@ -16,8 +18,10 @@ import { ILogService } from './services/log/ILogService';
|
|||
import { IShaderModuleService } from './services/shader/IShaderModuleService';
|
||||
|
||||
/** Service implements */
|
||||
import FontService from './services/asset/FontService';
|
||||
import IconService from './services/asset/IconService';
|
||||
import CameraService from './services/camera/CameraService';
|
||||
import ControlService from './services/component/ControlService';
|
||||
import GlobalConfigService from './services/config/ConfigService';
|
||||
import CoordinateSystemService from './services/coordinate/CoordinateSystemService';
|
||||
import InteractionService from './services/interaction/InteractionService';
|
||||
|
@ -25,7 +29,6 @@ import LayerService from './services/layer/LayerService';
|
|||
import LayerStyleService from './services/layer/LayerStyleService';
|
||||
import LogService from './services/log/LogService';
|
||||
import ShaderModuleService from './services/shader/ShaderModuleService';
|
||||
|
||||
// @see https://github.com/inversify/InversifyJS/blob/master/wiki/container_api.md#defaultscope
|
||||
const container = new Container();
|
||||
|
||||
|
@ -64,6 +67,14 @@ container
|
|||
.bind<IInteractionService>(TYPES.IInteractionService)
|
||||
.to(InteractionService)
|
||||
.inSingletonScope();
|
||||
container
|
||||
.bind<IFontService>(TYPES.IFontService)
|
||||
.to(FontService)
|
||||
.inSingletonScope();
|
||||
container
|
||||
.bind<IControlService>(TYPES.IControlService)
|
||||
.to(ControlService)
|
||||
.inSingletonScope();
|
||||
|
||||
// @see https://github.com/inversify/InversifyJS/blob/master/wiki/inheritance.md#what-can-i-do-when-my-base-class-is-provided-by-a-third-party-module
|
||||
decorate(injectable(), EventEmitter);
|
||||
|
|
|
@ -0,0 +1,243 @@
|
|||
import { LRUCache } from '@l7/utils';
|
||||
// @ts-ignore
|
||||
import TinySDF from '@mapbox/tiny-sdf';
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { buildMapping } from '../../utils/font_util';
|
||||
import {
|
||||
IFontAtlas,
|
||||
IFontMapping,
|
||||
IFontMappingItem,
|
||||
IFontOptions,
|
||||
IFontService,
|
||||
} from './IFontService';
|
||||
export const DEFAULT_CHAR_SET = getDefaultCharacterSet();
|
||||
export const DEFAULT_FONT_FAMILY = 'sans-serif';
|
||||
export const DEFAULT_FONT_WEIGHT = 'normal';
|
||||
export const DEFAULT_FONT_SIZE = 24;
|
||||
export const DEFAULT_BUFFER = 3;
|
||||
export const DEFAULT_CUTOFF = 0.25;
|
||||
export const DEFAULT_RADIUS = 8;
|
||||
const MAX_CANVAS_WIDTH = 1024;
|
||||
const BASELINE_SCALE = 1.0;
|
||||
const HEIGHT_SCALE = 1.0;
|
||||
const CACHE_LIMIT = 3;
|
||||
const VALID_PROPS = [
|
||||
'fontFamily',
|
||||
'fontWeight',
|
||||
'characterSet',
|
||||
'fontSize',
|
||||
'sdf',
|
||||
'buffer',
|
||||
'cutoff',
|
||||
'radius',
|
||||
];
|
||||
function getDefaultCharacterSet() {
|
||||
const charSet = [];
|
||||
for (let i = 32; i < 128; i++) {
|
||||
charSet.push(String.fromCharCode(i));
|
||||
}
|
||||
return charSet;
|
||||
}
|
||||
|
||||
function setTextStyle(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
fontFamily: string,
|
||||
fontSize: number,
|
||||
fontWeight: string,
|
||||
) {
|
||||
ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
|
||||
ctx.fillStyle = 'black';
|
||||
ctx.textBaseline = 'middle';
|
||||
// ctx.textAlign = 'left';
|
||||
}
|
||||
function populateAlphaChannel(alphaChannel: number[], imageData: ImageData) {
|
||||
// populate distance value from tinySDF to image alpha channel
|
||||
for (let i = 0; i < alphaChannel.length; i++) {
|
||||
imageData.data[4 * i + 3] = alphaChannel[i];
|
||||
}
|
||||
}
|
||||
|
||||
@injectable()
|
||||
export default class FontService implements IFontService {
|
||||
public fontAtlas: IFontAtlas;
|
||||
private fontOptions: IFontOptions;
|
||||
private key: string;
|
||||
private cache: LRUCache = new LRUCache(CACHE_LIMIT);
|
||||
public init() {
|
||||
this.fontOptions = {
|
||||
fontFamily: DEFAULT_FONT_FAMILY,
|
||||
fontWeight: DEFAULT_FONT_WEIGHT,
|
||||
characterSet: DEFAULT_CHAR_SET,
|
||||
fontSize: DEFAULT_FONT_SIZE,
|
||||
buffer: DEFAULT_BUFFER,
|
||||
sdf: true,
|
||||
cutoff: DEFAULT_CUTOFF,
|
||||
radius: DEFAULT_RADIUS,
|
||||
};
|
||||
this.key = '';
|
||||
}
|
||||
|
||||
public get scale() {
|
||||
return HEIGHT_SCALE;
|
||||
}
|
||||
|
||||
public get canvas(): HTMLCanvasElement {
|
||||
const data = this.cache.get(this.key);
|
||||
return data && data.data;
|
||||
}
|
||||
|
||||
public get mapping(): IFontMapping {
|
||||
const data = this.cache.get(this.key);
|
||||
return data && data.mapping;
|
||||
}
|
||||
|
||||
public setFontOptions(option: Partial<IFontOptions>) {
|
||||
this.fontOptions = {
|
||||
...this.fontOptions,
|
||||
...option,
|
||||
};
|
||||
|
||||
// const oldKey = this.key;
|
||||
this.key = this.getKey();
|
||||
|
||||
const charSet = this.getNewChars(this.key, this.fontOptions.characterSet);
|
||||
const cachedFontAtlas = this.cache.get(this.key);
|
||||
|
||||
if (cachedFontAtlas && charSet.length === 0) {
|
||||
// update texture with cached fontAtlas
|
||||
return;
|
||||
}
|
||||
// update fontAtlas with new settings
|
||||
const fontAtlas = this.generateFontAtlas(
|
||||
this.key,
|
||||
charSet,
|
||||
cachedFontAtlas,
|
||||
);
|
||||
this.fontAtlas = fontAtlas;
|
||||
|
||||
// update cache
|
||||
this.cache.set(this.key, fontAtlas);
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
this.cache.clear();
|
||||
}
|
||||
|
||||
private generateFontAtlas(
|
||||
key: string,
|
||||
characterSet: string[],
|
||||
cachedFontAtlas: IFontAtlas,
|
||||
): IFontAtlas {
|
||||
const {
|
||||
fontFamily,
|
||||
fontWeight,
|
||||
fontSize,
|
||||
buffer,
|
||||
sdf,
|
||||
radius,
|
||||
cutoff,
|
||||
} = this.fontOptions;
|
||||
let canvas = cachedFontAtlas && cachedFontAtlas.data;
|
||||
if (!canvas) {
|
||||
canvas = document.createElement('canvas');
|
||||
canvas.width = MAX_CANVAS_WIDTH;
|
||||
}
|
||||
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
|
||||
setTextStyle(ctx, fontFamily, fontSize, fontWeight);
|
||||
|
||||
// 1. build mapping
|
||||
const { mapping, canvasHeight, xOffset, yOffset } = buildMapping({
|
||||
getFontWidth: (char) => ctx.measureText(char).width,
|
||||
fontHeight: fontSize * HEIGHT_SCALE,
|
||||
buffer,
|
||||
characterSet,
|
||||
maxCanvasWidth: MAX_CANVAS_WIDTH,
|
||||
...(cachedFontAtlas && {
|
||||
mapping: cachedFontAtlas.mapping,
|
||||
xOffset: cachedFontAtlas.xOffset,
|
||||
yOffset: cachedFontAtlas.yOffset,
|
||||
}),
|
||||
});
|
||||
|
||||
// 2. update canvas
|
||||
// copy old canvas data to new canvas only when height changed
|
||||
if (canvas.height !== canvasHeight) {
|
||||
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||
canvas.height = canvasHeight;
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
}
|
||||
setTextStyle(ctx, fontFamily, fontSize, fontWeight);
|
||||
|
||||
// 3. layout characters
|
||||
if (sdf) {
|
||||
const tinySDF = new TinySDF(
|
||||
fontSize,
|
||||
buffer,
|
||||
radius,
|
||||
cutoff,
|
||||
fontFamily,
|
||||
fontWeight,
|
||||
);
|
||||
// used to store distance values from tinySDF
|
||||
// tinySDF.size equals `fontSize + buffer * 2`
|
||||
const imageData = ctx.getImageData(0, 0, tinySDF.size, tinySDF.size);
|
||||
|
||||
for (const char of characterSet) {
|
||||
populateAlphaChannel(tinySDF.draw(char), imageData);
|
||||
// 考虑到描边,需要保留 sdf 的 buffer,不能像 deck.gl 一样直接减去
|
||||
ctx.putImageData(imageData, mapping[char].x, mapping[char].y);
|
||||
}
|
||||
} else {
|
||||
for (const char of characterSet) {
|
||||
ctx.fillText(
|
||||
char,
|
||||
mapping[char].x,
|
||||
mapping[char].y + fontSize * BASELINE_SCALE,
|
||||
);
|
||||
}
|
||||
}
|
||||
return {
|
||||
xOffset,
|
||||
yOffset,
|
||||
mapping,
|
||||
data: canvas,
|
||||
width: canvas.width,
|
||||
height: canvas.height,
|
||||
};
|
||||
}
|
||||
|
||||
private getKey() {
|
||||
const {
|
||||
fontFamily,
|
||||
fontWeight,
|
||||
fontSize,
|
||||
buffer,
|
||||
sdf,
|
||||
radius,
|
||||
cutoff,
|
||||
} = this.fontOptions;
|
||||
if (sdf) {
|
||||
return `${fontFamily} ${fontWeight} ${fontSize} ${buffer} ${radius} ${cutoff}`;
|
||||
}
|
||||
return `${fontFamily} ${fontWeight} ${fontSize} ${buffer}`;
|
||||
}
|
||||
|
||||
private getNewChars(key: string, characterSet: string[]): string[] {
|
||||
const cachedFontAtlas = this.cache.get(key);
|
||||
if (!cachedFontAtlas) {
|
||||
return characterSet;
|
||||
}
|
||||
|
||||
const newChars: string[] = [];
|
||||
const cachedMapping = cachedFontAtlas.mapping;
|
||||
const cachedCharSet = new Set(Object.keys(cachedMapping));
|
||||
const charSet = new Set(characterSet);
|
||||
charSet.forEach((char: string) => {
|
||||
if (!cachedCharSet.has(char)) {
|
||||
newChars.push(char);
|
||||
}
|
||||
});
|
||||
|
||||
return newChars;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
export interface IFontOptions {
|
||||
fontFamily: string;
|
||||
fontWeight: string;
|
||||
characterSet: string[];
|
||||
fontSize: number;
|
||||
buffer: number;
|
||||
sdf: boolean;
|
||||
cutoff: number;
|
||||
radius: number;
|
||||
}
|
||||
export interface IFontMappingOption {
|
||||
characterSet: string[];
|
||||
getFontWidth: (char: string, i: number) => number;
|
||||
fontHeight: number;
|
||||
buffer: number;
|
||||
maxCanvasWidth: number;
|
||||
mapping: IFontMapping;
|
||||
xOffset: number;
|
||||
yOffset: number;
|
||||
}
|
||||
export interface IFontMappingItem {
|
||||
x: number;
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
advance: number;
|
||||
}
|
||||
export interface IFontMapping {
|
||||
[key: string]: IFontMappingItem;
|
||||
[key: number]: IFontMappingItem;
|
||||
}
|
||||
export interface IFontAtlas {
|
||||
xOffset: number;
|
||||
yOffset: number;
|
||||
mapping: IFontMapping;
|
||||
data: HTMLCanvasElement;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
export interface IFontService {
|
||||
mapping: IFontMapping;
|
||||
fontAtlas: IFontAtlas;
|
||||
canvas: HTMLCanvasElement;
|
||||
scale: number;
|
||||
init(): void;
|
||||
setFontOptions(option: Partial<IFontOptions>): void;
|
||||
destroy(): void;
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
import EventEmitter from 'eventemitter3';
|
||||
import { ITexture2D } from '../renderer/ITexture2D';
|
||||
export type IImage = HTMLImageElement | File | string;
|
||||
export type Listener = (...args: any[]) => void;
|
||||
export interface IIconValue {
|
||||
x: number;
|
||||
y: number;
|
||||
|
@ -16,6 +18,7 @@ export interface IICONMap {
|
|||
}
|
||||
export interface IIconService {
|
||||
canvasHeight: number;
|
||||
on(event: string, fn: EventEmitter.ListenerFn, context?: any): this;
|
||||
init(): void;
|
||||
addImage(id: string, image: IImage): void;
|
||||
hasImage(id: string): boolean;
|
||||
|
@ -23,4 +26,5 @@ export interface IIconService {
|
|||
getTexture(): ITexture2D;
|
||||
getIconMap(): IICONMap;
|
||||
getCanvas(): HTMLCanvasElement;
|
||||
destroy(): void;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { EventEmitter } from 'eventemitter3';
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { TYPES } from '../../types';
|
||||
import { buildIconMaping } from '../../utils/font_util';
|
||||
import { gl } from '../renderer/gl';
|
||||
import { IRendererService } from '../renderer/IRendererService';
|
||||
import { ITexture2D } from '../renderer/ITexture2D';
|
||||
import {
|
||||
IIcon,
|
||||
|
@ -15,7 +14,7 @@ const BUFFER = 3;
|
|||
const MAX_CANVAS_WIDTH = 1024;
|
||||
const imageSize = 64;
|
||||
@injectable()
|
||||
export default class IconService implements IIconService {
|
||||
export default class IconService extends EventEmitter implements IIconService {
|
||||
public canvasHeight: number;
|
||||
private textrure: ITexture2D;
|
||||
private canvas: HTMLCanvasElement;
|
||||
|
@ -31,23 +30,20 @@ export default class IconService implements IIconService {
|
|||
|
||||
public addImage(id: string, image: IImage) {
|
||||
let imagedata = new Image();
|
||||
if (this.hasImage(id)) {
|
||||
throw new Error('Image Id already exists');
|
||||
}
|
||||
|
||||
this.loadImage(image).then((img) => {
|
||||
imagedata = img as HTMLImageElement;
|
||||
this.iconData.push({
|
||||
id,
|
||||
image: imagedata,
|
||||
width: imageSize,
|
||||
height: imageSize,
|
||||
});
|
||||
this.update();
|
||||
});
|
||||
this.iconData.push({
|
||||
id,
|
||||
image: imagedata,
|
||||
width: imageSize,
|
||||
height: imageSize,
|
||||
});
|
||||
const { mapping, canvasHeight } = buildIconMaping(
|
||||
this.iconData,
|
||||
BUFFER,
|
||||
MAX_CANVAS_WIDTH,
|
||||
);
|
||||
this.iconMap = mapping;
|
||||
this.canvasHeight = canvasHeight;
|
||||
this.updateIconAtlas();
|
||||
}
|
||||
|
||||
public getTexture(): ITexture2D {
|
||||
|
@ -57,15 +53,32 @@ export default class IconService implements IIconService {
|
|||
public getIconMap() {
|
||||
return this.iconMap;
|
||||
}
|
||||
|
||||
public getCanvas() {
|
||||
return this.canvas;
|
||||
}
|
||||
|
||||
public hasImage(id: string): boolean {
|
||||
throw new Error('Method not implemented.');
|
||||
return this.iconMap.hasOwnProperty(id);
|
||||
}
|
||||
|
||||
public removeImage(id: string): void {
|
||||
throw new Error('Method not implemented.');
|
||||
if (this.hasImage(id)) {
|
||||
this.iconData = this.iconData.filter((icon) => {
|
||||
return icon.id !== id;
|
||||
});
|
||||
delete this.iconMap[id];
|
||||
this.update();
|
||||
}
|
||||
}
|
||||
public destroy(): void {
|
||||
this.iconData = [];
|
||||
this.iconMap = {};
|
||||
}
|
||||
private update() {
|
||||
this.updateIconMap();
|
||||
this.updateIconAtlas();
|
||||
this.emit('imageUpdate');
|
||||
}
|
||||
|
||||
private updateIconAtlas() {
|
||||
|
@ -75,13 +88,16 @@ export default class IconService implements IIconService {
|
|||
const { x, y, image } = this.iconMap[item];
|
||||
this.ctx.drawImage(image, x, y, imageSize, imageSize);
|
||||
});
|
||||
// const { createTexture2D } = this.rendererService;
|
||||
// this.textrure = createTexture2D({
|
||||
// data: this.canvas,
|
||||
// width: this.canvas.width,
|
||||
// height: this.canvasHeight,
|
||||
// mag: gl.LINEAR,
|
||||
// });
|
||||
}
|
||||
|
||||
private updateIconMap() {
|
||||
const { mapping, canvasHeight } = buildIconMaping(
|
||||
this.iconData,
|
||||
BUFFER,
|
||||
MAX_CANVAS_WIDTH,
|
||||
);
|
||||
this.iconMap = mapping;
|
||||
this.canvasHeight = canvasHeight;
|
||||
}
|
||||
|
||||
private loadImage(url: IImage) {
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
import { DOM } from '@l7/utils';
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { IMapService } from '../map/IMapService';
|
||||
import {
|
||||
IControl,
|
||||
IControlCorners,
|
||||
IControlService,
|
||||
IControlServiceCfg,
|
||||
} from './IControlService';
|
||||
|
||||
@injectable()
|
||||
export default class ControlService implements IControlService {
|
||||
public container: HTMLElement;
|
||||
public controlCorners: IControlCorners;
|
||||
public controlContainer: HTMLElement;
|
||||
private controls: IControl[] = [];
|
||||
public init(cfg: IControlServiceCfg) {
|
||||
this.container = cfg.container;
|
||||
this.initControlPos();
|
||||
}
|
||||
|
||||
public addControl(ctr: IControl, mapService: IMapService): void {
|
||||
ctr.addTo(mapService); // scene对象
|
||||
this.controls.push(ctr);
|
||||
}
|
||||
|
||||
public removeControl(ctr: IControl): this {
|
||||
const index = this.controls.indexOf(ctr);
|
||||
if (index > -1) {
|
||||
this.controls.splice(index, 1);
|
||||
}
|
||||
ctr.remove();
|
||||
return this;
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
for (const ctr of this.controls) {
|
||||
ctr.remove();
|
||||
}
|
||||
this.controls = [];
|
||||
this.clearControlPos();
|
||||
}
|
||||
|
||||
private initControlPos() {
|
||||
const corners: IControlCorners = (this.controlCorners = {});
|
||||
const l = 'l7-';
|
||||
const container = (this.controlContainer = DOM.create(
|
||||
'div',
|
||||
l + 'control-container',
|
||||
this.container,
|
||||
));
|
||||
|
||||
function createCorner(vSide: string, hSide: string) {
|
||||
const className = l + vSide + ' ' + l + hSide;
|
||||
|
||||
corners[vSide + hSide] = DOM.create('div', className, container);
|
||||
}
|
||||
|
||||
createCorner('top', 'left');
|
||||
createCorner('top', 'right');
|
||||
createCorner('bottom', 'left');
|
||||
createCorner('bottom', 'right');
|
||||
}
|
||||
|
||||
private clearControlPos() {
|
||||
for (const i in this.controlCorners) {
|
||||
if (this.controlCorners[i]) {
|
||||
DOM.remove(this.controlCorners[i]);
|
||||
}
|
||||
}
|
||||
DOM.remove(this.controlContainer);
|
||||
delete this.controlCorners;
|
||||
delete this.controlContainer;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
import { IMapService } from '../map/IMapService';
|
||||
export enum PositionType {
|
||||
'TOPRIGHT' = 'topright',
|
||||
'TOPLEFT' = 'topleft',
|
||||
'BOTTOMRIGHT' = 'bottomright',
|
||||
'BOTTOMLEFT' = 'bottomleft',
|
||||
}
|
||||
export interface IControlOption {
|
||||
position: PositionType;
|
||||
}
|
||||
export interface IControlServiceCfg {
|
||||
container: HTMLElement;
|
||||
}
|
||||
export interface IControlCorners {
|
||||
[key: string]: HTMLElement;
|
||||
}
|
||||
export interface IControl {
|
||||
setPosition(pos: PositionType): void;
|
||||
addTo(map: IMapService): void;
|
||||
onAdd(map: IMapService): HTMLElement;
|
||||
hide(): void;
|
||||
show(): void;
|
||||
remove(): void;
|
||||
}
|
||||
export interface IControlService {
|
||||
container: HTMLElement;
|
||||
controlCorners: IControlCorners;
|
||||
controlContainer: HTMLElement;
|
||||
init(cfg: IControlServiceCfg): void;
|
||||
addControl(ctr: IControl, map: IMapService): void;
|
||||
removeControl(ctr: IControl): void;
|
||||
destroy(): void;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import { ILngLat, IMapService } from '../map/IMapService';
|
||||
export interface IMarkerScene {
|
||||
getMapService(): IMapService;
|
||||
[key: string]: any;
|
||||
}
|
||||
export interface IMarker {
|
||||
addTo(scene: IMarkerScene): void;
|
||||
remove(): void;
|
||||
setLnglat(lngLat: ILngLat): this;
|
||||
getLnglat(): ILngLat;
|
||||
getElement(): HTMLElement;
|
||||
togglePopup(): this;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
import { ILngLat, IMapService } from '../map/IMapService';
|
||||
import { IMarkerScene } from './IMarkerService';
|
||||
export interface IPopup {
|
||||
addTo(scene: IMarkerScene): this;
|
||||
remove(): void;
|
||||
setLnglat(lngLat: ILngLat): this;
|
||||
getLnglat(): ILngLat;
|
||||
setHTML(html: string): this;
|
||||
setText(text: string): this;
|
||||
setMaxWidth(maxWidth: string): this;
|
||||
isOpen(): boolean;
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
import { Map } from 'mapbox-gl';
|
||||
import { IViewport } from '../camera/ICameraService';
|
||||
export type Point = [number, number];
|
||||
export type Bounds = [[number, number], [number, number]];
|
||||
|
@ -10,9 +11,22 @@ export interface IPoint {
|
|||
y: number;
|
||||
}
|
||||
export interface IMapService {
|
||||
map: AMap.Map | Map;
|
||||
init(config: Partial<IMapConfig>): void;
|
||||
onCameraChanged(callback: (viewport: IViewport) => void): void;
|
||||
// init map
|
||||
addMarkerContainer(): void;
|
||||
getMarkerContainer(): HTMLElement;
|
||||
// MapEvent // 定义事件类型
|
||||
|
||||
on(type: string, hander: (...args: any[]) => void): void;
|
||||
off(type: string, hander: (...args: any[]) => void): void;
|
||||
// get dom
|
||||
getContainer(): HTMLElement | null;
|
||||
getSize(): [number, number];
|
||||
// get map status method
|
||||
getMinZoom(): number;
|
||||
getMaxZoom(): number;
|
||||
getZoom(): number;
|
||||
getCenter(): ILngLat;
|
||||
getPitch(): number;
|
||||
|
@ -52,6 +66,11 @@ export interface IMapConfig {
|
|||
*/
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* 地图
|
||||
*/
|
||||
token?: string;
|
||||
|
||||
/**
|
||||
* 中心点
|
||||
*/
|
||||
|
@ -76,6 +95,17 @@ export interface IMapConfig {
|
|||
* 底图样式
|
||||
*/
|
||||
style?: string;
|
||||
/**
|
||||
* 最小缩放等级
|
||||
*/
|
||||
minZoom?: number;
|
||||
|
||||
/**
|
||||
* 最大缩放等级
|
||||
*/
|
||||
maxZoom?: number;
|
||||
|
||||
attributionControl?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
import { EventEmitter } from 'eventemitter3';
|
||||
import { IImage } from '../asset/IIconService';
|
||||
import { ILayer } from '../layer/ILayerService';
|
||||
import { IMapConfig } from '../map/IMapService';
|
||||
import { IRenderConfig } from '../renderer/IRendererService';
|
||||
|
||||
export interface ISceneService {
|
||||
on(type: string, hander: (...args: any[]) => void): void;
|
||||
off(type: string, hander: (...args: any[]) => void): void;
|
||||
removeAllListeners(event?: string): this;
|
||||
init(config: IMapConfig & IRenderConfig): void;
|
||||
addLayer(layer: ILayer): void;
|
||||
render(): void;
|
||||
destroy(): void;
|
||||
}
|
||||
export const SceneEventList = ['loaded', 'resize', 'destroy'];
|
||||
|
|
|
@ -3,8 +3,10 @@ import { inject, injectable } from 'inversify';
|
|||
import { AsyncParallelHook, AsyncSeriesHook } from 'tapable';
|
||||
import { TYPES } from '../../types';
|
||||
import { createRendererContainer } from '../../utils/dom';
|
||||
import { IFontService } from '../asset/IFontService';
|
||||
import { IIconService, IImage } from '../asset/IIconService';
|
||||
import { ICameraService, IViewport } from '../camera/ICameraService';
|
||||
import { IControlService } from '../component/IControlService';
|
||||
import { IGlobalConfig, IGlobalConfigService } from '../config/IConfigService';
|
||||
import { IInteractionService } from '../interaction/IInteractionService';
|
||||
import { ILayer, ILayerService } from '../layer/ILayerService';
|
||||
|
@ -18,11 +20,18 @@ import { ISceneService } from './ISceneService';
|
|||
*/
|
||||
@injectable()
|
||||
export default class Scene extends EventEmitter implements ISceneService {
|
||||
@inject(TYPES.IIconService)
|
||||
public readonly iconService: IIconService;
|
||||
/**
|
||||
* 使用各种 Service
|
||||
*/
|
||||
@inject(TYPES.IIconService)
|
||||
private readonly iconService: IIconService;
|
||||
|
||||
@inject(TYPES.IFontService)
|
||||
private readonly fontService: IFontService;
|
||||
|
||||
@inject(TYPES.IControlService)
|
||||
private readonly controlService: IControlService;
|
||||
|
||||
@inject(TYPES.ILogService)
|
||||
private readonly logger: ILogService;
|
||||
|
||||
|
@ -78,8 +87,18 @@ export default class Scene extends EventEmitter implements ISceneService {
|
|||
|
||||
public init(globalConfig: IGlobalConfig) {
|
||||
this.configService.setAndCheckConfig(globalConfig);
|
||||
// 初始化资源管理 字体,图片
|
||||
|
||||
// 初始化资源管理 图片
|
||||
this.iconService.init();
|
||||
// 字体资源
|
||||
this.fontService.init();
|
||||
|
||||
this.controlService.init({
|
||||
container: document.getElementById(
|
||||
this.configService.getConfig().id || 'map',
|
||||
) as HTMLElement,
|
||||
});
|
||||
|
||||
/**
|
||||
* 初始化底图
|
||||
*/
|
||||
|
@ -137,6 +156,8 @@ export default class Scene extends EventEmitter implements ISceneService {
|
|||
if (!this.inited) {
|
||||
// 首次渲染需要等待底图、相机初始化
|
||||
await this.hooks.init.promise(this.configService.getConfig());
|
||||
// 初始化marker 容器
|
||||
this.map.addMarkerContainer();
|
||||
this.emit('loaded');
|
||||
this.inited = true;
|
||||
|
||||
|
@ -153,6 +174,8 @@ export default class Scene extends EventEmitter implements ISceneService {
|
|||
this.layerService.clean();
|
||||
this.configService.reset();
|
||||
this.interactionService.destroy();
|
||||
this.controlService.destroy();
|
||||
this.removeAllListeners();
|
||||
window.removeEventListener('resize', this.handleWindowResized, false);
|
||||
}
|
||||
private handleWindowResized = () => {
|
||||
|
|
|
@ -10,7 +10,9 @@ const TYPES = {
|
|||
IRendererService: Symbol.for('IRendererService'),
|
||||
IShaderModuleService: Symbol.for('IShaderModuleService'),
|
||||
IIconService: Symbol.for('IIconService'),
|
||||
IFontService: Symbol.for('IFontService'),
|
||||
IInteractionService: Symbol.for('IInteractionService'),
|
||||
IControlService: Symbol.for('IControlService'),
|
||||
|
||||
/** multi-pass */
|
||||
ClearPass: Symbol.for('ClearPass'),
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
const docStyle = window.document.documentElement.style;
|
||||
type ELType = HTMLElement | SVGElement;
|
||||
export function createRendererContainer(domId: string): HTMLDivElement | null {
|
||||
const $wrapper = document.getElementById(domId);
|
||||
|
||||
|
|
|
@ -1,10 +1,49 @@
|
|||
import {
|
||||
IIcon,
|
||||
IICONMap,
|
||||
IIconService,
|
||||
IIconValue,
|
||||
IImage,
|
||||
} from '../services/asset/IIconService';
|
||||
import { IFontMappingOption } from '../services/asset/IFontService';
|
||||
import { IIcon, IICONMap } from '../services/asset/IIconService';
|
||||
/**
|
||||
* tiny-sdf 中每个 glyph 的宽度(加上 buffer 24 + 3 + 3 = 30)
|
||||
*/
|
||||
const glyphSizeInSDF = 30;
|
||||
export function buildMapping({
|
||||
characterSet,
|
||||
getFontWidth,
|
||||
fontHeight,
|
||||
buffer,
|
||||
maxCanvasWidth,
|
||||
mapping = {},
|
||||
xOffset = 0,
|
||||
yOffset = 0,
|
||||
}: IFontMappingOption) {
|
||||
let row = 0;
|
||||
let x = xOffset;
|
||||
Array.from(characterSet).forEach((char: string, i: number) => {
|
||||
if (!mapping[char]) {
|
||||
const width = getFontWidth(char, i);
|
||||
if (x + glyphSizeInSDF > maxCanvasWidth) {
|
||||
x = 0;
|
||||
row++;
|
||||
}
|
||||
mapping[char] = {
|
||||
x,
|
||||
y: yOffset + row * glyphSizeInSDF,
|
||||
width: glyphSizeInSDF,
|
||||
height: glyphSizeInSDF,
|
||||
advance: width,
|
||||
};
|
||||
x += glyphSizeInSDF;
|
||||
}
|
||||
});
|
||||
|
||||
const rowHeight = fontHeight + buffer * 2;
|
||||
|
||||
return {
|
||||
mapping,
|
||||
xOffset: x,
|
||||
yOffset: yOffset + row * rowHeight,
|
||||
canvasHeight: nextPowOfTwo(yOffset + (row + 1) * rowHeight),
|
||||
};
|
||||
}
|
||||
|
||||
export function buildIconMaping(
|
||||
icons: IIcon[],
|
||||
buffer: number,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
declare module 'probe.gl' {
|
||||
class Log {
|
||||
constructor(options: { id: string });
|
||||
|
@ -8,4 +9,5 @@ declare module 'probe.gl' {
|
|||
info(message: string): () => any;
|
||||
error(message: string): () => any;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <reference path="../../../node_modules/eventemitter3/index.d.ts" />
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import {
|
||||
IFontService,
|
||||
IGlobalConfigService,
|
||||
IIconService,
|
||||
ILayer,
|
||||
|
@ -6,6 +7,7 @@ import {
|
|||
ILayerPlugin,
|
||||
ILayerStyleAttribute,
|
||||
ILayerStyleOptions,
|
||||
IMapService,
|
||||
IModel,
|
||||
IMultiPassRenderer,
|
||||
IRendererService,
|
||||
|
@ -59,9 +61,13 @@ export default class BaseLayer implements ILayer {
|
|||
public styleAttributes: {
|
||||
[key: string]: Required<ILayerStyleAttribute>;
|
||||
} = {};
|
||||
|
||||
@lazyInject(TYPES.IIconService)
|
||||
protected readonly iconService: IIconService;
|
||||
|
||||
@lazyInject(TYPES.IFontService)
|
||||
protected readonly fontService: IFontService;
|
||||
|
||||
protected layerSource: Source;
|
||||
|
||||
private encodedData: Array<{ [key: string]: unknown }>;
|
||||
|
@ -73,6 +79,9 @@ export default class BaseLayer implements ILayer {
|
|||
@lazyInject(TYPES.IRendererService)
|
||||
private readonly rendererService: IRendererService;
|
||||
|
||||
@lazyInject(TYPES.IMapService)
|
||||
private readonly map: IMapService;
|
||||
|
||||
constructor(initializationOptions: Partial<ILayerInitializationOptions>) {
|
||||
this.initializationOptions = initializationOptions;
|
||||
}
|
||||
|
@ -150,6 +159,14 @@ export default class BaseLayer implements ILayer {
|
|||
}
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* zoom to layer Bounds
|
||||
*/
|
||||
public fitBounds(): void {
|
||||
const source = this.getSource();
|
||||
const extent = source.extent;
|
||||
this.map.fitBounds([[extent[0], extent[1]], [extent[2], extent[3]]]);
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
this.models.forEach((model) => model.destroy());
|
||||
|
|
|
@ -61,70 +61,87 @@ export default class PointLayer extends BaseLayer {
|
|||
data: this.getEncodedData(),
|
||||
iconMap: this.iconService.getIconMap(),
|
||||
});
|
||||
this.models.push(
|
||||
createModel({
|
||||
attributes: {
|
||||
a_Position: createAttribute({
|
||||
buffer: createBuffer({
|
||||
data: buffer.attributes.positions,
|
||||
type: gl.FLOAT,
|
||||
this.fontService.setFontOptions({
|
||||
characterSet: ['人', '之', '初'],
|
||||
fontFamily: 'sans-serif',
|
||||
fontWeight: 'normal',
|
||||
});
|
||||
this.iconService.on('imageUpdate', () => {
|
||||
this.models.push(
|
||||
createModel({
|
||||
attributes: {
|
||||
a_Position: createAttribute({
|
||||
buffer: createBuffer({
|
||||
data: buffer.attributes.positions,
|
||||
type: gl.FLOAT,
|
||||
}),
|
||||
size: 3,
|
||||
}),
|
||||
size: 3,
|
||||
}),
|
||||
a_normal: createAttribute({
|
||||
buffer: createBuffer({
|
||||
data: buffer.attributes.normals,
|
||||
type: gl.FLOAT,
|
||||
a_normal: createAttribute({
|
||||
buffer: createBuffer({
|
||||
data: buffer.attributes.normals,
|
||||
type: gl.FLOAT,
|
||||
}),
|
||||
size: 3,
|
||||
}),
|
||||
size: 3,
|
||||
}),
|
||||
a_color: createAttribute({
|
||||
buffer: createBuffer({
|
||||
data: buffer.attributes.colors,
|
||||
type: gl.FLOAT,
|
||||
a_color: createAttribute({
|
||||
buffer: createBuffer({
|
||||
data: buffer.attributes.colors,
|
||||
type: gl.FLOAT,
|
||||
}),
|
||||
size: 4,
|
||||
}),
|
||||
size: 4,
|
||||
}),
|
||||
a_size: createAttribute({
|
||||
buffer: createBuffer({
|
||||
data: buffer.attributes.sizes,
|
||||
type: gl.FLOAT,
|
||||
a_size: createAttribute({
|
||||
buffer: createBuffer({
|
||||
data: buffer.attributes.sizes,
|
||||
type: gl.FLOAT,
|
||||
}),
|
||||
size: 1,
|
||||
}),
|
||||
size: 1,
|
||||
}),
|
||||
a_uv: createAttribute({
|
||||
buffer: createBuffer({
|
||||
data: buffer.attributes.uv,
|
||||
type: gl.FLOAT,
|
||||
a_uv: createAttribute({
|
||||
buffer: createBuffer({
|
||||
data: buffer.attributes.uv,
|
||||
type: gl.FLOAT,
|
||||
}),
|
||||
size: 2,
|
||||
}),
|
||||
size: 2,
|
||||
}),
|
||||
// a_shape: createAttribute({
|
||||
// buffer: createBuffer({
|
||||
// data: buffer.attributes.miters,
|
||||
// type: gl.FLOAT,
|
||||
// }),
|
||||
// size: 3,
|
||||
// a_shape: createAttribute({
|
||||
// buffer: createBuffer({
|
||||
// data: buffer.attributes.miters,
|
||||
// type: gl.FLOAT,
|
||||
// }),
|
||||
// size: 3,
|
||||
// }),
|
||||
},
|
||||
uniforms: {
|
||||
...uniforms,
|
||||
u_opacity: this.styleOption.opacity as number,
|
||||
u_texture: createTexture2D({
|
||||
data: this.iconService.getCanvas(),
|
||||
width: 1024,
|
||||
height: this.iconService.canvasHeight,
|
||||
}),
|
||||
},
|
||||
fs,
|
||||
vs,
|
||||
depth: { enable: false },
|
||||
blend: {
|
||||
enable: true,
|
||||
func: {
|
||||
srcRGB: gl.SRC_ALPHA,
|
||||
srcAlpha: 1,
|
||||
dstRGB: gl.ONE_MINUS_SRC_ALPHA,
|
||||
dstAlpha: 1,
|
||||
},
|
||||
},
|
||||
primitive: gl.POINTS,
|
||||
count: buffer.verticesCount,
|
||||
// elements: createElements({
|
||||
// data: buffer.indexArray,
|
||||
// type: gl.UNSIGNED_INT,
|
||||
// }),
|
||||
},
|
||||
uniforms: {
|
||||
...uniforms,
|
||||
u_opacity: this.styleOption.opacity as number,
|
||||
u_texture: createTexture2D({
|
||||
data: this.iconService.getCanvas(),
|
||||
width: 1024,
|
||||
height: this.iconService.canvasHeight,
|
||||
}),
|
||||
},
|
||||
fs,
|
||||
vs,
|
||||
primitive: gl.POINTS,
|
||||
count: buffer.verticesCount,
|
||||
// elements: createElements({
|
||||
// data: buffer.indexArray,
|
||||
// type: gl.UNSIGNED_INT,
|
||||
// }),
|
||||
}),
|
||||
);
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@ uniform sampler2D u_texture;
|
|||
varying vec4 v_color;
|
||||
varying vec2 v_uv;
|
||||
void main(){
|
||||
vec2 pos= v_uv + gl_PointCoord / vec2(1024.,128.)*64.;
|
||||
pos.y= 1.- pos.y;
|
||||
vec2 pos= v_uv + gl_PointCoord / vec2(1024.,128.)* 64.;
|
||||
// pos.y= 1.- pos.y;
|
||||
vec4 textureColor=texture2D(u_texture,pos);
|
||||
if(v_color == vec4(0.)){
|
||||
gl_FragColor= textureColor;
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
uniform sampler2D u_sdf_map;
|
||||
uniform float u_gamma_scale : 0.5;
|
||||
uniform float u_font_size : 24;
|
||||
uniform float u_opacity : 1.0;
|
||||
uniform vec4 u_stroke : [0, 0, 0, 1];
|
||||
uniform float u_strokeWidth : 2.0;
|
||||
uniform float u_halo_blur : 0.5;
|
||||
|
||||
varying vec4 v_color;
|
||||
varying vec2 v_uv;
|
||||
varying float v_gamma_scale;
|
||||
|
||||
void main() {
|
||||
// get sdf from atlas
|
||||
float dist = texture2D(u_sdf_map, v_uv).a;
|
||||
|
||||
float fontScale = u_font_size / 24.0;
|
||||
|
||||
lowp float buff = (6.0 - u_strokeWidth / fontScale) / SDF_PX;
|
||||
highp float gamma = (u_halo_blur * 1.19 / SDF_PX + EDGE_GAMMA) / (fontScale * u_gamma_scale);
|
||||
|
||||
highp float gamma_scaled = gamma * v_gamma_scale;
|
||||
|
||||
highp float alpha = smoothstep(buff - gamma_scaled, buff + gamma_scaled, dist);
|
||||
|
||||
gl_FragColor = mix(v_color * u_opacity, u_stroke, smoothstep(0., 0.5, 1. - dist)) * alpha;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
attribute vec3 a_Position;
|
||||
attribute vec2 a_tex;
|
||||
attribute vec2 a_offset;
|
||||
attribute vec4 a_color;
|
||||
attribute float a_size;
|
||||
|
||||
uniform vec2 u_sdf_map_size;
|
||||
uniform vec2 u_viewport_size;
|
||||
|
||||
uniform float u_activeId : 0;
|
||||
uniform vec4 u_activeColor : [1.0, 0.0, 0.0, 1.0];
|
||||
|
||||
varying vec2 v_uv;
|
||||
varying float v_gamma_scale;
|
||||
varying vec4 v_color;
|
||||
#pragma include "projection"
|
||||
void main() {
|
||||
v_color = a_color;
|
||||
v_uv = a_tex / u_sdf_map_size;
|
||||
|
||||
// 文本缩放比例
|
||||
float fontScale = a_size / 24.;
|
||||
|
||||
vec4 project_pos = project_position(vec4(a_Position, 1.0));
|
||||
|
||||
vec4 projected_position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0));
|
||||
|
||||
gl_Position = vec4(projected_position.xy / projected_position.w
|
||||
+ a_offset * fontScale / u_viewport_size * 2., 0.0, 1.0);
|
||||
v_gamma_scale = gl_Position.w;
|
||||
|
||||
|
||||
}
|
|
@ -24,6 +24,7 @@
|
|||
"gl-matrix": "^3.1.0",
|
||||
"inversify": "^5.0.1",
|
||||
"mapbox-gl": "^1.2.1",
|
||||
"@l7/utils": "0.0.1",
|
||||
"viewport-mercator-project": "^6.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -14,6 +14,7 @@ import {
|
|||
Point,
|
||||
TYPES,
|
||||
} from '@l7/core';
|
||||
import { DOM } from '@l7/utils';
|
||||
import { inject, injectable } from 'inversify';
|
||||
import Viewport from './Viewport';
|
||||
|
||||
|
@ -21,21 +22,53 @@ const AMAP_API_KEY: string = '15cd8a57710d40c9b7c0e3cc120f1200';
|
|||
const AMAP_VERSION: string = '1.4.8';
|
||||
const LNGLAT_OFFSET_ZOOM_THRESHOLD = 12;
|
||||
|
||||
/// <reference path="../../../../../node_modules/@types/amap-js-api/index.d.ts" />
|
||||
|
||||
/**
|
||||
* AMapService
|
||||
*/
|
||||
@injectable()
|
||||
export default class AMapService implements IMapService {
|
||||
public map: AMap.Map & IAMapInstance;
|
||||
|
||||
@inject(TYPES.ICoordinateSystemService)
|
||||
private readonly coordinateSystemService: ICoordinateSystemService;
|
||||
|
||||
private map: AMap.Map;
|
||||
private markerContainer: HTMLElement;
|
||||
|
||||
private viewport: Viewport;
|
||||
|
||||
private cameraChangedCallback: (viewport: IViewport) => void;
|
||||
|
||||
// init
|
||||
public addMarkerContainer(): void {
|
||||
const mapContainer = this.map.getContainer();
|
||||
if (mapContainer !== null) {
|
||||
const amap = mapContainer.getElementsByClassName(
|
||||
'amap-maps',
|
||||
)[0] as HTMLElement;
|
||||
this.markerContainer = DOM.create('div', 'l7_marker', amap);
|
||||
}
|
||||
}
|
||||
public getMarkerContainer(): HTMLElement {
|
||||
return this.markerContainer;
|
||||
}
|
||||
|
||||
// map event
|
||||
public on(type: string, handle: (...args: any[]) => void): void {
|
||||
this.map.on(type, handle);
|
||||
}
|
||||
|
||||
public off(type: string, handle: (...args: any[]) => void): void {
|
||||
this.map.off(type, handle);
|
||||
}
|
||||
|
||||
public getContainer(): HTMLElement | null {
|
||||
return this.map.getContainer();
|
||||
}
|
||||
|
||||
public getSize(): [number, number] {
|
||||
const size = this.map.getSize();
|
||||
return [size.getWidth(), size.getHeight()];
|
||||
}
|
||||
|
||||
public getZoom(): number {
|
||||
return this.map.getZoom();
|
||||
}
|
||||
|
@ -46,12 +79,15 @@ export default class AMapService implements IMapService {
|
|||
lat: center.getLat(),
|
||||
};
|
||||
}
|
||||
|
||||
public getPitch(): number {
|
||||
return this.map.getPitch();
|
||||
}
|
||||
|
||||
public getRotation(): number {
|
||||
return this.map.getRotation();
|
||||
}
|
||||
|
||||
public getBounds(): Bounds {
|
||||
// @ts-ignore
|
||||
const amapBound = this.map.getBounds().toBounds();
|
||||
|
@ -59,8 +95,17 @@ export default class AMapService implements IMapService {
|
|||
const SW = amapBound.getSouthWest();
|
||||
return [[NE.getLng(), NE.getLat()], [SW.getLng(), SW.getLat()]];
|
||||
}
|
||||
public setRotation(rotation: number): number {
|
||||
return this.setRotation(rotation);
|
||||
|
||||
public getMinZoom(): number {
|
||||
const zooms = this.map.get('zooms') as [number, number];
|
||||
return zooms[0];
|
||||
}
|
||||
public getMaxZoom(): number {
|
||||
const zooms = this.map.get('zooms') as [number, number];
|
||||
return zooms[1];
|
||||
}
|
||||
public setRotation(rotation: number): void {
|
||||
return this.map.setRotation(rotation);
|
||||
}
|
||||
|
||||
public zoomIn(): void {
|
||||
|
|
|
@ -12,9 +12,16 @@ import {
|
|||
IViewport,
|
||||
TYPES,
|
||||
} from '@l7/core';
|
||||
import { DOM } from '@l7/utils';
|
||||
import { inject, injectable } from 'inversify';
|
||||
import mapboxgl, { Map } from 'mapbox-gl';
|
||||
import mapboxgl, { IControl, Map } from 'mapbox-gl';
|
||||
import Viewport from './Viewport';
|
||||
const EventMap: {
|
||||
[key: string]: any;
|
||||
} = {
|
||||
mapmove: 'move',
|
||||
camerachange: 'move',
|
||||
};
|
||||
|
||||
mapboxgl.accessToken =
|
||||
'pk.eyJ1IjoieGlhb2l2ZXIiLCJhIjoiY2pxcmc5OGNkMDY3cjQzbG42cXk5NTl3YiJ9.hUC5Chlqzzh0FFd_aEc-uQ';
|
||||
|
@ -25,76 +32,130 @@ const LNGLAT_OFFSET_ZOOM_THRESHOLD = 12;
|
|||
*/
|
||||
@injectable()
|
||||
export default class MapboxService implements IMapService {
|
||||
public map: Map & IMapboxInstance;
|
||||
@inject(TYPES.ICoordinateSystemService)
|
||||
private readonly coordinateSystemService: ICoordinateSystemService;
|
||||
|
||||
private map: Map & IMapboxInstance;
|
||||
private viewport: Viewport;
|
||||
private markerContainer: HTMLElement;
|
||||
private cameraChangedCallback: (viewport: IViewport) => void;
|
||||
|
||||
// init
|
||||
public addMarkerContainer(): void {
|
||||
const container = this.map.getCanvasContainer();
|
||||
this.markerContainer = DOM.create('div', 'l7_marker', container);
|
||||
}
|
||||
|
||||
public getMarkerContainer(): HTMLElement {
|
||||
return this.markerContainer;
|
||||
}
|
||||
|
||||
// map event
|
||||
public on(type: string, handle: (...args: any[]) => void): void {
|
||||
this.map.on(EventMap[type] || type, handle);
|
||||
}
|
||||
public off(type: string, handle: (...args: any[]) => void): void {
|
||||
this.map.off(EventMap[type] || type, handle);
|
||||
}
|
||||
|
||||
public getContainer(): HTMLElement | null {
|
||||
return this.map.getContainer();
|
||||
}
|
||||
|
||||
public getSize(): [number, number] {
|
||||
const size = this.map.transform;
|
||||
return [size.width, size.height];
|
||||
}
|
||||
// get mapStatus method
|
||||
|
||||
public getZoom(): number {
|
||||
return this.map.getZoom();
|
||||
}
|
||||
|
||||
public getCenter(): ILngLat {
|
||||
return this.map.getCenter();
|
||||
}
|
||||
|
||||
public getPitch(): number {
|
||||
return this.map.getPitch();
|
||||
}
|
||||
|
||||
public getRotation(): number {
|
||||
return this.map.getBearing();
|
||||
}
|
||||
|
||||
public getBounds(): Bounds {
|
||||
return this.map.getBounds().toArray() as Bounds;
|
||||
}
|
||||
|
||||
public getMinZoom(): number {
|
||||
return this.map.getMinZoom();
|
||||
}
|
||||
|
||||
public getMaxZoom(): number {
|
||||
return this.map.getMaxZoom();
|
||||
}
|
||||
|
||||
public setRotation(rotation: number): void {
|
||||
this.map.setBearing(rotation);
|
||||
}
|
||||
|
||||
public zoomIn(): void {
|
||||
this.map.zoomIn();
|
||||
}
|
||||
|
||||
public zoomOut(): void {
|
||||
this.map.zoomOut();
|
||||
}
|
||||
|
||||
public panTo(p: [number, number]): void {
|
||||
this.map.panTo(p);
|
||||
}
|
||||
|
||||
public panBy(pixel: [number, number]): void {
|
||||
this.panTo(pixel);
|
||||
}
|
||||
|
||||
public fitBounds(bound: Bounds): void {
|
||||
this.map.fitBounds(bound);
|
||||
}
|
||||
|
||||
public setMaxZoom(max: number): void {
|
||||
this.map.setMaxZoom(max);
|
||||
}
|
||||
|
||||
public setMinZoom(min: number): void {
|
||||
this.map.setMinZoom(min);
|
||||
}
|
||||
|
||||
public setZoomAndCenter(zoom: number, center: [number, number]): void {
|
||||
this.map.flyTo({
|
||||
zoom,
|
||||
center,
|
||||
});
|
||||
}
|
||||
|
||||
public setMapStyle(style: string): void {
|
||||
this.map.setStyle(style);
|
||||
}
|
||||
// TODO: 计算像素坐标
|
||||
public pixelToLngLat(pixel: [number, number]): ILngLat {
|
||||
return this.map.unproject(pixel);
|
||||
}
|
||||
|
||||
public lngLatToPixel(lnglat: [number, number]): IPoint {
|
||||
return this.map.project(lnglat);
|
||||
}
|
||||
|
||||
public containerToLngLat(pixel: [number, number]): ILngLat {
|
||||
throw new Error('Method not implemented.');
|
||||
return this.map.unproject(pixel);
|
||||
}
|
||||
|
||||
public lngLatToContainer(lnglat: [number, number]): IPoint {
|
||||
throw new Error('Method not implemented.');
|
||||
return this.map.project(lnglat);
|
||||
}
|
||||
|
||||
public async init(mapConfig: IMapConfig): Promise<void> {
|
||||
const { id, ...rest } = mapConfig;
|
||||
|
||||
const { id, attributionControl = false, ...rest } = mapConfig;
|
||||
this.viewport = new Viewport();
|
||||
|
||||
/**
|
||||
|
@ -104,9 +165,9 @@ export default class MapboxService implements IMapService {
|
|||
// @ts-ignore
|
||||
this.map = new mapboxgl.Map({
|
||||
container: id,
|
||||
attributionControl,
|
||||
...rest,
|
||||
});
|
||||
|
||||
this.map.on('move', this.handleCameraChanged);
|
||||
|
||||
// 不同于高德地图,需要手动触发首次渲染
|
||||
|
@ -117,12 +178,16 @@ export default class MapboxService implements IMapService {
|
|||
'https://api.tiles.mapbox.com/mapbox-gl-js/v1.2.1/mapbox-gl.css';
|
||||
$link.rel = 'stylesheet';
|
||||
document.head.appendChild($link);
|
||||
this.removeLogoControl();
|
||||
}
|
||||
|
||||
public onCameraChanged(callback: (viewport: IViewport) => void): void {
|
||||
this.cameraChangedCallback = callback;
|
||||
}
|
||||
|
||||
// 同步不同底图的配置项
|
||||
private initMapConig(): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
private handleCameraChanged = () => {
|
||||
// @see https://github.com/mapbox/mapbox-gl-js/issues/2572
|
||||
const { lat, lng } = this.map.getCenter().wrap();
|
||||
|
@ -150,4 +215,16 @@ export default class MapboxService implements IMapService {
|
|||
|
||||
this.cameraChangedCallback(this.viewport);
|
||||
};
|
||||
private removeLogoControl(): void {
|
||||
// @ts-ignore
|
||||
const controls = this.map._controls as IControl[];
|
||||
const logoCtr = controls.find((ctr: IControl) => {
|
||||
if (ctr.hasOwnProperty('_updateLogo')) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
if (logoCtr) {
|
||||
this.map.removeControl(logoCtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
/// <reference path="../../../node_modules/@types/amap-js-api/index.d.ts" />
|
||||
|
||||
import { IControl } from 'mapbox-gl';
|
||||
|
||||
interface Window {
|
||||
onLoad: () => void;
|
||||
}
|
||||
|
@ -8,23 +11,21 @@ interface IAMapEvent {
|
|||
near: number;
|
||||
far: number;
|
||||
height: number;
|
||||
pitch: number;
|
||||
rotation: number;
|
||||
pitch: number;
|
||||
rotation: number;
|
||||
aspect: number;
|
||||
position: {x: number; y: number;};
|
||||
}
|
||||
position: { x: number; y: number };
|
||||
};
|
||||
}
|
||||
|
||||
interface IAMapInstance {
|
||||
on(eventName: string, handler: (event: IAMapEvent) => void): void;
|
||||
getZoom(): number;
|
||||
getCenter(): {lat: number; lng: number};
|
||||
[key:string]: Function;
|
||||
get(key: string): unknown;
|
||||
}
|
||||
|
||||
interface IMapboxInstance {
|
||||
_controls: IControl[];
|
||||
transform: {
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
"@l7/core": "^0.0.1",
|
||||
"@l7/maps": "^0.0.1",
|
||||
"@l7/renderer": "^0.0.1",
|
||||
"mapbox-gl": "^1.2.1",
|
||||
"inversify": "^5.0.1",
|
||||
"inversify-inject-decorators": "^3.1.0",
|
||||
"reflect-metadata": "^0.1.13"
|
||||
|
|
|
@ -2,24 +2,29 @@ import {
|
|||
Bounds,
|
||||
container,
|
||||
IconService,
|
||||
IControl,
|
||||
IControlService,
|
||||
IIconService,
|
||||
IImage,
|
||||
ILayer,
|
||||
ILngLat,
|
||||
IMapConfig,
|
||||
IMapService,
|
||||
IMarker,
|
||||
IPoint,
|
||||
IRenderConfig,
|
||||
IRendererService,
|
||||
ISceneService,
|
||||
MapType,
|
||||
Point,
|
||||
SceneEventList,
|
||||
SceneService,
|
||||
TYPES,
|
||||
} from '@l7/core';
|
||||
import { AMapService, MapboxService } from '@l7/maps';
|
||||
import { ReglRendererService } from '@l7/renderer';
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { Map } from 'mapbox-gl';
|
||||
|
||||
// 绑定渲染引擎服务
|
||||
container
|
||||
|
@ -39,10 +44,12 @@ container
|
|||
* scene.render();
|
||||
*/
|
||||
class Scene {
|
||||
@inject(TYPES.IIconService)
|
||||
public map: AMap.Map | Map;
|
||||
protected readonly iconService: IIconService;
|
||||
private sceneService: ISceneService;
|
||||
private mapService: IMapService;
|
||||
private controlService: IControlService;
|
||||
|
||||
public constructor(config: IMapConfig & IRenderConfig) {
|
||||
const { type = MapType.amap } = config;
|
||||
|
||||
|
@ -55,6 +62,7 @@ class Scene {
|
|||
} else {
|
||||
throw new Error('不支持的地图服务');
|
||||
}
|
||||
|
||||
// this.mapService = mapService;
|
||||
// DEMO 中切换底图实现时,需要重新绑定底图服务
|
||||
// @see https://github.com/inversify/InversifyJS/blob/master/wiki/container_api.md#containerrebindserviceidentifier-serviceidentifier
|
||||
|
@ -75,6 +83,12 @@ class Scene {
|
|||
this.sceneService.init(config);
|
||||
this.mapService = container.get<IMapService>(TYPES.IMapService);
|
||||
this.iconService = container.get<IIconService>(TYPES.IIconService);
|
||||
this.controlService = container.get<IControlService>(TYPES.IControlService);
|
||||
this.map = this.mapService.map; // 暴露原生map方法
|
||||
}
|
||||
|
||||
public getMapService(): IMapService {
|
||||
return this.mapService;
|
||||
}
|
||||
|
||||
public addLayer(layer: ILayer): void {
|
||||
|
@ -84,25 +98,65 @@ class Scene {
|
|||
public render(): void {
|
||||
this.sceneService.render();
|
||||
}
|
||||
|
||||
// asset method
|
||||
public addImage(id: string, img: IImage) {
|
||||
// this.sceneService.
|
||||
this.iconService.addImage(id, img);
|
||||
}
|
||||
|
||||
public hasImage(id: string) {
|
||||
this.iconService.hasImage(id);
|
||||
}
|
||||
|
||||
public removeImage(id: string) {
|
||||
this.iconService.removeImage(id);
|
||||
}
|
||||
|
||||
// map control method
|
||||
public addControl(ctr: IControl) {
|
||||
this.controlService.addControl(ctr, this.mapService);
|
||||
}
|
||||
|
||||
public removeControl(ctr: IControl) {
|
||||
this.controlService.removeControl(ctr);
|
||||
}
|
||||
|
||||
// marker
|
||||
public addMarker(marker: IMarker) {
|
||||
marker.addTo(this);
|
||||
}
|
||||
// map envent;
|
||||
|
||||
public on(type: string, handle: (...args: any[]) => void): void {
|
||||
SceneEventList.indexOf(type) === -1
|
||||
? this.mapService.on(type, handle)
|
||||
: this.sceneService.on(type, handle);
|
||||
}
|
||||
|
||||
public off(type: string, handle: (...args: any[]) => void): void {
|
||||
SceneEventList.indexOf(type) === -1
|
||||
? this.mapService.off(type, handle)
|
||||
: this.sceneService.off(type, handle);
|
||||
}
|
||||
|
||||
// map method
|
||||
|
||||
public getZoom(): number {
|
||||
return this.mapService.getZoom();
|
||||
}
|
||||
|
||||
public getCenter(): ILngLat {
|
||||
return this.mapService.getCenter();
|
||||
}
|
||||
|
||||
public getPitch(): number {
|
||||
return this.mapService.getPitch();
|
||||
}
|
||||
|
||||
public getRotation(): number {
|
||||
return this.mapService.getRotation();
|
||||
}
|
||||
|
||||
public getBounds(): Bounds {
|
||||
return this.mapService.getBounds();
|
||||
}
|
||||
|
@ -115,21 +169,27 @@ class Scene {
|
|||
public zoomIn(): void {
|
||||
this.mapService.zoomIn();
|
||||
}
|
||||
|
||||
public zoomOut(): void {
|
||||
this.mapService.zoomOut();
|
||||
}
|
||||
|
||||
public panTo(p: Point): void {
|
||||
this.mapService.panTo(p);
|
||||
}
|
||||
|
||||
public panBy(pixel: Point): void {
|
||||
this.mapService.panTo(pixel);
|
||||
}
|
||||
|
||||
public fitBounds(bound: Bounds): void {
|
||||
this.mapService.fitBounds(bound);
|
||||
}
|
||||
|
||||
public setZoomAndCenter(zoom: number, center: Point): void {
|
||||
this.mapService.setZoomAndCenter(zoom, center);
|
||||
}
|
||||
|
||||
public setMapStyle(style: string): void {
|
||||
this.mapService.setMapStyle(style);
|
||||
}
|
||||
|
@ -138,12 +198,15 @@ class Scene {
|
|||
public pixelToLngLat(pixel: Point): ILngLat {
|
||||
return this.mapService.pixelToLngLat(pixel);
|
||||
}
|
||||
|
||||
public lngLatToPixel(lnglat: Point): IPoint {
|
||||
return this.mapService.lngLatToPixel(lnglat);
|
||||
}
|
||||
|
||||
public containerToLngLat(pixel: Point): ILngLat {
|
||||
return this.mapService.containerToLngLat(pixel);
|
||||
}
|
||||
|
||||
public lngLatToContainer(lnglat: Point): IPoint {
|
||||
return this.mapService.lngLatToContainer(lnglat);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
"@turf/invariant": "^6.1.2",
|
||||
"@turf/meta": "^6.0.2",
|
||||
"d3-dsv": "^1.1.1",
|
||||
"d3-hexbin": "^0.2.2",
|
||||
"eventemitter3": "^3.1.0",
|
||||
"gl-matrix": "^3.1.0",
|
||||
"inversify": "^5.0.1",
|
||||
|
@ -40,6 +41,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@types/d3-dsv": "^1.0.36",
|
||||
"@types/d3-hexbin": "^0.2.3",
|
||||
"@types/gl-matrix": "^2.4.5",
|
||||
"@types/lodash": "^4.14.138",
|
||||
"@types/viewport-mercator-project": "^6.1.0"
|
||||
|
|
|
@ -6,6 +6,7 @@ import json from './parser/json';
|
|||
import Source from './source';
|
||||
import { cluster } from './transform/cluster';
|
||||
import { aggregatorToGrid } from './transform/grid';
|
||||
import { pointToHexbin } from './transform/hexagon';
|
||||
export default Source;
|
||||
registerParser('geojson', geojson);
|
||||
registerParser('image', image);
|
||||
|
@ -13,6 +14,7 @@ registerParser('csv', csv);
|
|||
registerParser('json', json);
|
||||
registerTransform('cluster', cluster);
|
||||
registerTransform('grid', aggregatorToGrid);
|
||||
registerTransform('hexagon', pointToHexbin);
|
||||
export {
|
||||
getTransform,
|
||||
registerTransform,
|
||||
|
|
|
@ -41,7 +41,6 @@ export default class Source extends EventEmitter {
|
|||
});
|
||||
this.init();
|
||||
}
|
||||
|
||||
private excuteParser(): void {
|
||||
const parser = this.parser;
|
||||
const type: string = parser.type || 'geojson';
|
||||
|
|
|
@ -2,13 +2,8 @@
|
|||
* 生成四边形热力图
|
||||
*/
|
||||
import { IParserCfg, IParserData, ISourceCFG, ITransform } from '@l7/core';
|
||||
import { max, mean, min, sum } from './statistics';
|
||||
const statMap: { [key: string]: any } = {
|
||||
min,
|
||||
max,
|
||||
mean,
|
||||
sum,
|
||||
};
|
||||
import { statMap } from './statistics';
|
||||
|
||||
interface IGridHash {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
import { aProjectFlat, unProjectFlat } from '@l7/utils';
|
||||
import { hexbin } from 'd3-hexbin';
|
||||
const R_EARTH = 6378000;
|
||||
import {
|
||||
IParseDataItem,
|
||||
IParserCfg,
|
||||
IParserData,
|
||||
ISourceCFG,
|
||||
ITransform,
|
||||
} from '@l7/core';
|
||||
import { statMap } from './statistics';
|
||||
interface IHexBinItem<T> extends Array<T> {
|
||||
x: number;
|
||||
y: number;
|
||||
[key: string]: any;
|
||||
}
|
||||
interface IRawData {
|
||||
coordinates: [number, number];
|
||||
[key: string]: any;
|
||||
}
|
||||
export function pointToHexbin(data: IParserData, option: ITransform) {
|
||||
const dataArray = data.dataArray;
|
||||
const { size = 10 } = option;
|
||||
const pixlSize = ((size / (2 * Math.PI * R_EARTH)) * (256 << 20)) / 2;
|
||||
const screenPoints: IRawData[] = dataArray.map((point: IParseDataItem) => {
|
||||
const [x, y] = aProjectFlat(point.coordinates);
|
||||
return {
|
||||
...point,
|
||||
coordinates: [x, y],
|
||||
};
|
||||
});
|
||||
|
||||
const newHexbin = hexbin<IRawData>()
|
||||
.radius(pixlSize)
|
||||
.x((d: IRawData) => d.coordinates[0])
|
||||
.y((d: IRawData) => d.coordinates[1]);
|
||||
const hexbinBins = newHexbin(screenPoints);
|
||||
|
||||
const result: IParserData = {
|
||||
dataArray: hexbinBins.map((hex: IHexBinItem<IRawData>, index: number) => {
|
||||
if (option.field && option.method) {
|
||||
const columns = getColumn(hex, option.field);
|
||||
hex[option.method] = statMap[option.method](columns);
|
||||
}
|
||||
return {
|
||||
[option.method]: hex[option.method],
|
||||
count: hex.length,
|
||||
coordinates: unProjectFlat([hex.x, hex.y]),
|
||||
_id: index + 1,
|
||||
};
|
||||
}),
|
||||
radius: pixlSize,
|
||||
};
|
||||
return result;
|
||||
}
|
||||
function getColumn(data: IHexBinItem<IRawData>, columnName: string) {
|
||||
return data.map((item: IRawData) => {
|
||||
return item[columnName];
|
||||
});
|
||||
}
|
|
@ -69,3 +69,9 @@ function mean(x: number[]) {
|
|||
}
|
||||
|
||||
export { sum, max, min, mean };
|
||||
export const statMap: { [key: string]: any } = {
|
||||
min,
|
||||
max,
|
||||
mean,
|
||||
sum,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
const docStyle = window.document.documentElement.style;
|
||||
type ELType = HTMLElement | SVGElement;
|
||||
export function createRendererContainer(domId: string): HTMLDivElement | null {
|
||||
const $wrapper = document.getElementById(domId);
|
||||
|
||||
if ($wrapper) {
|
||||
const $container = document.createElement('div');
|
||||
$container.style.cssText += `
|
||||
position: absolute;
|
||||
top: 0;
|
||||
z-index:10;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
pointer-events: none;
|
||||
`;
|
||||
$container.id = 'l7_canvaslayer';
|
||||
$wrapper.appendChild($container);
|
||||
return $container;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function trim(str: string) {
|
||||
return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, '');
|
||||
}
|
||||
|
||||
// @function splitWords(str: String): String[]
|
||||
// Trims and splits the string on whitespace and returns the array of parts.
|
||||
export function splitWords(str: string) {
|
||||
return trim(str).split(/\s+/);
|
||||
}
|
||||
|
||||
function testProp(props: string[]): string {
|
||||
if (!docStyle) {
|
||||
return props[0];
|
||||
}
|
||||
for (const i in props) {
|
||||
if (props[i] && props[i] in docStyle) {
|
||||
return props[i];
|
||||
}
|
||||
}
|
||||
|
||||
return props[0];
|
||||
}
|
||||
export function create(
|
||||
tagName: string,
|
||||
className?: string,
|
||||
container?: HTMLElement,
|
||||
) {
|
||||
const el = document.createElement(tagName);
|
||||
el.className = className || '';
|
||||
|
||||
if (container) {
|
||||
container.appendChild(el);
|
||||
}
|
||||
return el;
|
||||
}
|
||||
// @function remove(el: HTMLElement)
|
||||
// Removes `el` from its parent element
|
||||
export function remove(el: ELType) {
|
||||
const parent = el.parentNode;
|
||||
if (parent) {
|
||||
parent.removeChild(el);
|
||||
}
|
||||
}
|
||||
|
||||
// @function addClass(el: HTMLElement, name: String)
|
||||
// Adds `name` to the element's class attribute.
|
||||
export function addClass(el: ELType, name: string) {
|
||||
if (el.classList !== undefined) {
|
||||
const classes = splitWords(name);
|
||||
for (let i = 0, len = classes.length; i < len; i++) {
|
||||
el.classList.add(classes[i]);
|
||||
}
|
||||
} else if (!hasClass(el, name)) {
|
||||
const className = getClass(el);
|
||||
setClass(el, (className ? className + ' ' : '') + name);
|
||||
}
|
||||
}
|
||||
|
||||
// @function removeClass(el: HTMLElement, name: String)
|
||||
// Removes `name` from the element's class attribute.
|
||||
export function removeClass(el: ELType, name: string) {
|
||||
if (el.classList !== undefined) {
|
||||
el.classList.remove(name);
|
||||
} else {
|
||||
setClass(
|
||||
el,
|
||||
trim((' ' + getClass(el) + ' ').replace(' ' + name + ' ', ' ')),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// @function hasClass(el: HTMLElement, name: String): Boolean
|
||||
// Returns `true` if the element's class attribute contains `name`.
|
||||
export function hasClass(el: ELType, name: string) {
|
||||
if (el.classList !== undefined) {
|
||||
return el.classList.contains(name);
|
||||
}
|
||||
const className = getClass(el);
|
||||
return (
|
||||
className.length > 0 &&
|
||||
new RegExp('(^|\\s)' + name + '(\\s|$)').test(className)
|
||||
);
|
||||
}
|
||||
|
||||
// @function setClass(el: HTMLElement, name: String)
|
||||
// Sets the element's class.
|
||||
export function setClass(el: ELType, name: string) {
|
||||
if (el instanceof HTMLElement) {
|
||||
el.className = name;
|
||||
} else {
|
||||
// in case of SVG element
|
||||
el.className.baseVal = name;
|
||||
}
|
||||
}
|
||||
|
||||
// @function getClass(el: HTMLElement): String
|
||||
// Returns the element's class.
|
||||
export function getClass(el: ELType) {
|
||||
// Check if the element is an SVGElementInstance and use the correspondingElement instead
|
||||
// (Required for linked SVG elements in IE11.)
|
||||
if (el instanceof SVGElement) {
|
||||
el = el.correspondingElement;
|
||||
}
|
||||
return el.className.baseVal === undefined
|
||||
? el.className
|
||||
: el.className.baseVal;
|
||||
}
|
||||
|
||||
export function empty(el: ELType) {
|
||||
while (el.firstChild) {
|
||||
el.removeChild(el.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
const transformProp = testProp(['transform', 'WebkitTransform']);
|
||||
|
||||
export function setTransform(el: ELType, value: string) {
|
||||
// @ts-ignore
|
||||
el.style[transformProp] = value;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
export function bindAll(fns: string[], context: any) {
|
||||
fns.forEach((fn) => {
|
||||
if (!context[fn]) {
|
||||
return;
|
||||
}
|
||||
context[fn] = context[fn].bind(context);
|
||||
});
|
||||
}
|
|
@ -1,4 +1,12 @@
|
|||
import { BBox } from '@turf/helpers';
|
||||
import {
|
||||
BBox,
|
||||
Coord,
|
||||
degreesToRadians,
|
||||
isObject,
|
||||
radiansToLength,
|
||||
Units,
|
||||
} from '@turf/helpers';
|
||||
|
||||
const originShift = (2 * Math.PI * 6378137) / 2.0;
|
||||
export type Point = [number, number] | [number, number, number];
|
||||
/**
|
||||
|
@ -6,7 +14,7 @@ export type Point = [number, number] | [number, number, number];
|
|||
* @param {dataArray} data 地理坐标数据
|
||||
* @return {Array} dataExtent
|
||||
*/
|
||||
export function extent(data: any[]) {
|
||||
export function extent(data: any[]): BBox {
|
||||
const dataExtent: BBox = [Infinity, Infinity, -Infinity, -Infinity];
|
||||
data.forEach((item) => {
|
||||
const { coordinates } = item;
|
||||
|
@ -150,7 +158,40 @@ export function aProjectFlat(lnglat: number[]) {
|
|||
const b = 0.5;
|
||||
const c = -0.5 / Math.PI;
|
||||
d = 0.5;
|
||||
x = scale * (a * x + b) - 215440491;
|
||||
y = scale * (c * y + d) - 106744817;
|
||||
x = scale * (a * x + b);
|
||||
y = scale * (c * y + d);
|
||||
return [parseInt(x.toString(), 10), parseInt(y.toString(), 10)];
|
||||
}
|
||||
export function unProjectFlat(px: number[]): [number, number] {
|
||||
const a = 0.5 / Math.PI;
|
||||
const b = 0.5;
|
||||
const c = -0.5 / Math.PI;
|
||||
let d = 0.5;
|
||||
const scale = 256 << 20;
|
||||
let [x, y] = px;
|
||||
x = (x / scale - b) / a;
|
||||
y = (y / scale - d) / c;
|
||||
y = (Math.atan(Math.pow(Math.E, y)) - Math.PI / 4) * 2;
|
||||
d = Math.PI / 180;
|
||||
const lat = y / d;
|
||||
const lng = x / d;
|
||||
return [lng, lat];
|
||||
}
|
||||
export function lnglatDistance(
|
||||
coordinates1: [number, number],
|
||||
coordinates2: [number, number],
|
||||
units?: Units,
|
||||
): number {
|
||||
const dLat = degreesToRadians(coordinates2[1] - coordinates1[1]);
|
||||
const dLon = degreesToRadians(coordinates2[0] - coordinates1[0]);
|
||||
const lat1 = degreesToRadians(coordinates1[1]);
|
||||
const lat2 = degreesToRadians(coordinates2[1]);
|
||||
const a =
|
||||
Math.pow(Math.sin(dLat / 2), 2) +
|
||||
Math.pow(Math.sin(dLon / 2), 2) * Math.cos(lat1) * Math.cos(lat2);
|
||||
|
||||
return radiansToLength(
|
||||
2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)),
|
||||
(units = 'meters'),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
export { djb2hash, BKDRHash } from './hash';
|
||||
import * as DOM from './dom';
|
||||
export * from './fetchData';
|
||||
export * from './geo';
|
||||
export * from './lru_cache';
|
||||
export * from './event';
|
||||
export { DOM };
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/**
|
||||
* LRU Cache class with limit
|
||||
*
|
||||
* Update order for each get/set operation
|
||||
* Delete oldest when reach given limit
|
||||
*/
|
||||
type callback = (...args: any[]) => void;
|
||||
interface ICache {
|
||||
[key: string]: any;
|
||||
}
|
||||
export class LRUCache {
|
||||
private limit: number;
|
||||
private cache: ICache;
|
||||
private destroy: (value: any, key: string) => void;
|
||||
private order: any[];
|
||||
constructor(limit = 50, destroy?: callback) {
|
||||
this.limit = limit;
|
||||
this.destroy = destroy || this.defaultDestroy;
|
||||
this.order = [];
|
||||
this.clear();
|
||||
}
|
||||
|
||||
public clear() {
|
||||
this.order.forEach((key) => {
|
||||
this.delete(key);
|
||||
});
|
||||
this.cache = {};
|
||||
// access/update order, first item is oldest, last item is newest
|
||||
this.order = [];
|
||||
}
|
||||
|
||||
public get(key: string) {
|
||||
const value = this.cache[key];
|
||||
if (value) {
|
||||
// update order
|
||||
this.deleteOrder(key);
|
||||
this.appendOrder(key);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public set(key: string, value: any) {
|
||||
if (!this.cache[key]) {
|
||||
// if reach limit, delete the oldest
|
||||
if (Object.keys(this.cache).length === this.limit) {
|
||||
this.delete(this.order[0]);
|
||||
}
|
||||
|
||||
this.cache[key] = value;
|
||||
this.appendOrder(key);
|
||||
} else {
|
||||
// if found in cache, delete the old one, insert new one to the first of list
|
||||
this.delete(key);
|
||||
|
||||
this.cache[key] = value;
|
||||
this.appendOrder(key);
|
||||
}
|
||||
}
|
||||
|
||||
public delete(key: string) {
|
||||
const value = this.cache[key];
|
||||
if (value) {
|
||||
this.deleteCache(key);
|
||||
this.deleteOrder(key);
|
||||
this.destroy(value, key);
|
||||
}
|
||||
}
|
||||
|
||||
private deleteCache(key: string) {
|
||||
delete this.cache[key];
|
||||
}
|
||||
|
||||
private deleteOrder(key: string) {
|
||||
const index = this.order.findIndex((o) => o === key);
|
||||
if (index >= 0) {
|
||||
this.order.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private appendOrder(key: string) {
|
||||
this.order.push(key);
|
||||
}
|
||||
private defaultDestroy(value: any, key: string) {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,400 @@
|
|||
.l7-marker {
|
||||
position: absolute !important;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 5;
|
||||
}
|
||||
.l7-popup-anchor-top,
|
||||
.l7-popup-anchor-top-left,
|
||||
.l7-popup-anchor-top-right {
|
||||
-webkit-flex-direction: column;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-bottom,
|
||||
.l7-popup-anchor-bottom-left,
|
||||
.l7-popup-anchor-bottom-right {
|
||||
-webkit-flex-direction: column-reverse;
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-left {
|
||||
-webkit-flex-direction: row;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-right {
|
||||
-webkit-flex-direction: row-reverse;
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
.l7-popup {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
will-change: transform;
|
||||
pointer-events: none;
|
||||
z-index: 5;
|
||||
}
|
||||
.l7-popup-tip {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: 10px solid transparent;
|
||||
z-index: 1;
|
||||
}
|
||||
.l7-popup-anchor-top .l7-popup-tip {
|
||||
-webkit-align-self: center;
|
||||
align-self: center;
|
||||
border-top: none;
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-top-left .l7-popup-tip {
|
||||
-webkit-align-self: flex-start;
|
||||
align-self: flex-start;
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-top-right .l7-popup-tip {
|
||||
-webkit-align-self: flex-end;
|
||||
align-self: flex-end;
|
||||
border-top: none;
|
||||
border-right: none;
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-bottom .l7-popup-tip {
|
||||
-webkit-align-self: center;
|
||||
align-self: center;
|
||||
border-bottom: none;
|
||||
border-top-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-bottom-left .l7-popup-tip {
|
||||
-webkit-align-self: flex-start;
|
||||
align-self: flex-start;
|
||||
border-bottom: none;
|
||||
border-left: none;
|
||||
border-top-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-bottom-right .l7-popup-tip {
|
||||
-webkit-align-self: flex-end;
|
||||
align-self: flex-end;
|
||||
border-bottom: none;
|
||||
border-right: none;
|
||||
border-top-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-left .l7-popup-tip {
|
||||
-webkit-align-self: center;
|
||||
align-self: center;
|
||||
border-left: none;
|
||||
border-right-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-right .l7-popup-tip {
|
||||
-webkit-align-self: center;
|
||||
align-self: center;
|
||||
border-right: none;
|
||||
border-left-color: #fff;
|
||||
}
|
||||
|
||||
.l7-popup-close-button {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
font-size: 25px;
|
||||
line-height: 20px;
|
||||
border-radius: 0 3px 0 0;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.l7-popup-close-button:hover {
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.l7-popup-content {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
padding: 10px 10px 15px;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-top-left .l7-popup-content {
|
||||
border-top-left-radius: 0;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-top-right .l7-popup-content {
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-bottom-left .l7-popup-content {
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
.l7-popup-anchor-bottom-right .l7-popup-content {
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
.l7-popup-track-pointer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.l7-popup-track-pointer * {
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.l7-map:hover .l7-popup-track-pointer {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.l7-map:active .l7-popup-track-pointer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.l7-popup-close-button {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
border: 0;
|
||||
border-radius: 0 3px 0 0;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.l7-popup-close-button:hover {
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.l7-popup-content {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
padding: 10px 10px 15px;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* general toolbar styles */
|
||||
|
||||
.l7-bar {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.l7-bar a,
|
||||
.l7-bar a:hover {
|
||||
background-color: #fff;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
line-height: 30px;
|
||||
font-size: 30px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
color: #8E9DAB;
|
||||
}
|
||||
.l7-bar a,
|
||||
.l7-control-layers-toggle {
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
display: block;
|
||||
}
|
||||
.l7-bar a:hover {
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
.l7-bar a:first-child {
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
.l7-bar a:last-child {
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom: none;
|
||||
}
|
||||
.l7-bar a.l7-disabled {
|
||||
cursor: default;
|
||||
background-color: #f4f4f4;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
|
||||
/* control positioning */
|
||||
|
||||
.l7-control-container {
|
||||
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
}
|
||||
.l7-control-hide {
|
||||
display: none;
|
||||
}
|
||||
.l7-control {
|
||||
position: relative;
|
||||
z-index: 800;
|
||||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
|
||||
pointer-events: auto;
|
||||
}
|
||||
.l7-top,
|
||||
.l7-bottom {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
}
|
||||
.l7-top {
|
||||
top: 0;
|
||||
}
|
||||
.l7-right {
|
||||
right: 0;
|
||||
}
|
||||
.l7-bottom {
|
||||
bottom: 0;
|
||||
}
|
||||
.l7-left {
|
||||
left: 0;
|
||||
}
|
||||
.l7-control {
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
.l7-right .l7-control {
|
||||
float: right;
|
||||
}
|
||||
.l7-top .l7-control {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.l7-bottom .l7-control {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.l7-left .l7-control {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.l7-right .l7-control {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
/* attribution and scale controls */
|
||||
|
||||
.l7-control-container .l7-control-attribution {
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
margin: 0;
|
||||
}
|
||||
.l7-control-attribution,
|
||||
.l7-control-scale-line {
|
||||
padding: 0 5px;
|
||||
color: #333;
|
||||
}
|
||||
.l7-control-attribution a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.l7-control-attribution a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.l7-container .l7-control-attribution,
|
||||
.l7-container .l7-control-scale {
|
||||
font-size: 11px;
|
||||
padding: 5px 5px 2px 5px;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
.l7-left .l7-control-scale {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.l7-bottom .l7-control-scale {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.l7-control-scale-line {
|
||||
border: 2px solid #8E9DAB;
|
||||
border-top: none;
|
||||
color: #8e9dab;
|
||||
line-height: 1.1;
|
||||
padding: 2px 5px 1px;
|
||||
font-size: 11px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
.l7-control-scale-line:not(:first-child) {
|
||||
border-top: 2px solid #777;
|
||||
border-bottom: none;
|
||||
margin-top: -2px;
|
||||
}
|
||||
.l7-control-scale-line:not(:first-child):not(:last-child) {
|
||||
border-bottom: 2px solid #777;
|
||||
}
|
||||
|
||||
.l7-touch .l7-control-attribution,
|
||||
.l7-touch .l7-control-layers,
|
||||
.l7-touch .l7-bar {
|
||||
box-shadow: none;
|
||||
}
|
||||
.l7-touch .l7-control-layers,
|
||||
.l7-touch .l7-bar {
|
||||
border: 2px solid rgba(0,0,0,0.2);
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
|
||||
/* layers control */
|
||||
|
||||
.l7-control-layers {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.l7-control-layers-toggle {
|
||||
background-image: url(../images/layers.svg);
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
.l7-retina .l7-control-layers-toggle {
|
||||
background-image: url(../images/layers.svg);
|
||||
background-size: 26px 26px;
|
||||
}
|
||||
.l7-touch .l7-control-layers-toggle {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
}
|
||||
.l7-control-layers .l7-control-layers-list,
|
||||
.l7-control-layers-expanded .l7-control-layers-toggle {
|
||||
display: none;
|
||||
}
|
||||
.l7-control-layers-expanded .l7-control-layers-list {
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.l7-control-layers-expanded {
|
||||
padding: 6px 10px 6px 6px;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
}
|
||||
.l7-control-layers-scrollbar {
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
padding-right: 5px;
|
||||
}
|
||||
.l7-control-layers-selector {
|
||||
margin-top: 2px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
.l7-control-layers label {
|
||||
display: block;
|
||||
}
|
||||
.l7-control-layers-separator {
|
||||
height: 0;
|
||||
border-top: 1px solid #ddd;
|
||||
margin: 5px -10px 5px -6px;
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1566292427369" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8341" width="32" height="32" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M256 341.333333l256 128 256-128-256-128-256 128z m276.864-208.384l341.034667 173.909334c20.736 10.581333 28.202667 34.56 16.682666 53.632a41.386667 41.386667 0 0 1-16.64 15.317333l-341.077333 173.909333a46.336 46.336 0 0 1-41.728 0L150.101333 375.808c-20.736-10.581333-28.202667-34.56-16.682666-53.632a41.386667 41.386667 0 0 1 16.64-15.317333l341.077333-173.909334c12.970667-6.613333 28.757333-6.613333 41.728 0z m0 587.349334a45.653333 45.653333 0 0 1-41.728 0l-341.034667-176.938667c-20.736-10.752-28.202667-35.157333-16.682666-54.528a41.642667 41.642667 0 0 1 16.64-15.573333 34.901333 34.901333 0 0 1 32.213333 0l308.906667 160.213333c12.928 6.741333 28.714667 6.741333 41.685333 0l308.864-160.213333a34.901333 34.901333 0 0 1 32.170667 0c20.736 10.752 28.202667 35.157333 16.682666 54.528a41.642667 41.642667 0 0 1-16.64 15.573333l-341.077333 176.938667z m0 170.666666a45.653333 45.653333 0 0 1-41.728 0l-341.034667-176.938666c-20.736-10.752-28.202667-35.157333-16.682666-54.528a41.642667 41.642667 0 0 1 16.64-15.573334 34.901333 34.901333 0 0 1 32.213333 0l308.906667 160.213334c12.928 6.741333 28.714667 6.741333 41.685333 0l308.864-160.213334a34.901333 34.901333 0 0 1 32.170667 0c20.736 10.752 28.202667 35.157333 16.682666 54.528a41.642667 41.642667 0 0 1-16.64 15.573334l-341.077333 176.938666z" fill="#000000" p-id="8342"></path></svg>
|
After Width: | Height: | Size: 1.7 KiB |
|
@ -1,3 +1,5 @@
|
|||
import '!style-loader!css-loader!./css/l7.css';
|
||||
import { Marker, Popup, Scale, Zoom } from '@l7/component';
|
||||
import { Point } from '@l7/layers';
|
||||
import { Scene } from '@l7/scene';
|
||||
import * as React from 'react';
|
||||
|
@ -15,7 +17,7 @@ export default class PointImage extends React.Component {
|
|||
id: 'map',
|
||||
pitch: 0,
|
||||
type: 'mapbox',
|
||||
style: 'mapbox://styles/mapbox/streets-v9',
|
||||
style: 'mapbox://styles/mapbox/dark-v10',
|
||||
zoom: 1,
|
||||
});
|
||||
scene.addImage(
|
||||
|
@ -23,26 +25,41 @@ export default class PointImage extends React.Component {
|
|||
'https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*kzTMQqS2QdUAAAAAAAAAAABkARQnAQ',
|
||||
);
|
||||
const pointLayer = new Point({});
|
||||
const p1 = {
|
||||
type: 'FeatureCollection',
|
||||
features: [
|
||||
{
|
||||
type: 'Feature',
|
||||
properties: {},
|
||||
geometry: {
|
||||
type: 'Point',
|
||||
coordinates: [83.671875, 44.84029065139799],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// console.log(zoomControl);
|
||||
//
|
||||
pointLayer
|
||||
.source(data)
|
||||
// .color('blue')
|
||||
.shape('00')
|
||||
.size(14);
|
||||
.size(40);
|
||||
scene.addLayer(pointLayer);
|
||||
scene.render();
|
||||
scene.on('loaded', () => {
|
||||
const zoomControl = new Zoom({
|
||||
position: 'bottomright',
|
||||
});
|
||||
const scaleControl = new Scale();
|
||||
const popup = new Popup({
|
||||
offsets: [0, 20],
|
||||
})
|
||||
.setLnglat({
|
||||
lng: 120.19382669582967,
|
||||
lat: 30.258134,
|
||||
})
|
||||
.setText('hello')
|
||||
.addTo(scene);
|
||||
|
||||
const maker = new Marker();
|
||||
maker
|
||||
.setLnglat({
|
||||
lng: 120.19382669582967,
|
||||
lat: 30.258134,
|
||||
})
|
||||
.addTo(scene);
|
||||
scene.addControl(zoomControl);
|
||||
scene.addControl(scaleControl);
|
||||
});
|
||||
}
|
||||
|
||||
public render() {
|
||||
|
|
299
yarn.lock
299
yarn.lock
|
@ -2057,7 +2057,7 @@
|
|||
resolved "https://registry.yarnpkg.com/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz#8a83f9335c7860effa2eeeca254332aa0aeed8f2"
|
||||
integrity sha1-ioP5M1x4YO/6Lu7KJUMyqgru2PI=
|
||||
|
||||
"@mapbox/tiny-sdf@^1.1.0":
|
||||
"@mapbox/tiny-sdf@^1.1.0", "@mapbox/tiny-sdf@^1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/tiny-sdf/-/tiny-sdf-1.1.1.tgz#16a20c470741bfe9191deb336f46e194da4a91ff"
|
||||
integrity sha512-Ihn1nZcGIswJ5XGbgFAvVumOgWpvIjBX9jiRlIl46uQG9vJOF51ViBYHF95rEZupuyQbEmhLaDPLQlU7fUTsBg==
|
||||
|
@ -2690,12 +2690,20 @@
|
|||
"@svgr/plugin-svgo" "^4.3.1"
|
||||
loader-utils "^1.2.3"
|
||||
|
||||
"@turf/distance@^6.0.1":
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@turf/distance/-/distance-6.0.1.tgz#0761f28784286e7865a427c4e7e3593569c2dea8"
|
||||
integrity sha512-q7t7rWIWfkg7MP1Vt4uLjSEhe5rPfCO2JjpKmk7JC+QZKEQkuvHEqy3ejW1iC7Kw5ZcZNR3qdMGGz+6HnVwqvg==
|
||||
dependencies:
|
||||
"@turf/helpers" "6.x"
|
||||
"@turf/invariant" "6.x"
|
||||
|
||||
"@turf/helpers@6.x", "@turf/helpers@^6.1.4":
|
||||
version "6.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@turf/helpers/-/helpers-6.1.4.tgz#d6fd7ebe6782dd9c87dca5559bda5c48ae4c3836"
|
||||
integrity sha512-vJvrdOZy1ngC7r3MDA7zIGSoIgyrkWcGnNIEaqn/APmw+bVLF2gAW7HIsdTxd12s5wQMqEpqIQrmrbRRZ0xC7g==
|
||||
|
||||
"@turf/invariant@^6.1.2":
|
||||
"@turf/invariant@6.x", "@turf/invariant@^6.1.2":
|
||||
version "6.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@turf/invariant/-/invariant-6.1.2.tgz#6013ed6219f9ac2edada9b31e1dfa5918eb0a2f7"
|
||||
integrity sha512-WU08Ph8j0J2jVGlQCKChXoCtI50BB3yEH21V++V0T4cR1T27HKCxkehV2sYMwTierfMBgjwSwDIsxnR4/2mWXg==
|
||||
|
@ -2769,6 +2777,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/d3-dsv/-/d3-dsv-1.0.36.tgz#e91129d7c02b1b814838d001e921e8b9a67153d0"
|
||||
integrity sha512-jbIWQ27QJcBNMZbQv0NSQMHnBDCmxghAxePxgyiPH1XPCRkOsTBei7jcdi3fDrUCGpCV3lKrSZFSlOkhUQVClA==
|
||||
|
||||
"@types/d3-hexbin@^0.2.3":
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-hexbin/-/d3-hexbin-0.2.3.tgz#75a86a3d2e782ca3070ebcce789abdb88036abda"
|
||||
integrity sha512-R/mmx2FJucHACRvGFoI+6jpr3mOAD6wuU2OjuCixxGRPHdmQNlMtBGBwxTmTs//kJvBzk9/vMhn47QOcY8Afrg==
|
||||
|
||||
"@types/d3-scale@^2.1.1":
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-2.1.1.tgz#405e58771ec6ae7b8f7b4178ee1887620759e8f7"
|
||||
|
@ -3761,6 +3774,14 @@ babel-plugin-const-enum@^0.0.2:
|
|||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
"@babel/plugin-syntax-typescript" "^7.3.3"
|
||||
|
||||
babel-plugin-css-modules-transform@^1.6.2:
|
||||
version "1.6.2"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-css-modules-transform/-/babel-plugin-css-modules-transform-1.6.2.tgz#eecf4889637bf1c56cda25ee21df060775d1bd22"
|
||||
integrity sha512-zBsI54N5n979vfYpqFzQ6oRwEiVcmLH5REyaincNW+Ecl52nvRsQPYIbDcJzHePrXI20YSRUw6G/qbPwZZDgfg==
|
||||
dependencies:
|
||||
css-modules-require-hook "^4.0.6"
|
||||
mkdirp "^0.5.1"
|
||||
|
||||
babel-plugin-dynamic-import-node@2.3.0, babel-plugin-dynamic-import-node@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz#f00f507bdaa3c3e3ff6e7e5e98d90a7acab96f7f"
|
||||
|
@ -3950,6 +3971,14 @@ babel-plugin-transform-minify-booleans@^6.9.4:
|
|||
resolved "https://registry.yarnpkg.com/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.9.4.tgz#acbb3e56a3555dd23928e4b582d285162dd2b198"
|
||||
integrity sha1-rLs+VqNVXdI5KOS1gtKFFi3SsZg=
|
||||
|
||||
babel-plugin-transform-postcss@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-transform-postcss/-/babel-plugin-transform-postcss-0.3.0.tgz#1f2e5d047bbd0ce84ac443c4715003d3796ee237"
|
||||
integrity sha512-Sn4coeHvw3PCc22KVWtrkFFTh/K3G1ZCl26O3HZyLBgna987oHqTjJui+ofVUmglaWqydmFiEQd999uXWrmQLQ==
|
||||
dependencies:
|
||||
debug "^2.6.0"
|
||||
postcss-load-config "^1.1.0"
|
||||
|
||||
babel-plugin-transform-property-literals@^6.9.4:
|
||||
version "6.9.4"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.9.4.tgz#98c1d21e255736573f93ece54459f6ce24985d39"
|
||||
|
@ -5000,7 +5029,7 @@ concat-map@0.0.1:
|
|||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||
|
||||
concat-stream@^1.4.7, concat-stream@^1.5.0, concat-stream@~1.6.0:
|
||||
concat-stream@^1.5.0, concat-stream@~1.6.0:
|
||||
version "1.6.2"
|
||||
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
|
||||
integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==
|
||||
|
@ -5267,6 +5296,19 @@ corejs-upgrade-webpack-plugin@^2.0.0:
|
|||
resolve-from "^5.0.0"
|
||||
webpack "^4.38.0"
|
||||
|
||||
cosmiconfig@^2.1.0, cosmiconfig@^2.1.1:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-2.2.2.tgz#6173cebd56fac042c1f4390edf7af6c07c7cb892"
|
||||
integrity sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==
|
||||
dependencies:
|
||||
is-directory "^0.3.1"
|
||||
js-yaml "^3.4.3"
|
||||
minimist "^1.2.0"
|
||||
object-assign "^4.1.0"
|
||||
os-homedir "^1.0.1"
|
||||
parse-json "^2.2.0"
|
||||
require-from-string "^1.1.0"
|
||||
|
||||
cosmiconfig@^5.0.0, cosmiconfig@^5.1.0, cosmiconfig@^5.2.0, cosmiconfig@^5.2.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a"
|
||||
|
@ -5404,7 +5446,7 @@ css-loader@^2.1.1:
|
|||
postcss-value-parser "^3.3.0"
|
||||
schema-utils "^1.0.0"
|
||||
|
||||
css-loader@^3.0.0:
|
||||
css-loader@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.2.0.tgz#bb570d89c194f763627fcf1f80059c6832d009b2"
|
||||
integrity sha512-QTF3Ud5H7DaZotgdcJjGMvyDj5F3Pn1j/sC6VBEOVp94cbwqyIBdcs/quzj4MC1BKQSrTpQznegH/5giYbhnCQ==
|
||||
|
@ -5422,6 +5464,24 @@ css-loader@^3.0.0:
|
|||
postcss-value-parser "^4.0.0"
|
||||
schema-utils "^2.0.0"
|
||||
|
||||
css-modules-require-hook@^4.0.6:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/css-modules-require-hook/-/css-modules-require-hook-4.2.3.tgz#6792ca412b15e23e6f9be6a07dcef7f577ff904d"
|
||||
integrity sha1-Z5LKQSsV4j5vm+agfc739Xf/kE0=
|
||||
dependencies:
|
||||
debug "^2.2.0"
|
||||
generic-names "^1.0.1"
|
||||
glob-to-regexp "^0.3.0"
|
||||
icss-replace-symbols "^1.0.2"
|
||||
lodash "^4.3.0"
|
||||
postcss "^6.0.1"
|
||||
postcss-modules-extract-imports "^1.0.0"
|
||||
postcss-modules-local-by-default "^1.0.1"
|
||||
postcss-modules-resolve-imports "^1.3.0"
|
||||
postcss-modules-scope "^1.0.0"
|
||||
postcss-modules-values "^1.1.1"
|
||||
seekout "^1.0.1"
|
||||
|
||||
css-select-base-adapter@^0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7"
|
||||
|
@ -5447,6 +5507,15 @@ css-select@^2.0.0:
|
|||
domutils "^1.7.0"
|
||||
nth-check "^1.0.2"
|
||||
|
||||
css-selector-tokenizer@^0.7.0:
|
||||
version "0.7.1"
|
||||
resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz#a177271a8bca5019172f4f891fc6eed9cbf68d5d"
|
||||
integrity sha512-xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA==
|
||||
dependencies:
|
||||
cssesc "^0.1.0"
|
||||
fastparse "^1.1.1"
|
||||
regexpu-core "^1.0.0"
|
||||
|
||||
css-to-react-native@^2.0.3:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-2.3.2.tgz#e75e2f8f7aa385b4c3611c52b074b70a002f2e7d"
|
||||
|
@ -5492,6 +5561,11 @@ csscolorparser@~1.0.2:
|
|||
resolved "https://registry.yarnpkg.com/csscolorparser/-/csscolorparser-1.0.3.tgz#b34f391eea4da8f3e98231e2ccd8df9c041f171b"
|
||||
integrity sha1-s085HupNqPPpgjHizNjfnAQfFxs=
|
||||
|
||||
cssesc@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4"
|
||||
integrity sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=
|
||||
|
||||
cssesc@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
|
||||
|
@ -5591,6 +5665,11 @@ d3-format@1:
|
|||
resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.4.1.tgz#c45f74b17c5a290c072a4ba7039dd19662cd5ce6"
|
||||
integrity sha512-TUswGe6hfguUX1CtKxyG2nymO+1lyThbkS1ifLX0Sr+dOQtAD5gkrffpHnx+yHNKUZ0Bmg5T4AjUQwugPDrm0g==
|
||||
|
||||
d3-hexbin@^0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/d3-hexbin/-/d3-hexbin-0.2.2.tgz#9c5837dacfd471ab05337a9e91ef10bfc4f98831"
|
||||
integrity sha1-nFg32s/UcasFM3qeke8Qv8T5iDE=
|
||||
|
||||
d3-interpolate@1:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.3.2.tgz#417d3ebdeb4bc4efcc8fd4361c55e4040211fd68"
|
||||
|
@ -6721,6 +6800,11 @@ fast-levenshtein@~2.0.4:
|
|||
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
||||
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
|
||||
|
||||
fastparse@^1.1.1:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9"
|
||||
integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==
|
||||
|
||||
fastq@^1.6.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.6.0.tgz#4ec8a38f4ac25f21492673adb7eae9cfef47d1c2"
|
||||
|
@ -7148,6 +7232,13 @@ gaze@^1.0.0:
|
|||
dependencies:
|
||||
globule "^1.0.0"
|
||||
|
||||
generic-names@^1.0.1:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/generic-names/-/generic-names-1.0.3.tgz#2d786a121aee508876796939e8e3bff836c20917"
|
||||
integrity sha1-LXhqEhruUIh2eWk56OO/+DbCCRc=
|
||||
dependencies:
|
||||
loader-utils "^0.2.16"
|
||||
|
||||
genfun@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/genfun/-/genfun-5.0.0.tgz#9dd9710a06900a5c4a5bf57aca5da4e52fe76537"
|
||||
|
@ -7895,20 +7986,20 @@ humanize-ms@^1.2.1:
|
|||
dependencies:
|
||||
ms "^2.0.0"
|
||||
|
||||
husky@^3.0.4:
|
||||
version "3.0.5"
|
||||
resolved "https://registry.yarnpkg.com/husky/-/husky-3.0.5.tgz#d7db27c346645a8dc52df02aa534a377ad7925e0"
|
||||
integrity sha512-cKd09Jy9cDyNIvAdN2QQAP/oA21sle4FWXjIMDttailpLAYZuBE7WaPmhrkj+afS8Sj9isghAtFvWSQ0JiwOHg==
|
||||
husky@^3.0.9:
|
||||
version "3.0.9"
|
||||
resolved "https://registry.yarnpkg.com/husky/-/husky-3.0.9.tgz#a2c3e9829bfd6b4957509a9500d2eef5dbfc8044"
|
||||
integrity sha512-Yolhupm7le2/MqC1VYLk/cNmYxsSsqKkTyBhzQHhPK1jFnC89mmmNVuGtLNabjDI6Aj8UNIr0KpRNuBkiC4+sg==
|
||||
dependencies:
|
||||
chalk "^2.4.2"
|
||||
ci-info "^2.0.0"
|
||||
cosmiconfig "^5.2.1"
|
||||
execa "^1.0.0"
|
||||
get-stdin "^7.0.0"
|
||||
is-ci "^2.0.0"
|
||||
opencollective-postinstall "^2.0.2"
|
||||
pkg-dir "^4.2.0"
|
||||
please-upgrade-node "^3.2.0"
|
||||
read-pkg "^5.1.1"
|
||||
read-pkg "^5.2.0"
|
||||
run-node "^1.0.0"
|
||||
slash "^3.0.0"
|
||||
|
||||
|
@ -7919,11 +8010,18 @@ iconv-lite@0.4, iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-
|
|||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3"
|
||||
|
||||
icss-replace-symbols@^1.1.0:
|
||||
icss-replace-symbols@^1.0.2, icss-replace-symbols@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded"
|
||||
integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=
|
||||
|
||||
icss-utils@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-3.0.1.tgz#ee70d3ae8cac38c6be5ed91e851b27eed343ad0f"
|
||||
integrity sha1-7nDTroysOMa+XtkehRsn7tNDrQ8=
|
||||
dependencies:
|
||||
postcss "^6.0.2"
|
||||
|
||||
icss-utils@^4.0.0, icss-utils@^4.1.0, icss-utils@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467"
|
||||
|
@ -9050,7 +9148,7 @@ js-tokens@^3.0.2:
|
|||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
|
||||
integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls=
|
||||
|
||||
js-yaml@^3.13.1:
|
||||
js-yaml@^3.13.1, js-yaml@^3.4.3:
|
||||
version "3.13.1"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
|
||||
integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
|
||||
|
@ -9565,7 +9663,7 @@ lodash@4.17.14:
|
|||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba"
|
||||
integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw==
|
||||
|
||||
lodash@4.17.15, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.15.0, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1, lodash@~4.17.10:
|
||||
lodash@4.17.15, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.15.0, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1, lodash@^4.3.0, lodash@~4.17.10:
|
||||
version "4.17.15"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
|
||||
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
|
||||
|
@ -10892,7 +10990,7 @@ os-browserify@^0.3.0:
|
|||
resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
|
||||
integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=
|
||||
|
||||
os-homedir@^1.0.0:
|
||||
os-homedir@^1.0.0, os-homedir@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
|
||||
integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
|
||||
|
@ -10921,11 +11019,6 @@ os-name@^3.0.0:
|
|||
macos-release "^2.2.0"
|
||||
windows-release "^3.1.0"
|
||||
|
||||
os-shim@^0.1.2:
|
||||
version "0.1.3"
|
||||
resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917"
|
||||
integrity sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc=
|
||||
|
||||
os-tmpdir@^1.0.0, os-tmpdir@~1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
|
||||
|
@ -11456,6 +11549,16 @@ postcss-less@^3.1.0:
|
|||
dependencies:
|
||||
postcss "^7.0.14"
|
||||
|
||||
postcss-load-config@^1.1.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-1.2.0.tgz#539e9afc9ddc8620121ebf9d8c3673e0ce50d28a"
|
||||
integrity sha1-U56a/J3chiASHr+djDZz4M5Q0oo=
|
||||
dependencies:
|
||||
cosmiconfig "^2.1.0"
|
||||
object-assign "^4.1.0"
|
||||
postcss-load-options "^1.2.0"
|
||||
postcss-load-plugins "^2.3.0"
|
||||
|
||||
postcss-load-config@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.1.0.tgz#c84d692b7bb7b41ddced94ee62e8ab31b417b003"
|
||||
|
@ -11464,6 +11567,22 @@ postcss-load-config@^2.0.0:
|
|||
cosmiconfig "^5.0.0"
|
||||
import-cwd "^2.0.0"
|
||||
|
||||
postcss-load-options@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-load-options/-/postcss-load-options-1.2.0.tgz#b098b1559ddac2df04bc0bb375f99a5cfe2b6d8c"
|
||||
integrity sha1-sJixVZ3awt8EvAuzdfmaXP4rbYw=
|
||||
dependencies:
|
||||
cosmiconfig "^2.1.0"
|
||||
object-assign "^4.1.0"
|
||||
|
||||
postcss-load-plugins@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-load-plugins/-/postcss-load-plugins-2.3.0.tgz#745768116599aca2f009fad426b00175049d8d92"
|
||||
integrity sha1-dFdoEWWZrKLwCfrUJrABdQSdjZI=
|
||||
dependencies:
|
||||
cosmiconfig "^2.1.1"
|
||||
object-assign "^4.1.0"
|
||||
|
||||
postcss-loader@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-3.0.0.tgz#6b97943e47c72d845fa9e03f273773d4e8dd6c2d"
|
||||
|
@ -11487,6 +11606,13 @@ postcss-media-query-parser@^0.2.3:
|
|||
resolved "https://registry.yarnpkg.com/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz#27b39c6f4d94f81b1a73b8f76351c609e5cef244"
|
||||
integrity sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=
|
||||
|
||||
postcss-modules-extract-imports@^1.0.0:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.1.tgz#dc87e34148ec7eab5f791f7cd5849833375b741a"
|
||||
integrity sha512-6jt9XZwUhwmRUhb/CkyJY020PYaPJsCyt3UjbaWo6XEbH/94Hmv6MP7fG2C5NDU/BcHzyGYxNtHvM+LTf9HrYw==
|
||||
dependencies:
|
||||
postcss "^6.0.1"
|
||||
|
||||
postcss-modules-extract-imports@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e"
|
||||
|
@ -11494,6 +11620,14 @@ postcss-modules-extract-imports@^2.0.0:
|
|||
dependencies:
|
||||
postcss "^7.0.5"
|
||||
|
||||
postcss-modules-local-by-default@^1.0.1:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz#f7d80c398c5a393fa7964466bd19500a7d61c069"
|
||||
integrity sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=
|
||||
dependencies:
|
||||
css-selector-tokenizer "^0.7.0"
|
||||
postcss "^6.0.1"
|
||||
|
||||
postcss-modules-local-by-default@^2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-2.0.6.tgz#dd9953f6dd476b5fd1ef2d8830c8929760b56e63"
|
||||
|
@ -11513,6 +11647,23 @@ postcss-modules-local-by-default@^3.0.2:
|
|||
postcss-selector-parser "^6.0.2"
|
||||
postcss-value-parser "^4.0.0"
|
||||
|
||||
postcss-modules-resolve-imports@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-modules-resolve-imports/-/postcss-modules-resolve-imports-1.3.0.tgz#398d3000b95ae969420cdf4cd83fa8067f1c5eae"
|
||||
integrity sha1-OY0wALla6WlCDN9M2D+oBn8cXq4=
|
||||
dependencies:
|
||||
css-selector-tokenizer "^0.7.0"
|
||||
icss-utils "^3.0.1"
|
||||
minimist "^1.2.0"
|
||||
|
||||
postcss-modules-scope@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz#d6ea64994c79f97b62a72b426fbe6056a194bb90"
|
||||
integrity sha1-1upkmUx5+XtipytCb75gVqGUu5A=
|
||||
dependencies:
|
||||
css-selector-tokenizer "^0.7.0"
|
||||
postcss "^6.0.1"
|
||||
|
||||
postcss-modules-scope@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.1.0.tgz#ad3f5bf7856114f6fcab901b0502e2a2bc39d4eb"
|
||||
|
@ -11521,6 +11672,14 @@ postcss-modules-scope@^2.1.0:
|
|||
postcss "^7.0.6"
|
||||
postcss-selector-parser "^6.0.0"
|
||||
|
||||
postcss-modules-values@^1.1.1:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz#ecffa9d7e192518389f42ad0e83f72aec456ea20"
|
||||
integrity sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=
|
||||
dependencies:
|
||||
icss-replace-symbols "^1.1.0"
|
||||
postcss "^6.0.1"
|
||||
|
||||
postcss-modules-values@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-2.0.0.tgz#479b46dc0c5ca3dc7fa5270851836b9ec7152f64"
|
||||
|
@ -11537,6 +11696,13 @@ postcss-modules-values@^3.0.0:
|
|||
icss-utils "^4.0.0"
|
||||
postcss "^7.0.6"
|
||||
|
||||
postcss-plugin@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-plugin/-/postcss-plugin-1.0.0.tgz#f763814565b87b93e13449fcf9d75941c566b070"
|
||||
integrity sha1-92OBRWW4e5PhNEn8+ddZQcVmsHA=
|
||||
dependencies:
|
||||
postcss "^6.0.8"
|
||||
|
||||
postcss-reporter@^6.0.0:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss-reporter/-/postcss-reporter-6.0.1.tgz#7c055120060a97c8837b4e48215661aafb74245f"
|
||||
|
@ -11607,6 +11773,15 @@ postcss-value-parser@^4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9"
|
||||
integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ==
|
||||
|
||||
postcss@^6.0.1, postcss@^6.0.2, postcss@^6.0.8:
|
||||
version "6.0.23"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324"
|
||||
integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==
|
||||
dependencies:
|
||||
chalk "^2.4.1"
|
||||
source-map "^0.6.1"
|
||||
supports-color "^5.4.0"
|
||||
|
||||
postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.5, postcss@^7.0.6, postcss@^7.0.7:
|
||||
version "7.0.17"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.17.tgz#4da1bdff5322d4a0acaab4d87f3e782436bad31f"
|
||||
|
@ -11616,20 +11791,20 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.1
|
|||
source-map "^0.6.1"
|
||||
supports-color "^6.1.0"
|
||||
|
||||
postcss@^7.0.18:
|
||||
version "7.0.18"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.18.tgz#4b9cda95ae6c069c67a4d933029eddd4838ac233"
|
||||
integrity sha512-/7g1QXXgegpF+9GJj4iN7ChGF40sYuGYJ8WZu8DZWnmhQ/G36hfdk3q9LBJmoK+lZ+yzZ5KYpOoxq7LF1BxE8g==
|
||||
dependencies:
|
||||
chalk "^2.4.2"
|
||||
source-map "^0.6.1"
|
||||
supports-color "^6.1.0"
|
||||
|
||||
potpack@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/potpack/-/potpack-1.0.1.tgz#d1b1afd89e4c8f7762865ec30bd112ab767e2ebf"
|
||||
integrity sha512-15vItUAbViaYrmaB/Pbw7z6qX2xENbFSTA7Ii4tgbPtasxm5v6ryKhKtL91tpWovDJzTiZqdwzhcFBCwiMVdVw==
|
||||
|
||||
pre-commit@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/pre-commit/-/pre-commit-1.2.2.tgz#dbcee0ee9de7235e57f79c56d7ce94641a69eec6"
|
||||
integrity sha1-287g7p3nI15X95xW186UZBpp7sY=
|
||||
dependencies:
|
||||
cross-spawn "^5.0.1"
|
||||
spawn-sync "^1.0.15"
|
||||
which "1.2.x"
|
||||
|
||||
prelude-ls@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
|
||||
|
@ -12356,7 +12531,7 @@ read-pkg@^3.0.0:
|
|||
normalize-package-data "^2.3.2"
|
||||
path-type "^3.0.0"
|
||||
|
||||
read-pkg@^5.1.1:
|
||||
read-pkg@^5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc"
|
||||
integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==
|
||||
|
@ -12521,7 +12696,7 @@ regenerate-unicode-properties@^8.1.0:
|
|||
dependencies:
|
||||
regenerate "^1.4.0"
|
||||
|
||||
regenerate@^1.4.0:
|
||||
regenerate@^1.2.1, regenerate@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
|
||||
integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==
|
||||
|
@ -12573,6 +12748,15 @@ regexp.prototype.flags@^1.2.0:
|
|||
dependencies:
|
||||
define-properties "^1.1.2"
|
||||
|
||||
regexpu-core@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b"
|
||||
integrity sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=
|
||||
dependencies:
|
||||
regenerate "^1.2.1"
|
||||
regjsgen "^0.2.0"
|
||||
regjsparser "^0.1.4"
|
||||
|
||||
regexpu-core@^4.5.4:
|
||||
version "4.5.5"
|
||||
resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.5.5.tgz#aaffe61c2af58269b3e516b61a73790376326411"
|
||||
|
@ -12585,11 +12769,23 @@ regexpu-core@^4.5.4:
|
|||
unicode-match-property-ecmascript "^1.0.4"
|
||||
unicode-match-property-value-ecmascript "^1.1.0"
|
||||
|
||||
regjsgen@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7"
|
||||
integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=
|
||||
|
||||
regjsgen@^0.5.0:
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.0.tgz#a7634dc08f89209c2049adda3525711fb97265dd"
|
||||
integrity sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==
|
||||
|
||||
regjsparser@^0.1.4:
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c"
|
||||
integrity sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=
|
||||
dependencies:
|
||||
jsesc "~0.5.0"
|
||||
|
||||
regjsparser@^0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.0.tgz#f1e6ae8b7da2bae96c99399b868cd6c933a2ba9c"
|
||||
|
@ -12742,6 +12938,11 @@ require-directory@^2.1.1:
|
|||
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
||||
integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
|
||||
|
||||
require-from-string@^1.1.0:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418"
|
||||
integrity sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=
|
||||
|
||||
require-main-filename@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
|
||||
|
@ -13042,6 +13243,14 @@ schema-utils@^2.0.0:
|
|||
ajv "^6.10.2"
|
||||
ajv-keywords "^3.4.1"
|
||||
|
||||
schema-utils@^2.0.1:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.5.0.tgz#8f254f618d402cc80257486213c8970edfd7c22f"
|
||||
integrity sha512-32ISrwW2scPXHUSusP8qMg5dLUawKkyV+/qIEV9JdXKx+rsM6mi8vZY8khg2M69Qom16rtroWXD3Ybtiws38gQ==
|
||||
dependencies:
|
||||
ajv "^6.10.2"
|
||||
ajv-keywords "^3.4.1"
|
||||
|
||||
scss-tokenizer@^0.2.3:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1"
|
||||
|
@ -13050,6 +13259,11 @@ scss-tokenizer@^0.2.3:
|
|||
js-base64 "^2.1.8"
|
||||
source-map "^0.4.2"
|
||||
|
||||
seekout@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/seekout/-/seekout-1.0.2.tgz#09ba9f1bd5b46fbb134718eb19a68382cbb1b9c9"
|
||||
integrity sha1-CbqfG9W0b7sTRxjrGaaDgsuxuck=
|
||||
|
||||
select-hose@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
|
||||
|
@ -13479,14 +13693,6 @@ space-separated-tokens@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.4.tgz#27910835ae00d0adfcdbd0ad7e611fb9544351fa"
|
||||
integrity sha512-UyhMSmeIqZrQn2UdjYpxEkwY9JUrn8pP+7L4f91zRzOQuI8MF1FGLfYU9DKCYeLdo7LXMxwrX5zKFy7eeeVHuA==
|
||||
|
||||
spawn-sync@^1.0.15:
|
||||
version "1.0.15"
|
||||
resolved "https://registry.yarnpkg.com/spawn-sync/-/spawn-sync-1.0.15.tgz#b00799557eb7fb0c8376c29d44e8a1ea67e57476"
|
||||
integrity sha1-sAeZVX63+wyDdsKdROih6mfldHY=
|
||||
dependencies:
|
||||
concat-stream "^1.4.7"
|
||||
os-shim "^0.1.2"
|
||||
|
||||
spdx-correct@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4"
|
||||
|
@ -13882,6 +14088,14 @@ style-loader@^0.23.1:
|
|||
loader-utils "^1.1.0"
|
||||
schema-utils "^1.0.0"
|
||||
|
||||
style-loader@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.0.0.tgz#1d5296f9165e8e2c85d24eee0b7caf9ec8ca1f82"
|
||||
integrity sha512-B0dOCFwv7/eY31a5PCieNwMgMhVGFe9w+rh7s/Bx8kfFkrth9zfTZquoYvdw8URgiqxObQKcpW51Ugz1HjfdZw==
|
||||
dependencies:
|
||||
loader-utils "^1.2.3"
|
||||
schema-utils "^2.0.1"
|
||||
|
||||
style-search@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/style-search/-/style-search-0.1.0.tgz#7958c793e47e32e07d2b5cafe5c0bf8e12e77902"
|
||||
|
@ -14025,7 +14239,7 @@ supports-color@^3.2.3:
|
|||
dependencies:
|
||||
has-flag "^1.0.0"
|
||||
|
||||
supports-color@^5.2.0, supports-color@^5.3.0:
|
||||
supports-color@^5.2.0, supports-color@^5.3.0, supports-color@^5.4.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
||||
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
|
||||
|
@ -15173,13 +15387,6 @@ which@1, which@^1.2.14, which@^1.2.9, which@^1.3.0, which@^1.3.1:
|
|||
dependencies:
|
||||
isexe "^2.0.0"
|
||||
|
||||
which@1.2.x:
|
||||
version "1.2.14"
|
||||
resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5"
|
||||
integrity sha1-mofEN48D6CfOyvGs31bHNsAcFOU=
|
||||
dependencies:
|
||||
isexe "^2.0.0"
|
||||
|
||||
wide-align@^1.1.0:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457"
|
||||
|
|
Loading…
Reference in New Issue