如何在输入视口时启动动画SVG? [英] How to start an animated SVG on entering viewport?

查看:120
本文介绍了如何在输入视口时启动动画SVG?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要你们的帮助。我无法找到解决问题的好方法。我在我的网站上有一些动画SVG的部分。我为此使用了vivus.js。 https://maxwellito.github.io/vivus-instant/
问题是当用户在带有动画SVG的部分上滚动时,我无法找到启动动画的解决方案。

解决方案

要在SVG滚动到视图时触发动画,需要解决两个步骤:


  1. 检测SVG何时可见

  2. 最初暂停动画,然后在需要时触发



检测元素何时可见



您需要为滚动事件添加事件处理程序。在该事件处理程序中,您将页面滚动位置( window.scrollY )与页面上SVG的位置进行比较。你可以使用 getBoundingClientRect()来获得它。



请参阅下面的演示,了解实现此技术的示例代码。



开始动画运行



第二步实际上是在那时触发动画。如何让动画暂停然后开始运行取决于你正在使用的动画方法。



SVG SMIL动画



在第一个例子中,我们使用的是作为SVG标准一部分的SMIL动画元素。



要有一个动画等待你开始运行,将开始属性设置为indefinite。您可以通过在< animate> 元素上调用 beginElement()来启动它。



  //获取SVGvar页面上的位置svgLocation = document.getElementById(mysvg ).getBoundingClientRect(); //触发动画start的滚动偏移量//在这种情况下,它是SVG.var的底部offsetToTriggerAnimation = svgLocation.y + svgLocation.height; //处理滚动事件的函数.//为文档添加一个事件处理程序,用于onscroll事件函数scrollAnimTriggerCheck(evt){var viewBottom = window.scrollY + window.innerHeight; if(viewBottom> offsetToTriggerAnimation){//启动SMIL动画document.getElementById(anim)。beginElement(); //删除事件处理程序,使其不再触发document.removeEventListener(scroll,scrollAnimTriggerCheck); //为文件添加一个事件处理程序,用于onscrolleventdocument.addEventListener(scroll,scrollAnimTriggerCheck);  

  svg {border:solid 1px grey;} p {margin-bottom:1000px;}  

 < p>向下滚动< / p>< svg id =mysvg> < rect x =0width =150height =150fill =rebeccapurple> < animate id =animattributeName =xfrom =0to =150dur =2sfill =freezebegin =indefinite/> < / RECT>< / SVG><峰; br><峰; br><峰; br><峰; br>  



CSS动画



