如何在删除活动 class 时反转 CSS 过渡动画?
How to reverse a CSS transition animation when removing an active class?
我正在使用 VueJS 构建的应用程序中使用相当简单的图标动画。
我正在使用 Vue 过渡来实现背景元素的淡入淡出效果,但希望在图标本身上有一个简单的 shift up 动画。
我让它在向上移动时按我希望的方式工作,但是当 _active class 被移除时,是否可以反转转换?
我要做的就是让图标向上移动,单击时背景淡入,然后向下移动到它的 og 位置,背景淡出。
我已经准备好 Codesandbox 和下面的代码
Codesandbox:
https://codesandbox.io/s/animated-icon-f96df?file=/src/components/HelloWorld.vue:0-8880
<template>
<div class="wrapper">
<div class="_isActiveOrNot">{{ active }}</div>
<div class="_icons">
<div @click="activate" class="_main">
<transition name="slide">
<div :class="[active ? '_active' : '', '_cast']">
<svg
class="_icon"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M6.6 9.9C7.26274 9.9 7.8 9.36273 7.8 8.7C7.8 8.03726 7.26274 7.5 6.6 7.5C5.93726 7.5 5.4 8.03726 5.4 8.7C5.4 9.36273 5.93726 9.9 6.6 9.9ZM6.6 12.3C8.58822 12.3 10.2 10.6882 10.2 8.7C10.2 6.71178 8.58822 5.1 6.6 5.1C4.61178 5.1 3 6.71178 3 8.7C3 10.6882 4.61178 12.3 6.6 12.3Z"
fill="#712EFF"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M6.66011 13.2C5.66597 13.2 4.86006 14.0059 4.86006 15L4.86005 16.8C4.86005 17.4628 4.32279 18 3.66004 18C2.9973 18 2.46005 17.4628 2.46005 16.8L2.46006 15C2.46008 12.6804 4.3405 10.8 6.66011 10.8C8.97969 10.8 10.8601 12.6804 10.8601 15V15.6C10.8601 16.2628 10.3228 16.8 9.66008 16.8C8.99734 16.8 8.46008 16.2628 8.46008 15.6V15C8.46008 14.0059 7.6542 13.2 6.66011 13.2Z"
fill="#712EFF"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M17.4001 9.9C16.7374 9.9 16.2001 9.36273 16.2001 8.7C16.2001 8.03726 16.7374 7.5 17.4001 7.5C18.0628 7.5 18.6001 8.03726 18.6001 8.7C18.6001 9.36273 18.0628 9.9 17.4001 9.9ZM17.4001 12.3C15.4118 12.3 13.8001 10.6882 13.8001 8.7C13.8001 6.71178 15.4118 5.1 17.4001 5.1C19.3883 5.1 21.0001 6.71178 21.0001 8.7C21.0001 10.6882 19.3883 12.3 17.4001 12.3Z"
fill="#712EFF"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M17.34 13.2C18.3341 13.2 19.14 14.0059 19.14 15V16.8C19.14 17.4628 19.6772 18 20.34 18C21.0027 18 21.54 17.4628 21.54 16.8V15C21.54 12.6804 19.6596 10.8 17.34 10.8C15.0204 10.8 13.14 12.6804 13.14 15V15.6C13.14 16.2628 13.6772 16.8 14.34 16.8C15.0027 16.8 15.54 16.2628 15.54 15.6V15C15.54 14.0059 16.3459 13.2 17.34 13.2Z"
fill="#712EFF"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M12.0601 16.5C11.066 16.5 10.2601 17.3059 10.2601 18.3L10.26 20.1C10.26 20.7628 9.72278 21.3 9.06003 21.3C8.3973 21.3 7.86005 20.7628 7.86005 20.1L7.86006 18.3C7.86007 15.9804 9.7405 14.1 12.0601 14.1C14.3797 14.1 16.2601 15.9804 16.2601 18.3V20.1C16.2601 20.7628 15.7229 21.3 15.0601 21.3C14.3973 21.3 13.8601 20.7628 13.8601 20.1V18.3C13.8601 17.3059 13.0542 16.5 12.0601 16.5Z"
fill="#712EFF"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M12 13.2C12.6628 13.2 13.2 12.6628 13.2 12C13.2 11.3373 12.6628 10.8 12 10.8C11.3373 10.8 10.8 11.3373 10.8 12C10.8 12.6628 11.3373 13.2 12 13.2ZM12 15.6C13.9883 15.6 15.6 13.9883 15.6 12C15.6 10.0118 13.9883 8.4 12 8.4C10.0118 8.4 8.39999 10.0118 8.39999 12C8.39999 13.9883 10.0118 15.6 12 15.6Z"
fill="#712EFF"
/>
</svg>
</div>
</transition>
<transition name="fade" mode="out-in">
<div v-if="active" key="1" class="_circle">
<svg
class="_icon"
width="40"
height="40"
viewBox="0 0 40 40"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect width="40" height="40" rx="20" fill="#F9F9FF" />
</svg>
</div>
</transition>
<transition name="fade" mode="out-in">
<div v-if="active" key="2" class="_text">
<svg
class="_icon"
width="30"
height="12"
viewBox="0 0 30 12"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M8.99159 10.146C8.87959 10.2393 8.66959 10.3653 8.36159 10.524C8.06293 10.6827 7.69426 10.8227 7.25559 10.944C6.81693 11.0653 6.33159 11.1213 5.79959 11.112C4.98759 11.0933 4.25959 10.9487 3.61559 10.678C2.98093 10.398 2.43959 10.02 1.99159 9.544C1.55293 9.068 1.21693 8.522 0.983594 7.906C0.75026 7.29 0.633594 6.632 0.633594 5.932C0.633594 4.88667 0.843594 3.96267 1.26359 3.16C1.68359 2.35733 2.26693 1.72733 3.01359 1.27C3.76959 0.812666 4.64693 0.584 5.64559 0.584C6.33626 0.584 6.94759 0.677333 7.47959 0.863999C8.01159 1.05067 8.44559 1.25133 8.78159 1.466L7.98359 3.384C7.75026 3.20667 7.43759 3.02467 7.04559 2.838C6.66293 2.642 6.21959 2.544 5.71559 2.544C5.19293 2.544 4.70293 2.68867 4.24559 2.978C3.79759 3.26733 3.43359 3.65933 3.15359 4.154C2.88293 4.63933 2.74759 5.19467 2.74759 5.82C2.74759 6.48267 2.87359 7.066 3.12559 7.57C3.37759 8.06467 3.73693 8.452 4.20359 8.732C4.67026 9.012 5.21626 9.152 5.84159 9.152C6.39226 9.152 6.86359 9.06333 7.25559 8.886C7.64759 8.70867 7.94626 8.522 8.15159 8.326L8.99159 10.146ZM13.2793 11.168C12.71 11.168 12.192 11.056 11.7253 10.832C11.268 10.5987 10.904 10.244 10.6333 9.768C10.3626 9.292 10.2273 8.68533 10.2273 7.948C10.2273 7.25733 10.3673 6.66 10.6473 6.156C10.9273 5.652 11.296 5.26467 11.7533 4.994C12.2106 4.714 12.696 4.574 13.2093 4.574C13.816 4.574 14.2733 4.672 14.5813 4.868C14.8986 5.064 15.1506 5.27867 15.3373 5.512L15.4633 4.882H17.2833V11H15.3233V10.244C15.23 10.3373 15.09 10.4587 14.9033 10.608C14.726 10.7573 14.502 10.888 14.2313 11C13.9606 11.112 13.6433 11.168 13.2793 11.168ZM13.8393 9.572C14.5206 9.572 15.0153 9.264 15.3233 8.648V7.15C15.2113 6.85133 15.0153 6.61333 14.7353 6.436C14.4646 6.25867 14.1426 6.17 13.7693 6.17C13.3493 6.17 12.9853 6.32867 12.6773 6.646C12.3693 6.954 12.2153 7.35533 12.2153 7.85C12.2153 8.17667 12.29 8.47067 12.4393 8.732C12.5886 8.99333 12.7846 9.19867 13.0273 9.348C13.2793 9.49733 13.55 9.572 13.8393 9.572ZM21.2909 11.126C20.7869 11.126 20.3156 11.0373 19.8769 10.86C19.4476 10.6827 19.0836 10.4353 18.7849 10.118L19.5969 9.04C19.8956 9.31067 20.1709 9.50667 20.4229 9.628C20.6843 9.74 20.9176 9.796 21.1229 9.796C21.3656 9.796 21.5663 9.75867 21.7249 9.684C21.8836 9.60933 21.9629 9.488 21.9629 9.32C21.9629 9.16133 21.8976 9.03533 21.7669 8.942C21.6456 8.84867 21.4869 8.774 21.2909 8.718C21.0949 8.65267 20.8849 8.58733 20.6609 8.522C20.1009 8.34467 19.6949 8.088 19.4429 7.752C19.2003 7.40667 19.0789 7.03333 19.0789 6.632C19.0789 6.324 19.1583 6.016 19.3169 5.708C19.4849 5.39067 19.7463 5.12933 20.1009 4.924C20.4649 4.70933 20.9316 4.602 21.5009 4.602C22.0143 4.602 22.4483 4.65333 22.8029 4.756C23.1576 4.85867 23.4936 5.02667 23.8109 5.26L23.0689 6.408C22.8916 6.268 22.6909 6.15133 22.4669 6.058C22.2523 5.95533 22.0516 5.89933 21.8649 5.89C21.6129 5.88067 21.4169 5.92733 21.2769 6.03C21.1369 6.12333 21.0669 6.23533 21.0669 6.366C21.0576 6.54333 21.1229 6.68333 21.2629 6.786C21.4123 6.88867 21.5989 6.968 21.8229 7.024C22.0469 7.08 22.2663 7.14533 22.4809 7.22C22.9196 7.36933 23.2696 7.584 23.5309 7.864C23.7923 8.13467 23.9229 8.49867 23.9229 8.956C23.9229 9.32933 23.8249 9.684 23.6289 10.02C23.4423 10.3467 23.1529 10.6127 22.7609 10.818C22.3783 11.0233 21.8883 11.126 21.2909 11.126ZM26.1386 2.194H28.0986V4.854H29.5826V6.38H28.0986V11H26.1386V6.38H25.1866V4.854H26.1386V2.194Z"
fill="#1A0050"
/>
</svg>
</div>
</transition>
</div>
</div>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
active: false,
};
},
computed: {},
methods: {
activate() {
this.active = !this.active;
},
},
};
</script>
<style lang="sass" scoped>
.wrapper
display: flex
flex-direction: column
justify-content: center
align-items: center
height: 100vh
background-color: #d4caff
._isActiveOrNot
margin-bottom: 50px
font-weight: bold
color: purple
._icons
display: flex
justify-content: space-around
align-items: flex-end
width: 100%
._icon
cursor: pointer
transform: scale(2)
._main
position: relative
display: flex
flex-direction: column
justify-content: center
align-items: center
min-height: 124px
._circle
position: absolute
top: 20px
z-index: 1
._cast
z-index: 2
._text
position: absolute
bottom: 0
z-index: 2
._active
transition: all .5s ease-in-out
transform: translateY(-20px)
.fade-enter-active, .fade-leave-active
transition: opacity .8s ease-in-out
.fade-enter, .fade-leave-to
opacity: 0
</style>
是的,CSS 内置了此功能 - 您只需要让 transition
属性 保留在元素的基本样式上,这样无论修饰符是否存在,它都适用class 是 added/removed.
例如:
.sliding-box {
transition: transform .5s;
background: green;
height: 5em;
width: 5em;
}
.sliding-box.active {
transform: translateX(5em);
}
<div class="sliding-box"></div>
<br>
<button
onclick="document
.getElementsByClassName('sliding-box')[0]
.classList.toggle('active')">
Toggle Slide</button>
我正在使用 VueJS 构建的应用程序中使用相当简单的图标动画。 我正在使用 Vue 过渡来实现背景元素的淡入淡出效果,但希望在图标本身上有一个简单的 shift up 动画。
我让它在向上移动时按我希望的方式工作,但是当 _active class 被移除时,是否可以反转转换?
我要做的就是让图标向上移动,单击时背景淡入,然后向下移动到它的 og 位置,背景淡出。
我已经准备好 Codesandbox 和下面的代码
Codesandbox: https://codesandbox.io/s/animated-icon-f96df?file=/src/components/HelloWorld.vue:0-8880
<template>
<div class="wrapper">
<div class="_isActiveOrNot">{{ active }}</div>
<div class="_icons">
<div @click="activate" class="_main">
<transition name="slide">
<div :class="[active ? '_active' : '', '_cast']">
<svg
class="_icon"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M6.6 9.9C7.26274 9.9 7.8 9.36273 7.8 8.7C7.8 8.03726 7.26274 7.5 6.6 7.5C5.93726 7.5 5.4 8.03726 5.4 8.7C5.4 9.36273 5.93726 9.9 6.6 9.9ZM6.6 12.3C8.58822 12.3 10.2 10.6882 10.2 8.7C10.2 6.71178 8.58822 5.1 6.6 5.1C4.61178 5.1 3 6.71178 3 8.7C3 10.6882 4.61178 12.3 6.6 12.3Z"
fill="#712EFF"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M6.66011 13.2C5.66597 13.2 4.86006 14.0059 4.86006 15L4.86005 16.8C4.86005 17.4628 4.32279 18 3.66004 18C2.9973 18 2.46005 17.4628 2.46005 16.8L2.46006 15C2.46008 12.6804 4.3405 10.8 6.66011 10.8C8.97969 10.8 10.8601 12.6804 10.8601 15V15.6C10.8601 16.2628 10.3228 16.8 9.66008 16.8C8.99734 16.8 8.46008 16.2628 8.46008 15.6V15C8.46008 14.0059 7.6542 13.2 6.66011 13.2Z"
fill="#712EFF"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M17.4001 9.9C16.7374 9.9 16.2001 9.36273 16.2001 8.7C16.2001 8.03726 16.7374 7.5 17.4001 7.5C18.0628 7.5 18.6001 8.03726 18.6001 8.7C18.6001 9.36273 18.0628 9.9 17.4001 9.9ZM17.4001 12.3C15.4118 12.3 13.8001 10.6882 13.8001 8.7C13.8001 6.71178 15.4118 5.1 17.4001 5.1C19.3883 5.1 21.0001 6.71178 21.0001 8.7C21.0001 10.6882 19.3883 12.3 17.4001 12.3Z"
fill="#712EFF"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M17.34 13.2C18.3341 13.2 19.14 14.0059 19.14 15V16.8C19.14 17.4628 19.6772 18 20.34 18C21.0027 18 21.54 17.4628 21.54 16.8V15C21.54 12.6804 19.6596 10.8 17.34 10.8C15.0204 10.8 13.14 12.6804 13.14 15V15.6C13.14 16.2628 13.6772 16.8 14.34 16.8C15.0027 16.8 15.54 16.2628 15.54 15.6V15C15.54 14.0059 16.3459 13.2 17.34 13.2Z"
fill="#712EFF"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M12.0601 16.5C11.066 16.5 10.2601 17.3059 10.2601 18.3L10.26 20.1C10.26 20.7628 9.72278 21.3 9.06003 21.3C8.3973 21.3 7.86005 20.7628 7.86005 20.1L7.86006 18.3C7.86007 15.9804 9.7405 14.1 12.0601 14.1C14.3797 14.1 16.2601 15.9804 16.2601 18.3V20.1C16.2601 20.7628 15.7229 21.3 15.0601 21.3C14.3973 21.3 13.8601 20.7628 13.8601 20.1V18.3C13.8601 17.3059 13.0542 16.5 12.0601 16.5Z"
fill="#712EFF"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M12 13.2C12.6628 13.2 13.2 12.6628 13.2 12C13.2 11.3373 12.6628 10.8 12 10.8C11.3373 10.8 10.8 11.3373 10.8 12C10.8 12.6628 11.3373 13.2 12 13.2ZM12 15.6C13.9883 15.6 15.6 13.9883 15.6 12C15.6 10.0118 13.9883 8.4 12 8.4C10.0118 8.4 8.39999 10.0118 8.39999 12C8.39999 13.9883 10.0118 15.6 12 15.6Z"
fill="#712EFF"
/>
</svg>
</div>
</transition>
<transition name="fade" mode="out-in">
<div v-if="active" key="1" class="_circle">
<svg
class="_icon"
width="40"
height="40"
viewBox="0 0 40 40"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect width="40" height="40" rx="20" fill="#F9F9FF" />
</svg>
</div>
</transition>
<transition name="fade" mode="out-in">
<div v-if="active" key="2" class="_text">
<svg
class="_icon"
width="30"
height="12"
viewBox="0 0 30 12"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M8.99159 10.146C8.87959 10.2393 8.66959 10.3653 8.36159 10.524C8.06293 10.6827 7.69426 10.8227 7.25559 10.944C6.81693 11.0653 6.33159 11.1213 5.79959 11.112C4.98759 11.0933 4.25959 10.9487 3.61559 10.678C2.98093 10.398 2.43959 10.02 1.99159 9.544C1.55293 9.068 1.21693 8.522 0.983594 7.906C0.75026 7.29 0.633594 6.632 0.633594 5.932C0.633594 4.88667 0.843594 3.96267 1.26359 3.16C1.68359 2.35733 2.26693 1.72733 3.01359 1.27C3.76959 0.812666 4.64693 0.584 5.64559 0.584C6.33626 0.584 6.94759 0.677333 7.47959 0.863999C8.01159 1.05067 8.44559 1.25133 8.78159 1.466L7.98359 3.384C7.75026 3.20667 7.43759 3.02467 7.04559 2.838C6.66293 2.642 6.21959 2.544 5.71559 2.544C5.19293 2.544 4.70293 2.68867 4.24559 2.978C3.79759 3.26733 3.43359 3.65933 3.15359 4.154C2.88293 4.63933 2.74759 5.19467 2.74759 5.82C2.74759 6.48267 2.87359 7.066 3.12559 7.57C3.37759 8.06467 3.73693 8.452 4.20359 8.732C4.67026 9.012 5.21626 9.152 5.84159 9.152C6.39226 9.152 6.86359 9.06333 7.25559 8.886C7.64759 8.70867 7.94626 8.522 8.15159 8.326L8.99159 10.146ZM13.2793 11.168C12.71 11.168 12.192 11.056 11.7253 10.832C11.268 10.5987 10.904 10.244 10.6333 9.768C10.3626 9.292 10.2273 8.68533 10.2273 7.948C10.2273 7.25733 10.3673 6.66 10.6473 6.156C10.9273 5.652 11.296 5.26467 11.7533 4.994C12.2106 4.714 12.696 4.574 13.2093 4.574C13.816 4.574 14.2733 4.672 14.5813 4.868C14.8986 5.064 15.1506 5.27867 15.3373 5.512L15.4633 4.882H17.2833V11H15.3233V10.244C15.23 10.3373 15.09 10.4587 14.9033 10.608C14.726 10.7573 14.502 10.888 14.2313 11C13.9606 11.112 13.6433 11.168 13.2793 11.168ZM13.8393 9.572C14.5206 9.572 15.0153 9.264 15.3233 8.648V7.15C15.2113 6.85133 15.0153 6.61333 14.7353 6.436C14.4646 6.25867 14.1426 6.17 13.7693 6.17C13.3493 6.17 12.9853 6.32867 12.6773 6.646C12.3693 6.954 12.2153 7.35533 12.2153 7.85C12.2153 8.17667 12.29 8.47067 12.4393 8.732C12.5886 8.99333 12.7846 9.19867 13.0273 9.348C13.2793 9.49733 13.55 9.572 13.8393 9.572ZM21.2909 11.126C20.7869 11.126 20.3156 11.0373 19.8769 10.86C19.4476 10.6827 19.0836 10.4353 18.7849 10.118L19.5969 9.04C19.8956 9.31067 20.1709 9.50667 20.4229 9.628C20.6843 9.74 20.9176 9.796 21.1229 9.796C21.3656 9.796 21.5663 9.75867 21.7249 9.684C21.8836 9.60933 21.9629 9.488 21.9629 9.32C21.9629 9.16133 21.8976 9.03533 21.7669 8.942C21.6456 8.84867 21.4869 8.774 21.2909 8.718C21.0949 8.65267 20.8849 8.58733 20.6609 8.522C20.1009 8.34467 19.6949 8.088 19.4429 7.752C19.2003 7.40667 19.0789 7.03333 19.0789 6.632C19.0789 6.324 19.1583 6.016 19.3169 5.708C19.4849 5.39067 19.7463 5.12933 20.1009 4.924C20.4649 4.70933 20.9316 4.602 21.5009 4.602C22.0143 4.602 22.4483 4.65333 22.8029 4.756C23.1576 4.85867 23.4936 5.02667 23.8109 5.26L23.0689 6.408C22.8916 6.268 22.6909 6.15133 22.4669 6.058C22.2523 5.95533 22.0516 5.89933 21.8649 5.89C21.6129 5.88067 21.4169 5.92733 21.2769 6.03C21.1369 6.12333 21.0669 6.23533 21.0669 6.366C21.0576 6.54333 21.1229 6.68333 21.2629 6.786C21.4123 6.88867 21.5989 6.968 21.8229 7.024C22.0469 7.08 22.2663 7.14533 22.4809 7.22C22.9196 7.36933 23.2696 7.584 23.5309 7.864C23.7923 8.13467 23.9229 8.49867 23.9229 8.956C23.9229 9.32933 23.8249 9.684 23.6289 10.02C23.4423 10.3467 23.1529 10.6127 22.7609 10.818C22.3783 11.0233 21.8883 11.126 21.2909 11.126ZM26.1386 2.194H28.0986V4.854H29.5826V6.38H28.0986V11H26.1386V6.38H25.1866V4.854H26.1386V2.194Z"
fill="#1A0050"
/>
</svg>
</div>
</transition>
</div>
</div>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
active: false,
};
},
computed: {},
methods: {
activate() {
this.active = !this.active;
},
},
};
</script>
<style lang="sass" scoped>
.wrapper
display: flex
flex-direction: column
justify-content: center
align-items: center
height: 100vh
background-color: #d4caff
._isActiveOrNot
margin-bottom: 50px
font-weight: bold
color: purple
._icons
display: flex
justify-content: space-around
align-items: flex-end
width: 100%
._icon
cursor: pointer
transform: scale(2)
._main
position: relative
display: flex
flex-direction: column
justify-content: center
align-items: center
min-height: 124px
._circle
position: absolute
top: 20px
z-index: 1
._cast
z-index: 2
._text
position: absolute
bottom: 0
z-index: 2
._active
transition: all .5s ease-in-out
transform: translateY(-20px)
.fade-enter-active, .fade-leave-active
transition: opacity .8s ease-in-out
.fade-enter, .fade-leave-to
opacity: 0
</style>
是的,CSS 内置了此功能 - 您只需要让 transition
属性 保留在元素的基本样式上,这样无论修饰符是否存在,它都适用class 是 added/removed.
例如:
.sliding-box {
transition: transform .5s;
background: green;
height: 5em;
width: 5em;
}
.sliding-box.active {
transform: translateX(5em);
}
<div class="sliding-box"></div>
<br>
<button
onclick="document
.getElementsByClassName('sliding-box')[0]
.classList.toggle('active')">
Toggle Slide</button>