html5使用canvas的 bezierCurveTo()方法绘制地图轨迹曲线(三次贝塞尔曲线)

参考:Canvas基于百度地图绘制流动曲线_清山博客-CSDN博客_百度地图流向图

<!DOCTYPE html>
<html>
 
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <style type="text/css">
        .main {
            width: 1024px;
            margin: 10px auto;
            position: relative;
        }
        
        #stylelist {
            padding: 5px;
            border: 1px solid #e3e3e3;
        }
        
        #allmap {
            width: 1024px;
            height: 600px;
            overflow: hidden;
            font-family: "微软雅黑";
            border: 1px solid #9E9E9E;
            position: absolute;
            top: 0;
            left: 0;
        }
        
        #point,
        #line {
            width: 1024px;
            height: 600px;
            z-index: 100;
            background: transparent;
            position: absolute;
            top: 0;
            left: 0;
        }
    </style>
    <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=jLZE4wcUhQKyFaDOGhBFcare"></script>
    <title>地图展示</title>
</head>
 
<body>
    <div class="main">
        地图样式:
        <select id="stylelist" onchange="changeStyle()">
            <option value="normal">默认地图样式</option>
            <option value="light">清新蓝风格</option>
            <option value="dark">黑夜风格</option>
            <option value="redalert">红色警戒风格</option>
            <option value="googlelite">精简风格</option>
            <option value="grassgreen">自然绿风格</option>
            <option value="midnight" selected="selected">午夜蓝风格</option>
            <option value="pink">浪漫粉风格</option>
            <option value="darkgreen">青春绿风格</option>
            <option value="bluish">清新蓝绿风格</option>
            <option value="grayscale">高端灰风格</option>
            <option value="hardedge">强边界风格</option>
        </select> </div>
    <div class="main">
        <div id="allmap"></div>
        <canvas id="line" width="600" height="600"></canvas>
        <canvas id="point" width="600" height="600"></canvas>
    </div>
</body>
 
</html>
 
<script type="text/javascript">
    // 百度地图
    var map = new BMap.Map("allmap");
    map.centerAndZoom(new BMap.Point(104.077506, 30.655077), 9); //中心位置:成都
    map.addControl(new BMap.MapTypeControl({
        mapTypes: [
            BMAP_NORMAL_MAP,
            BMAP_HYBRID_MAP
        ]
    }));
    map.setCurrentCity("成都");
    map.enableScrollWheelZoom(false);
    var mapStyle = {
        features: ["road", "building", "water", "land"],
        style: "midnight",
    };
    map.setMapStyle(mapStyle);
 
    //地图样式切换
    function changeStyle() {
        var stylectl = document.getElementById("stylelist");
        var style = stylectl.options[stylectl.selectedIndex].value;
        var mapStyle = {
            features: ["road", "building", "water", "land"],
            style: style,
        };
        map.setMapStyle(mapStyle);
        switch (style) {
            case "normal":
            case "googlelite":
            case "pink":
                _linecolor = "#2196F3";
                _titlecolor = "#FF5722";
                break;
 
            case "midnight":
            case "redalert":
                _linecolor = "#ffda4a";
                _titlecolor = "#ff0";
                break;
            case "normal":
                _linecolor = "#2196F3";
                _titlecolor = "#FF5722";
                break;
            default:
                _linecolor = "#FF9800";
                break;
        }
        drawLine()
    }
