簡體   English   中英

實現無限文字微調,從下往上旋轉文字動畫

[英]Achieve infinite text spinner, spinning text from bottom to top animation

我正在嘗試實現從底部到頂部的無限旋轉輪。 到目前為止,我得到了以下信息: 紡車示例

什么工作:

  1. 它從下到上旋轉
  2. 到達結尾后再次從第一個字符串開始

我想要什么/什么是不正確的:
我希望動畫是無限的,換句話說,應該沒有過渡。 當動畫到達它的最后一個元素時,它不能跳回它的第一個元素,而是將它平滑地附加到它的底部以創建一個從底部到頂部持續動畫

我怎樣才能實現這種行為? 為了達到給定的效果,我使用了 js - 我需要更多的 js 還是回退到純 css 動畫?

class Spinner extends Component {

    state = {
      active: 0
    };

    interval;

    componentDidMount() {
        this.interval = setInterval(() => {
            this.setState({active: this.state.active === this.props.content.length - 1 ? 0 : this.state.active + 1});
        }, 1000);
    }

    componentWillUnmount() {
        clearInterval(this.interval);
    }

    setPosition = () => {
        const n = 100 / this.props.content.length;
        return n * this.state.active * -1;
    };

    render() {
        const style = {
            transform: 'translateY(' + this.setPosition() + '%)'
        };

        return (
            <div className="spinner--list d-inline-block align-self-start">
                <ul className="p-0 m-0" style={style}>
                    {
                        this.props.content.map((item, index) => {
                            return (
                                <li key={index}>
                                    <h1>{item}</h1>
                                </li>
                            );
                        })
                    }
                </ul>
            </div>
        );
    }

}
.spinner--list {
    max-height: calc((10px + 2vw) * 1.5);
    overflow: hidden;
}

.spinner--list ul {
    list-style-type: none;
    transition: transform 1s;
    will-change: transform;
}

.spinner--container h1 {
    font-size: calc(10px + 2vw);
    line-height: 1.5;
    margin: 0;
}

@keyframes CSS 解決方案

 body { color: black; padding: 0; margin: 0; } .text { padding: 20px 0; display: flex; position: relative; } .item-1, .item-2, .item-3 { position: absolute; padding: 20px 0; margin: 0; margin-left: 5px; animation-duration: 4s; animation-timing-function: ease-in-out; animation-iteration-count: infinite; } .item-1{ animation-name: anim-1; } .item-2{ animation-name: anim-2; } .item-3{ animation-name: anim-3; } @keyframes anim-1 { 0%, 8.3% { top: -50%; opacity: 0; } 8.3%,25% { top: 0%; opacity: 1; } 33.33%, 100% { top: 50%; opacity: 0; } } @keyframes anim-2 { 0%, 33.33% { top: -50%; opacity: 0; } 41.63%, 58.29% { top: 0%; opacity: 1; } 66.66%, 100% { top: 50%; opacity: 0; } } @keyframes anim-3 { 0%, 66.66% { top: -50%; opacity: 0; } 74.96%, 91.62% { top: 0%; opacity: 1; } 100% { top: 50%; opacity: 0; } }
 <div class="text">This is a <div class="items"> <p class="item-1">test.</p> <p class="item-2">bug.</p> <p class="item-3">fail.</p> </div> </div>

這是一個沒有ul的解決方案,可以自動調整到您想要旋轉的可變數量的文本。 該解決方案使用keyframes和 CSS 中的一個小技巧/幻覺來僅在兩個span -s 上創建無限旋轉動畫。 每次動畫迭代后,每個跨度的文本都使用 JS 更改。 更改的文本取決於 HTML 中的data-texts屬性。 在你的 ReactJS 代碼中,你可以簡單地在這些data-texts屬性中輸入你想要旋轉的所有data-texts

 const spinnerTexts = document.querySelectorAll('[class^="spinner__text--"]') const texts = spinnerTexts[0].dataset.texts.split(',') const textPositions = [0, 1] function initializeSpinnerTexts() { spinnerTexts.forEach((spinnerText, index) => { // Initialize the spinner texts' text spinnerText.innerText = texts[textPositions[index]] // Change text after every animation iteration spinnerText.addEventListener('animationiteration', e => { e.target.innerText = texts[++textPositions[index] % texts.length] }) }) } window.onload = initializeSpinnerTexts
 * { margin: 0; padding: 0; } .spinner { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); overflow: hidden; } .spinner__text { position: relative; display: inline-block; /* width has to be set to be >= largest spinning text width */ width: 50px; } .spinner__text--top, .spinner__text--bottom { display: inline-block; animation: 1s ease 1.05s infinite running none; } .spinner__text--top { animation-name: spinTop; } /* Bottom text spinner has to be configured so that it is positioned right at the same position as the top one */ .spinner__text--bottom { position: absolute; top: 0; left: 0; opacity: 0; animation-name: spinBottom; } @keyframes spinTop { from { transform: translateY(0%); } to { transform: translateY(-100%); } } @keyframes spinBottom { from { opacity: 1; transform: translateY(100%); } to { opacity: 1; transform: translateY(0%); } }
 <div class="spinner"> This is a <!-- Uses two spans to create an illusion of infinite spinning --> <div class="spinner__text"> <span class="spinner__text--top" data-texts="test., bug., fail."></span> <span class="spinner__text--bottom" data-texts="text., bug., fail."></span> </div> </div>


更新

您不能直接使用keyframes在每次動畫迭代之間添加延遲。 但是,您可以調整keyframes的值和animation-duration的值,使每次迭代之間看起來都有延遲; 實際上,您正在制作它,以便在每個動畫結束時都不會發生任何事情。 下面是一個示例(它類似於上面的示例,但對animation-durationkeyframes稍作調整。

 const spinnerTexts = document.querySelectorAll('[class^="spinner__text--"]') const texts = spinnerTexts[0].dataset.texts.split(',') const textPositions = [0, 1] function initializeSpinnerTexts() { spinnerTexts.forEach((spinnerText, index) => { // Initialize the spinner texts' text spinnerText.innerText = texts[textPositions[index]] // Change text after every animation iteration spinnerText.addEventListener('animationiteration', e => { e.target.innerText = texts[++textPositions[index] % texts.length] }) }) } window.onload = initializeSpinnerTexts
 * { margin: 0; padding: 0; } .spinner { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); overflow: hidden; } .spinner__text { position: relative; display: inline-block; width: 50px; } .spinner__text--top, .spinner__text--bottom { display: inline-block; /* Changed animation duration */ animation: 5s ease 2s infinite running none; } .spinner__text--top { animation-name: spinTop; } .spinner__text--bottom { position: absolute; top: 0; left: 0; opacity: 0; animation-name: spinBottom; } @keyframes spinTop { 0% { transform: translateY(0%); } /* Spin finishes after 20% of animation duration (1s) */ 20% { transform: translateY(-100%); } /* Nothing from 20% until 100% of animation duration (4s) */ /* This makes it looks like there's a delay between each animation */ 100% { transform: translateY(-100%); } } @keyframes spinBottom { /* Similar to spinTop's logic */ 0% { opacity: 1; transform: translateY(100%); } 20% { opacity: 1; transform: translateY(0%); } 100% { opacity: 1; transform: translateY(0%); } }
 <div class="spinner"> This is a <!-- Uses two spans to create an illusion of infinite spinning --> <div class="spinner__text"> <span class="spinner__text--top" data-texts="test., bug., fail."></span> <span class="spinner__text--bottom" data-texts="text., bug., fail."></span> </div> </div>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM