简单的几行代码封装一个文字入场动画组件,复制即可

前言

由于自己很喜欢ant motion的文字动画,vue里又找不到合适的封装好的,所以找到了几个参考的简单的封装了一个组件,适用于各种标题的文字入场动画,复制即用。

使用示例

<TextAnimate style="color: #1899ff; font-size: 50px" :mode="1">
  this is a animate 1
</TextAnimate>
// 1000毫秒后执行动画
<TextAnimate style="color: #1899ff; font-size: 50px" :mode="1" :delay="1000">
  this is a animate 1
</TextAnimate>

效果演示

入场动画1

在这里插入图片描述

入场动画2

在这里插入图片描述

入场动画3

在这里插入图片描述

入场动画4

在这里插入图片描述

入场动画5

在这里插入图片描述

vue2版本

<script>
export default {
  props: {
    /**
     * 动画模式
     */
    mode: { type: Number, default: 1 },
    /**
     * 延迟动画时间 1000=1s
     */
    delay: { type: Number, default: 0 },
  },
  data() {
    return {
      text: "",
    };
  },
  mounted() {
    this.text = this.$slots.default[0].text;
  },
  computed: {
    animateName() {
      const animateClassData = {
        1: "one",
        2: "two",
        3: "three",
        4: "four",
        5: "five",
      };
      return animateClassData[this.mode] || "one";
    },
  },
};
</script>
<template>
  <div
    class="animate"
    :class="animateName"
    :style="{ '--delay': `${delay / 1000}s` }"
  >
    <template v-for="item in text.split('')">
      <span style="white-space: pre">{{ item }}</span>
    </template>
  </div>
</template>
<style lang="scss" scoped>
.one {
  span {
    opacity: 0;
    transform: translate(-150px, 0) scale(0.3);
    animation: leftRight 0.5s forwards;
  }
  @keyframes leftRight {
    40% {
      transform: translate(50px, 0) scale(0.7);
      opacity: 1;
    }

    60% {
    }

    80% {
      transform: translate(0) scale(2);
      opacity: 0;
    }

    100% {
      transform: translate(0) scale(1);
      opacity: 1;
    }
  }
}
.two {
  span {
    opacity: 0;
    transform: translate(-150px, -50px) rotate(-180deg) scale(3);
    animation: revolveScale 0.4s forwards;
  }
  @keyframes revolveScale {
    60% {
      transform: translate(20px, 20px) rotate(30deg) scale(0.3);
    }

    100% {
      transform: translate(0) rotate(0) scale(1);
      opacity: 1;
    }
  }
}
.three {
  span {
    opacity: 0;
    transform: translate(200px, -100px) scale(2);
    animation: ballDrop 0.3s forwards;
  }
  @keyframes ballDrop {
    60% {
      transform: translate(0, 20px) rotate(-180deg) scale(0.5);
    }

    100% {
      transform: translate(0) rotate(0deg) scale(1);
      opacity: 1;
    }
  }
}

.four {
  span {
    opacity: 0;
    transform: rotate(-180deg) translate(150px, 0);
    animation: twister 0.5s forwards;
  }

  @keyframes twister {
    10% {
      opacity: 1;
    }
    100% {
      transform: rotate(0deg) translate(0);
      opacity: 1;
    }
  }
}
.five {
  span {
    opacity: 0;
    transform: translate(0, -100px) rotate(360deg) scale(0);
    animation: revolveDrop 0.3s forwards;
  }

  @keyframes revolveDrop {
    30% {
      transform: translate(0, -50px) rotate(180deg) scale(1);
    }

    60% {
      transform: translate(0, 20px) scale(0.8) rotate(0deg);
    }

    100% {
      transform: translate(0) scale(1) rotate(0deg);
      opacity: 1;
    }
  }
}
.animate {
  span {
    display: inline-block;
  }
  $n: 20;
  @for $i from 1 through $n {
    span:nth-of-type(#{$i}) {
      animation-delay: calc(0.05s * #{$i - 1} + var(--delay));
    }
  }
}
</style>

vue3+ts版本

<script lang="ts" setup>
import { computed, getCurrentInstance, onMounted, ref } from "vue";
const props = defineProps({
  /**
   * 动画模式
   */
  mode: { type: Number, default: 1 },
  /**
   * 延迟动画时间 1000=1s
   */
  delay: { type: Number, default: 0 },
});
const instance = getCurrentInstance();
const text = ref("");
onMounted(() => {
  let arr = instance!.slots!.default?.()!;
  text.value = arr[0].children as any;
});
/**
 * 计算类名
 */
const animateName = computed(() => {
  const animateClassData: Record<number, string> = {
    1: "one",
    2: "two",
    3: "three",
    4: "four",
    5: "five",
  };
  return animateClassData[props.mode] || "one";
});
</script>
<template>
  <div
    class="animate"
    :class="animateName"
    :style="{ '--delay': `${delay / 1000}s` }"
  >
    <template v-for="item in text.split('')">
      <span style="white-space: pre">{{ item }}</span>
    </template>
  </div>
</template>
<style lang="scss" scoped>
.one {
  span {
    opacity: 0;
    transform: translate(-150px, 0) scale(0.3);
    animation: leftRight 0.5s forwards;
  }
  @keyframes leftRight {
    40% {
      transform: translate(50px, 0) scale(0.7);
      opacity: 1;
    }

    60% {
    }

    80% {
      transform: translate(0) scale(2);
      opacity: 0;
    }

    100% {
      transform: translate(0) scale(1);
      opacity: 1;
    }
  }
}
.two {
  span {
    opacity: 0;
    transform: translate(-150px, -50px) rotate(-180deg) scale(3);
    animation: revolveScale 0.4s forwards;
  }
  @keyframes revolveScale {
    60% {
      transform: translate(20px, 20px) rotate(30deg) scale(0.3);
    }

    100% {
      transform: translate(0) rotate(0) scale(1);
      opacity: 1;
    }
  }
}
.three {
  span {
    opacity: 0;
    transform: translate(200px, -100px) scale(2);
    animation: ballDrop 0.3s forwards;
  }
  @keyframes ballDrop {
    60% {
      transform: translate(0, 20px) rotate(-180deg) scale(0.5);
    }

    100% {
      transform: translate(0) rotate(0deg) scale(1);
      opacity: 1;
    }
  }
}

.four {
  span {
    opacity: 0;
    transform: rotate(-180deg) translate(150px, 0);
    animation: twister 0.5s forwards;
  }

  @keyframes twister {
    10% {
      opacity: 1;
    }
    100% {
      transform: rotate(0deg) translate(0);
      opacity: 1;
    }
  }
}
.five {
  span {
    opacity: 0;
    transform: translate(0, -100px) rotate(360deg) scale(0);
    animation: revolveDrop 0.3s forwards;
  }

  @keyframes revolveDrop {
    30% {
      transform: translate(0, -50px) rotate(180deg) scale(1);
    }

    60% {
      transform: translate(0, 20px) scale(0.8) rotate(0deg);
    }

    100% {
      transform: translate(0) scale(1) rotate(0deg);
      opacity: 1;
    }
  }
}
.animate {
  span {
    display: inline-block;
  }
  $n: 20;
  @for $i from 1 through $n {
    span:nth-of-type(#{$i}) {
      animation-delay: calc(0.05s * #{$i - 1} + var(--delay));
    }
  }
}
</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值