最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue3中實現(xiàn)過渡動畫的方法小結(jié)

 更新時間:2024年10月31日 11:25:40   作者:熊的貓  
這篇文章主要為大家詳細(xì)介紹了Vue3中實現(xiàn)過渡動畫的一些常用方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

前言

首先拋開 vue 本身,假設(shè)需要給某個 Dom 元素實現(xiàn)一些過渡動畫,那么下面這些事是必須的:

  • 實現(xiàn)目標(biāo)元素不同時刻下的樣式,常見做法就是抽取在不同的 css 選擇器中
  • 根據(jù)不同時刻切換不同的 css 選擇器以達(dá)到樣式的變化
  • 設(shè)置樣式過度的方式和時間,如:transition: all .5s ease

而在 vue 中實現(xiàn)過渡動畫,那就不得不提到其內(nèi)置的 transition 組件,而 transition 組件幫我們實現(xiàn)了第一件事,就是對組件不同時刻設(shè)置不同的 css 選擇器,甚至于可以對這個選擇器進(jìn)行自定義,因此,我們只需要完成后面兩件事即可,當(dāng)然這里對 transition 組件的用法就不過多進(jìn)行介紹.

當(dāng)然這里的實現(xiàn)動畫的方式,會從下面幾個方面來實現(xiàn):

  • CSS3 transition 屬性
  • CSS3 @keyframes 幀動畫
  • 第三方庫 animate.css
  • 第三方庫 gsap —— GreenSock Animation Platform,在官方文檔中有提及的

<transition> 組件 + CSS3 transition 屬性

話不多說,直接來實現(xiàn)一個簡單的 顯示/隱藏 的過渡動畫:

  • 顯示時:從左側(cè)滑入,且透明度增大
  • 隱藏時:從右側(cè)滑出,且透明度減小

// toggle.vue
<script setup lang="ts">
import { ref } from 'vue'

const isShow = ref(true)

const toggle = () => {
  isShow.value = !isShow.value
}

</script>

<template>
  <transition name="fade">
    <h1 v-if="isShow">this is h1 content!</h1>
  </transition>
  <div>
    <button @click="toggle">toggle</button>
  </div>
</template>

<style>
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

.fade-enter-from {
  transform: translateX(-30px);
}

.fade-enter-to ,
.fade-leave-to {
  transform: translateX(30px);
}

.fade-enter-to,
.fade-leave-from {
  opacity: 1;
}

.fade-enter-active,
.fade-leave-active {
  transition: all .5s ease;
}

h1 {
  width: 300px;
  margin: 10px auto;
}
</style>

<transition> 組件 + CSS3 @keyframes 幀動畫

css 中除了使用 transition 屬性實現(xiàn)不同樣式間的過渡,也可以直接使用 @keyframes 來實現(xiàn)幀動畫.

// hang.vue
<script setup lang="ts">
import { ref } from 'vue'

const isShow = ref(true)

const hang = () => {
  isShow.value = !isShow.value
}

</script>

<template>
  <transition name="fade">
    <h1 v-if="isShow">this is h1 content!</h1>
  </transition>
  <div>
    <button @click="hang">trigger</button>
  </div>
</template>

<style>
.fade-enter-active {
  animation: hang 0.5s 1 ease;
}

.fade-leave-active {
  animation: hang 0.5s 1 ease reverse;
}

@keyframes hang {
  0% {
    transform: translateY(30px) rotateZ(30deg);
    opacity: 0;
  }

  25% {
    transform: translateY(24px) rotateZ(24deg);
    opacity: 0.3;
  }

  50% {
    transform: translateY(18px) rotateZ(18deg);
    opacity: 0.6;
  }

  75% {
    transform: translateY(12px) rotateZ(12deg);
    opacity: 0.8;
  }

  100% {
    transform: translateY(-5px) rotateZ(0deg);
    opacity: 1;
  }
}

h1 {
  width: 300px;
  margin: 10px auto;
}
</style>

<transition> 組件 + 第三方庫 animate.css

直接使用 animate.css 中對應(yīng)效果的動畫名,配合 animation 屬性進(jìn)行使用即可.

對應(yīng)的效果和動畫名可通過 animat.style 效果預(yù)覽 查看

// animate.vue
<script setup lang="ts">
import { ref } from 'vue'
import './animate.css'

const isShow = ref(true)

const hang = () => {
  isShow.value = !isShow.value
}

