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

前言

由于自己很喜欢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>

猜你喜欢

转载自blog.csdn.net/wz9608/article/details/132341104