Created
August 11, 2020 14:52
-
-
Save simon-engledew/4e57bce177d4dda28f42f4f15b40636b to your computer and use it in GitHub Desktop.
Animated text carousel with no dependencies.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const TextCarousel: React.FunctionComponent = ({ children }) => { | |
const [index, setIndex] = React.useState(0); | |
const max = React.Children.count(children); | |
const ms = 5000; | |
React.useEffect( | |
function () { | |
const interval = setInterval(function () { | |
setIndex((index) => (index + 1) % max); | |
}, ms); | |
return function () { | |
clearInterval(interval); | |
}; | |
}, | |
[max] | |
); | |
const start = ((200 / ms) * 100).toFixed(0); | |
const end = (((ms - 200) / ms) * 100).toFixed(0); | |
return ( | |
<ul> | |
<style jsx>{` | |
@keyframes carousel { | |
from { | |
transform: translateY(-20px); | |
opacity: 0; | |
} | |
${start}% { | |
transform: translateY(0); | |
opacity: 1; | |
} | |
${end}% { | |
transform: translateY(0); | |
opacity: 1; | |
} | |
to { | |
transform: translateY(20px); | |
opacity: 0; | |
} | |
} | |
ul { | |
display: grid; | |
} | |
ul, | |
ul li { | |
margin: 0; | |
padding: 0; | |
} | |
ul li { | |
grid-column: 1; | |
grid-row: 1; | |
opacity: 0; | |
list-style-type: none; | |
opacity: 0; | |
} | |
ul li.selected { | |
animation: carousel ${ms}ms infinite; | |
} | |
`}</style> | |
{React.Children.map(children, (child, n) => ( | |
<li className={n === index ? 'selected' : undefined} key={n}> | |
{child} | |
</li> | |
))} | |
</ul> | |
); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment