# View Animation (opens new window) 示例
开始学
ol
会觉得很奇怪,因为从ArcGIS API for JS 3.x
刚转过来,它里面并没有将控制分辨率、缩放级别、地图范围、投影等分离出来,这些相关的API全在map对象里面,而ol
将它们封装到了View
中。
# 1 View对象
View
对象是代表地图的简单2D
视图,可以用于更改地图中心、分辨率、和旋转的对象;其中的projection属性,确定地图的坐标系(默认是墨卡托投影EPSG:3857
)。
View有三种状态:
- center:视图的初始中心。
- resolution:视图的初始分辨率。单位是projection每像素的单位(例如米/像素),所有关于地图缩放有关的计算都是使用
resolution
。 - rotation:视图的初始旋转(弧度)(顺时针正旋转,0表示北)。
跟地图缩放有关的还有zoom
属性,但实际上zoom
没有封装在view
对象中,不过view
中还是提供了setZoom()
和getZoom()
方法访问zoom
属性。
# 2 状态的限制
通过setCenter
、setResolution
和setRotation
方法可以改变view的状态。但地图不可能无限的放大或缩小,所以使用resolutions
设置地图的所有层级的分辨率或使用maxResolution
、MaxZoom
和zoomFactor
限制缩放的大小。如果设置了resolutions
属性,其他三个属性将失效。
# 3 Animation动画
当改变view状态的时候,可以使用animate(option)
方法从原来的状态平滑的过渡到另一个状态。
option
配置对象,以JSON
对象的方式配置参数,同时也可以有多个配置对象形成链式连续的动画效果。
type | Description |
---|---|
center | 动画结束后view的中心 |
zoom | 动画结束后view的缩放级别,优先于resolution |
resolution | 动画结束后view的地图分辨率,如果设置了zoom 则该配置项会被忽略 |
rotation | 动画结束后view的旋转角度,顺时针正旋转,0表示北 |
anchor | 锚点,是一个Coordinate类型的参数,用于固定某点进行动画 |
duration | 动画的过渡时间,单位为毫米 |
easing | 动画使用的缓冲函数。该函数将为每一帧调用,并带有表示动画持续时间的一小部分的数字。应该返回一个0到1之间的数字,表示向目标状态的进展。 |
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<style>
.map {
height: 400px;
width: 100%;
}
</style>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/build/ol.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/css/ol.css">
<title>View</title>
</head>
<body>
<h2>My Map</h2>
<div id="map" class="map"></div>
<script type="text/javascript">
window.onload =function(){
var shenzhen = [113.958334,22.535640];
/*
* 地图表现:必备三要素,
* 图层(Layer)
* 视图(View)
* 目标容器(target)
* */
var map = new ol.Map({
view:new ol.View({
center:ol.proj.fromLonLat(shenzhen),
zoom:8,
minzoom:6,
maxzoom:12,
rotation:Math.PI/6
}),
layers:[
new ol.layer.Tile({
source:new ol.source.OSM()
})
],
target:"map"
});
map.on("click",function (e) {
var point = e.coordinate;
console.log("x:"+point[0]+",y:"+point[1]);
});
/*
*View对象:
*View对象是代表地图的简单2D视图,可以用于更改地图中心、分辨率、和旋转的对象;
* projection属性,确定中心的坐标系(默认是墨卡托投影EPSG:3857)
*
* View三种状态:
* center:视图的初始中心。如果未设置用户投影,则使用projection选项指定中心的坐标系,如果未设置,则不会获取图层源,但是稍后可以使用设置中心#setCenter。
* resolution:视图的初始分辨率。单位是projection每像素的单位(例如米/像素)
* rotation:视图的初始旋转(弧度)(顺时针正旋转,0表示北)。
*
* 常用属性还有:zoom,resolutions。如果设置了resolutions,则maxResolution,minResolution, minZoom,maxZoom,和zoomFactor选项都将被忽略。
*/
//地图视图的初始化参数
var view = map.getView();
var zoom = view.getZoom();
var center = view.getCenter();
var rotation = view.getRotation();
document.getElementById("zoom-out").onclick = function(e){
var view = map.getView();
var zoom = view.getZoom();
view.setZoom(zoom - 1);
};
document.getElementById("zoom-in").onclick = function(e){
var view = map.getView();
var zoom = view.getZoom();
view.setZoom(zoom + 1);
};
document.getElementById("panto").onclick = function(e){
var view = map.getView();
//参数为ol.Coordinate
var mak = ol.proj.fromLonLat(shenzhen);
view.setCenter(mak);
};
document.getElementById("reset").onclick = function(e){
view.setCenter(center);
view.setZoom(zoom);
view.setRotation(rotation);
};
// var shenzhen = [1280091112800911.302100137,2611260.0825854577];
/*
animate(var_args)
例子: view.animate({zoom: view.getZoom() + 1});
view.animate({zoom: 10}, {center: [0, 0]});将多个动画放在一起,先缩放后平移
参数:center、zoom、resolution、rotation、duration、easing、anchor
默认情况下,动画持续一秒钟,并 in-and-out easing缓进缓出,
duration:设置动画持续时间(单位:毫秒);
easing:设置动画进出方式;
anchor锚点:用于rotation或resolution固定旋转的原点;
**/
document.getElementById("rotate-left").onclick = function (e) {
view.animate({
rotation:view.getRotation()+Math.PI/2
});
};
document.getElementById("rotate-right").onclick = function (e) {
view.animate({
rotation:view.getRotation()-Math.PI/2
});
};
document.getElementById("fly-to-shenzhen").onclick = function () {
var rotation = view.getRotation();
flyTo(shenzhen,function () {
console.log("执行完回调");
});
};
function flyTo(location, done) {
var duration = 2000;
var zoom = view.getZoom();
var parts = 2;
var called = false;
function callback(complete) {
--parts;
if (called) {
return;
}
if (parts === 0 || !complete) {
called = true;
done(complete);
}
}
view.animate({
center: ol.proj.fromLonLat(shenzhen),
duration: duration
}, callback);
view.animate({
zoom: zoom - 1,
duration: duration / 2
}, {
zoom: zoom,
duration: duration / 2
}, callback);
}
/**
* 注意:当多个option配置对象时,每个状态(zoom,resolution,rotation)都是相对原始状态的
*/
document.getElementById("rotate-around-shenzhen").onclick = function(){
var rotation = view.getRotation();
view.animate({
rotation: rotation + Math.PI,//是原始状态旋转180
anchor: ol.proj.fromLonLat(shenzhen),
easing: ol.easing.easeIn
},{
rotation: rotation + 2*Math.PI,//是原始状态旋转360
anchor: ol.proj.fromLonLat(shenzhen),
easing: ol.easing.easeOut
})
}
}
</script>
<hr>
<div>
<p>View动画animation</p>
<p>让View平滑地改变状态(中心点、缩放级别、旋转)</p>
<button id="zoom-out">放大</button>
<button id="zoom-in">缩小</button>
<button id="panto">定位</button>
<button id="reset">复位</button>
<button id="rotate-left" title="Rotate clockwise">↻</button>
<button id="rotate-right" title="Rotate counterclockwise">↺</button>
<button id="rotate-around-shenzhen">Rotate around shenzhen</button>
<button id="fly-to-shenzhen">Fly to ShenZhen</button>
</div>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179