zoukankan      html  css  js  c++  java
  • d3操作svg路径动画,及dom移动

    图片跟随路径循环运动,dom也跟着路径运动(利用实时获取坐标位置的方法,改变transform)

    1,准备路径

      a,自己脑补路径

      b,在ps上画好,然后在保存成png-24图片,背景透明,在网站https://www.vectorizer.io/上生成path路径

    2,以下是完整代码及注释

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        #con {
            width: 500px;
            height: 500px;
            background: #146257;
            position: relative;
        }
    </style>
    </head>
    <body>
        <div id="con">
            <svg id="svg"></svg>
        </div>
    </body>
    <script src="../libs/d3.js"></script>
    <script src="../libs/jquery.js"></script>
    <script>
        var con = $('#con');//dom容器
        var svg = d3.selectAll('#svg')//d3操作的svg对象和jq对象不一样
                            .attr('width','500')//d3操作的对象px属性都不能带单位
                            .attr('height','500')
                            .attr("display","inline-block")
                            .attr('viewBox','0 0 5000 5000');//通过png-svg转换的把实际坐标放大了10倍
                      svg.append('path')//插入路径
                            .attr("id","motionPath")
                            .attr("stroke","rgba(0,0,0,1)")
                            .attr("fill","none")
                            .attr("stroke-miterlimit","10")
                            .attr("d","M1240 2976 l-245 -22 -155 -72 c-85 -41 -160 -79 -167 -85 -27 -28 -223 -632 -223 -687 0 -13 30 -138 66 -279 64 -248 68 -260 142 -399 83 -158 72 -146 281 -292 148 -102 301 -177                                              841 -413 l285 -124 165 -26 c91 -15 215 -29 275 -32 61 -4 229 -25 375 -47 170 -25 318 -42 411 -45 143 -5 148 -5 255 26 89 27 164 62 413 194 274 146 311 169 381 234 74 70 77 74                                           103 162 15 49 27 99 27 111 0 12 -21 94 -47 183 l-48 161 -126 136 -126 135 -329 49 c-312 46 -508 64 -736 65 l-78 1 -118 143 c-106 127 -128 160 -207 315 l-88 173 -176 167 -177                                              167 -305 63 c-204 42 -324 62 -364 61 -33 -1 -170 -11 -305 -23z");
    
                      svg.append('image')//插入图片
                           .attr("id","img")
                           .attr("xlink:href",'../imgs/2.png')
                           .attr("x","-130")
                           .attr("y","-390")
                           .attr("width","260")
                           .attr("height","390");
    
                     svg.append('animateMotion')//插入动画图片运动动画
                          .attr("id","animimg")
                          .attr("xlink:href","#img")
                          .attr("dur","100s")
                          .attr("begin","0s")
                          .attr("fill","freeze")
                          .attr("cy","0")
                          .attr("repeatCount","indefinite");
                d3.selectAll($("#animimg")).append('mpath')//让上面的动画关联运动路径
                                .attr("xlink:href","#motionPath"); 
                creatDom();//创建提示dom
                move1({//让提示dom跟着路径运动
                          id: '#motionPath',//路径id
                          class:'.con1'//dom的class
                            });
                 function move1(obj){
                     var path = $(obj.id)[0];//获取路径dom对象
                     var tol = path.getTotalLength();//获取路径总长
                     var start = path.getPointAtLength(0);//获取路径上开始点的坐标
                     var time = 1000;//
                     var interval = time /10;//运动帧数 运动帧数 * time为运动总时间
                     var i = 0;
                     var per = tol / time;
                     var ttn = +new Date();
                     var then = +new Date(),now,delta;
                    function move(){
                               requestAnimationFrame(move);//循环调用move函数 调用间隔取决于浏览器绘制时间
                               now = Date.now();
                          delta = now - then;
                                if (delta > interval) {//当时间间隔大于运动帧数的时候调用绘制动画函数
                           then = now - (delta % interval);//更新时间
                           draw();
                              }
                     }
                     var x = start.x/10 + 30 + 'px';
                     var y = start.y/10 - 50 + 'px';
                     $(obj.class).css({
                                transform: 'translate(' + x + ',' + y+')'
                      });
                      move();
                      function draw(){
                              i++;
                              start = path.getPointAtLength(i*per);
                              x = start.x/10 + 30 + 'px';
                              y = start.y/10 - 50 + 'px';
                             $(obj.class).css({
                                       transform: 'translate(' + x + ',' + y+')'
                             });
                             i === time && (i = 0);
                    }
                 }
                 function creatDom(){
    
                          var dom1 = $('<div class="con1"><div class="cartips1"></div></div>').css({
                                                               194,
                                                               height: 95,
                                                               boxShadow: '1px 0px 5px #ddb16a,0px 1px 5px #ddb16a,-1px 0px 5px #ddb16a,0px -1px 5px #ddb16a',
                                                               position:'absolute',
                                                               left: 0,
                                                               top: 0
                                                               });
                         con.append(dom1);
                         var p1 = '<p>状态: 道路拥堵<br>信息: 预计拥堵10分钟<br>拥堵长度: 2公里<br>时间: <span class="settipsTime1"></span></p>';
                         var $p1 = $(p1).css({
                                 color: '#ffffff',
                                 fontSize: 14,
                                 paddingLeft: 12,
                                 paddingTop: -5,
                                 textAlign: 'left'
                            });
                         $('.cartips1').append($p1);
                         $('.settipsTime1').text(getTime());
                          function getTime(){
                                   var data = new Date(),
                                    year = data.getFullYear(),
                                    mon = data.getMonth() + 1,
                                    day = data.getDate(),
                                    hour = data.getHours(),
                                    minu = data.getMinutes();
                                    mon < 10 && (mon = '0' + mon);
                                    day < 10 && (day = '0' + day);
                                    hour < 10 && (hour = '0' + hour);
                                    minu < 10 && (minu = '0' + minu);
                                    return year + '-' + mon + '-' + day + ' ' + hour + ":" + minu;
                                  }
                     }
    </script>
    </html>
  • 相关阅读:
    AcWing 1027. 方格取数 dp
    AcWing 1014. 登山 dp
    acwing 482. 合唱队形 dp
    LeetCode 1463. 摘樱桃II dp
    LeetCode 100. 相同的树 树的遍历
    LeetCode 336. 回文对 哈希
    LeetCode 815. 公交路线 最短路 哈希
    算法问题实战策略 DARPA大挑战 二分
    算法问题实战策略 LUNCHBOX 贪心
    AcWing 1100. 抓住那头牛 BFS
  • 原文地址:https://www.cnblogs.com/smedas/p/12603891.html
Copyright © 2011-2022 走看看