近期需要有个动画效果,实现河流流向,当时预备了两套方案,一套是放箭头,只是标注一个点,箭头方向就是河流的流向,另一套是用canvas写一个点移动的效果,后来选择了用图标的方案,所以这边记录下另一套,防止以后代码找不到了。
效果大致是以下的样子
效果: https://kaixin51.github.io/other/olpointmove.html
不怎么会canvas 所以特效可能有点丑
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="css/ol.css">
<script type="text/javascript" src="js/jquery.3.5.1.js"></script>
<script type="text/javascript" src="js/ol.js"></script>
</head>
<div id="map" style="width: 100%;height: 500px;"></div>
</body>
<script>
let key = '38714c443b01bbf3f85d0c036e7c6411'
let animateCanvas;
const projection = ol.proj.get('EPSG:4326')
const projectionExtent = projection.getExtent()
const res = [
1.40625,
0.703125,
0.3515625,
0.17578125,
0.087890625,
0.0439453125,
0.02197265625,
0.010986328125,
0.0054931640625,
0.00274658203125,
0.001373291015625,
0.0006866455078125,
0.00034332275390625,
0.000171661376953125,
0.0000858306884765625,
0.00004291534423828125,
0.000021457672119140625,
0.000010728836059570312,
0.000005364418029785156,
0.000002682209014892578,
0.000001341104507446289
const matrixIds = [
var map = new ol.Map({
target: 'map',
controls: ol.control.defaults({
attribution: false,
zoom: false,
rotate: false
}),
view: new ol.View({
projection: projection,
center: [121.419383, 28.661179],
zoom: 10,
minZoom: 2,
maxZoom: 18,
extent: [-180, -90, 180, 90]
var tdtVectorLayer = new ol.layer.Tile({
minResolution: 0.000001341104507446289,
maxResolution: 1.40625,
visible: false,
source: new ol.source.WMTS({
crossOrigin: 'anonymous',
name: '天地图矢量',
url: 'http://t{0-7}.tianditu.gov.cn/vec_c/wmts?tk=' + key,
layer: 'vec',
style: 'default',
matrixSet: 'c',
format: 'tiles',
wrapX: true,
tileGrid: new ol.tilegrid.WMTS({
origin: ol.extent.getTopLeft(projectionExtent),
resolutions: res.slice(0, 20),
matrixIds: matrixIds
var tdtImgLayer = new ol.layer.Tile({
minResolution: 0.000001341104507446289,
maxResolution: 1.40625,
source: new ol.source.WMTS({
crossOrigin: 'anonymous',
name: '天地图矢量',
url: 'http://t{0-7}.tianditu.gov.cn/img_c/wmts?tk=' + key,
layer: 'img',
style: 'default',
matrixSet: 'c',
format: 'tiles',
wrapX: true,
tileGrid: new ol.tilegrid.WMTS({
origin: ol.extent.getTopLeft(projectionExtent),
resolutions: res.slice(0, 20),
matrixIds: matrixIds
var lineStrings = []
var baseLayerGroup = new ol.layer.Group({
layers: [tdtImgLayer, tdtVectorLayer]
map.addLayer(baseLayerGroup)
var source = new ol.source.Vector({
warpX: false
var vector = new ol.layer.Vector({
source: source,
map.addLayer(vector)
var format = new ol.format.GeoJSON()
$.ajax({
url: 'json/lines.json',
type: 'get',
dataType: 'json',
async: false,
success: function (result) {
let features = format.readFeatures(result)
source.addFeatures(features)
features.forEach(element => {
lineStrings.push({
geom:element.getGeometry(),
length:formatLength(element.getGeometry()),
let canvasLayer;
getCanvasLayer()
let isAnminate = false
var timer;
function getCanvasLayer(features) {
var canvasOption = new Object();
canvasOption.ratio = 1;
canvasOption.canvasFunction = function (extent, resolution, pixelRatio, size, projection) {
console.log("改变")
if (!animateCanvas) {
animateCanvas = document.createElement('canvas');
animateCanvas.width = size[0] * pixelRatio;
animateCanvas.height = size[1] * pixelRatio;
animateCanvas.style.width = size[0] * pixelRatio + 'px';
animateCanvas.style.height = size[1] * pixelRatio + 'px';
var ctx = animateCanvas.getContext('2d')
ctx.scale(pixelRatio, pixelRatio);
if(!isAnminate){
drawFrame()
isAnminate = true
function drawFrame() {
timer = requestAnimationFrame(drawFrame);
render()
function render(){
ctx.clearRect(0,0,size[0],size[1]);
$.each(lineStrings,function(index,linestring){
ctx.beginPath();
var scale = timer/linestring.length
scale = timer/(linestring.length/10)-Math.trunc(timer/(linestring.length/10))
var lnglat = linestring.geom.getCoordinateAt(scale);
lnglat = map.getPixelFromCoordinate(lnglat);
var grad=ctx.createRadialGradient(lnglat[0],lnglat[1],0.4,lnglat[0],lnglat[1],5)
grad.addColorStop(0,"#fff");
grad.addColorStop(1,"rgba(68, 165, 255, 0.3)");
ctx.fillStyle=grad;
ctx.arc(lnglat[0], lnglat[1], 4, 0, Math.PI * 2, true);
ctx.fill();
ctx.closePath();
map.render()
return animateCanvas
var canvasSource = new ol.source.ImageCanvas(canvasOption);
canvasLayer = new ol.layer.Image({
source: canvasSource,
zIndex: 600
});
map.addLayer(canvasLayer);
var global = typeof window === 'undefined' ? {} : window;
var requestAnimationFrame = global.requestAnimationFrame || global.mozRequestAnimationFrame || global.webkitRequestAnimationFrame || global.msRequestAnimationFrame || function (callback) {
return global.setTimeout(callback, 1000 / 60);
function closeFrame() {
cancelAnimationFrame(timer)
function formatLength(line) {
var sourceProj = this.map.getView().getProjection()
var length = ol.sphere.getLength(line, {
projection: sourceProj
return Math.trunc(length)+1
</script>
</html>
通过上述代码,我们成功地实现了在OpenLayers地图上的动画效果。此外,为了使动画效果更加流畅,你可能需要优化代码,例如使用更快的动画插值函数、减少路径点的数量等。在下面的示例中,我们将创建一个简单的地图,并在地图上添加一个移动的标记,以模拟动画效果。在引入OpenLayers之后,我们可以开始编写实现动画效果的代码。现在,我们已经创建了一个移动的标记,但它还没有动画效果。为了实现动画效果,我们可以使用OpenLayers的动画模块。是标记图标的文件名,你需要将其替换为你自己的图标文件路径。
做项目时,本来打算仿照官网的Example中动画制作,引入vue中后,发现它引用的库函数一直报错,最后我去vue中安装的依赖库中去查找这个函数,果然没有。也就是说官方例子使用的库和我安装的OL库存在一定差异。
后来我还是用笨方法去解决了,最终效果如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190319151929120.gif)...
function MoveOnLine(start,end,jsonobj){
var x = [parseFloat(jsonobj.startx),parseFloat(jsonobj.starty)];
openlayers基础入门到实战平铺图层。对于提供预呈现、平铺的网格图像的层源,这些网格按特定分辨率的缩放级别组织。图像图层。服务器呈现的映像,可用于任意范围和分辨率。(3)ol.layer.Vector()很常用矢量图层。矢量平铺图层。图层用于客户端呈现矢量平铺数据。
为了提升人机交互的体验,OpenLayers提供了一系列的地图动画效果,它们主要由ol.animation类提供,动画效果可以单独使用,也可以组合使用,下面开始介绍。
2、主要类和参数
在ol.animation中,最常用到的四个类如下所示,它们分别对应平移、弹跳、旋转、缩放。
ol.animation.pan
ol.animation.bounce
ol.animation.rotate
ol.animation.zoom
要创建一个动画效果的步骤如下所示:
// 第一步:获取当前视图