</script>
<script type="text/javascript">
    var _linecolor = "#ffda4a";
    var _titlecolor = "#ff0";
    let _t = 0; //圆点滚动控制
 
    //曲线1:成都->南充
    var line1 = {
        //成都
        begin: {
            x: 514,
            y: 316
        },
        control1: {
            x: 646,
            y: 126
        },
        control2: {
            x: 846,
            y: 328
        },
        //南充
        end: {
            x: 958,
            y: 251
        },
    };
 
    //曲线2:内江->成都
    var line2 = {
        //内江
        begin: {
            x: 729,
            y: 567
        },
        //成都
        end: {
            x: 514,
            y: 316
        },
        control1: {
            x: 666,
            y: 333
        },
        control2: {
            x: 508,
            y: 528
        },
    };
 
    //曲线3:雅安->成都
    var line3 = {
        //雅安
        begin: {
            x: 289,
            y: 462
        },
        //成都
        end: {
            x: 514,
            y: 316
        },
        control1: {
            x: 391,
            y: 293
        },
        control2: {
            x: 389,
            y: 402
        },
    };
 
    //绘制曲线
    function drawLine() {
        let lineCanvas = document.getElementById("line");
        let ctx = lineCanvas.getContext("2d");
        lineCanvas.width = 1024;
        lineCanvas.height = 600;
        ctx.clearRect(0, 0, 1024, 600);
 
        //左下角文字
        ctx.beginPath();
        ctx.moveTo(0, 580);
        ctx.font = "18px bold 黑体";
        ctx.fillStyle = _titlecolor;
        ctx.fillText("流动人员人事档案转入转出示意图", 10, 30);
        ctx.stroke();
        ctx.closePath();
 
        //曲线1:成都->南充
        ctx.beginPath();
        ctx.moveTo(line1.begin.x, line1.begin.y);
        ctx.bezierCurveTo(line1.control1.x, line1.control1.y, line1.control2.x, line1.control2.y, line1.end.x, line1.end.y);
        ctx.strokeStyle = _linecolor; //2196F3
        ctx.lineWidth = 2;
        ctx.stroke();
        ctx.closePath();
 
        //曲线2:内江->成都
        ctx.beginPath();
        ctx.moveTo(line2.begin.x, line2.begin.y);
        ctx.bezierCurveTo(line2.control1.x, line2.control1.y, line2.control2.x, line2.control2.y, line2.end.x, line2.end.y);
        ctx.strokeStyle = _linecolor; //FF9800
        ctx.lineWidth = 2;
        ctx.stroke();
        ctx.closePath();
 
        //曲线3:雅安->成都
        ctx.beginPath();
        ctx.moveTo(line3.begin.x, line3.begin.y);
        ctx.bezierCurveTo(line3.control1.x, line3.control1.y, line3.control2.x, line3.control2.y, line3.end.x, line3.end.y);
        ctx.strokeStyle = _linecolor;
        ctx.lineWidth = 2;
        ctx.stroke();
        ctx.closePath();
    }
    drawLine();
 
    //绘制某一时刻的点
    function drawPoint(ctx, t, point1, text, textcolor) {
 
        //根据三次贝塞尔曲线的公式,获取某时刻t[0-1]的贝塞尔曲线上的点     
        let x = point1.begin.x * Math.pow((1 - _t), 3) + 3 * _t * point1.control1.x * Math.pow((1 - _t), 2) + 3 * point1.control2.x * Math.pow(_t, 2) * (1 - _t) + point1.end.x * Math.pow(_t, 3);
        let y = point1.begin.y * Math.pow((1 - _t), 3) + 3 * _t * point1.control1.y * Math.pow((1 - _t), 2) + 3 * point1.control2.y * Math.pow(_t, 2) * (1 - _t) + point1.end.y * Math.pow(_t, 3);
 
        //点移出曲线后,重新开始
        let max_x = point1.end.x > point1.begin.x ? point1.end.x : point1.begin.x;
        if (x > max_x) {
            _t = 0;
            x = point1.begin.x;
            y = point1.begin.y;
        }
 
        ctx.beginPath();
        //画小圆点
        ctx.moveTo(point1.begin.x, point1.begin.y);
        ctx.arc(x, y, 4, 0, 2 * Math.PI, false);
        ctx.fillStyle = "#e95b55";
        ctx.fill();
 
        //显示文字
        ctx.font = 'bold 12px Arial';
        ctx.textAlign = 'left';
        ctx.textBaseline = 'bottom';
        ctx.fillStyle = textcolor;
        ctx.fillText(text, x, y - 12);
        //显示当前坐标
        //ctx.fillText("x:" + parseInt(x), x, y - 24);
        //ctx.fillText("y:" + parseInt(y), x, y - 12);
        ctx.closePath();
    }
 
    //绘制某一时刻的点,连续绘制形成动图
    function drawOneMoment() {
        let pointCanvas = document.getElementById("point");
        let ctx = pointCanvas.getContext("2d");
        pointCanvas.width = 1024;
        pointCanvas.height = 600;
        //清除画布
        ctx.clearRect(0, 0, 1024, 600);
        //逐个绘点
        drawPoint(ctx, _t, line1, "转出1000", '#0c79d0') //成都->南充
        drawPoint(ctx, _t, line2, "转入600", "orangered") //内江->成都
        drawPoint(ctx, _t, line3, "转入400", "orangered") //雅安->成都 
        _t += 0.01;
    }
    setInterval(drawOneMoment, 60);
</script>

关于我的需求如下:

部分效果图(点击不同的地点对应显示不同的板块和路径):

 

 我的完整代码实现:

<!DOCTYPE html>
<html>

<head>
    <title></title>
    <script type="text/javascript" src="js/jquery-1.8.0.min.js"></script>
