openlayers聚合效果效果下,渲染自定义样式,动态展示

openlayers聚合效果效果下,渲染自定义样式,动态展示

先上效果

openlayers 聚合自定义渲染加动作效果

这个动态效果想过很久,本来只是一个静态的,但是甲方爸爸不满意,那就得做动态,这个是最终的效果。首先openlayer官网上我没有找见我需要的相关的动态效果方法,我这里首先是一个聚合效果,然后聚合点中需要加入一个动态效果。
如何实现聚合效果openlayers官网上也有,那我就不多说了,然后是一个点渲染效果,在这里依旧参考openlayers官网上的效果用canvas渲染。

canvas渲染代码

style =	new Style({
	renderer(coordinates, state) {
		const ctx = state.context;
		const gradientOutside = ctx.createRadialGradient(coordinates[0], coordinates[1], radius * 0.6 , coordinates[0], coordinates[1], radius * 1 );
		gradientOutside.addColorStop(0, 'rgba(255, 255, 255, 0.5)');
		gradientOutside.addColorStop(0.6, 'rgba(255, 255, 255, 0.3)');
		gradientOutside.addColorStop(0.7, 'rgba(255, 255, 255, 0.2)');
		gradientOutside.addColorStop(0.9, "rgba(255, 255, 255, 0.1)");
		gradientOutside.addColorStop(1, "rgba(255, 255, 255, 0)");

		//绘制放射性渐变圆
		ctx.beginPath();// 创建一个新路径方法
		ctx.arc(coordinates[0], coordinates[1], radius * 1, 0, 2 * Math.PI, true); // 圆圈路径
		ctx.fillStyle = gradientOutside; // 描述颜色
		ctx.fill();// 填充当前样式

		ctx.globalCompositeOperation = 'source-over';

		const gradientInside = ctx.createRadialGradient(coordinates[0], coordinates[1], radius * 0.6 , coordinates[0], coordinates[1], radius * 0.8 );
		gradientInside.addColorStop(0, 'rgba(36, 137, 201, 0.6)');
		gradientInside.addColorStop(1, "rgba(36, 137, 201, 0.6)");

		//绘制放射性渐变圆
		ctx.beginPath();// 创建一个新路径方法
		ctx.arc(coordinates[0], coordinates[1], radius * 0.8, 0, 2 * Math.PI, true); // 圆圈路径
		ctx.fillStyle = gradientInside; // 描述颜色
		ctx.fill();// 填充当前样式

		ctx.globalCompositeOperation = 'source-over';

		const gradient = ctx.createRadialGradient(coordinates[0], coordinates[1], radius * 0.5 , coordinates[0], coordinates[1], radius * 0.7 );
		gradient.addColorStop(0, 'rgba(44, 138, 202, 0.3)');
		gradient.addColorStop(0.3, 'rgba(44, 138, 202, 0.3)');
		gradient.addColorStop(0.5, 'rgba(44, 138, 202, 0.5)');
		gradient.addColorStop(0.7, "rgba(44, 138, 202, 0.7)");
		gradient.addColorStop(1, "rgba(44, 138, 202, 1)");

		//绘制放射性渐变圆
		ctx.beginPath();// 创建一个新路径方法
		ctx.arc(coordinates[0], coordinates[1], radius * 0.7, 0, 2 * Math.PI, true); // 圆圈路径
		ctx.fillStyle = gradient; // 描述颜色
		ctx.fill();// 填充当前样式

		ctx.globalCompositeOperation = 'source-over';
		
		if ( radius > 29 ) {
			ctx.beginPath();
			ctx.font = font;
			ctx.fillStyle = '#fff'
			ctx.fillText(size, coordinates[0] - (radius/2.2) , coordinates[1]+ (radius/4.5) );
		} else if ( radius > 19 ) {
			ctx.beginPath();
			ctx.font = font;
			ctx.fillStyle = '#fff'
			ctx.fillText(size, coordinates[0] - (radius/1.8) , coordinates[1]+ (radius/3.5) );
		}	else {
			ctx.beginPath();
			ctx.font = font;
			ctx.fillStyle = '#fff'
			ctx.fillText(size, coordinates[0] - (radius/2.7) , coordinates[1]+ (radius/2.3) );
		}
	},
})

动作效果

动作效果我想了很久,首先还是查看mdn文档,mdn上的例子大概是要用requestAnimationFrame () 方法,实际上方法是对的,但是我这里因为渲染聚合点,所以有多个返回的style,如果要调用渲染方法的话势必会造成无限递归,虽然渲染点位的增多,程序就卡死的越快,而且无法消除之前的递归事件,之后我在openlayer官网找到例子使用layer.on(‘postrender’, animate);方法做动态效果,一次渲染所有点,保证只有一个递归函数存在在页面中,减少浏览器性能消耗。

function animate (event) {
	i += 0.015
	let cos = Math.abs(Math.cos(i))
	let vectorContext = getVectorContext(event);
	let features = event.target.getSource().getFeatures();

	features.map( ( item ) => {	

		if ( item.values_.features.length === 1 ) {
			return;
		}

		let style = new Style({
			image: new CircleStyle({
				radius: item.get('radius') * ( 0.8 + 0.3 * cos ),
				stroke: new Stroke({
					color: `rgba(255, 255, 255, ${ 1 - cos } )`,
					width:  1 + cos  ,
				}),
			}),
			zIndex: 700
		})
		vectorContext.setStyle( style );
		vectorContext.drawGeometry( item.getGeometry() );	
	});

	map.render();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值