From 1ef1063281497f32fcfa4f14b07d99399c0bb765 Mon Sep 17 00:00:00 2001
From: jinglun-cloud <jinglun2019@foxmail.com>
Date: 星期四, 07 五月 2026 15:04:17 +0800
Subject: [PATCH] refactor(设备运动): 重构条码设备运动逻辑,提取运动常量并优化代码结构
---
src/main/webapp/components/MapCanvas.js | 464 ++++++++++++++++++++++++++--------------------------------
1 files changed, 208 insertions(+), 256 deletions(-)
diff --git a/src/main/webapp/components/MapCanvas.js b/src/main/webapp/components/MapCanvas.js
index 636f184..daaec0f 100644
--- a/src/main/webapp/components/MapCanvas.js
+++ b/src/main/webapp/components/MapCanvas.js
@@ -10,7 +10,25 @@
// 浠呮湰鍦版祴璇曠敤
const FAKE_MAX_LAYER = 1730000;
-const FAKE_MAX_CRN_LAYER = 4800
+const FAKE_MAX_CRN_LAYER = 4800;
+
+// 鏉$爜璁惧杩愬姩瀛﹀父閲忥紙setDeviceInfoByBarcode 閾捐矾浣跨敤锛�
+// 杩欓噷闆嗕腑鏀炬槸涓轰簡璁� tickBarcodeTrackSpriteMotion / updateMotionSpeed
+// 绛夊唴閮ㄦ柟娉曚笉鍐嶆暎甯冨ぇ閲� magic number
+const MOTION = {
+ DEFAULT_TICKER_DELTA_MS: 16.667, // dt 缂哄け鏃舵寜绾� 60fps 浼扮畻
+ FALLBACK_BASE_V_FACTOR: 2, // baseV 鍏滃簳 = sprite.width * factor
+ FALLBACK_BASE_V_MIN: 20,
+ STALE_INTERVAL_MULT: 2.65, // 澶氬皯涓吀鍨嬫帹閫佸懆鏈熷悗鍒ゅ畾涓洪暱鏃堕棿鏃犳洿鏂�
+ SLOW_RADIUS_FACTOR: 6.5, // 杩涘叆璇ュ崐寰勫紑濮嬪仛鍋滄鍦嗙紦鍔�
+ SLOW_RADIUS_MIN: 72,
+ EASE_EXPONENT: 0.45, // 鍋滄鍦嗗唴閫熺巼涓庤窛绂荤殑骞傛鍏崇郴
+ INITIAL_SPEED_RATIO: 0.35, // 璧锋閫熷害 = 鐩爣閫熷害 * ratio
+ MAX_ACCEL_FACTOR: 1.75, // 鏈�澶у姞閫熷害 = baseV * factor
+ MAX_ACCEL_MIN: 22,
+ VELOCITY_EWMA_ALPHA: 0.2, // 鏈嶅姟绔潎閫熶及璁$殑 EWMA 骞虫粦绯绘暟
+ VELOCITY_SAMPLE_MAX_DT: 10 // 瓒呰繃璇ョ鏁扮殑鏍锋湰涓嶅弬涓庡潎閫熶及璁�
+};
/**
* 閫氱敤杞鍣ㄧ被
* 灏佽甯﹁姹傚彇娑堛�佸钩婊戝欢杩熻绠椼�侀敊璇��閬跨殑杞閫昏緫
@@ -1325,29 +1343,28 @@
return (value * 100).toFixed(1) + '%';
},
/******************setDeviceInfo浣跨敤鐨勫嚱鏁�:******************/
- // 鐜┛鏉$爜鍦ㄦ�婚暱涓婄殑鏈夌鍙锋宸�
- calcSignedSegmentDelta(fromBarcode, toBarcode, trackInfo, totalSegmentCount) {
+ /**
+ * 璁$畻涓ゆ潯鐮佷箣闂寸殑"娈靛樊"銆�
+ * - 鐜舰杞ㄩ亾鎸夋�绘鏁板彇妯★紝姘歌繙鍚戝墠鎺ㄨ繘锛圼0, totalSegmentCount)锛夈��
+ * - 闈炵幆褰㈣建閬撹繑鍥炴湁绗﹀彿宸紝鏂瑰悜鐢辫皟鐢ㄦ柟鍐冲畾銆�
+ */
+ calcSegmentDelta(fromBarcode, toBarcode, isAnnulus, totalSegmentCount) {
const from = Number(fromBarcode);
const to = Number(toBarcode);
if (!isFinite(from) || !isFinite(to)) return 0;
const raw = to - from;
- if (trackInfo.type !== 'annulus' || totalSegmentCount <= 0) return raw;
- // 闈炶礋鍙栨ā
+ if (!isAnnulus || totalSegmentCount <= 0) return raw;
return ((raw % totalSegmentCount) + totalSegmentCount) % totalSegmentCount;
},
+ /** 鎶婅澶囩洿鎺ュ榻愬埌 mappingInfo 涓婂苟娓呯悊 ticker */
finishDeviceMotion(sprite) {
- if (!sprite || !sprite.mappingInfo) {
- return false;
- }
- const mx = sprite.mappingInfo.x;
- const my = sprite.mappingInfo.y;
- if (!isFinite(mx) || !isFinite(my)) {
- return false;
- }
+ if (!sprite || !sprite.mappingInfo) return false;
+ const { x: mx, y: my, path: mPath } = sprite.mappingInfo;
+ if (!isFinite(mx) || !isFinite(my)) return false;
sprite.isFinish = true;
sprite.x = mx;
sprite.y = my;
- sprite.path = sprite.mappingInfo.path || sprite.path;
+ sprite.path = mPath || sprite.path;
sprite.rotation = G.getRotate(sprite.mappingInfo, sprite.mappingInfo.path) || sprite.rotation;
if (sprite.ticker) {
this.pixiApp.ticker.remove(sprite.ticker);
@@ -1357,35 +1374,17 @@
sprite._motionSpeed = undefined;
return true;
},
- /** Web 鎺ュ彛杩斿洖缁熶竴鎴愯澶囨暟缁� */
- parseBarcodeDevicesResponse(res) {
- return Array.isArray(res) ? res : res && res.code === 200 ? res.data : null;
- },
/** 鏉$爜璁惧锛氱紪鍙锋枃瀛� + 鐘舵�佽壊 */
applyBarcodeSpriteAppearance(sprite, device, deviceTypeInfo) {
const id = +device.index;
const taskNo = device.taskNo;
- if (taskNo != null && taskNo > 0) {
- sprite.textObj.text = id + '(' + taskNo + ')';
- } else {
- sprite.textObj.text = String(id);
- }
- const statusColor = device.statusColor;
- if (statusColor != null) {
- deviceTypeInfo.statusInfo.updateTextureColor(sprite, statusColor);
+ sprite.textObj.text = taskNo != null && taskNo > 0 ? id + '(' + taskNo + ')' : String(id);
+ if (device.statusColor != null) {
+ deviceTypeInfo.statusInfo.updateTextureColor(sprite, device.statusColor);
}
},
- /** 鏉$爜閿氱偣瀵硅薄锛堜袱澶勬瀯閫犲悎骞朵负鍚屼竴褰㈢姸锛� */
- createBarcodeAnchorState(
- trackId,
- minBarcode,
- maxBarcode,
- totalSegmentCount,
- barcode,
- point,
- path,
- angle
- ) {
+ /** 鏉$爜閿氱偣瀵硅薄锛坕nit 涓� sync 鍏辩敤锛� */
+ createBarcodeAnchorState(trackId, minBarcode, maxBarcode, totalSegmentCount, barcode, point, path, angle) {
return {
barcode,
x: point.x,
@@ -1398,33 +1397,26 @@
totalSegmentCount
};
},
+ /** 閿氱偣鏄惁闇�瑕侀噸缃細杞ㄩ亾銆佹潯鐮佸尯闂淬�佹鏁颁换涓�鍙樻洿閮借閲嶆柊寤虹珛 */
+ isBarcodeAnchorStale(anchor, sprite, minBarcode, maxBarcode, totalSegmentCount) {
+ return (
+ !anchor ||
+ anchor.trackId !== sprite.trackInfo.id ||
+ anchor.minBarcode !== minBarcode ||
+ anchor.maxBarcode !== maxBarcode ||
+ anchor.totalSegmentCount !== totalSegmentCount
+ );
+ },
/** 棣栨鏈夋潯鐮佹暟鎹細鎸� rgvPos 钀藉埌杞ㄩ亾涓婂苟寤虹珛閿氱偣 */
- initializeBarcodeTrackSprite(
- sprite,
- device,
- pathList,
- allDistance,
- minBarcode,
- maxBarcode,
- totalSegmentCount
- ) {
+ initializeBarcodeTrackSprite(sprite, device, pathList, allDistance, minBarcode, maxBarcode, totalSegmentCount) {
sprite.barcode = device.rgvPos;
sprite.time = nowMs();
- const passedSegmentCount = this.calcSignedSegmentDelta(
- minBarcode,
- device.rgvPos,
- sprite.trackInfo,
- totalSegmentCount
- );
+ const isAnnulus = sprite.trackInfo.type === 'annulus';
+ const passedSegmentCount = this.calcSegmentDelta(minBarcode, device.rgvPos, isAnnulus, totalSegmentCount);
const deltaDistance = (allDistance * passedSegmentCount) / totalSegmentCount;
const initPath = sprite.path;
- const initMovePoint = G.snapToAnnulusPath(
- sprite.trackInfo,
- sprite.x,
- sprite.y,
- initPath
- );
- let mappingInfo = G.getPositionAfterMove({
+ const initMovePoint = G.snapToAnnulusPath(sprite.trackInfo, sprite.x, sprite.y, initPath);
+ const mappingInfo = G.getPositionAfterMove({
point: initMovePoint,
pathList,
path: initPath,
@@ -1437,12 +1429,7 @@
sprite.rotation = G.getRotate(mappingInfo, mappingInfo.path) || sprite.rotation;
sprite.currentAngle = mappingInfo.angle;
sprite.mappingInfo = mappingInfo;
- const anchorPoint = G.snapToAnnulusPath(
- sprite.trackInfo,
- mappingInfo.x,
- mappingInfo.y,
- mappingInfo.path
- );
+ const anchorPoint = G.snapToAnnulusPath(sprite.trackInfo, mappingInfo.x, mappingInfo.y, mappingInfo.path);
sprite._barcodeAnchor = this.createBarcodeAnchorState(
sprite.trackInfo.id,
minBarcode,
@@ -1454,138 +1441,118 @@
mappingInfo.angle
);
},
+ /** 褰撳墠甯� dt(绉�)锛泃icker 涓嶅彲鐢ㄦ椂鎸夌害 60fps 浼拌 */
+ getMotionFrameDt() {
+ const ticker = this.pixiApp && this.pixiApp.ticker;
+ const dtMs = ticker && typeof ticker.deltaMS === 'number' ? ticker.deltaMS : MOTION.DEFAULT_TICKER_DELTA_MS;
+ return Math.max(0, dtMs) / 1000;
+ },
+ /**
+ * 鎺ㄨ繘 sprite._motionSpeed锛堝甫鍔犻�熷害涓婇檺鍜�"鍋滄鍦�"缂撳姩锛夛紝杩斿洖鏈抚鏈�澶у彲璧拌窛绂汇��
+ * 鏈嶅姟绔暱鏃堕棿鏈帹閫佹柊鏉$爜鏃讹紝闈犺繎鐩爣鐐硅闄嶉�熼伩鍏嶈秺杩�/鎶栧姩銆�
+ */
+ updateMotionSpeed(sprite, restDistance, dt) {
+ const baseV =
+ typeof sprite.maV === 'number' && isFinite(sprite.maV) && sprite.maV > 0
+ ? sprite.maV
+ : Math.max(sprite.width * MOTION.FALLBACK_BASE_V_FACTOR, MOTION.FALLBACK_BASE_V_MIN);
+ const msSinceUpdate = sprite.time ? nowMs() - sprite.time : 0;
+ const typicalIntervalMs = (sprite.lastDeltaTime || 1) * 1000;
+ const isStale = msSinceUpdate > typicalIntervalMs * MOTION.STALE_INTERVAL_MULT;
+ const slowRadius = Math.max(sprite.width * MOTION.SLOW_RADIUS_FACTOR, MOTION.SLOW_RADIUS_MIN);
+ const easing = isStale ? Math.min(1.0, Math.pow(restDistance / slowRadius, MOTION.EASE_EXPONENT)) : 1.0;
+ const targetSpeed = baseV * easing;
+ if (typeof sprite._motionSpeed !== 'number' || !isFinite(sprite._motionSpeed)) {
+ sprite._motionSpeed = targetSpeed * MOTION.INITIAL_SPEED_RATIO;
+ }
+ const maxAccel = Math.max(baseV * MOTION.MAX_ACCEL_FACTOR, MOTION.MAX_ACCEL_MIN);
+ const dv = targetSpeed - sprite._motionSpeed;
+ const cap = maxAccel * dt;
+ sprite._motionSpeed += Math.max(-cap, Math.min(cap, dv));
+ return Math.min(restDistance, Math.max(0, sprite._motionSpeed) * dt);
+ },
+ /**
+ * 鍗曠嚎闈炵幆褰㈣建閬擄細鏂瑰悜鍙栧喅浜庢潯鐮佽繘閫�锛岄渶瑕佽繑鍥炴湁绗﹀彿 step銆�
+ * 杩斿洖 null 琛ㄧず杩欏抚搴旂洿鎺ュ仠鍦� mappingInfo锛堟姇褰遍��鍖栨垨鐩寸嚎閫�鍖栵級銆�
+ */
+ computeSingleLineSignedStep(sprite, path, stepCap, restDistance) {
+ const remainAlong = G.lineSignedRemainAlong(
+ path,
+ sprite.x,
+ sprite.y,
+ sprite.mappingInfo.x,
+ sprite.mappingInfo.y
+ );
+ if (remainAlong == null) return stepCap;
+ const stepMag = Math.min(stepCap, Math.abs(remainAlong), restDistance);
+ if (stepMag >= EPSILON || restDistance <= EPSILON) {
+ return Math.sign(remainAlong) * stepMag;
+ }
+ // 鎶曞奖 stepMag 閫�鍖栦负 0 浣嗘姘忚窛绂讳粛瀛樺湪锛氱敤涓栫晫鍚戦噺涓庣洿绾挎柟鍚戠殑鍐呯Н鍏滃簳鍒ゆ柟鍚�
+ const lineStart = { x: path.startX, y: path.startY };
+ const lineEnd = { x: path.x, y: path.y };
+ if (G.calcDistance(lineStart, lineEnd) <= EPSILON) return null;
+ const { x: ux, y: uy } = G.normalizeVector(lineStart, lineEnd);
+ const hint = (sprite.mappingInfo.x - sprite.x) * ux + (sprite.mappingInfo.y - sprite.y) * uy;
+ if (hint === 0) return null;
+ return Math.sign(hint) * Math.min(stepCap, restDistance);
+ },
+ isSingleLineTrack(sprite, pathList) {
+ return pathList.length === 1 && pathList[0].type === 'line' && sprite.trackInfo.type !== 'annulus';
+ },
/** 鏉$爜璁惧姣忓抚鎻掑�肩Щ鍔紙Pixi ticker 鍥炶皟锛� */
tickBarcodeTrackSpriteMotion(sprite, pathList) {
- if (sprite.isFinish) {
- return;
- }
+ if (sprite.isFinish) return;
const restDistance = G.calcDistance(sprite, sprite.mappingInfo);
if (restDistance <= EPSILON) {
this.finishDeviceMotion(sprite);
return;
}
- const dtMs =
- this.pixiApp && this.pixiApp.ticker && typeof this.pixiApp.ticker.deltaMS === 'number'
- ? this.pixiApp.ticker.deltaMS
- : 16.667;
- const dt = Math.max(0, dtMs) / 1000;
- if (dt <= 0) {
- return;
- }
- const baseV =
- typeof sprite.maV === 'number' && isFinite(sprite.maV) && sprite.maV > 0
- ? sprite.maV
- : Math.max(sprite.width * 2, 20);
- const msSinceUpdate = sprite.time ? nowMs() - sprite.time : 0;
- const typicalIntervalMs = (sprite.lastDeltaTime || 1) * 1000;
- const isStale = msSinceUpdate > typicalIntervalMs * 2.65;
- const slowRadius = Math.max(sprite.width * 6.5, 72);
- const easing = isStale ? Math.min(1.0, Math.pow(restDistance / slowRadius, 0.45)) : 1.0;
- const targetSpeed = baseV * easing;
- if (typeof sprite._motionSpeed !== 'number' || !isFinite(sprite._motionSpeed)) {
- sprite._motionSpeed = targetSpeed * 0.35;
- }
- const maxAccel = Math.max(baseV * 1.75, 22);
- const dv = targetSpeed - sprite._motionSpeed;
- const cap = maxAccel * dt;
- sprite._motionSpeed += Math.max(-cap, Math.min(cap, dv));
+ const dt = this.getMotionFrameDt();
+ if (dt <= 0) return;
+
+ const stepCap = this.updateMotionSpeed(sprite, restDistance, dt);
const path = sprite.path;
- const stepCap = Math.min(restDistance, Math.max(0, sprite._motionSpeed) * dt);
- const singleLineTrack =
- pathList.length === 1 && pathList[0].type === 'line' && sprite.trackInfo.type !== 'annulus';
- let smoothDistance;
- if (singleLineTrack) {
- const remainAlong = G.lineSignedRemainAlong(
- path,
- sprite.x,
- sprite.y,
- sprite.mappingInfo.x,
- sprite.mappingInfo.y
- );
- if (remainAlong != null) {
- let stepMag = Math.min(stepCap, Math.abs(remainAlong), restDistance);
- if (stepMag < EPSILON && restDistance > EPSILON) {
- const lineStart = { x: path.startX, y: path.startY };
- const lineEnd = { x: path.x, y: path.y };
- const sl = G.calcDistance(lineStart, lineEnd);
- if (sl > EPSILON) {
- const { x: ux, y: uy } = G.normalizeVector(lineStart, lineEnd);
- const wdx = sprite.mappingInfo.x - sprite.x;
- const wdy = sprite.mappingInfo.y - sprite.y;
- const hint = wdx * ux + wdy * uy;
- stepMag = Math.min(stepCap, restDistance);
- if (hint === 0) {
- this.finishDeviceMotion(sprite);
- return;
- }
- smoothDistance = Math.sign(hint) * stepMag;
- } else {
- this.finishDeviceMotion(sprite);
- return;
- }
- } else {
- smoothDistance = Math.sign(remainAlong) * stepMag;
- }
- } else {
- smoothDistance = stepCap;
+ let signedStep;
+ if (this.isSingleLineTrack(sprite, pathList)) {
+ signedStep = this.computeSingleLineSignedStep(sprite, path, stepCap, restDistance);
+ if (signedStep == null) {
+ this.finishDeviceMotion(sprite);
+ return;
}
} else {
- smoothDistance = stepCap;
+ signedStep = stepCap;
}
- const movePointBarcode = G.snapToAnnulusPath(
- sprite.trackInfo,
- sprite.x,
- sprite.y,
- path
- );
- const angle = Math.atan2(sprite.y - path.y, sprite.x - path.x);
- const p = G.getPositionAfterMove({
- point: movePointBarcode,
+
+ const movePoint = G.snapToAnnulusPath(sprite.trackInfo, sprite.x, sprite.y, path);
+ const radialAngle = Math.atan2(sprite.y - path.y, sprite.x - path.x);
+ const next = G.getPositionAfterMove({
+ point: movePoint,
pathList,
path,
- deltaDistance: smoothDistance,
- angle
+ deltaDistance: signedStep,
+ angle: radialAngle
});
- sprite.path = p.path;
- sprite.x = p.x;
- sprite.y = p.y;
- sprite.rotation = G.getRotate(p, p.path) || sprite.rotation;
- const restDistanceAfter = G.calcDistance({ x: sprite.x, y: sprite.y }, sprite.mappingInfo);
- if (restDistanceAfter <= EPSILON || Math.abs(smoothDistance) >= restDistance - EPSILON) {
+ sprite.path = next.path;
+ sprite.x = next.x;
+ sprite.y = next.y;
+ sprite.rotation = G.getRotate(next, next.path) || sprite.rotation;
+ const restAfter = G.calcDistance({ x: sprite.x, y: sprite.y }, sprite.mappingInfo);
+ if (restAfter <= EPSILON || Math.abs(signedStep) >= restDistance - EPSILON) {
this.finishDeviceMotion(sprite);
}
},
/**
- * 鏍规嵁鏈嶅姟绔潯鐮佸埛鏂� mappingInfo銆侀�熷害涓� ticker銆�
- * rgvPosMax 閫氬父鏄棴鍖洪棿 [min, max]锛屼笖 max 瀵瑰簲 100% 涓� min 鍚屼竴鐐癸紙璧颁竴鍦堝洖鍒板師鐐癸級銆�
- * 鍥犳鎸� 鈥滄鏁� = max - min鈥� 鎹㈢畻璺濈銆�
+ * 鏍规嵁鏈嶅姟绔潯鐮佸埛鏂� mappingInfo銆侀�熷害浼拌涓� ticker銆�
+ * rgvPosMax 閫氬父鏄棴鍖洪棿 [min, max]锛宮ax 涓� min 鍦ㄨ建閬撲笂鍚岀偣锛堣蛋涓�鍦堝洖鍒板師鐐癸級锛�
+ * 鏁呮寜 娈垫暟 = max - min 鎹㈢畻璺濈銆�
*/
- syncBarcodeTrackSprite(
- sprite,
- device,
- oldSprite,
- pathList,
- allDistance,
- minBarcode,
- maxBarcode,
- totalSegmentCount
- ) {
+ syncBarcodeTrackSprite(sprite, device, prevBarcode, prevTime, pathList, allDistance, minBarcode, maxBarcode, totalSegmentCount) {
let anchor = sprite._barcodeAnchor;
- const needResetAnchor =
- !anchor ||
- anchor.trackId !== sprite.trackInfo.id ||
- anchor.minBarcode !== minBarcode ||
- anchor.maxBarcode !== maxBarcode ||
- anchor.totalSegmentCount !== totalSegmentCount;
- if (needResetAnchor) {
+ if (this.isBarcodeAnchorStale(anchor, sprite, minBarcode, maxBarcode, totalSegmentCount)) {
const anchorPath = sprite.path;
- const anchorPoint = G.snapToAnnulusPath(
- sprite.trackInfo,
- sprite.x,
- sprite.y,
- anchorPath
- );
- const anchorBarcode = oldSprite.barcode != null ? oldSprite.barcode : device.rgvPos;
+ const anchorPoint = G.snapToAnnulusPath(sprite.trackInfo, sprite.x, sprite.y, anchorPath);
+ const anchorBarcode = prevBarcode != null ? prevBarcode : device.rgvPos;
anchor = this.createBarcodeAnchorState(
sprite.trackInfo.id,
minBarcode,
@@ -1598,120 +1565,101 @@
);
sprite._barcodeAnchor = anchor;
}
- const passedSegmentCount = this.calcSignedSegmentDelta(
- anchor.barcode,
- device.rgvPos,
- sprite.trackInfo,
- totalSegmentCount
- );
+ const isAnnulus = sprite.trackInfo.type === 'annulus';
+ const passedSegmentCount = this.calcSegmentDelta(anchor.barcode, device.rgvPos, isAnnulus, totalSegmentCount);
const deltaDistance = (allDistance * passedSegmentCount) / totalSegmentCount;
const path = anchor.path || sprite.path;
- const barcodeMovePoint = { x: anchor.x, y: anchor.y };
- let finalPosition = G.getPositionAfterMove({
- point: barcodeMovePoint,
+ const finalPosition = G.getPositionAfterMove({
+ point: { x: anchor.x, y: anchor.y },
pathList,
path,
deltaDistance,
angle: anchor.angle
});
let curveDistance = G.calcDistance(sprite, finalPosition);
- if (!isFinite(curveDistance)) {
- curveDistance = deltaDistance;
- }
+ if (!isFinite(curveDistance)) curveDistance = deltaDistance;
sprite.mappingInfo = finalPosition;
+
const now = nowMs();
- const deltaTime = (now - oldSprite.time) / 1000 || 0;
+ const deltaTime = (now - prevTime) / 1000 || 0;
sprite.time = now;
sprite.barcode = device.rgvPos;
- if (deltaTime > 0 && deltaTime <= 10 && curveDistance > 0) {
+ if (deltaTime > 0 && deltaTime <= MOTION.VELOCITY_SAMPLE_MAX_DT && curveDistance > 0) {
sprite.lastDeltaTime = deltaTime;
const v = curveDistance / deltaTime;
- const alpha = 0.2;
- sprite.maV =
- typeof sprite.maV === 'number' && isFinite(sprite.maV)
- ? sprite.maV * (1 - alpha) + v * alpha
- : v;
+ const a = MOTION.VELOCITY_EWMA_ALPHA;
+ sprite.maV = typeof sprite.maV === 'number' && isFinite(sprite.maV) ? sprite.maV * (1 - a) + v * a : v;
}
+
if (curveDistance < EPSILON) {
this.finishDeviceMotion(sprite);
return;
}
sprite.isFinish = false;
- if (sprite.ticker) {
- return;
- }
+ if (sprite.ticker) return;
sprite.ticker = () => this.tickBarcodeTrackSpriteMotion(sprite, pathList);
this.pixiApp.ticker.add(sprite.ticker);
},
- // 閫傞厤涓嶅悓鎺ュ彛杩斿洖鐨勬暟鎹粨鏋�
+ /** 鐜┛鏉$爜鎺ュ彛鐨勮澶囨潯鐩� -> 鍐呴儴缁熶竴瀛楁 */
+ adaptAnnulusBarcodeDevice(device, deviceTypeInfo) {
+ const index = +device.index;
+ const sprite = deviceTypeInfo.pixiMap.get(index);
+ if (!sprite) return null;
+ const trackInfoParse = G.safeParseJson(sprite.trackInfo.value);
+ // 鍚庣杩斿洖褰㈠ "#27AE60" 鐨勯鑹插瓧绗︿覆
+ const hex = device.statusColor ? device.statusColor.split('#')[1] : null;
+ return {
+ index,
+ sprite,
+ statusColor: hex != null ? parseInt(hex, 16) : null,
+ minBarcode: trackInfoParse.barCodeStart,
+ maxBarcode: trackInfoParse.barCodeEnd,
+ rgvPos: device.rgvPos,
+ taskNo: device.taskNo
+ };
+ },
+ /** 鍘熺増鏉$爜鎺ュ彛锛堟寜 idName + statusInfo + laserValue锛�-> 鍐呴儴缁熶竴瀛楁 */
+ adaptOriginalBarcodeDevice(device, deviceTypeInfo) {
+ const index = +device[deviceTypeInfo.idName];
+ const sprite = deviceTypeInfo.pixiMap.get(index);
+ if (!sprite) return null;
+ const trackInfoParse = G.safeParseJson(sprite.trackInfo.value);
+ const statusInfo = deviceTypeInfo.statusInfo;
+ return {
+ index,
+ sprite,
+ statusColor: statusInfo.getStatus(device[statusInfo.name]),
+ minBarcode: trackInfoParse.barCodeStart,
+ maxBarcode: trackInfoParse.barCodeEnd,
+ rgvPos: (device.laserValue * FAKE_MAX_LAYER) / FAKE_MAX_CRN_LAYER,
+ taskNo: device.taskNo
+ };
+ },
deviceAdapter(type, res, trackType) {
- const devices = this.parseBarcodeDevicesResponse(res);
+ const devices = Array.isArray(res) ? res : res && res.code === 200 ? res.data : null;
+ if (!devices) return [];
const deviceTypeInfo = this.DEVICE_MAP[type];
- // 鐜┛鎺ュ彛
- if (trackType === 'annulus') {
- return devices.map((device) => {
- const index = +device.index;
- const sprite = deviceTypeInfo.pixiMap.get(index);
- if (!sprite) {
- return {};
- }
- const trackInfoParse = G.safeParseJson(sprite.trackInfo.value);
- const statusColorStr = device.statusColor.split('#')[1];
- const statusColor = parseInt(statusColorStr, 16);
- return {
- index,
- statusColor,
- sprite,
- minBarcode: trackInfoParse.barCodeStart,
- maxBarcode: trackInfoParse.barCodeEnd,
- rgvPos: device.rgvPos,
- taskNo: device.taskNo
- };
- });
+ const adapt =
+ trackType === 'annulus'
+ ? (d) => this.adaptAnnulusBarcodeDevice(d, deviceTypeInfo)
+ : (d) => this.adaptOriginalBarcodeDevice(d, deviceTypeInfo);
+ const out = [];
+ for (const device of devices) {
+ const item = adapt(device);
+ if (item) out.push(item);
}
- // 鍘熺増鎺ュ彛
- return devices.map((device) => {
- const index = +device[deviceTypeInfo.idName];
- const sprite = deviceTypeInfo.pixiMap.get(index);
- if (!sprite) {
- return {};
- }
- const trackInfoParse = G.safeParseJson(sprite.trackInfo.value);
- const minBarcode = trackInfoParse.barCodeStart;
- const maxBarcode = trackInfoParse.barCodeEnd;
- const statusInfo = deviceTypeInfo.statusInfo;
- const statusColor = statusInfo.getStatus(device[statusInfo.name]);
- return {
- index,
- statusColor,
- sprite,
- minBarcode,
- maxBarcode,
- rgvPos: device.laserValue * FAKE_MAX_LAYER / FAKE_MAX_CRN_LAYER,
- taskNo: device.taskNo
- };
- });
+ return out;
},
setDeviceInfoByBarcode(type, res, trackType = 'annulus') {
const devices = this.deviceAdapter(type, res, trackType);
const deviceTypeInfo = this.DEVICE_MAP[type];
- for (let i = 0; i < devices.length; i++) {
- const device = devices[i] || {};
+ for (const device of devices) {
const { sprite, minBarcode, maxBarcode } = device;
- if (!sprite) {
- continue;
- }
this.applyBarcodeSpriteAppearance(sprite, device, deviceTypeInfo);
const pathList = sprite.trackInfo.pathList;
const allDistance = G.getAllDistance(pathList);
const totalSegmentCount = Math.max(1, maxBarcode - minBarcode);
- const oldSprite = {
- ...sprite,
- x: sprite.x,
- y: sprite.y,
- mappingInfo: { ...sprite.mappingInfo }
- };
- if (!sprite.barcode && sprite.barcode !== 0) {
+ if (sprite.barcode == null) {
this.initializeBarcodeTrackSprite(
sprite,
device,
@@ -1723,10 +1671,14 @@
);
continue;
}
+ // sync 闇�瑕�"鍒锋柊鍓�"鐨勬潯鐮佷笌鏃堕棿鎴虫潵璁$畻娈靛樊/鐬椂閫熷害锛屽崟鐙彇涓や釜鏍囬噺姣� spread 鏁翠釜 sprite 渚垮疁寰楀
+ const prevBarcode = sprite.barcode;
+ const prevTime = sprite.time;
this.syncBarcodeTrackSprite(
sprite,
device,
- oldSprite,
+ prevBarcode,
+ prevTime,
pathList,
allDistance,
minBarcode,
--
Gitblit v1.9.1