</head>
<style type="text/css">
    .father {
        position: relative;
        height: 1080px;
        width: 1920px;
        margin: auto;
        text-align: center;
        background: url(images/back.jpg) no-repeat;
    }
    
    .canvas {
        position: absolute;
        top: 0;
        left: 0;
        z-index: 1;
    }
    
    .yingyeting {
        width: 330px;
        height: 114px;
        position: absolute;
        left: 783px;
        top: 328px;
        z-index: -2;
    }
    
    .lvsechuxing {
        width: 168px;
        height: 71px;
        position: absolute;
        left: 1200px;
        top: 585px;
        z-index: -2;
    }
    
    .zonghenengyuan {
        width: 95px;
        height: 206px;
        position: absolute;
        left: 1255px;
        top: 376px;
        z-index: -2;
    }
    
    .shaungtan {
        width: 128px;
        height: 72px;
        position: absolute;
        left: 1058px;
        top: 225px;
        z-index: -2;
    }
    
    .zhihuijiadian {
        width: 342px;
        height: 92px;
        position: absolute;
        left: 719px;
        top: 211px;
        z-index: -2;
    }
    
    .youhuahuanjing {
        width: 131px;
        height: 131px;
        position: absolute;
        left: 553px;
        top: 345px;
        z-index: -2;
    }
    
    .xinxigongshi {
        width: 76px;
        height: 42px;
        position: absolute;
        left: 570px;
        top: 640px;
        z-index: -2;
    }
    
    .wangshangguowang {
        width: 133px;
        height: 74px;
        position: absolute;
        left: 661px;
        top: 614px;
        z-index: -2;
    }
    
    .bianmin {
        width: 58px;
        height: 71px;
        position: absolute;
        left: 793px;
        top: 583px;
        z-index: -2;
    }
    
    .vip {
        width: 158px;
        height: 192px;
        position: absolute;
        left: 1177px;
        top: 207px;
        z-index: -2;
    }
    
    .zizhufuwu {
        width: 92px;
        height: 144px;
        position: absolute;
        left: 534px;
        top: 480px;
        z-index: -2;
    }
    
    .canvas {
        width: 1223px;
        height: 758px;
        position: absolute;
        left: 334px;
        top: 0;
        z-index: 6;
    }
    
    .pointcanvas {
        width: 1223px;
        height: 758px;
        position: absolute;
        left: 334px;
        top: 0;
        z-index: -1;
    }
    
    .canvas_bgp {
        width: 1223px;
        height: 758px;
        position: absolute;
        left: 334px;
        top: 0;
        z-index: -1;
    }
    
    .bottom {
        position: absolute;
        bottom: 13px;
        width: 1920px;
        height: 198px;
        margin: 0 auto;
        z-index: 2;
    }
    
    .bottom ul {
        display: flex;
        width: 1714px;
        margin: auto;
    }
    
    .bottom ul li {
        list-style: none;
        flex: 1;
        width: 134px;
        margin-right: 24px;
        height: 128px;
        background: url(images/notcheck.png) no-repeat;
        color: #388AE7;
    }
    
    .notcheckli {
        list-style: none;
        flex: 1;
        width: 134px;
        margin-right: 24px;
        height: 128px;
        background: url(images/notcheck.png) no-repeat;
        color: #388AE7;
    }
    
    .checkli {
        list-style: none;
        flex: 1;
        width: 134px;
        margin-right: 24px;
        height: 128px;
        background: url(images/check.png) no-repeat !important;
        color: #D7FFFF !important;
    }
    
    .li1_font {
        width: 102px;
        height: 16px;
        font-size: 16px;
        font-family: Microsoft YaHei;
        font-weight: bold;
        line-height: 14px;
        margin-left: 17px;
        margin-top: 19px;
    }
    
    .li2_font {
        width: 68px;
        height: 16px;
        font-size: 16px;
        font-family: Microsoft YaHei;
        font-weight: bold;
        line-height: 14px;
        margin-left: 34px;
        margin-top: 18px;
    }
    
    .li3_font {
        width: 103px;
        height: 16px;
        font-size: 16px;
        font-family: Microsoft YaHei;
        font-weight: bold;
        line-height: 14px;
        margin-left: 13px;
        margin-top: 18px;
    }
    
    .li4_font {
        width: 100px;
        height: 34px;
        font-size: 16px;
        font-family: Microsoft YaHei;
        font-weight: bold;
        line-height: 16px;
        margin-left: 16px;
        margin-top: 16px;
    }
    
    .li5_font {
        width: 102px;
        height: 16px;
        font-size: 16px;
        font-family: Microsoft YaHei;
        font-weight: bold;
        line-height: 14px;
        margin-left: 16px;
        margin-top: 18px;
    }
    
    .li6_font {
        width: 102px;
        height: 16px;
        font-size: 16px;
        font-family: Microsoft YaHei;
        font-weight: bold;
        line-height: 14px;
        margin-left: 16px;
        margin-top: 15px;
    }
    
    .li7_font {
        width: 68px;
        height: 16px;
        font-size: 16px;
        font-family: Microsoft YaHei;
        font-weight: bold;
        line-height: 14px;
        margin-left: 34px;
        margin-top: 18px;
    }
    
    .li8_font {
        width: 112px;
        height: 16px;
        font-size: 16px;
        font-family: Microsoft YaHei;
        font-weight: bold;
        line-height: 14px;
        margin-left: 11px;
        margin-top: 22px;
    }
    
    .li9_font {
        width: 85px;
        height: 16px;
        font-size: 16px;
        font-family: Microsoft YaHei;
        font-weight: bold;
        line-height: 14px;
        margin-left: 25px;
        margin-top: 20px;
    }
    
    .li10_font {
        width: 85px;
        height: 16px;
        font-size: 16px;
        font-family: Microsoft YaHei;
        font-weight: bold;
        line-height: 14px;
        margin-left: 22px;
        margin-top: 25px;
    }
    
    .li11_font {
        width: 112px;
        height: 16px;
        font-size: 16px;
        font-family: Microsoft YaHei;
        font-weight: bold;
        line-height: 14px;
        margin-left: 11px;
        margin-top: 20px;
    }
    
    .startPonit {
        width: 26px;
        height: 26px;
        position: absolute;
        left: 1060px;
        top: 543px;
        z-index: -2;
    }
    
    .endPonit {
        width: 26px;
        height: 26px;
        position: absolute;
        left: 928px;
        top: 403px;
        z-index: -2;
    }
    
    .rightTitle {
        width: 144px;
        height: 17px;
        margin-top: 30px;
        margin-left: 22px;
        text-align: left;
        font-size: 16px;
        font-family: Microsoft YaHei;
        font-weight: bold;
        color: #28F7FF;
        line-height: 10px;
    }
    
    .rightText {
        width: 295px;
        height: 105px;
        margin-left: 22px;
        margin-top: 10px;
        text-align: left;
        font-size: 13px;
        font-family: Microsoft YaHei;
        font-weight: bold;
        color: #FFFFFF;
        line-height: 18px;
    }
</style>

