RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 760615
Accepted
HamSter
HamSter
Asked:2020-12-20 01:00:04 +0000 UTC2020-12-20 01:00:04 +0000 UTC 2020-12-20 01:00:04 +0000 UTC

滚动时沿 svg 路径的对象移动

  • 772

有这个代码:

$(window).on('load resize', function() {
    initContainer();
});

$(window).scroll(function(){
    setMotionPath();
});

function initContainer() {
    var element = $('.svg');
    var motionPath = MorphSVGPlugin.pathDataToBezier("#way").reverse();
    TweenLite.set("#circle", { transformOrigin: "50% 50%" });    

    setMotionPath();    
};

function setMotionPath() {
    var element = $('.svg');
    var motionPath = MorphSVGPlugin.pathDataToBezier("#way").reverse();

     TweenLite.to("#circle", 0, {
            x: motionPath["x"],
            y: motionPath["y"]
        });
};
#circle {
  transform-origin: 0px 0px 0px;
}

html,
body {
  height: 200%;
  width: 100%;
  margin: 0;
  padding: 0;
}

svg {
  width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenMax.min.js"></script>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/MorphSVGPlugin.min.js"></script>



<svg class="svg" viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg">
  <path id="way" stroke="#000" stroke-dasharray="4,2" stroke-width="1" d="M 100,10 L 100,30 L 100,50 L 100,70 L 100,90 L 100,110 L 100,130 L 100,150 L 100,170 L 100,190 L 100,210 L 100,230 L 100,250 L 100,270 L 100,290 L 100,310"></path>

  <circle cx="100" cy="30" r="20" stroke="black" stroke-width="1" fill="orange" id="circle"/>
</svg>

代码笔

问题:如何让圆path在滚动时沿路径平滑移动(最好使用 TweenMax)?

PS:路径path可以任意,以直线为例,可以这样:

在此处输入图像描述

 <path id="pPath"
         d="m782.19032,61.21567c-5.10542,4.08434 -38.80117,92.91857 -108.23481,123.55105c-69.43365,30.63249 -187.87928,-10.21082 -178.68954,-76.58122c9.18974,-66.37041 135.80405,-60.24388 138.86731,8.16868c3.06326,68.41254 -36.759,102.1083 -107.21373,120.48779c-70.45474,18.37948 -128.9788,10.90961 -163.64275,0.48347c-34.66395,-10.42613 -110.54388,-54.17155 -159.01952,-99.52852"
          stroke-dasharray="5 2"
          stroke-width="2"
          stroke="#000"
          fill="transparent"/>
jquery
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Raz Galstyan
    2020-12-23T15:14:39Z2020-12-23T15:14:39Z

    这是更新的答案。这正是你想要的。

    我将尝试大致解释它是什么以及它是如何工作的。

    motionPath是一个包含直线坐标的数组,但它包含的不是逐个像素的所有坐标。并将线分成几段,为每段选择坐标(中心)。当您TweenLite.to通过该方法设置一对坐标时,动画到达并停止。但是如果你每次滚动都尝试给新的坐标,那么动画就不会流畅,因为当你没有完成路径的第一部分就滚动时,圆圈已经接收到新的坐标并跟随它们(离开线)。

    还有第二种选择。我们立即为该方法提供一个坐标数组,TweenLite.to并将动画标识符存储在一个变量tween = TweenLite.to........中。之后,我们就可以操作动画了(例如,暂停)。还有更重要的一点,tween它已经有了一个方法progress(),它的值可以从0到1。如果我们设置了一个中间进度,那么动画就会返回到它。

    我们就是这样做的,设置每个滚动的进度,并立即暂停动画。

    这是我们的预期结果。

    $(window).on('load resize', function() {
        initContainer();
    });
    
    $(window).scroll(function(){
        setMotionPath();
    });
    
    function initContainer() {
        var element = $('.svg');
        var motionPath = MorphSVGPlugin.pathDataToBezier("#way",{align:"#circle"}).reverse();
        TweenLite.set("#circle", {xPercent:-50, yPercent:-50});		
        setMotionPath();    
    };
    
    function setMotionPath() {
        var element = $('.svg');
        var way = $('#way');
        var motionPath = MorphSVGPlugin.pathDataToBezier("#way",{align:"#circle"}).reverse();
        var progress_val = $(window).scrollTop()/5000;
        tween = TweenLite.to("#circle", 3, {bezier:{values:motionPath, type:"cubic"}});
        tween.progress( progress_val ).pause();
    };
    #circle {
      transform-origin: 0px 0px 0px;
    }
    
    html,
    body {
      height: 400%;
      width: 100%;
      margin: 0;
      padding: 0;
    }
    
    svg {
      position: fixed;
      width: 100%;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenMax.min.js"></script>
    <script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/MorphSVGPlugin.min.js"></script>
    
    <svg class="svg" viewBox="0 0 900 900" xmlns="http://www.w3.org/2000/svg">
      <path id="way"
             d="m782.19032,61.21567c-5.10542,4.08434 -38.80117,92.91857 -108.23481,123.55105c-69.43365,30.63249 -187.87928,-10.21082 -178.68954,-76.58122c9.18974,-66.37041 135.80405,-60.24388 138.86731,8.16868c3.06326,68.41254 -36.759,102.1083 -107.21373,120.48779c-70.45474,18.37948 -128.9788,10.90961 -163.64275,0.48347c-34.66395,-10.42613 -110.54388,-54.17155 -159.01952,-99.52852"
              stroke-dasharray="5 2"
              stroke-width="2"
              stroke="#000"
              fill="transparent"/>
    
      <circle cx="100" cy="30" r="20" stroke="black" stroke-width="1" fill="orange" id="circle"/>
    </svg>

    对于一条直线。

    这里不需要reverse坐标。这个插件有很多选择。你可以亲眼看到这一切。

    $(window).on('load resize', function() {
        initContainer();
    });
    
    $(window).scroll(function(){
        setMotionPath();
    });
    
    function initContainer() {
        var element = $('.svg');
        var motionPath = MorphSVGPlugin.pathDataToBezier("#way",{align:"#circle"}).reverse();
        TweenLite.set("#circle", {xPercent:-50, yPercent:-50});		
        setMotionPath();    
    };
    
    function setMotionPath() {
        var element = $('.svg');
        var way = $('#way');
        var motionPath = MorphSVGPlugin.pathDataToBezier("#way",{align:"#circle"});
        var progress_val = $(window).scrollTop()/1000;
        tween = TweenLite.to("#circle", 3, {bezier:{values:motionPath, type:"cubic"}});
        tween.progress( progress_val ).pause();
    };
    #circle {
      transform-origin: 0px 0px 0px;
    }
    
    html,
    body {
      height: 400%;
      width: 100%;
      margin: 0;
      padding: 0;
    }
    
    svg {
      position: fixed;
      width: 100%;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenMax.min.js"></script>
    <script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/MorphSVGPlugin.min.js"></script>
    
    <svg class="svg" viewBox="0 0 900 900" xmlns="http://www.w3.org/2000/svg">
      <path id="way" stroke="#000" stroke-dasharray="4,2" stroke-width="1" d="M 100,10 L 100,30 L 100,50 L 100,70 L 100,90 L 100,110 L 100,130 L 100,150 L 100,170 L 100,190 L 100,210 L 100,230 L 100,250 L 100,270 L 100,290 L 100,310"></path>
      <circle cx="100" cy="30" r="20" stroke="black" stroke-width="1" fill="orange" id="circle"/>
    </svg>

    • 8

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    Python 3.6 - 安装 MySQL (Windows)

    • 1 个回答
  • Marko Smith

    C++ 编写程序“计算单个岛屿”。填充一个二维数组 12x12 0 和 1

    • 2 个回答
  • Marko Smith

    返回指针的函数

    • 1 个回答
  • Marko Smith

    我使用 django 管理面板添加图像,但它没有显示

    • 1 个回答
  • Marko Smith

    这些条目是什么意思,它们的完整等效项是什么样的

    • 2 个回答
  • Marko Smith

    浏览器仍然缓存文件数据

    • 1 个回答
  • Marko Smith

    在 Excel VBA 中激活工作表的问题

    • 3 个回答
  • Marko Smith

    为什么内置类型中包含复数而小数不包含?

    • 2 个回答
  • Marko Smith

    获得唯一途径

    • 3 个回答
  • Marko Smith

    告诉我一个像幻灯片一样创建滚动的库

    • 1 个回答
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Алексей Шиманский 如何以及通过什么方式来查找 Javascript 代码中的错误? 2020-08-03 00:21:37 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5