概要
CSSアニメーションでこんな動きを実現したい。
実装
1文字ごとにアニメーションさせるため1文字ごとに要素を区切る。
空白から文字をスライドさせるためspanを2重にしている(後述)。
<p class="animation">
<span><span>A</span></span>
<span><span>N</span></span>
<span><span>I</span></span>
<span><span>M</span></span>
<span><span>A</span></span>
<span><span>T</span></span>
<span><span>I</span></span>
<span><span>O</span></span>
<span><span>N</span></span>
</p>
<button @click="handleClick">toggle</button>
javascript部分はボタンがクリックされたら <p class="animation">
にactive
クラスを付けたり除いたりする。
const element = document.querySelector(".animation");
if (element.classList.contains('active')) {
element.classList.remove('active')
} else {
element.classList.add('active')
}
CSSはアニメーション前後の状態を規定する。
active classがついていないときは文字を横にずらしておき、active classが付いたときに元の位置に戻す。
外側のspanに overflow: hidden
をつけることでスライドした文字を隠す。
.animation span {
overflow: hidden;
display: inline-block;
}
.animation span span {
transform: translateX(50px);
transition: .5s;
}
.animation.active span span {
transform: translateX(0);
}
component化
こんな感じでcomponentにしておくと使いやすい
<template>
<p class="slide-in" :class="{active: active}" :style="myStyle">
<span v-for="(t, index) in text" :key="index">
<span>{{ t }}</span>
</span>
</p>
</template>
<script lang="ts">
import {Vue, Component, Prop} from 'vue-property-decorator'
@Component
export default class SlideIn extends Vue {
@Prop({default: ''})
text!: string
@Prop()
myStyle!: {}
@Prop({default: false})
active!: boolean
}
</script>
<style>
.slide-in span {
display: inline-block;
overflow: hidden;
}
.slide-in span span {
transform: translateX(50px);
transition: 0.5s;
}
.slide-in.active span span {
transform: translateX(0);
}
</style>
参考