current position:Home>Realize JS keyframes animation with web animations API -- infinite circular scrolling of text

Realize JS keyframes animation with web animations API -- infinite circular scrolling of text

2021-08-27 08:53:35 Liu 666

Record small thoughts

background

For the API The excavation of , From a need

  1. use css3 Realize a component of infinite circular scrolling of text , Do not use setInterval
  2. When the mouse clicks on it , Animation stops , Users can scroll through the scroll bar
  3. When the mouse leaves , Animation continues

Text scrolls infinitely , There are still many references on the Internet , Don't worry about this plan . The trouble is that , mouse hover Go up and pause 、 There is no problem restoring animation , But the scrolling of animation is not scrollTop Of , How do you know how much you've rolled , How can you just css Just realize the above requirements ?? And mouse hover Leave and let the scroll bar disappear , This demand can't be done ...

The pattern is smaller , I didn't say I could only use one div, You can use two div To achieve , One div It has no animation effect and a scroll bar div, The other one has animation effect and no scroll bar div, mouse hover On the way up , Switch to non animated div On , When the mouse leaves, switch back to the animation effect div On

So the key point to realize this requirement is ,1 You need to know the scrolling distance of the animation ,2 You need to tell the animation how far the scroll bar scrolls , Let the animation roll on

At first, my understanding of animation effects was mainly css3 Of animation, So I found out how to know animation The rolling distance of , And then I found out CSS Object Model (CSSOM), It can be used js operation css Of API, Allow dynamic reading and modification css style , I haven't used it before , So I really don't know . But when I use it , Maybe the usage is wrong , You can get other styles of the page , But you can't get the animation style , So I found that this method may not be very suitable , Just keep looking at other methods .

For a long time , Found out Web Animation API - stay JavaScript Middle release CSS keyframes Power , That's crucial , The technical difficulties were solved all at once . The key :effect.getComputedTiming().progress、currentTime

Okay , There are plans , Start implementation

effect

rowup.gif

Realization

The function point

  1. Text scrolls in an infinite loop

image.png

  1. Scrolling animation effects and mouse scrolling follow whether the mouse hover Switch , And the position of the elements rolling in the two ways should be well connected

Mainly used :

effect.getComputedTiming().progress: The scrolling progress of the animation , Multiply by the height of the text area , You know how far you've rolled currentTime: By setting this property, you can control the current scrolling position of the animation

Online effect and code ( The code is easy to understand , Just look at the code )


attach vue Component code , Scroll up and down , Other rolling directions can be adjusted by themselves translate3d y Shaft parameters

<template>
  <div
    :id='scrollWrapperId'
    :class='wrapperClassName'
  >
    <div
      class="scroll-hidden"
      :style="{height:height,width:width}"
    >
      <div class='scroll-content'>
        <slot></slot>
        <slot></slot>
      </div>
    </div>
    <div
      class="scroll-auto"
      :style="{width:width}"
    >
      <div>
        <slot></slot>
        <slot></slot>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: 'Scroll',
  props: {
    wrapperClassName: String,
    scrollWrapperId: {
      type: String,
      default: 'scroll-wrapper'
    },
    height: String, //  With units 
    width: {
      type: String,
      default: '100%'
    },
    options: { // keyframes Parameters 
      type: Object,
      default: () => ({
        duration: 3000
      })
    }
  },
  mounted() {
    let scrollTop;
    const scrollHiddenDom = document.querySelector(`#${this.scrollWrapperId}  > .scroll-hidden`);
    const scrollAutoDom = document.querySelector(`#${this.scrollWrapperId}  > .scroll-auto`);
    const animationContentDom = document.querySelector(`#${this.scrollWrapperId}  > .scroll-hidden > .scroll-content`);
    const offsetHeight = animationContentDom.offsetHeight / 2;

![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/263e8ed773cf4a488b9fa3930341bd3e~tplv-k3u1fbpfcp-watermark.image)
    const keyFrames = [
      {
        transform: 'translate3d(0, 0, 0)',
        offset: 0 // 0%
      }, {
        transform: 'translate3d(0, -50%, 0)',
        offset: 1 // 100%
      }
    ];
    const keyFramesOptions = {
      duration: this.options.duration / 1,
      delay: 0,
      iterations: Infinity,
      easing: 'linear',
      fill: 'forwards', //  Defines when the animation no longer plays , How the animation should apply the style to its target   When the animation is not playing , The target element retains the calculation style defined in the last key frame 
      direction: 'normal'//  Defines whether the animation should play normally 
    };

![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/146f6fc2ec6a4741a189a0f817a18f01~tplv-k3u1fbpfcp-watermark.image)
    if (!animationContentDom.animate) { //  If the browser does not support scrolling   Just show the sliding area directly 
      scrollHiddenDom.style.visibility = 'hidden';
      scrollHiddenDom.style.height = 0;
      scrollAutoDom.style.visibility = 'visible';
      scrollAutoDom.style.height = this.height;
      return;
    }
    const myanimation = animationContentDom.animate(keyFrames, Object.assign({}, keyFramesOptions, this.options));

    scrollHiddenDom.addEventListener('mouseenter', () => {
      myanimation.pause();
      const animationProcess = myanimation.effect.getComputedTiming().progress; // animation Rolling progress    Range 0-1
      scrollTop = offsetHeight * animationProcess;

      scrollHiddenDom.style.visibility = 'hidden';
      scrollHiddenDom.style.height = 0;
      scrollAutoDom.style.visibility = 'visible';
      scrollAutoDom.style.height = this.height;

      scrollAutoDom.scrollTop = scrollTop;
    });
    scrollAutoDom.addEventListener('mouseleave', () => {
      scrollHiddenDom.style.visibility = 'visible';
      scrollHiddenDom.style.height = this.height;
      scrollAutoDom.style.visibility = 'hidden';
      scrollAutoDom.style.height = 0;
      //  Through the rolling distance , Calculate the time value of the corresponding animation   jump to x second from start of animation
      myanimation.currentTime = scrollAutoDom.scrollTop / (offsetHeight / this.options.duration / 1);
      myanimation.play();
    });
  }
};
</script>
<style lang='scss' scoped>
.scroll-hidden {
  visibility: visible;
  overflow: hidden;
}
.scroll-auto {
  visibility: hidden;
  height: 0;
  overflow: auto;
}
</style>

 Copy code 

copyright notice
author[Liu 666],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2021/08/20210827085330947S.html

Random recommended