<body>
    <div align="center" class="father">
        <!-- 路径图 -->
        <canvas class="canvas" id="canvas"></canvas>
        <!-- 点运动轨迹 -->
        <canvas class="pointcanvas" id="point"></canvas>
        <!-- 置灰的导航图片 -->
        <img src="images/back_grey.png" class="canvas_bgp" id="back_grey_img">
        <!-- 精确版块图片 -->
        <img src="images/yingyeting.png" class="yingyeting" id="yingyeting_1">
        <img src="images/lvsechuxing.png" class="lvsechuxing" id="lvsechuxing_2">
        <img src="images/zonghenengyuan.png" class="zonghenengyuan" id="zonghenengyuan_3">
        <img src="images/shaungtan.png" class="shaungtan" id="shaungtan_4">
        <img src="images/zhihuijiadian.png" class="zhihuijiadian" id="zhihuijiadian_5">
        <img src="images/youhuahuanjing.png" class="youhuahuanjing" id="youhuahuanjing_6">
        <img src="images/xinxigongshi.png" class="xinxigongshi" id="xinxigongshi_7">
        <img src="images/wangshangguowang.png" class="wangshangguowang" id="wangshangguowang_8">
        <img src="images/bianmin.png" class="bianmin" id="bianmin_9">
        <img src="images/vip.png" class="vip" id="vip_10">
        <img src="images/zizhufuwu.png" class="zizhufuwu" id="zizhufuwu_11">

        <!-- 起点图标 -->
        <img src="images/startPoint.png" class="startPonit" id="startPoint">
        <span id="startPText" style="position: absolute;width: 80px;height: 30px;color: #00FDE8;z-index: -2;left: 985px;top: 545px;font-weight: bold;">当前位置</span>

        <!-- 终点图标 -->
        <img src="images/endPoint.png" class="endPonit" id="endPoint">

        <!-- 文字详情说明 -->
        <div id="right" style="position: absolute;width: 353px;height: 203px;top: 367px;left: 1530px;background: url(images/kuang.png) no-repeat;display: none;">
            <div id="rightTitle" class="rightTitle"></div>
            <div id="rightText" class="rightText"></div>
        </div>

        <!-- 底部菜单 -->
        <div class="bottom">
            <ul id="parent">
                <li>
                    <div style="width:48px;height:45px;margin-top:28px;margin-left:43px;background: url(images/1.png) no-repeat;">
                    </div>
                    <div class="li1_font">
                        营业厅数据屏
                    </div>
                </li>
                <li>
                    <div style="width:61px;height:48px;margin-top:28px;margin-left:37px;background: url(images/2.png) no-repeat;">
                    </div>
                    <div class="li2_font">
                        绿色出行
                    </div>
                </li>
                <li>
                    <div style="width:55px;height:46px;margin-top:28px;margin-left:39px;background: url(images/3.png) no-repeat;">
                    </div>
                    <div class="li3_font">
                        综合能源展示
                    </div>
                </li>
                <li>
                    <div style="width:56px;height:40px;margin-top:28px;margin-left:40px;background: url(images/4.png) no-repeat;">
                    </div>
                    <div class="li4_font">
                        “双碳”能源 展示区
                    </div>
                </li>
                <li>
                    <div style="width:51px;height:48px;margin-top:28px;margin-left:44px;background: url(images/5.png) no-repeat;">
                    </div>
                    <div class="li5_font">
                        智慧家电体验
                    </div>
                </li>
                <li>
                    <div style="width:50px;height:52px;margin-top:28px;margin-left:43px;background: url(images/6.png) no-repeat;">
                    </div>
                    <div class="li6_font">
                        优化营商环境
                    </div>
                </li>
                <li>
                    <div style="width:42px;height:49px;margin-top:28px;margin-left:46px;background: url(images/7.png) no-repeat;">
                    </div>
                    <div class="li7_font">
                        信息公示
                    </div>
                </li>
                <li>
                    <div style="width:52px;height:43px;margin-top:28px;margin-left:43px;background: url(images/8.png) no-repeat;">
                    </div>
                    <div class="li8_font">
                        网上国网体验区
                    </div>
                </li>
                <li>
                    <div style="width:42px;height:44px;margin-top:28px;margin-left:46px;background: url(images/9.png) no-repeat;">
                    </div>
                    <div class="li9_font">
                        便民服务区
                    </div>
                </li>
                <li>
                    <div style="width:40px;height:38px;margin-top:28px;margin-left:53px;background: url(images/10.png) no-repeat;">
                    </div>
                    <div class="li10_font">
                        VIP休息室
                    </div>
                </li>
                <li>
                    <div style="width:34px;height:45px;margin-top:28px;margin-left:51px;background: url(images/11.png) no-repeat;">
                    </div>
                    <div class="li11_font">
                        自助业务服务区
                    </div>
                </li>
            </ul>
        </div>
    </div>

    <script>
        let _t = 0; //圆点滚动控制
        var timer1, timer2, timer3, timer4; //定时器

        //定时返回主界面
        var countTimer = 60;
        var outTime = 60; //秒
        var count = 1; //计数

        //小球动画结束标志
        let endFlag1 = 1; //运动高度小于结束点高度
        let endFlag2 = 2; //运动高度大于结束点高度

        //营业厅数据屏
        var line1 = {
            begin: {
                x: 731,
                y: 551
            },
            control1: {
                x: 652,
                y: 510
            },
            control2: {
                x: 618,
                y: 502
            },
            end: {
                x: 610,
                y: 440
            },
        };

        //绿色出行
        var line2 = {
            begin: {
                x: 731,
                y: 551
            },
            control1: {
                x: 784,
                y: 470
            },
            control2: {
                x: 898,
                y: 493
            },
            end: {
                x: 921,
                y: 585
            },
        };
        //综合能源展示
        var line3 = {
            begin: {
                x: 731,
                y: 551
            },
            control1: {
                x: 781,
                y: 472
            },
            control2: {
                x: 858,
                y: 474
            },
            end: {
                x: 920,
                y: 465
            },
        };
        //双碳能源展示
        var line4 = {
            begin: {
                x: 731,
                y: 551
            },
            control1: {
                x: 840,
                y: 460
            },
            control2: {
                x: 839,
                y: 330
            },
            end: {
                x: 785,
                y: 295
            },
        };
        //智慧家电
        var line5 = {
            begin: {
                x: 731,
                y: 551
            },
            control1: {
                x: 310,
                y: 610
            },
            control2: {
                x: 380,
                y: 400
            },
            end: {
                x: 480,
                y: 302
            },
        };
        //优化营商环境
        var line6 = {
            begin: {
                x: 731,
                y: 551
            },
            control1: {
                x: 562,
                y: 460
            },
            control2: {
                x: 430,
                y: 465
            },
            end: {
                x: 345,
                y: 430
            },
        };
        //信息公示
        var line7 = {
            begin: {
                x: 731,
                y: 551
            },
            control1: {
                x: 554,
                y: 509
            },
            control2: {
                x: 326,
                y: 570
            },
            end: {
                x: 275,
                y: 640
            },
        };

        //网上国网体验区
        var line8 = {
            begin: {
                x: 731,
                y: 551
            },
            control1: {
                x: 595,
                y: 510
            },
            control2: {
                x: 420,
                y: 540
            },
            end: {
                x: 395,
                y: 615
            },
        };

        //便民服务区
        var line9 = {
            begin: {
                x: 731,
                y: 551
            },
            control1: {
                x: 595,
                y: 500
            },
            control2: {
                x: 510,
                y: 540
            },
            end: {
                x: 488,
                y: 585
            },
        };

        //VIP
        var line10 = {
            begin: {
                x: 731,
                y: 551
            },
            control1: {
                x: 795,
                y: 450
            },
            control2: {
                x: 790,
                y: 355
            },
            end: {
                x: 841,
                y: 313
            },
        };
        //自助服务
        var line11 = {
            begin: {
                x: 731,
                y: 551
            },
            control1: {
                x: 595,
                y: 510
            },
            control2: {
                x: 455,
                y: 545
            },
            end: {
                x: 290,
                y: 565
            },
        };

        var text1 = "向客户展示营业网点信息、抢修网点信息、停电信息公告、电网可开放容量、最新电价,用电政策等常规信息,还向来访者展现厅内数据分析,收集营业厅内的人流量、设备工作状态、温/湿度等数据。"
        var text2 = "过场景化的模型设计营造虚拟驾驶环境,用户在虚拟驾驶中可了解电动汽车的优势性能,以及充电桩办理服务流程。";
        var text3 = "展示内容包括多能互补+源网荷储、综合能源的发展历程,建设成果等、展示并介绍新型综合能源产品及解决方案。通过显示屏+演示沙盘互动展示的形式,为客户提供风力发电、光伏发电等方面的参考方案。";
        var text4 = "展示碳达峰/碳中和概念介绍、政策解读、新能源建设及并网情况、科普宣传片(碳达峰、碳中和人民生活的关系,生活中的节能知识)。";
        var text5 = "采用“家庭实物场景”+“展示体验”的展现形式, 构造家庭场景,进行智能家电的展示。用户可通过触摸屏控制墙上的指示灯,更好的体验智能家居给生活带来的便利。";
        var text6 = "通过多媒体图文的形式来进行讲解优化营商环境的必要性和相应的政策指导。始终坚持“以客户为中心”,围绕办电服务流程,展示相应的工作成效。";
        var text7 = "滚动播放如:停电信息公示、电价公示、营业人员与服务流程介绍、规章制度、“十项承诺”、“三不指定”等原本通过大面积展板展示的内容。";
        var text8 = "以互动体验的形式,让客户了解国网公司推出的线上产品,引导客户体验和下载相应的APP。";
        var text9 = "放置纸质表格或宣传册供客户使用/观看,配备有智能雨伞、便民药箱、宣传资料架、饮水机等。";
        var text10 = "根据客户业务需求配置相对应的客户经理等人员,针对客户需求进行一对一的服务,有效的进行业务解答和办理,快速响应客户所有用电需求。";
        var text11 = "提供全业务的自助办理,客户缴费保修传统业务,同时提供支持现金、二维码扫码付费业务。";
        var showText = "";


        /**************************监听鼠标60s没有发生动作的话则恢复成初始状态*************************************/
        setInterval(function() {
            console.log(countTimer)
            countTimer--;
            if (countTimer == 0) {
                console.log("执行初始化操作")
                setStartStatus();
            }
        }, 1000);

        var x_start;
        var y_start;
        //监听鼠标
        document.onmousemove = function(event) {
            var x1 = event.clientX;
            var y1 = event.clientY;
            if (x_start != x1 || y_start != y1) {
                countTimer = outTime;
            }
            x_start = x1;
            y_start = y1;
        };


        //回到初始状态
        function setStartStatus() {
            _t = 0;
            count = 1;
            clearInterval(timer1);
            clearTimeout(timer2);
            clearInterval(timer3);
            clearTimeout(timer4);
            //图片置灰显示
            $("#back_grey_img").css("z-index", -3);

            // 清除红点 否则下一次切换回此选项红点会闪过再从起点开始
            let pointCanvas = document.getElementById("point");
            let ctx = pointCanvas.getContext("2d");
            pointCanvas.width = 1223;
            pointCanvas.height = 758;
            ctx.clearRect(0, 0, 1223, 758);
            ctx.beginPath();
            let lineCanvas = document.getElementById("canvas");
            let ctx2 = lineCanvas.getContext("2d");
            lineCanvas.width = 1223;
            lineCanvas.height = 758;
            ctx2.clearRect(0, 0, 1223, 758);
            ctx2.beginPath();
            $("#point").css("z-index", -2);

            $("#startPoint").css("z-index", -2);
            $("#startPText").css("z-index", -2);
            $("#endPoint").css("z-index", -2);

            $("#yingyeting_1").css("z-index", -2);
            $("#lvsechuxing_2").css("z-index", -2);
            $("#zonghenengyuan_3").css("z-index", -2);
            $("#shaungtan_4").css("z-index", -2);
            $("#zhihuijiadian_5").css("z-index", -2);
            $("#youhuahuanjing_6").css("z-index", -2);
            $("#xinxigongshi_7").css("z-index", -2);
            $("#wangshangguowang_8").css("z-index", -2);
            $("#bianmin_9").css("z-index", -2);
            $("#vip_10").css("z-index", -2);
            $("#zizhufuwu_11").css("z-index", -2);

            $("#right").css("display", "none");

            const list = document.getElementById("parent").children;
            for (let i = 0; i < list.length; i++) {
                const element = list[i];
                element.children[1].style.color = '#388AE7';
                element.setAttribute('class', 'notcheckli');
            }
        }
        /******************************************************************************************************/

        // 点击事件
        $("ul li").click(function() {
            _t = 0;
            count = 1;
            clearInterval(timer1);
            clearTimeout(timer2);
            clearInterval(timer3);
            clearTimeout(timer4);
            $("#right").css("display", "none");
            // 清除红点 否则下一次切换回此选项红点会闪过再从起点开始
            let pointCanvas = document.getElementById("point");
            let ctx = pointCanvas.getContext("2d");
            pointCanvas.width = 1223;
            pointCanvas.height = 758;
            ctx.clearRect(0, 0, 1223, 758);
            ctx.beginPath();

            //type样式切换
            const list = document.getElementById("parent").children;
            for (let i = 0; i < list.length; i++) {
                const element = list[i];
                element.children[1].style.color = '#388AE7';
                element.setAttribute('class', $(this).index() == i ? 'checkli' : 'notcheckli')
            }
            $(this).find("div").eq(1).css('color', '#D7FFFF')

            //图片置灰显示
            $("#back_grey_img").css("z-index", 3);

            //起点图标展示
            $("#startPoint").css("z-index", 5);
            $("#startPText").css("z-index", 5);


            $("#yingyeting_1").css("z-index", -2);
            $("#lvsechuxing_2").css("z-index", -2);
            $("#zonghenengyuan_3").css("z-index", -2);
            $("#shaungtan_4").css("z-index", -2);
            $("#zhihuijiadian_5").css("z-index", -2);
            $("#youhuahuanjing_6").css("z-index", -2);
            $("#xinxigongshi_7").css("z-index", -2);
            $("#wangshangguowang_8").css("z-index", -2);
            $("#bianmin_9").css("z-index", -2);
            $("#vip_10").css("z-index", -2);
            $("#zizhufuwu_11").css("z-index", -2);

            $("#point").css("z-index", -2);
            setTimeout(function() {
                $("#right").fadeIn();
            }, 250)

            //精确版块图片展示、轨迹图显示、终点显示、运动轨迹展示
            if ($(this).index() == 0) { //营业厅
                $("#yingyeting_1").css("z-index", 5);
                $("#rightTitle").text("营业厅数据大屏");
                drawLine(line1); /*  */
                $("#endPoint").css("left", 928);
                $("#endPoint").css("top", 403);
                $("#endPoint").css("z-index", 11);
                $("#point").css("z-index", 6);
                timer1 = setInterval('drawOneMoment(line1,endFlag1)', 100);

                //文字逐个显示
                oneByOne(text1);
                //版块持续闪动2次
                var divId = $("#yingyeting_1");
                timer3 = setInterval(function() {
                    show(divId)
                }, 400);
                // timer4 = setTimeout(function() {
                //     clearInterval(timer3);
                // }, 1601);
            } else if ($(this).index() == 1) { //绿色出行
                $("#lvsechuxing_2").css("z-index", 5);
                $("#rightTitle").text("绿色出行");
                drawLine(line2);
                $("#endPoint").css("left", 1270);
                $("#endPoint").css("top", 605);
                $("#endPoint").css("z-index", 11);
                $("#point").css("z-index", 6);
                timer1 = setInterval('drawOneMoment(line2,endFlag2)', 100);
                oneByOne(text2);
                //持续闪动2次
                var divId = $("#lvsechuxing_2");
                timer3 = setInterval(function() {
                    show(divId)
                }, 400);
                // timer4 = setTimeout(function() {
                //     clearInterval(timer3);
                // }, 1601);
            } else if ($(this).index() == 2) { //综合能源展示
                $("#zonghenengyuan_3").css("z-index", 5);
                $("#rightTitle").text("综合能源展示");
                drawLine(line3);
                $("#endPoint").css("left", 1255);
                $("#endPoint").css("top", 445);
                $("#endPoint").css("z-index", 11);
                $("#point").css("z-index", 6);
                timer1 = setInterval('drawOneMoment(line3,endFlag1)', 100);
                oneByOne(text3);
                //持续闪动2次
                var divId = $("#zonghenengyuan_3");
                timer3 = setInterval(function() {
                    show(divId)
                }, 400);
                // timer4 = setTimeout(function() {
                //     clearInterval(timer3);
                // }, 1601);
            } else if ($(this).index() == 3) { //双碳能源展示
                $("#shaungtan_4").css("z-index", 5);
                $("#rightTitle").text("“双碳”能源展示区");
                drawLine(line4);
                $("#endPoint").css("left", 1105);
                $("#endPoint").css("top", 270);
                $("#endPoint").css("z-index", 11);
                $("#point").css("z-index", 6);
                timer1 = setInterval('drawOneMoment(line4,endFlag1)', 100);
                oneByOne(text4);
                //持续闪动2次
                var divId = $("#shaungtan_4");
                timer3 = setInterval(function() {
                    show(divId)
                }, 400);
                // timer4 = setTimeout(function() {
                //     clearInterval(timer3);
                // }, 1601);
            } else if ($(this).index() == 4) { //智慧家电体验
                $("#zhihuijiadian_5").css("z-index", 5);
                $("#rightTitle").text("智慧家电体验");
                drawLine(line5);
                $("#endPoint").css("left", 848);
                $("#endPoint").css("top", 275);
                $("#endPoint").css("z-index", 11);
                $("#point").css("z-index", 6);
                timer1 = setInterval('drawOneMoment(line5,endFlag1)', 100);
                oneByOne(text5);
                //持续闪动2次
                var divId = $("#zhihuijiadian_5");
                timer3 = setInterval(function() {
                    show(divId)
                }, 400);
                // timer4 = setTimeout(function() {
                //     clearInterval(timer3);
                // }, 1601);
            } else if ($(this).index() == 5) { //优化营商环境
                $("#youhuahuanjing_6").css("z-index", 5);
                $("#rightTitle").text("优化营商环境");
                drawLine(line6);
                $("#endPoint").css("left", 640);
                $("#endPoint").css("top", 410);
                $("#endPoint").css("z-index", 11);
                $("#point").css("z-index", 6);
                timer1 = setInterval('drawOneMoment(line6,endFlag1)', 100);
                oneByOne(text6);
                //持续闪动2次
                var divId = $("#youhuahuanjing_6");
                timer3 = setInterval(function() {
                    show(divId)
                }, 400);
                // timer4 = setTimeout(function() {
                //     clearInterval(timer3);
                // }, 1601);
            } else if ($(this).index() == 6) { //信息公示
                $("#xinxigongshi_7").css("z-index", 5);
                $("#rightTitle").text("信息公示");
                drawLine(line7);
                $("#endPoint").css("left", 595);
                $("#endPoint").css("top", 645);
                $("#endPoint").css("z-index", 11);
                $("#point").css("z-index", 6);
                timer1 = setInterval('drawOneMoment(line7,endFlag2)', 100);
                oneByOne(text7);
                //持续闪动2次
                var divId = $("#xinxigongshi_7");
                timer3 = setInterval(function() {
                    show(divId)
                }, 400);
                // timer4 = setTimeout(function() {
                //     clearInterval(timer3);
                // }, 1601);
            } else if ($(this).index() == 7) { //网上国网体验区
                $("#wangshangguowang_8").css("z-index", 5);
                $("#rightTitle").text("网上国网体验区");
                drawLine(line8);
                $("#endPoint").css("left", 710);
                $("#endPoint").css("top", 630);
                $("#endPoint").css("z-index", 11);
                $("#point").css("z-index", 6);
                timer1 = setInterval('drawOneMoment(line8,endFlag2)', 100);
                oneByOne(text8);
                //持续闪动2次
                var divId = $("#wangshangguowang_8");
                timer3 = setInterval(function() {
                    show(divId)
                }, 400);
                // timer4 = setTimeout(function() {
                //     clearInterval(timer3);
                // }, 1601);
            } else if ($(this).index() == 8) { //便民服务区 bianmin
                $("#bianmin_9").css("z-index", 5);
                $("#rightTitle").text("便民服务区");
                drawLine(line9);
                $("#endPoint").css("left", 810);
                $("#endPoint").css("top", 584);
                $("#endPoint").css("z-index", 11);
                $("#point").css("z-index", 6);
                timer1 = setInterval('drawOneMoment(line9,endFlag2)', 100);
                oneByOne(text9);
                //持续闪动2次
                var divId = $("#bianmin_9");
                timer3 = setInterval(function() {
                    show(divId)
                }, 400);
                // timer4 = setTimeout(function() {
                //     clearInterval(timer3);
                // }, 1601);
            } else if ($(this).index() == 9) { //VIP
                $("#vip_10").css("z-index", 5);
                $("#rightTitle").text("VIP休息室");
                drawLine(line10);
                $("#endPoint").css("left", 1200);
                $("#endPoint").css("top", 315);
                $("#endPoint").css("z-index", 11);
                $("#point").css("z-index", 6);
                timer1 = setInterval('drawOneMoment(line10,endFlag1)', 100);
                oneByOne(text10);
                //持续闪动2次
                var divId = $("#vip_10");
                timer3 = setInterval(function() {
                    show(divId)
                }, 400);
                // timer4 = setTimeout(function() {
                //     clearInterval(timer3);
                // }, 1601);
            } else if ($(this).index() == 10) { //自助业务服务区
                $("#zizhufuwu_11").css("z-index", 5);
                $("#rightTitle").text("自助业务服务区");
                drawLine(line11);
                $("#endPoint").css("left", 595);
                $("#endPoint").css("top", 550);
                $("#endPoint").css("z-index", 11);
                $("#point").css("z-index", 6);
                timer1 = setInterval('drawOneMoment(line11,endFlag2)', 100);
                oneByOne(text11);
                //持续闪动2次
                var divId = $("#zizhufuwu_11");
                timer3 = setInterval(function() {
                    show(divId)
                }, 400);
                // timer4 = setTimeout(function() {
                //     clearInterval(timer3);
                // }, 1601);
            }
        });


        //图片闪烁
        function show(imgid) {
            // if (imgid.style.visibility == "visible")
            //     imgid.style.visibility = "hidden";
            // else
            //     imgid.style.visibility = "visible";
            if (imgid.css('z-index') == -2)
                imgid.css("z-index", 5);
            else
                imgid.css("z-index", -2);
        }

        // 文字逐个显示
        function oneByOne(paper) {
            showText = paper;
            var screen = paper.substr(0, count);
            $("#rightText").html(screen)
            count++;
            if (count > paper.length) {
                return;
            } else {
                timer2 = setTimeout('oneByOne(showText)', 80);
            }
        }

        //绘制某一时刻的点
        function drawPoint(ctx, t, point1, text, textcolor, endFlag) {

            //根据三次贝塞尔曲线的公式,获取某时刻t[0-1]的贝塞尔曲线上的点     
            let x = point1.begin.x * Math.pow((1 - t), 3) + 3 * t * point1.control1.x * Math.pow((1 - t), 2) + 3 * point1
                .control2.x * Math.pow(t, 2) * (1 - t) + point1.end.x * Math.pow(t, 3);
            let y = point1.begin.y * Math.pow((1 - t), 3) + 3 * t * point1.control1.y * Math.pow((1 - t), 2) + 3 * point1
                .control2.y * Math.pow(t, 2) * (1 - t) + point1.end.y * Math.pow(t, 3);

            //点移出曲线后,重新开始
            if (endFlag === endFlag1) {
                let min_y = point1.end.y < point1.begin.y ? point1.end.y : point1.begin.y;
                if (y < min_y) {
                    _t = 0;

                    x = point1.begin.x;
                    y = point1.begin.y;
                }
            } else if (endFlag === endFlag2) {
                let min_y = point1.end.y > point1.begin.y ? point1.end.y : point1.begin.y;
                if (y > min_y) {
                    _t = 0;

                    x = point1.begin.x;
                    y = point1.begin.y;
                }
            }


            ctx.beginPath();
            //画小圆点
            ctx.moveTo(point1.begin.x, point1.begin.y);
            ctx.arc(x, y, 5, 0, 2 * Math.PI, false);
            ctx.fillStyle = "#e95b55";
            ctx.fill();

            //显示文字
            ctx.font = 'bold 12px Arial';
            ctx.textAlign = 'left';
            ctx.textBaseline = 'bottom';
            ctx.fillStyle = textcolor;
            ctx.fillText(text, x, y - 12);
            ctx.closePath();
        }


        //绘制某一时刻的点,连续绘制形成动图
        function drawOneMoment(line, endFlag) {
            let pointCanvas = document.getElementById("point");
            let ctx = pointCanvas.getContext("2d");
            pointCanvas.width = 1223;
            pointCanvas.height = 758;
            //清除画布
            ctx.clearRect(0, 0, 1223, 758);
            //逐个绘点
            drawPoint(ctx, _t, line, "", '#0c79d0', endFlag)
            _t += 0.01;
        }

        //绘制曲线
        function drawLine(line) {
            let lineCanvas = document.getElementById("canvas");
            let ctx = lineCanvas.getContext("2d");
            lineCanvas.width = 1223;
            lineCanvas.height = 758;
            ctx.clearRect(0, 0, 1223, 758);

            ctx.beginPath();
            ctx.moveTo(line.begin.x, line.begin.y);
            ctx.bezierCurveTo(line.control1.x, line.control1.y, line.control2.x, line.control2.y, line.end.x, line.end.y);
            ctx.strokeStyle = "#00FDE8"; //YELLOW
            ctx.lineWidth = 2;
            ctx.stroke();
            ctx.closePath();
        }
    </script>
</body>

</html>

说明   图中  line1-line11  的坐标都是以canvas画布的左上角(0,0)开始计算的坐标,往下 y越大,往右 x越大

补充:

根据三次贝塞尔曲线的公式,获取某时刻t[0-1]的贝塞尔曲线上的点    

计算机图形学:二次和三次贝塞尔曲线(通过Pymatplotlib绘制)_星空_MAX的博客-CSDN博客_三次贝塞尔

 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值