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>
  • 相关阅读:
    AVCODEC_MAX_AUDIO_FRAME_SIZE 未定义标识符
    ffmpeg -使用总结
    ubuntu 编译安装ffmpeg
    转-查看Linux CPU个数,核心,线程数
    fpga是什么
    div自适应水平垂直居中的方法
    css百分比问题——`top`、`left`、'translate'的百分比参照谁?
    经典面试题:二分查找/折半查找
    JavaScript预解析
    React--组件
  • 原文地址:https://www.cnblogs.com/smedas/p/12603891.html
Copyright © 2011-2022 走看看