[英]Achieve infinite text spinner, spinning text from bottom to top animation
我正在嘗試實現從底部到頂部的無限旋轉輪。 到目前為止,我得到了以下信息:
什么工作:
我想要什么/什么是不正確的:
我希望動畫是無限的,換句話說,應該沒有過渡。 當動畫到達它的最后一個元素時,它不能跳回它的第一個元素,而是將它平滑地附加到它的底部以創建一個從底部到頂部的持續動畫。
我怎樣才能實現這種行為? 為了達到給定的效果,我使用了 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-duration
和keyframes
稍作調整。
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.