@kimap/indoor-positioning-sdk-vue2 4.0.1 → 4.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/KMDOMMarker.js +142 -4
- package/src/KMUtil.js +783 -0
- package/src/KimapCore.browser.js +225 -0
- package/src/KimapCore.js +201 -1
package/package.json
CHANGED
package/src/KMDOMMarker.js
CHANGED
|
@@ -106,14 +106,30 @@ KMDOMMarker.prototype.setPosition = function(position) {
|
|
|
106
106
|
/**
|
|
107
107
|
* 平滑移动到目标位置
|
|
108
108
|
* @param {Object} targetPosition - { x, y, z }
|
|
109
|
-
* @param {number}
|
|
109
|
+
* @param {number|Object} durationOrConfig - 动画时长(毫秒)或配置对象
|
|
110
|
+
* 如果是数字:动画时长,默认 1000
|
|
111
|
+
* 如果是对象:{ duration: 1000, avoidObstacles: false }
|
|
112
|
+
* - duration: 动画时长(毫秒),默认 1000
|
|
113
|
+
* - avoidObstacles: 是否绕过障碍物,默认 false
|
|
110
114
|
* @returns {Promise} 动画完成后 resolve
|
|
111
115
|
*/
|
|
112
|
-
KMDOMMarker.prototype.animateTo = function(targetPosition,
|
|
116
|
+
KMDOMMarker.prototype.animateTo = function(targetPosition, durationOrConfig) {
|
|
113
117
|
var self = this;
|
|
114
|
-
duration = duration || 1000;
|
|
115
118
|
|
|
116
|
-
|
|
119
|
+
// 解析参数
|
|
120
|
+
var config = {};
|
|
121
|
+
if (typeof durationOrConfig === 'number') {
|
|
122
|
+
config.duration = durationOrConfig;
|
|
123
|
+
config.avoidObstacles = false;
|
|
124
|
+
} else if (typeof durationOrConfig === 'object' && durationOrConfig !== null) {
|
|
125
|
+
config.duration = durationOrConfig.duration || 1000;
|
|
126
|
+
config.avoidObstacles = durationOrConfig.avoidObstacles || false;
|
|
127
|
+
} else {
|
|
128
|
+
config.duration = 1000;
|
|
129
|
+
config.avoidObstacles = false;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return new Promise(function(resolve, reject) {
|
|
117
133
|
// 取消之前的动画
|
|
118
134
|
if (self._animationId) {
|
|
119
135
|
cancelAnimationFrame(self._animationId);
|
|
@@ -132,6 +148,28 @@ KMDOMMarker.prototype.animateTo = function(targetPosition, duration) {
|
|
|
132
148
|
z: targetPosition.z !== undefined ? targetPosition.z : startPosition.z
|
|
133
149
|
};
|
|
134
150
|
|
|
151
|
+
// 如果需要绕过障碍物,使用路径规划
|
|
152
|
+
if (config.avoidObstacles) {
|
|
153
|
+
self._animateAlongPath(startPosition, targetPos, config.duration)
|
|
154
|
+
.then(resolve)
|
|
155
|
+
.catch(reject);
|
|
156
|
+
} else {
|
|
157
|
+
// 直线移动
|
|
158
|
+
self._animateStraight(startPosition, targetPos, config.duration)
|
|
159
|
+
.then(resolve)
|
|
160
|
+
.catch(reject);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* 直线移动动画(内部方法)
|
|
167
|
+
* @private
|
|
168
|
+
*/
|
|
169
|
+
KMDOMMarker.prototype._animateStraight = function(startPosition, targetPos, duration) {
|
|
170
|
+
var self = this;
|
|
171
|
+
|
|
172
|
+
return new Promise(function(resolve) {
|
|
135
173
|
var startTime = null;
|
|
136
174
|
|
|
137
175
|
function animate(currentTime) {
|
|
@@ -167,6 +205,106 @@ KMDOMMarker.prototype.animateTo = function(targetPosition, duration) {
|
|
|
167
205
|
});
|
|
168
206
|
};
|
|
169
207
|
|
|
208
|
+
/**
|
|
209
|
+
* 沿路径移动动画(内部方法)
|
|
210
|
+
* @private
|
|
211
|
+
*/
|
|
212
|
+
KMDOMMarker.prototype._animateAlongPath = function(startPosition, targetPos, duration) {
|
|
213
|
+
var self = this;
|
|
214
|
+
|
|
215
|
+
return new Promise(function(resolve, reject) {
|
|
216
|
+
// 获取KMUtil和kidata
|
|
217
|
+
if (!self.sdk) {
|
|
218
|
+
console.warn('KMDOMMarker: SDK未初始化,使用直线移动');
|
|
219
|
+
return self._animateStraight(startPosition, targetPos, duration).then(resolve);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
var KMUtil = (typeof window !== 'undefined' && window.KimapSDK) ? window.KimapSDK.KMUtil : null;
|
|
223
|
+
if (!KMUtil) {
|
|
224
|
+
console.warn('KMDOMMarker: KMUtil未加载,使用直线移动');
|
|
225
|
+
return self._animateStraight(startPosition, targetPos, duration).then(resolve);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
var kidata = self.sdk.kidataContent || null;
|
|
229
|
+
|
|
230
|
+
// 计算路径(使用x, z坐标)
|
|
231
|
+
var start = { x: startPosition.x, z: startPosition.z };
|
|
232
|
+
var end = { x: targetPos.x, z: targetPos.z };
|
|
233
|
+
|
|
234
|
+
var path = KMUtil.findPath(start, end, kidata, { avoidObstacles: true });
|
|
235
|
+
|
|
236
|
+
if (!path || path.length < 2) {
|
|
237
|
+
console.warn('KMDOMMarker: 路径规划失败,使用直线移动');
|
|
238
|
+
return self._animateStraight(startPosition, targetPos, duration).then(resolve);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
console.log('KMDOMMarker: 使用路径规划,共' + path.length + '个路径点');
|
|
242
|
+
|
|
243
|
+
// 沿路径移动
|
|
244
|
+
var startTime = null;
|
|
245
|
+
var pathLength = KMUtil.calculatePathLength(path);
|
|
246
|
+
|
|
247
|
+
function animate(currentTime) {
|
|
248
|
+
if (!startTime) startTime = currentTime;
|
|
249
|
+
|
|
250
|
+
var elapsed = currentTime - startTime;
|
|
251
|
+
var progress = Math.min(elapsed / duration, 1);
|
|
252
|
+
|
|
253
|
+
// 使用 easeInOutQuad 缓动函数
|
|
254
|
+
var eased = progress < 0.5
|
|
255
|
+
? 2 * progress * progress
|
|
256
|
+
: 1 - Math.pow(-2 * progress + 2, 2) / 2;
|
|
257
|
+
|
|
258
|
+
// 根据进度计算当前应该在路径的哪个位置
|
|
259
|
+
var targetDistance = pathLength * eased;
|
|
260
|
+
var currentDistance = 0;
|
|
261
|
+
var currentPos = null;
|
|
262
|
+
|
|
263
|
+
// 遍历路径点,找到当前位置
|
|
264
|
+
for (var i = 1; i < path.length; i++) {
|
|
265
|
+
var segmentLength = Math.sqrt(
|
|
266
|
+
Math.pow(path[i].x - path[i - 1].x, 2) +
|
|
267
|
+
Math.pow(path[i].z - path[i - 1].z, 2)
|
|
268
|
+
);
|
|
269
|
+
|
|
270
|
+
if (currentDistance + segmentLength >= targetDistance) {
|
|
271
|
+
// 在这个线段上
|
|
272
|
+
var segmentProgress = (targetDistance - currentDistance) / segmentLength;
|
|
273
|
+
currentPos = {
|
|
274
|
+
x: path[i - 1].x + (path[i].x - path[i - 1].x) * segmentProgress,
|
|
275
|
+
y: startPosition.y + (targetPos.y - startPosition.y) * eased, // Y轴独立插值
|
|
276
|
+
z: path[i - 1].z + (path[i].z - path[i - 1].z) * segmentProgress
|
|
277
|
+
};
|
|
278
|
+
break;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
currentDistance += segmentLength;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// 如果没找到(理论上不应该发生),使用终点
|
|
285
|
+
if (!currentPos) {
|
|
286
|
+
currentPos = {
|
|
287
|
+
x: path[path.length - 1].x,
|
|
288
|
+
y: targetPos.y,
|
|
289
|
+
z: path[path.length - 1].z
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// 更新位置
|
|
294
|
+
self.setPosition(currentPos);
|
|
295
|
+
|
|
296
|
+
if (progress < 1) {
|
|
297
|
+
self._animationId = requestAnimationFrame(animate);
|
|
298
|
+
} else {
|
|
299
|
+
self._animationId = null;
|
|
300
|
+
resolve();
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
self._animationId = requestAnimationFrame(animate);
|
|
305
|
+
});
|
|
306
|
+
};
|
|
307
|
+
|
|
170
308
|
/**
|
|
171
309
|
* 设置偏移量
|
|
172
310
|
* @param {Object} offset - { x, y }
|