ArcGIS JS 基础教程(26):图层可见性与透明度控制
- 零、写在前面
- 一、功能介绍
- 二、功能实现
- 2.1 显隐与透明度
- 2.2 可见比例尺范围(3D 渐进加载)
- 三、功能应用
- 四、核心代码
- 五、在线示例
- 六、关键 API 说明
- 七、系列导航
零、写在前面
📌本系列教程完整目录:ArcGIS JS 系列基础教程(100个项目常用热门功能)
💡在线示例:完整可运行的 HTML 示例,无需任何环境配置,可直接在浏览器中打开体验
🗂️专栏导航:收藏 + 关注,专栏文章第一时间送达
❤️一键三连:点赞 + 评论 + 收藏
一、功能介绍
图层可见性与透明度是三维场景中最基础也最常用的显示控制手段,全部继承自Layer基类,适用于所有图层类型(FeatureLayer、SceneLayer、CSVLayer、GeoJSONLayer 等)。
layer.visible:控制图层显隐(boolean)。layer.opacity:控制整体透明度(0~1,1为不透明)。layer.minScale/layer.maxScale:控制图层的可见比例尺范围——在 3D 中对应相机的远近,可实现「近景显示细节、远景自动隐藏」的渐进式加载。
参考:官方 Layer API
💡注意:
VoxelLayer在 3D 中不支持修改opacity(官方明确限制),其余图层均正常。
二、功能实现
2.1 显隐与透明度
buildingsLayer.visible=false;// 隐藏buildingsLayer.opacity=0.4;// 半透明叠加2.2 可见比例尺范围(3D 渐进加载)
比例尺随相机拉远而变大。令maxScale为一个较小值,即可让图层在拉远(超出该比例)时自动隐藏:
// 仅当相机较近(currentScale <= 100000)时显示buildingsLayer.maxScale=100000;buildingsLayer.minScale=0;// 0 表示不限制三、功能应用
| 应用场景 | 配置 |
|---|---|
| 主题切换面板 | 同时仅visible = true相关图层 |
| 多专题对比 | 半透明(opacity = 0.4)叠加 |
| 按缩放渐进加载 | minScale/maxScale控制远近显隐 |
| 遮挡处理 | 隐藏被遮挡的底层图层 |
四、核心代码
📦完整代码已保存至
sample/lesson26_layer_visibility.html,可直接在浏览器打开。
<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>第26课:图层可见性与透明度控制</title><linkrel="stylesheet"href="https://js.arcgis.com/5.0/esri/themes/light/main.css"><scripttype="module"src="https://js.arcgis.com/5.0/"></script><style>*{margin:0;padding:0;box-sizing:border-box;}body{font-family:"Microsoft YaHei",sans-serif;}#mapContainer{width:100vw;height:100vh;}.page-title{position:absolute;top:20px;left:50%;transform:translateX(-50%);background:rgba(255,255,255,0.95);padding:10px 24px;border-radius:6px;font-size:18px;font-weight:bold;z-index:100;box-shadow:0 2px 8pxrgba(0,0,0,0.15);}.control-panel{position:absolute;top:80px;right:20px;background:rgba(255,255,255,0.95);padding:16px;border-radius:8px;box-shadow:0 2px 12pxrgba(0,0,0,0.15);z-index:100;min-width:300px;}.control-panel h3{margin:0 0 8px 0;font-size:14px;color:#333;}.section{margin-bottom:12px;padding-bottom:10px;border-bottom:1px solid #eee;}.section:last-child{border-bottom:none;margin-bottom:0;}.btn-row{display:flex;gap:8px;flex-wrap:wrap;margin-top:6px;}.btn-row button{flex:1;min-width:60px;padding:6px 0;border:1px solid #d9d9d9;border-radius:4px;background:white;cursor:pointer;font-size:12px;}.btn-row button:hover{border-color:#1890ff;color:#1890ff;}.btn-row button.on{background:#1890ff;color:white;border-color:#1890ff;}.info-card{margin-top:10px;padding:10px 12px;background:#f0f5ff;border-radius:6px;border-left:3px solid #1890ff;font-size:12px;line-height:1.6;}.info-card .val{font-weight:bold;color:#1890ff;}.status-text{position:absolute;bottom:20px;left:50%;transform:translateX(-50%);background:rgba(0,0,0,0.7);color:white;padding:8px 20px;border-radius:20px;font-size:13px;z-index:100;pointer-events:none;white-space:nowrap;}</style></head><body><h1class="page-title">第26课:图层可见性与透明度控制</h1><divclass="control-panel"><divclass="section"><h3>🏢 建筑图层(FeatureLayer)</h3><divclass="btn-row"><buttonid="btnBldVisible"class="on">👁️ 建筑显隐</button><buttonid="btnBldOpacity">🌗 建筑透明度</button></div><divclass="btn-row"><buttonid="btnBldScale">🔍 仅近景显示</button></div></div><divclass="section"><h3>🌐 地震图层(CSVLayer)</h3><divclass="btn-row"><buttonid="btnCsvVisible"class="on">👁️ 地震显隐</button><buttonid="btnCsvOpacity">🌗 地震透明度</button></div></div><divclass="section"><h3>🎯 视角切换</h3><divclass="btn-row"><buttonid="btnViewBld">🏢 建筑视角</button><buttonid="btnViewCsv">🌐 地震视角</button></div></div><divclass="info-card"><div>建筑状态:<spanclass="val"id="bldStatus">加载中...</span></div><div>地震状态:<spanclass="val"id="csvStatus">加载中...</span></div></div></div><divclass="status-text"id="statusText">图层可见性与透明度 | 显隐 / 透明度 / 比例尺范围</div><divid="mapContainer"></div><scripttype="module">constMap=await$arcgis.import("@arcgis/core/Map.js");constSceneView=await$arcgis.import("@arcgis/core/views/SceneView.js");constFeatureLayer=await$arcgis.import("@arcgis/core/layers/FeatureLayer.js");constCSVLayer=await$arcgis.import("@arcgis/core/layers/CSVLayer.js");constgetTianditu=await$arcgis.import("https://openlayers.vip/examples/resources/tianditu.js");constvecLayers=getTianditu.default({type:"vec_w"});constmap=newMap({basemap:{baseLayers:[vecLayers.base,vecLayers.anno]}});constview=newSceneView({container:"mapContainer",map:map,camera:{position:{longitude:121.435,latitude:31.245,z:4000},heading:30,tilt:60}});window.view=view;// ===== 建筑图层(面 + 拉伸) =====constbuildingsLayer=newFeatureLayer({url:"https://gs3d.geosceneonline.cn/server/rest/services/Hosted/ShangHaiBuilding/FeatureServer/0",elevationInfo:{mode:"on-the-ground"},outFields:["id","floor","year"],renderer:{type:"simple",symbol:{type:"polygon-3d",symbolLayers:[{type:"extrude",material:{color:"#D4B87C"},edges:{type:"solid",color:"#999999",size:0.5}}]},visualVariables:[{type:"size",field:"floor",axis:"height",valueUnit:"unknown"}]}});map.add(buildingsLayer);// ===== 地震图层(CSV 点) =====constcsvLayer=newCSVLayer({url:"https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_week.csv",copyright:"USGS Earthquakes",latitudeField:"latitude",longitudeField:"longitude",elevationInfo:{mode:"on-the-ground"},renderer:{type:"simple",symbol:{type:"point-3d",symbolLayers:[{type:"object",resource:{primitive:"sphere"},anchor:"bottom",material:{color:[255,80,0,0.85]}}]},visualVariables:[{type:"size",field:"mag",axis:"all",stops:[{value:2.5,size:8000},{value:6,size:40000}]}]}});map.add(csvLayer);view.when(()=>{buildingsLayer.when(()=>{document.getElementById("bldStatus").textContent="已加载";view.goTo(buildingsLayer.fullExtent,{duration:2000,easing:"cubic-out"});});csvLayer.when(()=>{document.getElementById("csvStatus").textContent="已加载";});});functionsetStatus(msg){document.getElementById("statusText").textContent=msg;}// 建筑显隐document.getElementById("btnBldVisible").addEventListener("click",function(){buildingsLayer.visible=!buildingsLayer.visible;this.classList.toggle("on",buildingsLayer.visible);setStatus("建筑图层:"+(buildingsLayer.visible?"显示":"隐藏"));});// 建筑透明度document.getElementById("btnBldOpacity").addEventListener("click",()=>{buildingsLayer.opacity=buildingsLayer.opacity===1?0.4:1;setStatus("建筑透明度:"+buildingsLayer.opacity);});// 建筑仅近景显示(比例尺范围)// 注意:用 minScale(缩小极限)——当地图拉远到 scale 超过 minScale 时隐藏;// maxScale 是放大极限(更近时隐藏),用错会导致初始拉远视角直接消失。letscaleOn=false;document.getElementById("btnBldScale").addEventListener("click",function(){scaleOn=!scaleOn;buildingsLayer.minScale=scaleOn?500000:0;this.classList.toggle("on",scaleOn);setStatus(scaleOn?"建筑:仅近景显示(拉远自动隐藏)":"建筑:比例尺限制已清除");});// 地震显隐document.getElementById("btnCsvVisible").addEventListener("click",function(){csvLayer.visible=!csvLayer.visible;this.classList.toggle("on",csvLayer.visible);setStatus("地震图层:"+(csvLayer.visible?"显示":"隐藏"));});// 地震透明度document.getElementById("btnCsvOpacity").addEventListener("click",()=>{csvLayer.opacity=csvLayer.opacity===1?0.4:1;setStatus("地震透明度:"+csvLayer.opacity);});// 视角切换:飞到建筑图层范围(上海局部)document.getElementById("btnViewBld").addEventListener("click",()=>{view.goTo(buildingsLayer.fullExtent,{duration:1500}).catch(()=>{});setStatus("视角:建筑图层(上海局部)");});// 视角切换:飞到地震图层范围(全球)document.getElementById("btnViewCsv").addEventListener("click",()=>{view.goTo(csvLayer.fullExtent,{duration:1500}).catch(()=>{});setStatus("视角:地震图层(全球)");});</script></body></html>五、在线示例
🔗在线体验:https://southjor.github.io/arcgis-examples/lessons/lesson26.html
操作说明:
- 场景加载上海建筑(FeatureLayer)与美国地震(CSVLayer)两个图层。
- 通过「建筑显隐 / 地震显隐」控制各自
visible。- 通过「透明度」按钮在
1.0与0.4间切换opacity。- 点击「仅近景显示」设置
maxScale = 100000,拉远相机后建筑自动隐藏。
六、关键 API 说明
| API | 说明 |
|---|---|
layer.visible | 图层显隐(boolean) |
layer.opacity | 图层透明度(0~1),VoxelLayer 在 3D 不支持 |
layer.minScale/layer.maxScale | 可见比例尺范围(0表示不限制) |
map.add(layer) | 加入场景 |
参考链接:Layer API
七、系列导航
⬅️上一篇:ArcGIS JS 基础教程(25):GeoJSONLayer 与 KML 图层
➡️下一篇:ArcGIS JS 基础教程(27):DisplayFilter 显示过滤器
💡小贴士:
visible/opacity是「即时显隐」,不影响数据与查询;而minScale/maxScale是按相机远近的自动显隐,适合用来做性能优化——远景隐藏细节图层,可显著降低渲染负担。