mapbox/minemap 动态扩散/水纹效果

官网上的demo使用div来做的,但当数据量变大后,地图移动会特别卡。因此需要用canvas来绘制。

非地图模式下,此段代码可以直接运行,

最终版本:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>添加圆形扩散效果标注</title>
    <link rel="stylesheet" href="//minedata.cn/minemapapi/v2.0.0/minemap.css">
    <script src="//minedata.cn/minemapapi/v2.0.0/minemap.js"></script>
    <style>
        html, body, #map {
            width: 100%;
            height: 100%;
        }

        html, body {
            margin: 0;
            padding: 0;
        }


    </style>
</head>
<body>
<div id="map">
</div>
<script>

    minemap.domainUrl = '//minedata.cn';
    minemap.dataDomainUrl = '//datahive.minedata.cn';
    minemap.spriteUrl = '//minedata.cn/minemapapi/v2.0.0/sprite/sprite';
    minemap.serviceUrl = '//minedata.cn/service';
    minemap.accessToken = '25cc55a69ea7422182d00d6b7c0ffa93';
    minemap.solution = 2365;
    var map = new minemap.Map({
        container: 'map',
        style: "//minedata.cn/service/solu/style/id/2365",
        center: [116.46,39.92],
        zoom: 12,

    });

    let canvasContainer = map._canvasContainer,

     mapboxCanvas = map._canvas,
         canvasOverlay = document.createElement("canvas");
    console.log(canvasContainer)
    canvasOverlay.style.position = "absolute";
    canvasOverlay.className = "overlay-canvas";
    canvasOverlay.width = parseInt(mapboxCanvas.style.width);
    canvasOverlay.height = parseInt(mapboxCanvas.style.height);
    canvasContainer.appendChild(canvasOverlay);

    var context = canvasOverlay.getContext("2d");

    var radius=10
    var zb2=[116.46,39.92]
    var zb=[]
    for(var i=0;i<100;i++){

        zb.push([zb2[0]+i*0.01,zb2[1]+i*0.01])
    }

    var reqAniID;
    function drawCircle(){

        zb.map(v => {
            context.beginPath()
            p=map.project([v[0], v[1]]);
            context.arc(parseInt(p.x),parseInt(p.y),radius,0,Math.PI * 2);
            context.stroke();
        })

        let prev = context.globalCompositeOperation;   //只显示canvas上原图像的重叠部分<br>
        context.globalCompositeOperation = 'destination-in';//设置主canvas的绘制透明度,圆圈中间的浅黄色部分<br>
        context.globalAlpha = 0.95;  //这一步目的是将canvas上的图像变的透明<br>
        context.fillRect(0,0,1920,900);  //在原图像上重叠新图像<br>
        context.globalCompositeOperation = prev; //下面代用的drawcricle方法,圆圈覆盖在正方形上
        context.closePath();
        context.lineWidth=2;
        context.strokeStyle='rgba(250,0,0,1)';
        context.stroke();
        radius +=0.3;//每帧半径增加0.
        if(radius>15){
            radius=5
        }

        reqAniID= requestAnimationFrame(drawCircle)
    }
    drawCircle()

    map.on('moveend', () => {

        canvasOverlay.height = parseInt(mapboxCanvas.style.height);
       // reqAniID= requestAnimationFrame(drawCircle)

    })
    map.on('move', () => {
      // cancelAnimationFrame(reqAniID)

        canvasOverlay.height = parseInt(mapboxCanvas.style.height);


    })





</script>
</body>

。。。。。

 

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>圆形扩散</title>
    <style>
        body {
            overflow: hidden;
            background: #000;
        }
        body,
        html {
            height: 100%;
            width: 100%;
            margin: 0;
            padding: 0;
        }
    </style>
</head>
<body>
<canvas id="canvas"></canvas>
</body>
<script type="text/javascript">
    var oAnim=document.getElementById('canvas');
    var context = oAnim.getContext("2d");
    var radius=10
    var zb=[[50,50],[100,100],[150,70]]
    var count=-1
    function drawCircle(){
        count+=1
        if(count<3){
        context.beginPath();
        render(radius);
        context.arc(zb[count][0],zb[count][1],radius,0,Math.PI * 2);
        context.closePath();
        context.lineWidth=2;
        context.strokeStyle='rgba(250,250,50,1)';
        context.stroke();
        radius +=0.5;//每帧半径增加0.5
        if(radius > 30){
            radius=10;
        }
        }
        else{
            count=-1
        }
        requestAnimationFrame(drawCircle)
    }
    function render(x) {
        let prev = context.globalCompositeOperation;   //只显示canvas上原图像的重叠部分<br>
        context.globalCompositeOperation = 'destination-in';//设置主canvas的绘制透明度,圆圈中间的浅黄色部分<br>
        context.globalAlpha = 0.95;  //这一步目的是将canvas上的图像变的透明<br>
        context.fillRect(0,0,40*x,40*x);  //在原图像上重叠新图像<br>
        context.globalCompositeOperation = prev; //下面代用的drawcricle方法,圆圈覆盖在正方形上
    };

    //在主canvas上画新圆
    drawCircle()


</script>
</html>

但是在地图上,以同样的绘图逻辑来处理,会出现问题,留待后面解决,另一种易理解的实现逻辑

!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>圆形扩散</title>
    <style>
        body {
            overflow: hidden;
            background: #000;
        }
        body,
        html {
            height: 100%;
            width: 100%;
            margin: 0;
            padding: 0;<
        }
    </style>
</head>
<body>
<canvas id="canvas"></canvas>
</body>
<script type="text/javascript">
    var oAnim=document.getElementById('canvas');
    var context = oAnim.getContext("2d");
    var radius=10
    var zb=[[50,50],[100,100],[150,70]]
    var count=-1

    function drawCircle(){
        count+=1
        if(count<3){
        context.beginPath();
        context.arc(zb[count][0],zb[count][1],radius,0,Math.PI * 2);
        context.closePath();
        context.lineWidth=2;
        context.strokeStyle='rgba(250,250,50,1)';
        context.stroke();
        radius +=0.3;//每帧半径增加0.
         if(radius > 30) {
             //当圆圈扩大到最大时,恢复画布到最初的状态
             radius = 10;
             context.clearRect(0,0,300,150);
         }
        }
        else{
            count=-1
        }
        requestAnimationFrame(drawCircle)
    }


    //在主canvas上画新圆
    drawCircle()


</script>
</html>
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值