feat(editor): 将电梯方向箭头移至图标左侧中间显示,并增加楼层显示偏移以避免视觉重叠

This commit is contained in:
xudan 2025-12-15 16:38:41 +08:00
parent af3ce43e42
commit 42716cac17

View File

@ -212,25 +212,26 @@ function drawElevatorIcon(
indicatorY = y + height + indicatorDistance; indicatorY = y + height + indicatorDistance;
} }
// 绘制方向箭头(不受指示器限制) // 绘制方向箭头 - 改为在电梯图标左侧中间显示
if (direction === 2) { if (direction === 2) {
// 向上状态 - 绿色箭头,显示在上方 // 向上状态 - 绿色箭头,显示在左侧
const arrowSize = Math.min(width, height) * 0.35; // 箭头大小为图标较小边的35% const arrowSize = Math.min(width, height) * 0.35; // 箭头大小为图标较小边的35%
const baseArrowY = y - indicatorDistance - arrowSize - height * 0.05; // 箭头基础位置 const arrowX = x - width * 0.5 - arrowSize; // 箭头在电梯左侧留50%电梯宽度的间距(增加更多间距)
const arrowY = cy - arrowSize / 2; // 垂直居中
// 添加上下移动动画 // 添加上下移动动画
const movementPeriod = 1500; // 动画周期 1.5 秒 const movementPeriod = 1500; // 动画周期 1.5 秒
const movementAmplitude = arrowSize * 0.15; // 移动幅度为箭头大小的15% const movementAmplitude = arrowSize * 0.15; // 移动幅度为箭头大小的15%
const movementPhase = (time % movementPeriod) / movementPeriod; const movementPhase = (time % movementPeriod) / movementPeriod;
const movementOffset = movementAmplitude * Math.sin(movementPhase * Math.PI * 2); const movementOffset = movementAmplitude * Math.sin(movementPhase * Math.PI * 2);
const arrowY = baseArrowY + movementOffset; // 应用移动偏移 const finalArrowY = arrowY + movementOffset; // 应用移动偏移
// 绘制发光背景(跟随箭头移动) // 绘制发光背景(跟随箭头移动)
const glowGradient = ctx.createRadialGradient(cx, arrowY + arrowSize/2, 0, cx, arrowY + arrowSize/2, arrowSize); const glowGradient = ctx.createRadialGradient(arrowX + arrowSize/2, finalArrowY + arrowSize/2, 0, arrowX + arrowSize/2, finalArrowY + arrowSize/2, arrowSize);
glowGradient.addColorStop(0, 'rgba(16, 185, 129, 0.4)'); glowGradient.addColorStop(0, 'rgba(16, 185, 129, 0.4)');
glowGradient.addColorStop(1, 'rgba(16, 185, 129, 0)'); glowGradient.addColorStop(1, 'rgba(16, 185, 129, 0)');
ctx.fillStyle = glowGradient; ctx.fillStyle = glowGradient;
ctx.fillRect(cx - arrowSize - 5, arrowY - 5, arrowSize * 2 + 10, arrowSize + 10); ctx.fillRect(arrowX - 5, finalArrowY - 5, arrowSize + 10, arrowSize + 10);
// 绘制向上箭头 // 绘制向上箭头
ctx.fillStyle = '#10b981'; ctx.fillStyle = '#10b981';
@ -238,34 +239,35 @@ function drawElevatorIcon(
ctx.shadowBlur = 6; ctx.shadowBlur = 6;
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(cx, arrowY); ctx.moveTo(arrowX + arrowSize/2, finalArrowY);
ctx.lineTo(cx - arrowSize, arrowY + arrowSize); ctx.lineTo(arrowX, finalArrowY + arrowSize);
ctx.lineTo(cx - arrowSize * 0.4, arrowY + arrowSize - arrowSize * 0.15); ctx.lineTo(arrowX + arrowSize * 0.1, finalArrowY + arrowSize - arrowSize * 0.15);
ctx.lineTo(cx, arrowY + arrowSize - arrowSize * 0.25); ctx.lineTo(arrowX + arrowSize/2, finalArrowY + arrowSize - arrowSize * 0.25);
ctx.lineTo(cx + arrowSize * 0.4, arrowY + arrowSize - arrowSize * 0.15); ctx.lineTo(arrowX + arrowSize * 0.9, finalArrowY + arrowSize - arrowSize * 0.15);
ctx.lineTo(cx + arrowSize, arrowY + arrowSize); ctx.lineTo(arrowX + arrowSize, finalArrowY + arrowSize);
ctx.closePath(); ctx.closePath();
ctx.fill(); ctx.fill();
ctx.shadowBlur = 0; ctx.shadowBlur = 0;
} else if (direction === 3) { } else if (direction === 3) {
// 向下状态 - 橙色箭头,显示在下方 // 向下状态 - 橙色箭头,显示在左侧
const arrowSize = Math.min(width, height) * 0.35; // 箭头大小为图标较小边的35% const arrowSize = Math.min(width, height) * 0.35; // 箭头大小为图标较小边的35%
const baseArrowY = y + height + indicatorDistance + height * 0.05; // 箭头基础位置 const arrowX = x - width * 0.5 - arrowSize; // 箭头在电梯左侧留50%电梯宽度的间距(增加更多间距)
const arrowY = cy - arrowSize / 2; // 垂直居中
// 添加上下移动动画 // 添加上下移动动画
const movementPeriod = 1500; // 动画周期 1.5 秒 const movementPeriod = 1500; // 动画周期 1.5 秒
const movementAmplitude = arrowSize * 0.15; // 移动幅度为箭头大小的15% const movementAmplitude = arrowSize * 0.15; // 移动幅度为箭头大小的15%
const movementPhase = (time % movementPeriod) / movementPeriod; const movementPhase = (time % movementPeriod) / movementPeriod;
const movementOffset = movementAmplitude * Math.sin(movementPhase * Math.PI * 2); const movementOffset = movementAmplitude * Math.sin(movementPhase * Math.PI * 2);
const arrowY = baseArrowY + movementOffset; // 应用移动偏移 const finalArrowY = arrowY + movementOffset; // 应用移动偏移
// 绘制发光背景(跟随箭头移动) // 绘制发光背景(跟随箭头移动)
const glowGradient = ctx.createRadialGradient(cx, arrowY + arrowSize/2, 0, cx, arrowY + arrowSize/2, arrowSize); const glowGradient = ctx.createRadialGradient(arrowX + arrowSize/2, finalArrowY + arrowSize/2, 0, arrowX + arrowSize/2, finalArrowY + arrowSize/2, arrowSize);
glowGradient.addColorStop(0, 'rgba(251, 146, 60, 0.4)'); glowGradient.addColorStop(0, 'rgba(251, 146, 60, 0.4)');
glowGradient.addColorStop(1, 'rgba(251, 146, 60, 0)'); glowGradient.addColorStop(1, 'rgba(251, 146, 60, 0)');
ctx.fillStyle = glowGradient; ctx.fillStyle = glowGradient;
ctx.fillRect(cx - arrowSize - 5, arrowY - 5, arrowSize * 2 + 10, arrowSize + 10); ctx.fillRect(arrowX - 5, finalArrowY - 5, arrowSize + 10, arrowSize + 10);
// 绘制向下箭头 // 绘制向下箭头
ctx.fillStyle = '#fb923c'; ctx.fillStyle = '#fb923c';
@ -273,12 +275,12 @@ function drawElevatorIcon(
ctx.shadowBlur = 6; ctx.shadowBlur = 6;
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(cx, arrowY + arrowSize); ctx.moveTo(arrowX + arrowSize/2, finalArrowY + arrowSize);
ctx.lineTo(cx - arrowSize, arrowY); ctx.lineTo(arrowX, finalArrowY);
ctx.lineTo(cx - arrowSize * 0.4, arrowY + arrowSize * 0.15); ctx.lineTo(arrowX + arrowSize * 0.1, finalArrowY + arrowSize * 0.15);
ctx.lineTo(cx, arrowY + arrowSize * 0.25); ctx.lineTo(arrowX + arrowSize/2, finalArrowY + arrowSize * 0.25);
ctx.lineTo(cx + arrowSize * 0.4, arrowY + arrowSize * 0.15); ctx.lineTo(arrowX + arrowSize * 0.9, finalArrowY + arrowSize * 0.15);
ctx.lineTo(cx + arrowSize, arrowY); ctx.lineTo(arrowX + arrowSize, finalArrowY);
ctx.closePath(); ctx.closePath();
ctx.fill(); ctx.fill();
@ -453,7 +455,7 @@ function drawElevatorMinimal(
elevatorDirection elevatorDirection
); );
// 在电梯图标右侧显示当前楼层 // 在电梯图标右侧显示当前楼层(增加偏移)
const { elevatorFloor } = elevatorData; const { elevatorFloor } = elevatorData;
if (elevatorFloor && elevatorFloor > 0) { if (elevatorFloor && elevatorFloor > 0) {
@ -472,8 +474,8 @@ function drawElevatorMinimal(
ctx.textAlign = 'left'; ctx.textAlign = 'left';
ctx.textBaseline = 'middle'; ctx.textBaseline = 'middle';
// 文字位置:电梯图标右侧,间距基于图标尺寸 // 文字位置:电梯图标右侧,增加偏移距离
const textX = x + w/2 + iconWidth/2 + iconWidth * 0.15; // 从图标中心右侧开始留15%图标宽度的间距 const textX = x + w/2 + iconWidth/2 + iconWidth * 0.6; // 从图标中心右侧开始留60%图标宽度的间距(增加更多偏移)
const textY = y + h/2; // 垂直居中 const textY = y + h/2; // 垂直居中
// 绘制楼层文字背景 // 绘制楼层文字背景