有几种方法可以触发动画启动当您使用CSS动画时。


  1. 动画属性放入它自己的样式集类,然后将该类添加到元素:

      .anim {
    animation-name:slide ;
    动画持续时间:2s;
    }

    myobject.classList.add(anim);


  //获取SVGvar页面上的位置svgLocation = document.getElementById(mysvg)。getBoundingClientRect(); //触发动画启动的滚动偏移量.//在这种情况下,它是SVG.var的底部offsetToTriggerAnimation = svgLocation.y + svgLocation.height; //处理滚动事件的函数。//为文档添加一个事件处理程序,用于onscroll事件函数scrollAnimTriggerCheck (evt){var viewBottom = window.scrollY + window.innerHeight; if(viewBottom> offsetToTriggerAnimation){//通过将动画CSS规则添加到rect元素document.querySelector(rect)来启动CSS动画.classList.add(anim);; //删除事件处理程序,使其不再触发document.removeEventListener(scroll,scrollAnimTriggerCheck); //为文件添加一个事件处理程序,用于onscrolleventdocument.addEventListener(scroll,scrollAnimTriggerCheck);  

  .anim {animation:slide 2s linear forward;} @keyframes slide {from {transform:translate(0px,0px); to {transform:translate(150px,0px); svg {border:solid 1px grey; } p {margin-bottom:1000px; }  

 < p>向下滚动< / p>< ; svg id =mysvg> < rect x =0width =150height =150fill =rebeccapurple/>< / svg>< br>< br>< br>< br>  


  1. 第二种方法是使用动画播放状态 CSS属性。并非所有浏览器都支持此功能。



    您的想法是将动画播放状态设置为<$ c最初$ c>暂停,然后在想要动画启动时将其更改为运行。您可以通过添加具有该属性的类(与上面类似)来实现。或者您可以直接设置 style.animationPlayState 属性,如下例所示。


  //获取SVGvar页面上的位置svgLocation = document.getElementById(mysvg)。getBoundingClientRect (); //触发动画start的滚动偏移量//在这种情况下,它是SVG.var的底部offsetToTriggerAnimation = svgLocation.y + svgLocation.height; //处理滚动事件的函数.//添加事件onscroll事件函数的文档处理程序scrollAnimTriggerCheck(evt){var viewBottom = window.scrollY + window.innerHeight; if(viewBottom> offsetToTriggerAnimation){//通过将animation-play-state设置为runningdocument.querySelector(rect)来启动CSS动画.style.animationPlayState =running; //删除事件处理程序,使其不再触发document.removeEventListener(scroll,scrollAnimTriggerCheck); //为文件添加一个事件处理程序,用于onscrolleventdocument.addEventListener(scroll,scrollAnimTriggerCheck);  

  .anim {animation:slide 2s linear forward; animation-play-state:paused;} @keyframes slide {from {transform:translate(0px,0px); to {transform:translate(150px,0px); svg {border:solid 1px grey; } p {margin-bottom:1000px; }  

 < p>向下滚动< / p>< ; svg id =mysvg> < rect x =0width =150height =150fill =rebeccapurpleclass =anim/>< / svg>< br>< br>< br>< br>  


I need some help from you guys. I can't find a good solution to my problem. I got sections in my website with some animated SVGs. I used vivus.js for this. https://maxwellito.github.io/vivus-instant/ The problem is that i can't find a solution to start the animation when the user scrolls on the section with the animated SVGs.

解决方案

To trigger an animation when the SVG scrolls into view, there are two steps you need to resolve:

  1. detect when the SVG is visible
  2. have the animation paused initially, then trigger it when you want

Detecting when an element is visible

You need to add an event handler for scroll events. In that event handler, you compare the page scroll location (window.scrollY) against the SVG's location on the page. You can get that using getBoundingClientRect().

See the demos below for example code implementing this technique.

Starting an animation running

The second step is actually triggering the animation at that time. How you keep an animation paused and then start it running, depends on the method of animation you are using.

SVG SMIL animation

In this first example, we are using the SMIL animation elements that are part of the SVG standard.

To have an animation wait for you to start it running, set the begin attribute to "indefinite". The you can start it running by calling beginElement() on the <animate> element.

// Get the position on the page of the SVG
var svgLocation = document.getElementById("mysvg").getBoundingClientRect();

// Scroll offset that triggers animation start.
// In this case it is the bottom of the SVG.
var offsetToTriggerAnimation = svgLocation.y + svgLocation.height;

// Function to handle the scroll event.
// Add an event handler to the document for the "onscroll" event
function scrollAnimTriggerCheck(evt)
{
  var viewBottom = window.scrollY + window.innerHeight;
  if (viewBottom > offsetToTriggerAnimation) {
    // Start the SMIL animation
    document.getElementById("anim").beginElement();
    // Remove the event handler so it doesn't trigger again
    document.removeEventListener("scroll", scrollAnimTriggerCheck);
  }
}

// Add an event handler to the document for the "onscroll" event
document.addEventListener("scroll", scrollAnimTriggerCheck);

svg {
  border: solid 1px grey;
}

p {
  margin-bottom: 1000px;
}

<p>Scroll down</p>

<svg id="mysvg">
  <rect x="0" width="150" height="150" fill="rebeccapurple">
    <animate id="anim" attributeName="x" from="0"  to="150" dur="2s"
             fill="freeze" begin="indefinite"/>
  </rect>
</svg>

<br>
<br>
<br>
<br>

CSS animation

There are a couple of way you can trigger an animation to start when you are using CSS animations.

  1. Put your animation property in its own style set class, then add that class to the element:

     .anim {
       animation-name: slide;
       animation-duration: 2s;
     }
    
     myobject.classList.add("anim");
    

// Get the position on the page of the SVG
var svgLocation = document.getElementById("mysvg").getBoundingClientRect();

// Scroll offset that triggers animation start.
// In this case it is the bottom of the SVG.
var offsetToTriggerAnimation = svgLocation.y + svgLocation.height;

// Function to handle the scroll event.
// Add an event handler to the document for the "onscroll" event
function scrollAnimTriggerCheck(evt)
{
  var viewBottom = window.scrollY + window.innerHeight;
  if (viewBottom > offsetToTriggerAnimation) {
    // Start the CSS animation by adding the animation CSS rules to the rect element
    document.querySelector("rect").classList.add("anim");;
    // Remove the event handler so it doesn't trigger again
    document.removeEventListener("scroll", scrollAnimTriggerCheck);
  }
}

// Add an event handler to the document for the "onscroll" event
document.addEventListener("scroll", scrollAnimTriggerCheck);

.anim {
  animation: slide 2s linear forwards;
}

@keyframes slide {
  from {
    transform: translate(0px, 0px);
  }

  to {
    transform: translate(150px, 0px);
  }
}

svg { border: solid 1px grey; }
p { margin-bottom: 1000px; }

<p>Scroll down</p>

<svg id="mysvg">
  <rect x="0" width="150" height="150" fill="rebeccapurple"/>
</svg>

<br>
<br>
<br>
<br>

  1. The second way is to make use of the animation-play-state CSS property. Not all browsers support this yet.

    The idea is that you set animation-play-state to paused initially, then change it to running when you want the animation to start. You can either do that by adding a class with that property (similar to above). Or you can set the style.animationPlayState property directly, as in the example below.

// Get the position on the page of the SVG
var svgLocation = document.getElementById("mysvg").getBoundingClientRect();

// Scroll offset that triggers animation start.
// In this case it is the bottom of the SVG.
var offsetToTriggerAnimation = svgLocation.y + svgLocation.height;

// Function to handle the scroll event.
// Add an event handler to the document for the "onscroll" event
function scrollAnimTriggerCheck(evt)
{
  var viewBottom = window.scrollY + window.innerHeight;
  if (viewBottom > offsetToTriggerAnimation) {
    // Start the CSS animation by setting the animation-play-state to "running"
    document.querySelector("rect").style.animationPlayState = "running";
    // Remove the event handler so it doesn't trigger again
    document.removeEventListener("scroll", scrollAnimTriggerCheck);
  }
}

// Add an event handler to the document for the "onscroll" event
document.addEventListener("scroll", scrollAnimTriggerCheck);

.anim {
  animation: slide 2s linear forwards;
  animation-play-state: paused;
}

@keyframes slide {
  from {
    transform: translate(0px, 0px);
  }

  to {
    transform: translate(150px, 0px);
  }
}

svg { border: solid 1px grey; }
p { margin-bottom: 1000px; }

<p>Scroll down</p>

<svg id="mysvg">
  <rect x="0" width="150" height="150" fill="rebeccapurple" class="anim"/>
</svg>

<br>
<br>
<br>
<br>

这篇关于如何在输入视口时启动动画SVG?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