高程灰度计算器
这是一个关于线性插值和数据可视化的典型需求。在 GIS 或 3D 地图开发中,我们经常需要将地形的高度(米)映射为颜色的灰度值(0-255)。
下面是一个完整的 HTML + JavaScript 解决方案。它包含一个控制面板用于输入最大高度,输入当前米数,使用数学公式计算对应的灰度值,并使用 HTML5 Canvas 绘制直观的图表。
核心逻辑说明
- 映射原理:假设最低点(0米)对应黑色(灰度0),最高点(用户输入的Z轴高度)对应白色(灰度255)。
- 计算公式:

- 图表展示:绘制一个从黑到白的渐变条,并在对应位置标记出当前数值。
<!doctype html>
<html lang="zh-CN"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>高程灰度可视化计算器</title><style>body {font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;background-color: #eef2f5;display: flex;justify-content: center;align-items: center;height: 100vh;margin: 0;}.main-card {background: white;padding: 2rem;border-radius: 12px;box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);width: 450px;}h2 {margin-top: 0;color: #333;text-align: center;}/* 输入区域样式 */.settings {background: #f8f9fa;padding: 15px;border-radius: 8px;margin-bottom: 25px;border: 1px solid #e9ecef;}.input-row {display: flex;justify-content: space-between;align-items: center;margin-bottom: 10px;}.input-row:last-child {margin-bottom: 0;}label {font-weight: 600;color: #555;font-size: 14px;}input[type="number"] {padding: 8px;border: 1px solid #ddd;border-radius: 4px;width: 100px;font-size: 16px;}/* 可视化渐变条与指针样式 */.visual-container {margin-bottom: 30px;position: relative;}.gradient-bar {height: 20px;width: 100%;border-radius: 4px;background: linear-gradient(to right, #000000, #ffffff);border: 1px solid #ccc;position: relative;}/* 刻度线样式 (0 和 Max) */.ticks {display: flex;justify-content: space-between;font-size: 12px;color: #666;margin-top: 5px;padding: 0 2px;}/* 动态指针 */.marker {position: absolute;top: -10px; /* 指针尖端向上 */left: 0%; /* 初始位置 */width: 0;height: 0;border-left: 10px solid transparent;border-right: 10px solid transparent;border-top: 15px solid #e74c3c; /* 红色倒三角 */transform: translateX(-50%); /* 居中修正 */transition: left 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94); /* 平滑移动动画 */z-index: 10;}/* 指针上方的数值标签 */.marker-label {position: absolute;top: -35px;left: 50%;transform: translateX(-50%);background: #333;color: #fff;padding: 4px 8px;border-radius: 4px;font-size: 12px;white-space: nowrap;opacity: 0; /* 默认隐藏,JS控制显示 */transition: opacity 0.2s;}/* 当指针激活时显示标签 */.marker.active .marker-label {opacity: 1;}/* 结果展示区域 */.results {display: grid;grid-template-columns: 1fr 1fr 1fr;gap: 15px;}.result-item {background: #fff;border: 1px solid #eee;padding: 15px;border-radius: 8px;text-align: center;box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);}.result-label {display: block;font-size: 12px;color: #888;margin-bottom: 8px;text-transform: uppercase;}.result-value {display: block;font-size: 20px;font-weight: bold;color: #2c3e50;font-family: "Consolas", monospace;}.color-box {display: inline-block;width: 20px;height: 20px;border-radius: 4px;margin-left: 8px;vertical-align: middle;border: 1px solid #ccc;}</style></head><body><div class="main-card"><h2>🏔️ 高程灰度可视化</h2><!-- 设置区 --><div class="settings"><div class="input-row"><label for="maxHeight">最大高度 (Z轴上限):</label><inputtype="number"id="maxHeight"value="1000"oninput="calculate()"/></div><div class="input-row"><label for="currentHeight">当前高度 (米):</label><inputtype="number"id="currentHeight"value="500"oninput="calculate()"/></div></div><!-- 可视化显示区 --><div class="visual-container"><div class="gradient-bar"><!-- 动态指针 --><div id="marker" class="marker"><div class="marker-label" id="markerLabel">500m</div></div></div><!-- 底部刻度 --><div class="ticks"><span>0m (黑)</span><span id="maxTick">1000m (白)</span></div></div><!-- 结果区 --><div class="results"><div class="result-item"><span class="result-label">颜色值 (Hex)</span><span class="result-value"><span id="resColor">#808080</span><span id="colorBox" class="color-box"></span></span></div><div class="result-item"><span class="result-label">灰度值 (0-255)</span><span class="result-value" id="resGray">128</span></div><div class="result-item"><span class="result-label">米数 (m)</span><span class="result-value" id="resMeter">500</span></div></div></div><script>function calculate() {// 1. 获取输入值const maxH =parseFloat(document.getElementById("maxHeight").value) || 1000;const currentH =parseFloat(document.getElementById("currentHeight").value) || 0;// 2. 计算比例 (0.0 到 1.0)let ratio = currentH / maxH;// 限制比例范围,防止指针跑出渐变条if (ratio < 0) ratio = 0;if (ratio > 1) ratio = 1;// 3. 计算灰度值const grayVal = Math.round(ratio * 255);// 4. 计算十六进制颜色const hex = grayVal.toString(16).padStart(2, "0");const colorHex = `#${hex}${hex}${hex}`;// 5. 更新 DOM 数值显示document.getElementById("resMeter").innerText = currentH;document.getElementById("resGray").innerText = grayVal;document.getElementById("resColor").innerText = colorHex;document.getElementById("colorBox").style.backgroundColor = colorHex;// 6. 更新可视化指针位置const marker = document.getElementById("marker");const markerLabel = document.getElementById("markerLabel");const maxTick = document.getElementById("maxTick");// 设置指针的 left 百分比位置marker.style.left = `${ratio * 100}%`;// 更新指针上的文字markerLabel.innerText = `${currentH}m`;// 激活指针显示(添加 active 类以显示标签)marker.classList.add("active");// 更新右下角的最大刻度文字maxTick.innerText = `${maxH}m (白)`;}// 初始化calculate();</script></body>
</html>
代码功能解析
- HTML 结构:
- 包含一个输入框 input 用于设置最大高度(例如 1000米)。
- 包含一个 canvas 元素,用于绘制可视化的渐变条。
- 包含三个 div 用于实时显示计算结果(颜色、灰度、米数)。
- JavaScript 逻辑:
- calculateGrayScale(current, max): 这是核心算法。它接收当前高度和最大高度,计算出比例,然后乘以 255 得到灰度值。同时它将 0-255 的整数转换为十六进制颜色字符串(例如 #808080)。
- updateChart():
- 使用 createLinearGradient 创建一个从左(黑)到右(白)的线性渐变,模拟地形高度的颜色变化。
- 在图表上绘制刻度线,标记出 0米、250米、500米等位置。
- 更新底部的文本显示。
- CSS 样式:
- 使用了 Flexbox 和 Grid 布局,使界面整洁美观。
- 卡片式设计,带有阴影,提升用户体验。