</script>

<template>
  <transition name="fade">
    <h1 v-if="isShow">this is h1 content!</h1>
  </transition>
  <div>
    <button @click="hang">trigger</button>
  </div>
</template>

<style>
.fade-enter-active {
  animation: flip 0.5s 1 ease;
}

.fade-leave-active {
  animation: flip 0.5s 1 ease reverse;
}

h1 {
  width: 300px;
  margin: 10px auto;
}
</style>

<transition> 組件 + 第三方庫 gsap

通過上面幾個簡單的動畫例子,其實不難發(fā)現(xiàn),無論是自己實現(xiàn)動畫,還是使用已有的 css 樣式庫都有一個缺點,就是不夠靈活,比如:某些 css 屬性值只能是一個不變的值

如果有些場景需要一些更復(fù)雜和靈活的 css 樣式,那么顯然前面提到的方式并不符合實際需求,換句話說,如果需要在 js 中實現(xiàn)樣式的過渡,以及設(shè)置動態(tài)的 css 樣式屬性值時,就有必要使用一些第三方庫,如:gsap,幫助我們更方便的實現(xiàn)需求.

// gsap.vue
<script setup>
import { ref } from "vue";
import gsap from "gsap";

let timeScaleTween = null;

const enter = (el) => {
  const tl = gsap.timeline(),
    atom = el,
    dur = 2,
    del = 0.5;

  tl.fromTo(
    ".electron",
    { rotationX: 90 },
    {
      rotationZ: -360,
      rotationX: 90,
      ease: "none",
      duration: dur,
      stagger: {
        each: -del,
        repeat: -1,
      },
    },
    0
  );
  tl.to(
    ".path",
    {
      rotationZ: 360,
      ease: "none",
      duration: dur,
      stagger: {
        each: -del,
        repeat: -1,
      },
    },
    0
  );

  // Add a rotation to the whole atom
  gsap.set(atom, { transformOrigin: "center center" });
  gsap.to(atom, { rotation: 360, ease: "none", repeat: -1, duration: 300 });

  // Skip the loading
  tl.progress(0.9999);

  timeScaleTween = gsap.to(tl, {
    duration: 0.75,
    timeScale: 0.1,
    paused: true,
  });
};

const slow = () => {
  timeScaleTween.play()
}

const reverse = () => {
  timeScaleTween.reverse()
}

const isShow = ref(false);

const show = () => {
  isShow.value = true
};
</script>

<template>
  <transition name="fade" @enter="enter">
    <div class="atom" v-if="isShow">
      <div class="orbit">
        <div class="path">
          <div class="electron"></div>
        </div>
      </div>
      <div class="orbit">
        <div class="path">
          <div class="electron"></div>
        </div>
      </div>
      <div class="orbit">
        <div class="path">
          <div class="electron"></div>
        </div>
      </div>
      <div class="orbit">
        <div class="path">
          <div class="electron"></div>
        </div>
      </div>
      <div class="nucleus"></div>
    </div>
  </transition>
  <div>
    <button @click="show">show</button>
    <button @click="slow">slow</button>
    <button @click="reverse">reverse</button>
  </div>
</template>

<style>
@import url("https://fonts.googleapis.com/css?family=Signika+Negative:300,400&display=swap");
body {
  font-family: "Signika Negative", sans-serif;
  font-weight: 300;
  background: grey;
  overflow: hidden;
  color: white;
  text-align: center;
}

.atom {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 300px;
  height: 300px;
  perspective: 1000;
  margin-left: -170px;
  margin-top: -146px;
  transform-style: preserve-3d;
}

.nucleus {
  position: absolute;
  top: 50%;
  left: 50%;
  margin: -10px 0 0 -10px;
  width: 25px;
  height: 25px;
  border-radius: 50%;
  background: #272727;
}

.orbit {
  position: absolute;
  top: 0;
  left: 0;
  width: 300px;
  height: 300px;
  border-radius: 300px;
  border: 5px solid #ccc;
  transform-style: preserve-3d;
  transform: rotateX(80deg) rotateY(20deg);
}

.orbit:nth-child(2) {
  transform: rotateX(80deg) rotateY(70deg);
}
.orbit:nth-child(3) {
  transform: rotateX(80deg) rotateY(-20deg);
}
.orbit:nth-child(4) {
  transform: rotateX(80deg) rotateY(-50deg);
}

