为地图添加动画图标

一、代码

css部分

页面主题内外边距设置为零,map容器使用绝对定位,width 100占满页面。

body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }

body部分

 <div id='map'></div>

js部分

1、创建一个pulsingDot对象,后续将作为map.addImage的第二个参数。

对象参数:width,height,data(绘图数据,由context.getImageData()获得),context(canvas对象,用于绘图)。

对象方法:

        onAdd():调用一次,负责创建一个canvas对象(context)给pulsingDot。

        render():在mapbox中被循环调用,根据t参数的不同,每次调用生成的绘图数据(data)也不同。返回true,通知mapbox image被更新。

var pulsingDot = {
    // pulsingDot对象属性
    width: size,
    height: size,
    data: new Uint8Array(size * size * 4),
	
    // onAdd方法,在addImage中被调用一次,创建一个画布对象赋值给pilsingDot.context。
    onAdd: function() {
        var canvas = document.createElement('canvas');
        canvas.width = this.width;
        canvas.height = this.height;
        this.context = canvas.getContext('2d');
    },
    
    // reder方法,在addImage后被循环调用。
    render: function() {
        // t是函数变量,由于是通过当前事件生成的,每次调用时值均不同。
        var duration = 1000;
        var t = (performance.now() % duration) / duration;
		
        // 设置内圆半径,外圆半径,获取到初始化(onAdd)时创建的画布对象。
        var radius = size / 2 * 0.3;
        var outerRadius = size / 2 * 0.7 * t + radius;
        var context = this.context;
        
        // 使用t变量绘图,分外圆和内圆两部分
        // draw outer circle
        context.clearRect(0, 0, this.width, this.height);
        context.beginPath();
        context.arc(this.width / 2, this.height / 2, outerRadius, 0, Math.PI * 2);
        context.fillStyle = 'rgba(255, 200, 200,' + (1 - t) + ')';
        context.fill();

        // draw inner circle
        context.beginPath();
        context.arc(this.width / 2, this.height / 2, radius, 0, Math.PI * 2);
        context.fillStyle = 'rgba(255, 100, 100, 1)';
        context.strokeStyle = 'white';
        context.lineWidth = 2 + 4 * (1 - t);
        context.fill();
        context.stroke();
        
        // 绘制完毕后,将绘图数据通过getImageData获取,赋值给pulsingDot.data
        // update this image's data with data from the canvas
        this.data = context.getImageData(0, 0, this.width, this.height).data;
        
        // 使用该方法使地图重新绘制
        // keep the map repainting
        map.triggerRepaint();

        // return `true` to let the map know that the image was updated
        return true;
    }
};

2、主函数,将pulsingDot对象以image的形式加载到地图上。 

map.on('load', function () {
    // 将这个封装了绘制动图方法的对象pulsingDot传入,使用addImage方法加载到地图上。
    map.addImage('pulsing-dot', pulsingDot, { pixelRatio: 2 });
    // 将map渲染到地图上,使用image(pulsing-dot)和一个feature(Point)。
    map.addLayer({
        "id": "points",
        "type": "symbol",
        "source": {
            "type": "geojson",
            "data": {
                "type": "FeatureCollection",
                "features": [{
                    "type": "Feature",
                    "geometry": {
                        "type": "Point",
                        "coordinates": [0, 0]
                    }
                }]
            }
        },
        "layout": {
            "icon-image": "pulsing-dot"
        }
    });
});

二、学习总结

1、map.addLayer(layer,beforeId?)

向map中添加图层。

参数:

layer(必选) 需添加的样式图层,style规范中有详细解释。http://www.mapbox.cn/mapbox-gl-js/style-spec/#layers​​​​​​​b

beforeId(可选) 渲染在哪个图层之上。

在本案例中使用情况如下:

    map.addLayer({
		// 独一无二的Layer名字(必选)
        "id": "points",
		// one of "fill", "line", "symbol", "circle", "heatmap", "fill-extrusion", 
        "raster", "hillshade", "background"(必选)
		// fill: 带有可选的边框的填充多边形
		// circle: 一个填充的实心圆
		// symbol: 图标或文本
        "type": "symbol",
		// 源 定义该图层的描述信息 可在外部定义 使用id链接到这里 source Style规范见 
        // http://www.mapbox.cn/mapbox-gl-js/style-spec/#sources
        "source": {
			// 源的类型
            "type": "geojson",
			// 源的数据
            "data": {
                "type": "FeatureCollection",
                "features": [{
                    "type": "Feature",
                    "geometry": {
                        "type": "Point",
                        "coordinates": [0, 0]
                    }
                }]
            }
        },
		// 布局设计属性
        "layout": {
            "icon-image": "pulsing-dot"
        }
    });

2、map.addImage(id, image, option)

向map中添加image

参数:

id(必选) Image独一无二的名字

image(必选) 

image((HTMLImageElement | ImageBitmap | ImageData | {width: number, height: number, data: (Uint8Array | Uint8ClampedArray)} | StyleImageInterface))The image as an HTMLImageElement , ImageData , ImageBitmap or object with width , height , and data properties with the same format as ImageData .

options((Object | null))(default {})Options object.(可选)

本案例中,使用{width: number, height: number, data: (Uint8Array | Uint8ClampedArray)} | StyleImageInterface))},并且多了onAdd(),render()两个方法。

// 该对象由width,height,data(Uint8Array)构成
var pulsingDot = {
    width: size,
    height: size,
    data: new Uint8Array(size * size * 4),
	
    onAdd: function() {
        var canvas = document.createElement('canvas');
        canvas.width = this.width;
        canvas.height = this.height;
        this.context = canvas.getContext('2d');
    },

    render: function() {
        var duration = 1000;
        var t = (performance.now() % duration) / duration;
		
        var radius = size / 2 * 0.3;
        var outerRadius = size / 2 * 0.7 * t + radius;
        var context = this.context;

        // draw outer circle
        context.clearRect(0, 0, this.width, this.height);
        context.beginPath();
        context.arc(this.width / 2, this.height / 2, outerRadius, 0, Math.PI * 2);
        context.fillStyle = 'rgba(255, 200, 200,' + (1 - t) + ')';
        context.fill();

        // draw inner circle
        context.beginPath();
        context.arc(this.width / 2, this.height / 2, radius, 0, Math.PI * 2);
        context.fillStyle = 'rgba(255, 100, 100, 1)';
        context.strokeStyle = 'white';
        context.lineWidth = 2 + 4 * (1 - t);
        context.fill();
        context.stroke();

        // update this image's data with data from the canvas
        this.data = context.getImageData(0, 0, this.width, this.height).data;

        // keep the map repainting
        map.triggerRepaint();

        // return `true` to let the map know that the image was updated
        return true;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值