├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .npmrc
├── .nvmrc
├── .prettierignore
├── .prettierrc.js
├── CHANGELOG.md
├── LICENSE
├── README.md
├── build
└── RemoveGlobalNamePlugin.js
├── lint-staged.config.js
├── package.json
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── rollup.config.js
├── scripts
├── .eslintrc.js
└── publish.sh
├── src
├── index.ts
├── packages
│ ├── event
│ │ └── index.ts
│ ├── gltf
│ │ └── index.ts
│ ├── index.ts
│ └── layer
│ │ └── index.ts
└── utils
│ └── threeUtil.js
├── test
├── ferrari.glb
└── index.html
├── tsconfig.json
└── types
└── global.d.ts
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | !.*
4 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line @typescript-eslint/no-var-requires,no-undef
2 | const { defineConfig } = require('eslint-define-config')
3 |
4 | // eslint-disable-next-line no-undef
5 | module.exports = defineConfig({
6 | root: true,
7 | parserOptions: {
8 | parser: '@typescript-eslint/parser',
9 | sourceType: 'module',
10 | ecmaFeatures: {
11 | jsx: true,
12 | tsx: true,
13 | },
14 | },
15 | env: {
16 | browser: true,
17 | node: false,
18 | },
19 | globals: {
20 | jest: 'readonly',
21 | "AMap": true,
22 | "particlesJS": true,
23 | "expect": true,
24 | "sinon": true,
25 | "Loca": true,
26 | "VueAmap": true
27 | },
28 | plugins: ['@typescript-eslint', 'import'],
29 | extends: [
30 | 'eslint:recommended',
31 | 'plugin:@typescript-eslint/recommended'
32 | ],
33 | overrides: [
34 | {
35 | files: ['*.ts', '*.vue'],
36 | rules: {
37 | 'no-undef': 'off',
38 | },
39 | },
40 | {
41 | files: ['**/__tests__/**', '**/gulpfile.ts'],
42 | rules: {
43 | 'no-console': 'off',
44 | },
45 | },
46 | ],
47 | rules: {
48 | // js/ts
49 | 'no-console': ['warn', { allow: ['error'] }],
50 | 'no-restricted-syntax': ['error', 'LabeledStatement', 'WithStatement'],
51 | camelcase: ['error', { properties: 'never' }],
52 |
53 | 'no-var': 'error',
54 | 'no-empty': ['error', { allowEmptyCatch: true }],
55 | 'no-void': 'error',
56 | 'prefer-const': [
57 | 'warn',
58 | { destructuring: 'all', ignoreReadBeforeAssign: true },
59 | ],
60 | 'prefer-template': 'error',
61 | 'object-shorthand': [
62 | 'error',
63 | 'always',
64 | { ignoreConstructors: false, avoidQuotes: true },
65 | ],
66 | 'block-scoped-var': 'error',
67 | 'no-constant-condition': ['error', { checkLoops: false }],
68 |
69 | '@typescript-eslint/explicit-module-boundary-types': 'off',
70 | '@typescript-eslint/no-explicit-any': 'off',
71 | '@typescript-eslint/no-non-null-assertion': 'off',
72 | '@typescript-eslint/no-non-null-asserted-optional-chain': 'off',
73 | '@typescript-eslint/consistent-type-imports': [
74 | 'error',
75 | { disallowTypeAnnotations: false },
76 | ],
77 | '@typescript-eslint/no-this-alias': ['off'],
78 |
79 | // vue
80 | 'vue/no-v-html': 'off',
81 | 'vue/require-default-prop': 'off',
82 | 'vue/require-explicit-emits': 'off',
83 | 'vue/multi-word-component-names': 'off',
84 |
85 | // import
86 | 'import/first': 'error',
87 | 'import/no-duplicates': 'error',
88 | 'import/order': [
89 | 'error',
90 | {
91 | groups: [
92 | 'builtin',
93 | 'external',
94 | 'internal',
95 | 'parent',
96 | 'sibling',
97 | 'index',
98 | 'object',
99 | 'type',
100 | ],
101 |
102 | pathGroupsExcludedImportTypes: ['type'],
103 | },
104 | ],
105 | },
106 | })
107 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Build and Release Folders
2 | bin-debug/
3 | bin-release/
4 | [Oo]bj/
5 | [Bb]in/
6 |
7 | # Other files and folders
8 | .settings/
9 |
10 | # Executables
11 | *.swf
12 | *.air
13 | *.ipa
14 | *.apk
15 |
16 | # Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
17 | # should NOT be excluded as they contain compiler settings and other important
18 | # information for Eclipse / Flash Builder.
19 |
20 | dist
21 | node_modules
22 | .idea
23 | *.log
24 | .temp
25 | .cache
26 | dist.zip
27 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | shamefully-hoist = true
2 | @fj:registry=https://npm.fjdynamics.com/repository/npm-hosted/
3 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | v16
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | *.sh
2 | node_modules
3 | *.md
4 | *.woff
5 | *.ttf
6 | .vscode
7 | .idea
8 | dist
9 | /public
10 | .husky
11 | .local
12 | /bin
13 | Dockerfile
14 | .eslintrc.js
15 | lint-staged.config.js
16 | postcss.config.js
17 | .prettierrc.js
18 | .commitlintrc.js
19 | tailwind.config.js
20 | config
21 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | endOfLine: 'auto', // 允许代码结尾是回车或者换行,\n\r
3 | printWidth: 120, // 换行字符串阈值
4 | htmlWhitespaceSensitivity: "ignore",
5 | tabWidth: 2, // 水平缩进的空格数
6 | useTabs: false,
7 | semi: false, // 句末是否加分号
8 | vueIndentScriptAndStyle: true,
9 | singleQuote: true, // 用单引号
10 | trailingComma: 'none', // 最后一个对象元素加逗号
11 | bracketSpacing: true, // 对象,数组加空格
12 | bracketSameLine: true, // > 是否另起一行
13 | arrowParens: 'always' // (x) => {} 是否要有小括号
14 | }
15 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ### 0.0.5
2 | * 解决与loca一起使用时坐标转换异常问题
3 | * Gltf增加configLoader,用于扩展gltf配置,增加扩展能力
4 | * 修改打包,es包后缀更改为mjs
5 |
6 | ### 0.0.4
7 | * 解决发包问题
8 |
9 | ### 0.0.3
10 | * ThreeLayer初始化参数增加onInit 和 onRender函数
11 | * Gltf增加 onLoaded 参数
12 |
13 | ### 0.0.2
14 | 修改GLTF的scale参数类型,从数组调整为Vec3
15 |
16 | ### 0.0.1
17 | 初始版本,完成threelayer图层和gltf加载
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 amap
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # @amap/three-layer
2 | [](https://www.npmjs.org/package/@amap/three-layer)
3 | [](https://npmjs.org/package/@amap/three-layer)
4 | 
5 | [](https://github.com/AMap-Web/amap-three)
6 | [](https://github.com/AMap-Web/amap-three)
7 |
8 | ### 示例
9 | [codepen示例](https://codepen.io/yangyanggu/pen/jOxyJqp)
10 |
11 | ### 简介
12 | 本项目为高德地图的threejs图层插件,包含ThreeLayer图层、ThreeGltf加载
13 |
14 | ### 加载方式
15 | 当前项目支持CDN加载和npm加载两种方式。
16 |
17 | #### CDN加载
18 | CDN加载需要先加载高德地图JS和threejs的库,代码如下
19 | ```js
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | ```
29 |
30 | #### npm加载
31 | npm加载可以直接使用安装库
32 | ```shell
33 | npm install '@amap/three-layer'
34 | ```
35 |
36 | ### 使用示例
37 |
38 | #### CDN方式
39 | ```js
40 |
41 |
42 |
43 |
44 |
45 |
75 | ```
76 |
77 | #### npm方式
78 | ```js
79 | import {AmbientLight} from 'three'
80 | import {ThreeLayer, ThreeGltf} from '@amap/three-layer'
81 | const map = new AMap.Map('app', {
82 | center: [120,31],
83 | zoom: 14,
84 | viewMode: '3D',
85 | pitch: 35
86 | })
87 | const layer = new ThreeLayer(map)
88 | layer.on('complete', () => {
89 | const light = new AmbientLight('#ffffff', 1);
90 | layer.add(light);
91 | const gltf = new ThreeGltf(layer, {
92 | url: 'https://a.amap.com/jsapi_demos/static/gltf/Duck.gltf',
93 | position: [120, 31],
94 | scale: 800,
95 | rotation: {
96 | x:90,
97 | y:0,
98 | z:0
99 | }
100 | })
101 | console.log('layer: ', layer)
102 | console.log('gltf: ', gltf)
103 | })
104 | ```
105 |
106 | ### API文档说明
107 |
108 | #### ThreeLayer图层说明
109 | 基于threejs实现的three图层类,提供了基础的添加、删除物体、转换坐标等功能
110 | `` new AMap.ThreeLayer(map: AMap.Map, options: ThreeLayerOptions) ``
111 | ###### 参数说明
112 | map: 地图实例对象
113 | options: ThreeLayer初始化参数,参数内容如下:
114 |
115 | | 属性名 | 属性类型 | 属性描述 |
116 | | ---- |-----------------|------------------------------------|
117 | | zIndex | Number | 图层的层级,默认为 120 |
118 | | visible | Boolean | 图层是否可见,默认为 true |
119 | | zooms | [Number,Number] | 图层缩放等级范围,默认 [2, 20] |
120 | | opacity | Number | 图层透明度,默认为 1 |
121 | | alpha | Boolean | canvas是否包含alpha (透明度)。默认为 false |
122 | | antialias | Boolean | 是否执行抗锯齿。默认为false |
123 | | customCoordsCenter | [Number,Number] | gl自定义图层渲染的中心点,默认为初始化时的地图中心点 |
124 | | onInit | Function(render: WebGLRenderer, scene: Scene, camera: Camera) | GlCustomLayer的init执行后触发回调,用于扩展处理能力 |
125 | | onRender | render: WebGLRenderer, scene: Scene, camera: Camera) | GlCustomLayer的render触发时触发该回调,用于替换刷新功能,可以用于增加threejs的后期处理 |
126 |
127 | ###### 成员函数
128 |
129 | | 函数名 | 入参 | 返回值 | 描述 |
130 | |-----|------------------------------------|--------------------------------------------------|------------------------------------|
131 | | update | 无 | 无 | 更新图层,执行后将在下次帧刷新时更新图层 |
132 | | convertLngLat | [Number,Number] (经纬度) | [Number,Number] | 将经纬度转化为世界坐标 |
133 | | add | Object(threejs的对象,包括灯光、Object3D等等) | 无 | 添加对象到场景中,支持所有可添加到场景的对象 |
134 | | remove | Object | 无 | 从场景中移除对象 |
135 | | getScene | 无 | THREE.Scene | 获取Threejs的场景对象 |
136 | | getCamera | 无 | THREE.PerspectiveCamera或THREE.OrthographicCamera | 获取Threejs的相机对象,根据viewMode不同获取的相机不同 |
137 | | getRender | 无 | THREE.WebGLRenderer | 获取Threejs的webglRender |
138 | | getMap | 无 | AMap.Map | 获取地图实例 |
139 | | getOpacity | 无 | Number | 获取图层透明度 |
140 | | setOpacity | Number | 无 | 设置图层透明度 值范围:0 - 1 |
141 | | getZooms | 无 | [Number,Number] | 获取显示层级范围 |
142 | | setZooms | [Number,Number] | 无 | 设置图层显示的层级范围 |
143 | | getzIndex | 无 | Number | 获取图层层级 |
144 | | setzIndex | Number | 无 | 设置图层层级 |
145 | | show | 无 | 无 | 显示图层 |
146 | | hide | 无 | 无 | 隐藏图层 |
147 | |destroy | 无 | 无 | 销毁图层 |
148 |
149 | ###### 事件列表
150 |
151 | | 事件名 | 参数 | 描述 |
152 | | ---- | ---- | ---- |
153 | | complete | 无 | 图层初始化成功 |
154 |
155 | #### ThreeGltf类说明
156 | 基于threejs实现的GLTF加载类,提供了基础的gltf模型加载,位置移动、缩放、旋转、高度等功能
157 | `` new AMap.ThreeGltf(layer: AMap.ThreeLayer, options: ThreeGltfOptions) ``
158 | ###### 参数说明
159 | layer: ThreeLayer实例对象
160 | options: ThreeGltf初始化参数,参数内容如下:
161 |
162 | | 属性名 | 属性类型 | 属性描述 |
163 | | ---- |-------------------------------------------------------------|-----------------------------------|
164 | | url | String | 模型加载地址 |
165 | | position | [Number,Number] | 模型的经纬度位置信息 |
166 | | height | Number | 模型离地高度,默认0 |
167 | | rotation | {x:Number, y: Number, z: Number} | 模型旋转角度,用于调整模型方向 默认 {x:0,y:0,z:0} |
168 | | scale | Number,{x:Number, y: Number, z: Number} | 模型缩放比例,可以传入数值或者VEC3数据,默认 1 |
169 | | angle | Number | 模型旋转角度,一般用于车辆模型角度使用,默认 0 |
170 | | onLoaded | Function(gltf: Group, animations: AnimationClip[]) | 模型加载完成后触发回调 |
171 | | configLoader | (loader: GLTFLoader) => void | 配置loader,用于添加draco等扩展 |
172 |
173 | ###### 成员函数
174 |
175 | | 函数名 | 入参 | 返回值 | 描述 |
176 | |-----|----------------------------------|--------------|------------------|
177 | | setScale | Number,{x:Number, y: Number, z: Number} | 无 | 设置缩放比例 |
178 | | setPosition | [Number,Number] (经纬度) | 无 | 设置模型位置 |
179 | | setRotation | {x:Number, y: Number, z: Number} | 无 | 旋转模型 |
180 | | setAngle | Number | 无 | 设置模型旋转角度 0 - 360 |
181 | | setHeight | Number | 无 | 设置离地高度 |
182 | | getAnimations | 无 | animations数组 | 获取gltf中携带的动画信息 |
183 | | getObject | 无 | Object3D | 获取模型对象 |
184 | | refresh | 无 | 无 | 刷新图层 |
185 | | show | 无 | 无 | 显示模型 |
186 | | hide | 无 | 无 | 隐藏模型 |
187 | | startAnimations | 无 | 无 | 执行gltf模型中的动画 |
188 | | stopAnimations | 无 | 无 | 停止gltf模型中的动画 |
189 | | remove | 无 | 无 | 从layer中移出模型 |
190 | | destroy | 无 | 无 | 销毁模型 |
191 |
192 | ###### 事件列表
193 |
194 | | 事件名 | 参数 | 描述 |
195 | | ---- |----------------------------------|----------------------------------------|
196 | | complete | {target: Object3D, animations: animations} | 模型初始化成功后触发,返回模型对象和gltf自带的的animations对象 |
197 |
--------------------------------------------------------------------------------
/build/RemoveGlobalNamePlugin.js:
--------------------------------------------------------------------------------
1 | import MagicString from 'magic-string'
2 |
3 | export default function RemoveGlobalNamePlugin () {
4 | return {
5 | name: 'remove-global-name-plugin', // this name will show up in warnings and errors
6 | renderChunk ( code , chunk) {
7 | const id = chunk.fileName;
8 | const magicString = new MagicString(code);
9 | if (!codeHasReplacements(code, id, magicString)) {
10 | return null;
11 | }
12 |
13 | const result = { code: magicString.toString() };
14 | result.map = magicString.generateMap({ hires: true });
15 | return result;
16 | }
17 | };
18 | function codeHasReplacements(code, id, magicString) {
19 | const pattern = /global.AMap\s=\s\{\}/
20 | let result = false;
21 | let match;
22 |
23 | // eslint-disable-next-line no-cond-assign
24 | if ((match = pattern.exec(code))) {
25 | result = true;
26 | const start = match.index;
27 | const end = start + match[0].length;
28 | const replacement = 'global.AMap = global.AMap || {}';
29 | magicString.overwrite(start, end, replacement);
30 | }
31 | return result;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/lint-staged.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'src/**/*.{js,ts,vue}': ['eslint --fix --ext .js,.ts,.vue']
3 | }
4 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@amap/three-layer",
3 | "version": "0.0.5",
4 | "description": "高德地图amap的threejs图层插件",
5 | "keywords": [
6 | "amap",
7 | "threejs",
8 | "高德地图",
9 | "threejs图层"
10 | ],
11 | "exports": {
12 | ".": {
13 | "require": "./dist/index.cjs",
14 | "import": "./dist/index.mjs",
15 | "types": "./dist/index.d.ts"
16 | },
17 | "./*": "./*"
18 | },
19 | "main": "dist/index.cjs",
20 | "module": "dist/index.mjs",
21 | "unpkg": "dist/index.js",
22 | "jsdelivr": "dist/index.js",
23 | "packageManager": "pnpm@7.9.4",
24 | "workspaces": [
25 | "src/*"
26 | ],
27 | "engines": {
28 | "node": ">= 16"
29 | },
30 | "scripts": {
31 | "build": "npm run clean:dist && cross-env NODE_ENV=production rollup -c rollup.config.js",
32 | "dev": "npm run clean:dist && cross-env NODE_ENV=development rollup -c rollup.config.js -w",
33 | "clean:dist": "rimraf dist",
34 | "lint": "eslint --fix --ext .js,.vue src/",
35 | "prettier": "prettier --write src/",
36 | "prepublishOnly": "npm run build"
37 | },
38 | "browserslist": [
39 | "> 1%",
40 | "not ie 11",
41 | "not op_mini all"
42 | ],
43 | "repository": "https://github.com/AMap-Web/amap-three",
44 | "author": "guyangyang <407042815@qq.com>",
45 | "license": "MIT",
46 | "bugs": {
47 | "url": "https://github.com/AMap-Web/amap-three/issues"
48 | },
49 | "homepage": "https://github.com/AMap-Web/amap-three",
50 | "dependencies": {
51 | "@amap/amap-jsapi-types": "^0.0.8",
52 | "@types/three": "0.143.0",
53 | "three": "0.143.0"
54 | },
55 | "devDependencies": {
56 | "@pnpm/logger": "4.0.0",
57 | "@pnpm/types": "8.5.0",
58 | "@rollup/plugin-commonjs": "^22.0.2",
59 | "@rollup/plugin-node-resolve": "^13.3.0",
60 | "@rollup/plugin-replace": "4.0.0",
61 | "@rollup/plugin-typescript": "^8.3.0",
62 | "@typescript-eslint/eslint-plugin": "5.35.1",
63 | "@typescript-eslint/parser": "5.35.1",
64 | "cross-env": "^7.0.3",
65 | "esbuild": "^0.15.5",
66 | "eslint": "8.22.0",
67 | "eslint-config-prettier": "8.3.0",
68 | "eslint-define-config": "1.6.0",
69 | "eslint-plugin-import": "2.25.3",
70 | "eslint-plugin-prettier": "^4.2.1",
71 | "fast-glob": "3.2.7",
72 | "fs-extra": "10.0.0",
73 | "gulp": "4.0.2",
74 | "lint-staged": "^12.4.0",
75 | "magic-string": "^0.25.7",
76 | "prettier": "^2.7.1",
77 | "rimraf": "3.0.2",
78 | "rollup": "^2.78.1",
79 | "rollup-plugin-esbuild": "4.9.3",
80 | "rollup-plugin-filesize": "9.1.2",
81 | "rollup-plugin-livereload": "^2.0.5",
82 | "rollup-plugin-serve": "^2.0.1",
83 | "typescript": "^4.7.4"
84 | },
85 | "types": "dist/index.d.ts",
86 | "files": [
87 | "dist",
88 | "src"
89 | ]
90 | }
91 |
--------------------------------------------------------------------------------
/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | #
2 | packages:
3 | - 'src/**'
4 | - '!packages/__mocks__'
5 | - '!**/__tests__/**'
6 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | // 将CommonJS模块转换为ES6
2 | import commonjs from '@rollup/plugin-commonjs'
3 | // 在node_模块中查找并绑定第三方依赖项
4 | import nodeResolve from '@rollup/plugin-node-resolve'
5 | // 开发服务器
6 | import serve from 'rollup-plugin-serve'
7 | // 热更新服务
8 | import livereload from 'rollup-plugin-livereload'
9 |
10 | import esbuild from 'rollup-plugin-esbuild'
11 | import typescript from '@rollup/plugin-typescript';
12 |
13 | import RemoveGlobalNamePlugin from "./build/RemoveGlobalNamePlugin";
14 |
15 |
16 | function isProd(){
17 | return process.env.NODE_ENV === 'production';
18 | }
19 |
20 | export default {
21 | external: [/^three/],
22 | input: 'src/index.ts',
23 | output: [
24 | {
25 | file: './dist/index.js',
26 | format: 'umd',
27 | sourcemap: true,
28 | name: 'AMap',
29 | plugins: [RemoveGlobalNamePlugin()],
30 | globals: {
31 | three: 'THREE',
32 | 'three/examples/jsm/loaders/GLTFLoader.js': 'THREE'
33 | }
34 | //当入口文件有export时,'umd'格式必须指定name
35 | //这样,在通过
8 |
9 |
10 |
11 |
12 |
13 |
14 |