.path {
  width: 300px;
  height: 300px;
  position: relative;
  transform-style: preserve-3d;
}

.electron {
  position: absolute;
  top: -5px;
  left: 50%;
  margin-left: -5px;
  width: 10px;
  height: 10px;
  border-radius: 10px;
  background: #ccc;
}
button{
  margin: 10px;
}
</style>

本文通過四種方式實現(xiàn)了一些簡單動畫,但其實在 vue 中實現(xiàn)動畫也不一定要使用 transition 組件,具體場景還是得具體分析.

以上就是Vue3中實現(xiàn)過渡動畫的方法小結(jié)的詳細(xì)內(nèi)容,更多關(guān)于Vue3過渡動畫的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vue 使用axios 數(shù)據(jù)請求第三方插件的使用教程詳解

    vue 使用axios 數(shù)據(jù)請求第三方插件的使用教程詳解

    這篇文章主要介紹了vue 使用axios 數(shù)據(jù)請求第三方插件的使用 ,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-07-07
  • vue實現(xiàn)頭像上傳功能

    vue實現(xiàn)頭像上傳功能

    這篇文章主要為大家詳細(xì)介紹了vue實現(xiàn)頭像上傳功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • vue+springboot實現(xiàn)項目的CORS跨域請求

    vue+springboot實現(xiàn)項目的CORS跨域請求

    這篇文章主要介紹了vue+springboot實現(xiàn)項目的CORS跨域請求,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • uniapp-vue3項目中引入高德地圖的具體操作

    uniapp-vue3項目中引入高德地圖的具體操作

    這篇文章主要介紹了uniapp-vue3項目中引入高德地圖的具體操作,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2025-05-05
  • vuex中store存儲store.commit和store.dispatch的用法

    vuex中store存儲store.commit和store.dispatch的用法

    這篇文章主要介紹了vuex中store存儲store.commit和store.dispatch的用法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07
  • Vue3+vite創(chuàng)建項目方式

    Vue3+vite創(chuàng)建項目方式

    本文介紹了如何使用Vite創(chuàng)建Vue項目,包括版本升級、命令變化以及配置vue-router、Vuex和AntDesignVue的方法,同時,也提供了降級Vue?CLI以兼容Vue2項目的步驟
    2024-12-12
  • vue?如何刪除數(shù)組中的某一條數(shù)據(jù)

    vue?如何刪除數(shù)組中的某一條數(shù)據(jù)

    這篇文章主要介紹了vue?如何刪除數(shù)組中的某一條數(shù)據(jù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Vue3中ref數(shù)組的監(jiān)聽實現(xiàn)方式

    Vue3中ref數(shù)組的監(jiān)聽實現(xiàn)方式

    Vue3中監(jiān)聽ref定義的數(shù)組,需根據(jù)監(jiān)聽需求選擇合適的監(jiān)聽方法,對于空數(shù)組,推薦使用深度監(jiān)聽來捕捉數(shù)組內(nèi)部變化,同時,確保修改數(shù)組的方式是響應(yīng)式的,以保證監(jiān)聽器能正常工作,根據(jù)具體需求,可以選擇直接深度監(jiān)聽、監(jiān)聽數(shù)組長度變化或提取屬性監(jiān)聽等方案
    2025-10-10
  • element-ui中select下拉框加載大數(shù)據(jù)渲染優(yōu)化方式

    element-ui中select下拉框加載大數(shù)據(jù)渲染優(yōu)化方式

    這篇文章主要介紹了element-ui中select下拉框加載大數(shù)據(jù)渲染優(yōu)化方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • vue 將頁面公用的頭部組件化的方法

    vue 將頁面公用的頭部組件化的方法

    本篇文章主要介紹了vue 將頁面公用的頭部組件化的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12

最新評論

道真| 福泉市| 陆川县| 鹤壁市| 黄骅市| 新化县| 玛纳斯县| 淅川县| 当雄县| 赤峰市| 西峡县| 秦安县| 合肥市| 奉化市| 成武县| 青岛市| 临泉县| 福清市| 饶河县| 南汇区| 枞阳县| 无锡市| 文化| 黄骅市| 白水县| 威远县| 子洲县| 三亚市| 惠州市| 墨竹工卡县| 龙里县| 永川市| 沈丘县| 和林格尔县| 肃南| 上蔡县| 通州区| 郧西县| 桃园市| 新津县| 浮梁县|