16-transition

一 transition基础用法

 <!-- 自定义类型名称 enter-to-class   enter-active-class   enter-from-class -->

 

<template>
  <div class="content">
    <button @click="flag = !flag">switch</button>
    <!-- 自定义类型名称 enter-to-class   enter-active-class   enter-from-class -->
    <transition name="fade">
      <div class="box" v-if="flag"></div>
    </transition>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const flag = ref<boolean>(true)
</script>

<style lang="less" scoped>
.fade-enter-from {
  width: 0;
  height: 0;
  transform: rotate(360deg);
}
.fade-enter-active {
  transition: all 1.5s ease;
}
.fade-enter-to {
  width: 200px;
  height: 200px;
}
.fade-leave-from {
  width: 200px;
  height: 200px;
  transform: rotate(360deg);
}
.fade-leave-active {
  transition: all 2s ease;
}
.fade-leave-to {
  width: 0;
  height: 0;
}
.box {
  width: 200px;
  height: 200px;
  background: red;
}
.content {
  position: absolute;
  left: 10px;
  top: 10px;
  background: blue;
}
</style>

二transition和animate结合

自定义过度类

enter-from-class       enter-active-class     enter-to-class   
leave-from-class       leave-active-class    leave-to-class

可以自定义class结合动画库animate.css

样式使用less
npm install less less-loader -D 


动画animate.css安装
npm install animate.css --save
import animated from 'animate.css' 
Vue.use(animated)

gsap安装
npm install gsap -S

<template>
  <div class="content">
    <button @click="flag = !flag">switch</button>
    <!-- :duration="500"   :duration="{ enter: 50, leave: 500 }" -->
    <transition
      :duration="{ enter: 50, leave: 500 }"
      enter-active-class="animate__animated animate__fadeIn"
      leave-active-class="animate__animated animate__fadeOut">
      <div class="box" v-if="flag"></div>
    </transition>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import 'animate.css'
const flag = ref<boolean>(true)
</script>

<style lang="less" scoped>
.box {
  width: 200px;
  height: 200px;
  background: red;
}
.content {
  position: absolute;
  left: 10px;
  top: 10px;
}
</style>

 三 tranisition生命周期和gsap

 

 

<template>
  <div class="content">
    <button @click="flag = !flag">switch</button>
    <!-- :duration="500"   :duration="{ enter: 50, leave: 500 }" -->
    <transition
      @before-enter="EnterFrom"
      @enter="EnterActive"
      @after-enter="EnterTo"
      @enter-cancelled="EnterCancel"
      @before-leave="LeaveFrom"
      @leave="Leave"
      @after-leave="LeaveTo"
      @leave-cancelled="LeaveCancel">
      <div class="box" v-if="flag"></div>
    </transition>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import 'animate.css'
const flag = ref<boolean>(true)
const EnterFrom = (el:Element) => {
  console.log('进入之前')
}

const EnterActive = (el:Element, done: Function) => {
  console.log('过度曲线')
  setTimeout(() => {
    done()
  }, 3000)
}

const EnterTo = (el:Element) => {
  console.log('过度完成')
}

const EnterCancel = (el:Element) => {
  console.log('过度效果被打断')
}

const LeaveFrom = (el:Element) => {
  console.log('离开之前')
}

const Leave = (el:Element, done:Function) => {
  console.log('离开过度曲线')
  setTimeout(() => {
    done()
  }, 5000)
}

const LeaveTo = (el:Element) => {
  console.log('离开完成')
}

const LeaveCancel = (el:Element) => {
  console.log('离开过度曲线被打断-----------')
}
</script>

<style lang="less" scoped>
.box {
  width: 200px;
  height: 200px;
  background: red;
}
.content {
  position: absolute;
  left: 10px;
  top: 10px;
}
</style>

使用gsap

 

