deck.gl视角过渡变换
目录
功能说明
本实例实现了deck.gl加载底图,控制地图视角由在不同位置过渡缩放变换,支持自定义过渡动画效果。
效果图
在线地址
deck.gl视角过渡变换
https://tool.giserdqy.com/deckgl/viewport-transition.html
实现原理
通过设置initialViewState属性中的longitude、latitude改变视角中心;transitionDuration属性调整平滑移动速度;transitionInterpolator设置过渡动画效果。
代码解析
- 此部分是引入在线deck.gl包,mapboxgl底图,设置了基本的css样式
<head>
<title>deck.gl Viewport Transition Example</title>
<script src="https://unpkg.com/deck.gl@^8.8.0/dist.min.js"></script>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v1.13.0/mapbox-gl.js"></script>
<style type="text/css">
body {
width: 100vw;
height: 100vh;
margin: 0;
}
#control-panel {
font-size: 12px;
font-family: Helvetica, Arial, sans-serif;
position: absolute;
top: 0;
left: 0;
margin: 12px;
padding: 20px;
line-height: 2;
z-index: 1;
background: #fff;
border: solid 1px #ccc;
border-bottom-color: #bbb;
border-radius: 3px;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.15);
}
</style>
</head>
<body>
<div id="control-panel">
</div>
</body>
- 这部分定义需要的基本库,ScatterplotLayer是加载视角切换的几个点,FlyToInterplolater是设置平滑过渡动画效果;初始化了视角切换的点位数据
const {DeckGL, ScatterplotLayer, FlyToInterpolator} = deck;
// Data
const CITIES = [
{"city":"San Francisco","state":"California","latitude":37.7751,"longitude":-122.4193},
{"city":"New York","state":"New York","latitude":40.6643,"longitude":-73.9385},
{"city":"Los Angeles","state":"California","latitude":34.051597,"longitude":-118.244263},
{"city":"London","state":"United Kingdom","latitude":51.5074,"longitude":-0.1278},
{"city":"Hyderabad","state":"India","latitude":17.3850,"longitude":78.4867}
];
- 这部分代码初始化DeckGL,并设置初始视角位置;将视角点以散点图层的形式展示出来
// Deck canvas
const deckgl = new DeckGL({
mapStyle: 'https://basemaps.cartocdn.com/gl/positron-nolabels-gl-style/style.json',
initialViewState: {
longitude: CITIES[0].longitude,
latitude: CITIES[0].latitude,
zoom: 10
},
controller: true,
layers: [
new ScatterplotLayer({
data: CITIES,
getPosition: d => [d.longitude, d.latitude],
getColor: [255, 180, 0],
radiusMinPixels: 10
})
]
});
- 该部分初始化切换视角radio按钮,并绑定切换视角的核心函数;说明见注释
// Create radio buttons
const inputs = d3.select('#control-panel').selectAll('div')
.data(CITIES)
.enter().append('div');
inputs.append('input')
.attr('type', 'radio')
.attr('name', 'city')
.attr('id', (d, i) => 'city-' + i)
.on('change', d => {
deckgl.setProps({// 设置deckgl的视角状态
initialViewState: {
longitude: d.longitude,// 经度
latitude: d.latitude, // 纬度
zoom: 10, // 缩放级别
transitionInterpolator: new FlyToInterpolator({speed: 1.5}), // 过渡动画效果
transitionDuration: 'auto' // 过渡速率
}
})
});
inputs.append('label')
.attr('for', (d, i) => 'city-' + i)
.text(d => d.city + ', ' + d.state);
// Default select the first city
inputs.select('input').node().checked = true;
源代码
拷贝到html文件中可直接用浏览器打开
<html>
<head>
<title>deck.gl Viewport Transition Example</title>
<script src="https://unpkg.com/deck.gl@^8.8.0/dist.min.js"></script>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v1.13.0/mapbox-gl.js"></script>
<style type="text/css">
body {
width: 100vw;
height: 100vh;
margin: 0;
}
#control-panel {
font-size: 12px;
font-family: Helvetica, Arial, sans-serif;
position: absolute;
top: 0;
left: 0;
margin: 12px;
padding: 20px;
line-height: 2;
z-index: 1;
background: #fff;
border: solid 1px #ccc;
border-bottom-color: #bbb;
border-radius: 3px;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.15);
}
</style>
</head>
<body>
<div id="control-panel">
</div>
</body>
<script type="text/javascript">
const {DeckGL, ScatterplotLayer, FlyToInterpolator} = deck;
// Data
const CITIES = [
{"city":"San Francisco","state":"California","latitude":37.7751,"longitude":-122.4193},
{"city":"New York","state":"New York","latitude":40.6643,"longitude":-73.9385},
{"city":"Los Angeles","state":"California","latitude":34.051597,"longitude":-118.244263},
{"city":"London","state":"United Kingdom","latitude":51.5074,"longitude":-0.1278},
{"city":"Hyderabad","state":"India","latitude":17.3850,"longitude":78.4867}
];
// Deck canvas
const deckgl = new DeckGL({
mapStyle: 'https://basemaps.cartocdn.com/gl/positron-nolabels-gl-style/style.json',
initialViewState: {
longitude: CITIES[0].longitude,
latitude: CITIES[0].latitude,
zoom: 10
},
controller: true,
layers: [
new ScatterplotLayer({
data: CITIES,
getPosition: d => [d.longitude, d.latitude],
getColor: [255, 180, 0],
radiusMinPixels: 10
})
]
});
// Create radio buttons
const inputs = d3.select('#control-panel').selectAll('div')
.data(CITIES)
.enter().append('div');
inputs.append('input')
.attr('type', 'radio')
.attr('name', 'city')
.attr('id', (d, i) => 'city-' + i)
.on('change', d => {
deckgl.setProps({
initialViewState: {
longitude: d.longitude,
latitude: d.latitude,
zoom: 10,
transitionInterpolator: new FlyToInterpolator({speed: 1.5}),
transitionDuration: 'auto'
}
})
});
inputs.append('label')
.attr('for', (d, i) => 'city-' + i)
.text(d => d.city + ', ' + d.state);
// Default select the first city
inputs.select('input').node().checked = true;
</script>
</html>