RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1273414
Accepted
Sevastopol'
Sevastopol'
Asked:2022-04-22 19:32:31 +0000 UTC2022-04-22 19:32:31 +0000 UTC 2022-04-22 19:32:31 +0000 UTC

在特定块的范围内绘制具有页面滚动绑定的 SVG 元素

  • 772

基于问题:使用绑定到页面滚动绘制 SVG 元素

我有以下 SVG 元素,其绘制动画是通过滚动文档的整个页面来触发的:

let p = document.getElementById('path');
let pl = p.getTotalLength();
p.style.strokeDasharray = pl; p.style.strokeDashoffset = pl; 
$(window).on('scroll',function(){
  let scrollTo = $(window).scrollTop() /
  (document.documentElement.scrollHeight - document.documentElement.clientHeight);
  draw = pl * scrollTo;
  p.style.strokeDashoffset = pl - draw;
})
body {margin: 0;}

.header, .footer {height: 150vh; background: chocolate;}

.parallax {height: 5000px; background: gold;}

#svg {
  position: fixed;
  top: 10px;
  left: 10px;
}

path {
  fill: none;
  stroke: black;
  stroke-width: 1px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="header"></div>

<div class="parallax">
<!--котейка-->
<svg id="svg" width="500px" height="200px" viewBox="150 0 1 150">

<path id="path" d="M154.5,2.4c0,0,5.5,8.6,2.9,17.5l-1.1-3.4c0,0,0.1,21.1-8.6,26.2l0-4.3c0,0-7.5,22.9-26.8,13.8  C117.2,39.6,110,30.6,99.1,26c-3.8-2.1-8.3-3.2-13.6-3.2c-4.1-0.3-8.4-0.3-13.2,0.3c-22.5,2.6-41.6,20.1-39.4,52  c0.1,0.8,0.2,1.9,0.3,3c-1.5,0.6-3,1.2-4.5,2l-9-10.4l-4.6,16.6L1,87.5l7.8,9.2l-6.3,0.4c0,0,6.4,10.8,10.5,14.2  c11,8.9,21.8,11.5,31.7,10.7c1.5,4.1,3,7.8,4.5,10.8c-3.6-3.6-4.9,2.6-2.3,5.2c1-0.3,1.6,0,2.6-1c1.3,3.3,3.3,2,3.9-0.6  c5.5,6.3,4.6-9.1-0.3-3.6c-1.1-4-1.9-7.9-2.5-11.8c1.4-0.3,2.8-0.7,4.1-1.1c1.4,4.4,2.9,8.5,4.4,11.8c-1.8,0.2-2.1,4.3-0.1,6.3  c1-0.3,1.6,0,2.6-1c1.3,3.3,3.3,2,3.9-0.6c5.5,6.3,4.6-9.1-0.3-3.6l-2,0c-1.2-5.2-2.1-10.3-2.8-15.1c17.9-8,30.1-24.3,30.1-24.3  l-7.4-0.5l10.1-7L75,82.9l0.5-16l-13.9,9.9c2-6.7,5.1-11.4,9.1-13.6c4.5-1.6,9.4-1.4,14.6,1.1c2.9,1.6,5.9,3.9,9.1,7.1  c14.5,17.9,0.4,52-3.9,61.5l0,0c-3.6-3.6-4.9,2.6-2.3,5.2c1-0.3,1.6,0,2.6-1c1.3,3.3,3.3,2,3.9-0.6c5.4,6.2,4.6-8.6-0.1-3.8  c4.6-6.4,9.1-12.8,13.2-19.2c-1.1,6.2-2.9,12.3-5.6,17.9c-3-2-3.9,3.5-1.5,5.9c1-0.3,1.6,0,2.6-1c1.3,3.3,3.3,2,3.9-0.6  c5.5,6.3,4.6-9.1-0.3-3.6l-0.2,0c2.8-6.3,10-23.9,13-42.3c3.5-10,4.9-20.1,3-30.5c5,3.3,12.8,5.4,23.9,0l-3.6-0.7  c0,0,18.4-1.7,22-16.2l-3,2.1C161.9,44.4,176.7,20.6,154.5,2.4z"/>

<!--глазки-->
<path d="M40.5,107.1c0,0-1.9-8.5-8.4-13.3c-0.4-2.5-1-4.1-1.7-4.1c-0.5,0-1,0.9-1.3,2.3c-1.7-0.8-3.6-1.3-5.8-1.4  c0,0-5.7,6.1-1.3,12.4c1.6,2.3,4.4,3.4,7.3,4c0.3,0.9,0.7,1.4,1.1,1.4c0.3,0,0.7-0.4,0.9-1.1C36,107.8,40.5,107.1,40.5,107.1z"/>
<path d="M68.1,86.2c-2.4,0.4-4.4,1.3-6.1,2.4c-0.7-1.4-1.5-2.2-2-2c-0.6,0.2-0.8,1.8-0.6,4.1 c-5.9,5.6-7.2,14.3-7.2,14.3s6,0.3,11.3-1.4c0.5,0.8,1,1.2,1.4,1.1c0.4-0.1,0.6-0.8,0.7-1.9c1.9-0.9,3.6-2.2,4.6-3.9 C73.8,92,68.1,86.2,68.1,86.2z"/>

</svg>
</div>

<div class="footer"></div>

问题:如何启动绑定到页面滚动但在块范围内的 SVG 元素的绘制动画.parallax?当块.parallax的顶部接触浏览器窗口的顶部时,元素绘制动画应该开始。当块.parallax的底部接触浏览器窗口的底部时,动画应该结束。

有兴趣通过问题标签中指示的任何方式和技术详细描述此类实现和实现本身。

javascript
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Alexander Lonberg
    2022-04-23T00:13:15Z2022-04-23T00:13:15Z

    而不是htmlElement.scrollTop像在另一个问题中那样,parallax.getBoundingClientRect()在指定的视口范围内使用。

    const htmlElem = document.querySelector('html')
    const parallax = document.querySelector('.parallax')
    const path = document.querySelector('#path')
    const pathLength = path.getTotalLength()
    path.style.strokeDasharray = pathLength
    path.style.strokeDashoffset = pathLength
    
    function rangeCalculator(begin, end, beginRange = 0, endRange = 100) {
      const inputRange = end - begin
      const outRange = endRange - beginRange
      return (current) => (
        beginRange + (outRange / (inputRange / (current - begin)))
      )
    }
    
    const calculate = (() => {
      let calc
      const remake = () => calc = rangeCalculator(0, parallax.getBoundingClientRect().height - htmlElem.clientHeight, 0, pathLength)
      window.addEventListener('resize', remake)
      remake()
      return () => {
        const { top, bottom } = parallax.getBoundingClientRect()
    
        // ... когда parallax не достиг верха, это всегда 0
        if (top >= 0) {
          return 0
        }
        // ... а когда коснется низа, это всегда pathLength
        if (bottom <= htmlElem.clientHeight) {
          return pathLength
        }
        // инвертируем знак, так как у нас parallax.top отрицательный, когда он выше границы
        return calc(-top)
      }
    })()
    
    document.addEventListener("scroll", () => {
      path.style.strokeDashoffset = pathLength - calculate()
    })
    body {
      margin: 0;
    }
    
    .header,
    .footer {
      height: 150vh;
      background: chocolate;
    }
    
    .parallax {
      height: 5000px;
      background: gold;
    }
    
    #svg {
      position: fixed;
      top: 10px;
      left: 10px;
    }
    
    path {
      fill: none;
      stroke: black;
      stroke-width: 1px;
    }
    <div class="header"></div>
    
    <div class="parallax">
      <!--котейка-->
      <svg id="svg" width="500px" height="200px" viewBox="150 0 1 150">
    
          <path id="path"
            d="M154.5,2.4c0,0,5.5,8.6,2.9,17.5l-1.1-3.4c0,0,0.1,21.1-8.6,26.2l0-4.3c0,0-7.5,22.9-26.8,13.8  C117.2,39.6,110,30.6,99.1,26c-3.8-2.1-8.3-3.2-13.6-3.2c-4.1-0.3-8.4-0.3-13.2,0.3c-22.5,2.6-41.6,20.1-39.4,52  c0.1,0.8,0.2,1.9,0.3,3c-1.5,0.6-3,1.2-4.5,2l-9-10.4l-4.6,16.6L1,87.5l7.8,9.2l-6.3,0.4c0,0,6.4,10.8,10.5,14.2  c11,8.9,21.8,11.5,31.7,10.7c1.5,4.1,3,7.8,4.5,10.8c-3.6-3.6-4.9,2.6-2.3,5.2c1-0.3,1.6,0,2.6-1c1.3,3.3,3.3,2,3.9-0.6  c5.5,6.3,4.6-9.1-0.3-3.6c-1.1-4-1.9-7.9-2.5-11.8c1.4-0.3,2.8-0.7,4.1-1.1c1.4,4.4,2.9,8.5,4.4,11.8c-1.8,0.2-2.1,4.3-0.1,6.3  c1-0.3,1.6,0,2.6-1c1.3,3.3,3.3,2,3.9-0.6c5.5,6.3,4.6-9.1-0.3-3.6l-2,0c-1.2-5.2-2.1-10.3-2.8-15.1c17.9-8,30.1-24.3,30.1-24.3  l-7.4-0.5l10.1-7L75,82.9l0.5-16l-13.9,9.9c2-6.7,5.1-11.4,9.1-13.6c4.5-1.6,9.4-1.4,14.6,1.1c2.9,1.6,5.9,3.9,9.1,7.1  c14.5,17.9,0.4,52-3.9,61.5l0,0c-3.6-3.6-4.9,2.6-2.3,5.2c1-0.3,1.6,0,2.6-1c1.3,3.3,3.3,2,3.9-0.6c5.4,6.2,4.6-8.6-0.1-3.8  c4.6-6.4,9.1-12.8,13.2-19.2c-1.1,6.2-2.9,12.3-5.6,17.9c-3-2-3.9,3.5-1.5,5.9c1-0.3,1.6,0,2.6-1c1.3,3.3,3.3,2,3.9-0.6  c5.5,6.3,4.6-9.1-0.3-3.6l-0.2,0c2.8-6.3,10-23.9,13-42.3c3.5-10,4.9-20.1,3-30.5c5,3.3,12.8,5.4,23.9,0l-3.6-0.7  c0,0,18.4-1.7,22-16.2l-3,2.1C161.9,44.4,176.7,20.6,154.5,2.4z" />
    
          <!--глазки-->
          <path
            d="M40.5,107.1c0,0-1.9-8.5-8.4-13.3c-0.4-2.5-1-4.1-1.7-4.1c-0.5,0-1,0.9-1.3,2.3c-1.7-0.8-3.6-1.3-5.8-1.4  c0,0-5.7,6.1-1.3,12.4c1.6,2.3,4.4,3.4,7.3,4c0.3,0.9,0.7,1.4,1.1,1.4c0.3,0,0.7-0.4,0.9-1.1C36,107.8,40.5,107.1,40.5,107.1z" />
          <path
            d="M68.1,86.2c-2.4,0.4-4.4,1.3-6.1,2.4c-0.7-1.4-1.5-2.2-2-2c-0.6,0.2-0.8,1.8-0.6,4.1 c-5.9,5.6-7.2,14.3-7.2,14.3s6,0.3,11.3-1.4c0.5,0.8,1,1.2,1.4,1.1c0.4-0.1,0.6-0.8,0.7-1.9c1.9-0.9,3.6-2.2,4.6-3.9 C73.8,92,68.1,86.2,68.1,86.2z" />
    
        </svg>
    </div>
    
    <div class="footer"></div>

    • 2

相关问题

  • 第二个 Instagram 按钮的 CSS 属性

  • 由于模糊,内容不可见

  • 弹出队列。消息显示不正确

  • 是否可以在 for 循环中插入提示?

  • 如何将 JSON 请求中的信息输出到数据表 Vuetify vue.js?

Sidebar

Stats

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

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +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
    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