<template>
  <div class="content">
    <button @click="flag = !flag">switch</button>
    <!-- :duration="500"   :duration="{ enter: 50, leave: 500 }" -->
    <transition
      @before-enter="EnterFrom"
      @enter="EnterActive"
      @leave="Leave">
      <div class="box" v-if="flag"></div>
    </transition>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import gsap from 'gsap'
const flag = ref<boolean>(true)
const EnterFrom = (el:Element) => {
  gsap.set(el, {
    width: 0,
    height: 0,
  })
}

const EnterActive = (el:Element, done: gsap.Callback) => {
  gsap.to(el, {
    width: 200,
    height: 200,
    onComplete: done
  })
}

const Leave = (el:Element, done: gsap.Callback) => {
  gsap.to(el, {
    width: 0,
    height: 0,
    onComplete: done
  })
}

</script>

<style lang="less" scoped>
.box {
  width: 200px;
  height: 200px;
  background: red;
}
.content {
  position: absolute;
  left: 10px;
  top: 10px;
}
</style>

四 appear

 

<template>
  <div class="content">
    <button @click="flag = !flag">switch</button>
    <!-- appear进入页面时候触发效果 -->
    <transition
      appear
      appear-active-class="animated__animated  animate__hinge">
      <div class="box" v-if="flag"></div>
    </transition>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import 'animate.css'
const flag = ref<boolean>(true)

</script>

<style lang="less" scoped>
.box {
  width: 200px;
  height: 200px;
  background: red;
}
.content {
  position: absolute;
  left: 10px;
  top: 10px;
}
</style>

五transition-group

<template>

  <div class="content">
    <button @click="add">add</button><button @click="pop">pop</button>
    <div class="wraps">
      <transition-group
        enter-active-class="animate__animated animate__bounceIn"
        leave-active-class="animate__animated animate__bounceOut">
        <div class="item" v-for="(item, index) in list" :key="index">{{ item }}</div>
      </transition-group>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue'
import 'animate.css'
const list = reactive<number[]>([1, 2, 3, 4, 5])

const add = () => {
  list.push(list.length + 1)
}
const pop = () => {
  list.pop()
}

</script>

<style lang="less" scoped>
.wraps {
  display: flex;
  flex-wrap: wrap;
  word-break: break-all;
  border: 1px solid #ccc;
  .item {
    margin: 10px;
    font-size: 30px;
  }
}
</style>

 六 平面动画效果

安装lodash
npm install lodash -S
npm install @types/lodash -D

 

<template>
  <div>
    <button @click="random">random</button>
    <transition-group class="wraps" tag="div" move-class="mmm">
      <div class="items" v-for="(item, index) in list" :key="item.id">
        {{ item.number }}
      </div>
    </transition-group>
  </div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import _  from 'lodash'
let list = ref(Array.apply(null, { length: 81 } as number[]).map((_, index) => {
  return {
    id: index,
    number: (index % 9) + 1
  }
}))
const random = () => {
  list.value = _.shuffle(list.value)
}
</script>

<style lang="less" scoped>
.wraps {
  display: flex;
  flex-wrap: wrap;
  width: calc(25px * 10 + 9px);
  .items {
    width: 25px;
    height: 25px;
    border: 1px solid #ccc;
    display: flex;
    justify-content: center;
    align-items: center;
  }
}
.mmm {
  transition: all 1s;
}
</style>

七 状态过度

 

<template>
  <div>
    <input v-model="num.current" step="20" type="number"/>
    <div>
      {{ num.tweendNumber.toFixed(0) }}
    </div>
  </div>
</template>

<script setup lang="ts">
import {  reactive, watch } from 'vue'
import gsap from 'gsap'

const num = reactive({
  current: 0,
  tweendNumber: 0
})

watch(() => num.current, (newVal, oldVal) => {
  gsap.to(num, {
    duration: 1,
    tweendNumber: newVal
  })
})

</script>

<style lang="less" scoped>

</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值