<div id="app">
<div class="controls">
<label>Time scale:</label><br/><span>10%</span> <input type="range" min="0.1" max="2" step="0.1" v-model.number="timeScale"/><span>200%</span>
</div>
<staggered-animation :time-scale="timeScale"/>
</div>
<script type="text/x-template" id="staggered-animation-template">
<div class="letters">
<span>h</span>
<span>a</span>
<span>p</span>
<span>p</span>
<span>y</span>
<span> </span>
<span>2</span>
<span>0</span>
<span>2</span>
<span>0</span>
<span>!</span>
</div>
</script>
.letters {
display: flex;
justify-content: center;
font-size: 60px;
}
body {
font-family: system-ui, -apple-system;
}
.controls > * {
vertical-align: middle;
}
label {
font-weight: bold;
}
View Compiled
let timeline
const colors = ['red', 'yellow', 'green', 'blue', 'purple']
Vue.component('staggered-animation', {
props: [
'timeScale'
],
template: '#staggered-animation-template',
mounted() {
const letters = [...this.$el.children]
timeline = gsap.timeline({ repeat: -1})
letters.forEach(l => {
timeline.from(l, { opacity: 0, scale: .5, duration: .5 }, '-=0.15')
})
colors.forEach(color => {
timeline.to(this.$el, { color, duration: 0.25 })
})
timeline.to(this.$el, { color: 'black', opacity: 0, scale: 2 })
},
watch: {
timeScale(value) {
timeline.timeScale(value)
}
}
})
new Vue({
el: '#app',
data() {
return {
timeScale: 1
}
}
});
View Compiled
This Pen doesn't use any external CSS resources.