diff --git a/src/services/editor/editor-drawers.ts b/src/services/editor/editor-drawers.ts index a5a8472..dc247e7 100644 --- a/src/services/editor/editor-drawers.ts +++ b/src/services/editor/editor-drawers.ts @@ -194,109 +194,113 @@ function drawElevatorIcon( } } - // 绘制电梯顶部指示器 - 基于电梯宽度自适应,增加距离避免被遮挡 - const indicatorWidth = width * 0.6; // 指示器宽度为电梯宽度的60% - const indicatorHeight = Math.max(6, width * 0.12); // 指示器高度为电梯宽度的12%,最小6px - const indicatorY = y - Math.max(10, width * 0.25); // 增加距离:电梯宽度的25%,最小10px + // 绘制电梯方向指示器 - 根据方向显示在上方或下方 + const indicatorWidth = width * 0.3; // 指示器宽度为电梯宽度的30%(缩小为装饰性条带) + const indicatorHeight = height * 0.04; // 指示器高度为电梯高度的4% + const indicatorDistance = height * 0.15; // 指示器与电梯的距离为电梯高度的15% - // 顶部指示器背景 - 金属质感 - const indicatorGradient = ctx.createLinearGradient(x + width/2 - indicatorWidth/2, indicatorY, x + width/2 + indicatorWidth/2, indicatorY + indicatorHeight); - indicatorGradient.addColorStop(0, '#6b7280'); - indicatorGradient.addColorStop(0.5, '#4b5563'); - indicatorGradient.addColorStop(1, '#374151'); - ctx.fillStyle = indicatorGradient; - ctx.fillRect(x + width/2 - indicatorWidth/2, indicatorY, indicatorWidth, indicatorHeight); - - // 根据方向在顶部指示器内显示状态,使用更大的箭头 + // 根据方向确定指示器位置 + let indicatorY: number; if (direction === 2) { - // 向上状态 - 绿色LED效果 + // 向上 - 指示器在电梯上方 + indicatorY = y - indicatorDistance - indicatorHeight; + } else if (direction === 3) { + // 向下 - 指示器在电梯下方 + indicatorY = y + height + indicatorDistance; + } else { + // 停止或未知 - 默认在下方 + indicatorY = y + height + indicatorDistance; + } + + // 绘制方向箭头(不受指示器限制) + if (direction === 2) { + // 向上状态 - 绿色箭头,显示在上方 + const arrowSize = Math.min(width, height) * 0.35; // 箭头大小为图标较小边的35% + const arrowY = y - indicatorDistance - arrowSize - height * 0.05; // 箭头位置,留出5%缓冲 + // 绘制发光背景 - const glowGradient = ctx.createRadialGradient(cx, indicatorY + indicatorHeight/2, 0, cx, indicatorY + indicatorHeight/2, indicatorHeight * 1.5); + const glowGradient = ctx.createRadialGradient(cx, arrowY + arrowSize/2, 0, cx, arrowY + arrowSize/2, arrowSize); glowGradient.addColorStop(0, 'rgba(16, 185, 129, 0.4)'); glowGradient.addColorStop(1, 'rgba(16, 185, 129, 0)'); ctx.fillStyle = glowGradient; - ctx.fillRect(x + width/2 - indicatorWidth/2 - 3, indicatorY - 3, indicatorWidth + 6, indicatorHeight + 6); + ctx.fillRect(cx - arrowSize - 5, arrowY - 5, arrowSize * 2 + 10, arrowSize + 10); - // 绘制向上箭头 - 更大更明显 + // 绘制向上箭头 ctx.fillStyle = '#10b981'; ctx.shadowColor = '#10b981'; - ctx.shadowBlur = 8; + ctx.shadowBlur = 6; - // 使用更大的箭头,占据整个指示器高度 - const arrowSize = Math.min(indicatorWidth * 0.4, indicatorHeight * 0.9); - const arrowTop = indicatorY + indicatorHeight * 0.1; - const arrowBottom = indicatorY + indicatorHeight * 0.9; - - // 主箭头 - 加粗版本 ctx.beginPath(); - ctx.moveTo(cx, arrowTop); - ctx.lineTo(cx - arrowSize, arrowBottom); - ctx.lineTo(cx - arrowSize * 0.4, arrowBottom - arrowSize * 0.2); - ctx.lineTo(cx, arrowBottom - arrowSize * 0.3); - ctx.lineTo(cx + arrowSize * 0.4, arrowBottom - arrowSize * 0.2); - ctx.lineTo(cx + arrowSize, arrowBottom); + ctx.moveTo(cx, arrowY); + ctx.lineTo(cx - arrowSize, arrowY + arrowSize); + ctx.lineTo(cx - arrowSize * 0.4, arrowY + arrowSize - arrowSize * 0.15); + ctx.lineTo(cx, arrowY + arrowSize - arrowSize * 0.25); + ctx.lineTo(cx + arrowSize * 0.4, arrowY + arrowSize - arrowSize * 0.15); + ctx.lineTo(cx + arrowSize, arrowY + arrowSize); ctx.closePath(); ctx.fill(); ctx.shadowBlur = 0; } else if (direction === 3) { - // 向下状态 - 红色LED效果 + // 向下状态 - 橙色箭头,显示在下方 + const arrowSize = Math.min(width, height) * 0.35; // 箭头大小为图标较小边的35% + const arrowY = y + height + indicatorDistance + height * 0.05; // 箭头位置,留出5%缓冲 + // 绘制发光背景 - const glowGradient = ctx.createRadialGradient(cx, indicatorY + indicatorHeight/2, 0, cx, indicatorY + indicatorHeight/2, indicatorHeight * 1.5); - glowGradient.addColorStop(0, 'rgba(239, 68, 68, 0.4)'); - glowGradient.addColorStop(1, 'rgba(239, 68, 68, 0)'); + const glowGradient = ctx.createRadialGradient(cx, arrowY + arrowSize/2, 0, cx, arrowY + arrowSize/2, arrowSize); + glowGradient.addColorStop(0, 'rgba(251, 146, 60, 0.4)'); + glowGradient.addColorStop(1, 'rgba(251, 146, 60, 0)'); ctx.fillStyle = glowGradient; - ctx.fillRect(x + width/2 - indicatorWidth/2 - 3, indicatorY - 3, indicatorWidth + 6, indicatorHeight + 6); + ctx.fillRect(cx - arrowSize - 5, arrowY - 5, arrowSize * 2 + 10, arrowSize + 10); - // 绘制向下箭头 - 更大更明显 - ctx.fillStyle = '#ef4444'; - ctx.shadowColor = '#ef4444'; - ctx.shadowBlur = 8; + // 绘制向下箭头 + ctx.fillStyle = '#fb923c'; + ctx.shadowColor = '#fb923c'; + ctx.shadowBlur = 6; - // 使用更大的箭头,占据整个指示器高度 - const arrowSize = Math.min(indicatorWidth * 0.4, indicatorHeight * 0.9); - const arrowTop = indicatorY + indicatorHeight * 0.1; - const arrowBottom = indicatorY + indicatorHeight * 0.9; - - // 主箭头 - 加粗版本 ctx.beginPath(); - ctx.moveTo(cx, arrowBottom); - ctx.lineTo(cx - arrowSize, arrowTop); - ctx.lineTo(cx - arrowSize * 0.4, arrowTop + arrowSize * 0.2); - ctx.lineTo(cx, arrowTop + arrowSize * 0.3); - ctx.lineTo(cx + arrowSize * 0.4, arrowTop + arrowSize * 0.2); - ctx.lineTo(cx + arrowSize, arrowTop); + ctx.moveTo(cx, arrowY + arrowSize); + ctx.lineTo(cx - arrowSize, arrowY); + ctx.lineTo(cx - arrowSize * 0.4, arrowY + arrowSize * 0.15); + ctx.lineTo(cx, arrowY + arrowSize * 0.25); + ctx.lineTo(cx + arrowSize * 0.4, arrowY + arrowSize * 0.15); + ctx.lineTo(cx + arrowSize, arrowY); ctx.closePath(); ctx.fill(); ctx.shadowBlur = 0; } else if (direction === 1) { - // 停止状态 - 黄色LED效果 + // 停止状态 - 黄色LED效果,显示在下方 // 绘制发光背景 - const glowGradient = ctx.createRadialGradient(cx, indicatorY + indicatorHeight/2, 0, cx, indicatorY + indicatorHeight/2, indicatorHeight); + const glowGradient = ctx.createRadialGradient(cx, indicatorY + indicatorHeight/2, 0, cx, indicatorY + indicatorHeight/2, indicatorHeight * 1.5); glowGradient.addColorStop(0, 'rgba(245, 158, 11, 0.3)'); glowGradient.addColorStop(1, 'rgba(245, 158, 11, 0)'); ctx.fillStyle = glowGradient; - ctx.fillRect(x + width/2 - indicatorWidth/2 - 2, indicatorY - 2, indicatorWidth + 4, indicatorHeight + 4); + ctx.fillRect(x + width/2 - indicatorWidth/2 - 3, indicatorY - 3, indicatorWidth + 6, indicatorHeight + 6); // 绘制停止标志 ctx.fillStyle = '#f59e0b'; ctx.shadowColor = '#f59e0b'; - ctx.shadowBlur = 6; - const stopSize = Math.min(indicatorHeight * 0.6, indicatorWidth * 0.18); + ctx.shadowBlur = 4; + const stopSize = Math.min(indicatorHeight, indicatorWidth * 0.8); // 绘制矩形停止标志 ctx.fillRect(cx - stopSize/2, indicatorY + (indicatorHeight - stopSize)/2, stopSize, stopSize); - // 添加脉冲效果 - const pulsePhase = (time % 2000) / 2000 * Math.PI * 2; - const pulseAlpha = 0.3 + 0.2 * Math.sin(pulsePhase); - ctx.fillStyle = `rgba(245, 158, 11, ${pulseAlpha})`; - ctx.fillRect(cx - stopSize/2 - 2, indicatorY + (indicatorHeight - stopSize)/2 - 2, stopSize + 4, stopSize + 4); - ctx.shadowBlur = 0; } + // 只有停止状态才显示装饰性指示器条 + if (direction === 1) { + // 指示器背景 - 金属质感 + const indicatorGradient = ctx.createLinearGradient(x + width/2 - indicatorWidth/2, indicatorY, x + width/2 + indicatorWidth/2, indicatorY + indicatorHeight); + indicatorGradient.addColorStop(0, '#6b7280'); + indicatorGradient.addColorStop(0.5, '#4b5563'); + indicatorGradient.addColorStop(1, '#374151'); + ctx.fillStyle = indicatorGradient; + ctx.fillRect(x + width/2 - indicatorWidth/2, indicatorY, indicatorWidth, indicatorHeight); + } + // 添加电梯边框 - 金属边缘效果 ctx.strokeStyle = '#1f2937'; ctx.lineWidth = 2; @@ -677,7 +681,7 @@ export function drawPoint(ctx: CanvasRenderingContext2D, pen: MapPen): void { ctx.strokeStyle = largeTypeStrokeColor || largeGeneralStrokeColor || largeThemeStrokeColor || ''; ctx.stroke(); - // 电梯点:使用Canvas绘制的电梯图标 + // 电梯点:使用Canvas绘制的电梯图标 if (type === MapPointType.电梯点) { // 绘制Canvas电梯图标和状态 if (pen.point) {