AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

FLIP,一種高端優雅但簡單易用的前端動畫思維

來源: 責編: 時間:2024-05-16 08:58:35 126觀看
導讀有一種能夠快速實現復雜動畫交互的動畫思維 FLIP,為了介紹這個動畫思維,我準備了三個案例。一、FLIPFLIP 是四個單詞的首字母,First、Last、Invert、Play,這四個單詞給我們提供了完成動畫的具體思路。First 表示元素初始

79b28資訊網——每日最新資訊28at.com

有一種能夠快速實現復雜動畫交互的動畫思維 FLIP,為了介紹這個動畫思維,我準備了三個案例。79b28資訊網——每日最新資訊28at.com

一、FLIP

FLIP 是四個單詞的首字母,First、Last、Invert、Play,這四個單詞給我們提供了完成動畫的具體思路。79b28資訊網——每日最新資訊28at.com

First 表示元素初始時的具體信息,在 html 環境中,這個事情是比較容易就能做到的,我們可以利用 getBoundingClientRect 或者 getComputedStyle 來拿到元素的初始信息。79b28資訊網——每日最新資訊28at.com

Last 表示元素結束時的位置信息。此時我們可以直接改變元素的位置,把元素放到新的節點上去。這樣我們就可以直接使用同樣的方式拿到結束時的元素具體信息。79b28資訊網——每日最新資訊28at.com

Invert 表示倒置。雖然元素到了結束時的節點位置,但是視覺上我們并沒有看到,此時要設計讓元素動畫從 First 通過動畫的方式變換到 Last,剛好我們又記錄了動畫的開始和結束信息,因此我們可以利用自己熟悉的動畫方式來完成 Invert。79b28資訊網——每日最新資訊28at.com

Play 表示動畫開始執行。在代碼上通常 Invert 表示傳參,Play 表示具體的動畫執行。79b28資訊網——每日最新資訊28at.com

接下來我們使用三個案例來進一步學習這個動畫思想。79b28資訊網——每日最新資訊28at.com

二、案例一:元素 X 軸位置隨機變化

案例效果如圖所示。79b28資訊網——每日最新資訊28at.com

79b28資訊網——每日最新資訊28at.com

案例的 html 結構如下:79b28資訊網——每日最新資訊28at.com

<div id="container">  <div class="item">1</div>  <div class="item">2</div>  <div class="item">3</div>  <div class="item">4</div>  <div class="item">5</div></div><button id="sort">隨機排序</button>

先獲取兩個關鍵 DOM 對象。79b28資訊網——每日最新資訊28at.com

const container = document.getElementById('container')const sortBtn = document.getElementById('sort')

First,記錄元素初始位置信息。此時我們把開始的 X 位置信息保存在子節點對象上,我們也可以單獨另起一個數組來保存所有子節點的具體信息。79b28資訊網——每日最新資訊28at.com

// 記錄開始位置信息function record(container) {  const all = [...container.children]  all.forEach((item, i) => {    const rect = item.getBoundingClientRect()    item.startX = rect.left  })}

Last,直接改變元素的節點位置。因為改變之后,元素在新的節點上,那么我們這里就可以單獨快捷獲取元素改變之后的位置信息,所以可以封裝一個方法,只改變元素的節點位置信息,而在需要的時候獲取 Last 即可。79b28資訊網——每日最新資訊28at.com

當然也可以單獨在這一步把屬性位置信息保存起來。79b28資訊網——每日最新資訊28at.com

function change() {  const all = [...container.children]  const len = all.length  all.forEach((item, i) => {    const newIndex = Math.floor(Math.random() * len)    if (newIndex !== i) {      const nextDOM = item.nextElementSibling      container.insertBefore(item, all[newIndex])      container.insertBefore(all[newIndex], nextDOM)    }  })}

Invert 和 play 在代碼實現上往往會耦合在一起,Invert 表示參數傳入,play 表示動畫執行。因此我們可以最后再定義一個方法 play 表示動畫的執行。79b28資訊網——每日最新資訊28at.com

function play(container) {  const all = [...container.children]  const len = all.length  all.forEach((item, i) => {    const rect = item.getBoundingClientRect()    const currentX = rect.left    item.animate([      { transform: `translateX(${item.startX - currentX}px)` },      { transform: 'translateX(0px)' }    ], {duration: 600})  })}

這里我使用了一個 DOM 元素自帶的 animate 方法,來完成動畫的實現,該方法目前還是一個實驗性的 api,在 2022 年提出,目前最新版的 chrome 瀏覽器已經支持。79b28資訊網——每日最新資訊28at.com

該動畫接口使用起來也比較簡單,跟 keyframes 類似。79b28資訊網——每日最新資訊28at.com

animate(keyframes, options)

keyframes 表示關鍵幀數組,options 表示動畫持續時間,或者包含多個時間屬性,用于配置動畫函數或者 iterations、delay 等常見屬性,與 css 的動畫屬性基本保持一致。79b28資訊網——每日最新資訊28at.com

你也可以自己封裝一個類似的方法,或者使用成熟的第三方工具庫,能達到類似效果的方式也比較多。79b28資訊網——每日最新資訊28at.com

然后在點擊按鈕時,執行即可。79b28資訊網——每日最新資訊28at.com

sortBtn.onclick = () => {  record(container)  change()  play(container)}

三、案例二:多屬性變化

案例效果展示如圖:79b28資訊網——每日最新資訊28at.com

79b28資訊網——每日最新資訊28at.com

元素多屬性動畫并不會增加多少實現復雜度,只是多記錄幾個元素而已。這個案例包含了 x/y/backgroundColor 三個屬性。79b28資訊網——每日最新資訊28at.com

First,記錄初始信息。79b28資訊網——每日最新資訊28at.com

// 記錄開始位置信息function record(container) {  const all = [...container.children]  all.forEach((item, i) => {    const rect = item.getBoundingClientRect()    item.startX = rect.left    item.startY = rect.top    item.bgColor = getComputedStyle(item)['backgroundColor']  })}

Last,直接改變元素節點位置。79b28資訊網——每日最新資訊28at.com

因為改變節點位置之后,能夠輕易獲取到元素新的位置的具體屬性,所以這一步可以稱之為 Last。79b28資訊網——每日最新資訊28at.com

function change() {  const all = [...container.children]  const len = all.length  all.forEach((item, i) => {    const newIndex = Math.floor(Math.random() * len)    if (newIndex !== i) {      const nextDOM = item.nextElementSibling      container.insertBefore(item, all[newIndex])      container.insertBefore(all[newIndex], nextDOM)    }  })}

Invert and Play。79b28資訊網——每日最新資訊28at.com

function play(container) {  const all = [...container.children]  const len = all.length  all.forEach((item, i) => {    const rect = item.getBoundingClientRect()    const currentX = rect.left    const currentY = rect.top    const bgColor = getComputedStyle(item, false)["backgroundColor"]    item.animate([      { transform: `translate(${item.startX - currentX}px, ${item.startY - currentY}px)`, backgroundColor: item.bgColor },      { transform: 'translate(0px, 0px)', backgroundColor: bgColor }    ], {duration: 600})  })}

最后,點擊執行。79b28資訊網——每日最新資訊28at.com

sortBtn.onclick = () => {  record(container)  change()  play(container)}

四、案例三:共享元素動畫

上面那兩個案例,在實踐中基本上沒什么用,主要用于輔助學習。因此大家可能對于高級感和優雅感的體會不是那么深刻。79b28資訊網——每日最新資訊28at.com

第三個案例則以在實踐中,在前端很少有項目能夠做到的共享元素動畫,來為大家介紹這種動畫思想方案的厲害之處。79b28資訊網——每日最新資訊28at.com

79b28資訊網——每日最新資訊28at.com

共享元素動畫在前端是一個很少被提及的概念,但是在客戶端的開發中,卻已經運用非常廣泛。79b28資訊網——每日最新資訊28at.com

79b28資訊網——每日最新資訊28at.com

對于前端而言,這代表了未來頁面交互的主要發展方向。例如在小紅書的 web 端已經實現了該功能。79b28資訊網——每日最新資訊28at.com

在 FLIP 的指導思想下,該功能實現起來也并不復雜。79b28資訊網——每日最新資訊28at.com

First,記錄元素的初始信息。79b28資訊網——每日最新資訊28at.com

const all = [...list.children]// 記錄開始位置信息all.forEach((item, i) => {  const rect = item.getBoundingClientRect()  item.startX = rect.left  item.startY = rect.top  item.width = rect.width  item.height = rect.height})

當我們點擊元素時,此時有兩個元素位置信息在發生變化,一個是背景彈窗。他的變化比較簡單,就是透明度的變化,因此我們不用記錄他的信息。另外一個就是共享的元素 item,此時我們記錄了四個信息:startX、startY、width、height。79b28資訊網——每日最新資訊28at.com

Last,點擊元素之后,出現彈窗。此時我們把相關的兩個節點插入到正確的位置上即可。79b28資訊網——每日最新資訊28at.com

function change(element) {  current = element.cloneNode(true)  modal = document.createElement('div')  modal.id = 'modal'  modal.appendChild(current)  document.body.appendChild(modal)}

Invert and Play. 也是比較簡單,就是獲取新節點的位置,然后設置動畫即可。79b28資訊網——每日最新資訊28at.com

function play(preItem) {  modal.animate([    {backgroundColor: `rgba(0, 0, 0, 0)`},    {backgroundColor: `rgba(0, 0, 0, ${0.3})`}  ], {duration: 600})  const rect = current.getBoundingClientRect()  const currentX = rect.left  const currentY = rect.top  const width = rect.width  const height = rect.height  const x = preItem.startX - currentX - (width - preItem.width) / 2  const y = preItem.startY - currentY - (height - preItem.height) / 2  console.log(x, y)  current.animate([    {      transform: `translate(${x}px, ${y}px)`,      width: `${preItem.width}px`,      height: `${preItem.height}px`    },    {      transform: 'translate(0px, 0px)',      height: `${height}px`,      width: `${width}px`    }  ], {duration: 600})}

最后給每個元素添加點擊事件。79b28資訊網——每日最新資訊28at.com

all.forEach((item, i) => {  item.onclick = (event) => {    change(event.target)    play(event.target)  }})

彈窗上也需要新增一個點擊事件,用于執行彈窗消失的動畫。79b28資訊網——每日最新資訊28at.com

modal.onclick = () => {  const ani = modal.animate([    {backgroundColor: `rgba(0, 0, 0, ${0.3})`},    {backgroundColor: `rgba(0, 0, 0, 0)`}  ], {duration: 600})  const rect = current.getBoundingClientRect()  const currentX = rect.left  const currentY = rect.top  const width = rect.width  const height = rect.height  const x = element.startX - currentX - (width - element.width) / 2  const y = element.startY - currentY - 100  current.animate([    {      transform: 'translate(0px, 0px)',      height: `${height}px`,      width: `${width}px`    },    {      transform: `translate(${x}px, ${y}px)`,      width: `${element.width}px`,      height: `${element.height}px`    },  ], {duration: 600})  console.log(x, y)  ani.onfinish = () => {    modal.remove()  }}

并在運動結束之后,刪除彈窗節點。79b28資訊網——每日最新資訊28at.com

ani.onfinish = () => {  modal.remove()}

一個共享元素動畫,就這么簡單的實現了。79b28資訊網——每日最新資訊28at.com

五、共享元素動畫擴展思考

如果我們要結合路由切換轉場來實現共享元素動畫,其實實現原理也是一樣的,非常的簡單,我們只需要在路由切換時,把共享元素的初始位置信息記錄下來并作為參數傳遞給下一個頁面即可。79b28資訊網——每日最新資訊28at.com

也就是說,我們只需要把這里的兩個點擊事件,結合路由事件和參數傳遞,就能做到跟小紅書一樣的共享元素路由轉場效果。79b28資訊網——每日最新資訊28at.com

不過至于如何封裝讓代碼更加簡潔,本文就不再擴展啦,交給大家自己思考。79b28資訊網——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-88310-0.htmlFLIP,一種高端優雅但簡單易用的前端動畫思維

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 詳解 PyTypeObject,Python 類型對象的載體

下一篇: Android:excludeFromRecents屬性使用分析

標簽:
  • 熱門焦點
  • 6月iOS設備好評榜:第一蟬聯榜首近一年

    作為安兔兔各種榜單里變化最小的那個,2023年6月的iOS好評榜和上個月相比沒有任何排名上的變化,僅僅是部分設備好評率的下降,長年累月的用戶評價和逐漸退出市場的老款機器讓這
  • 掘力計劃第 20 期:Flutter 混合開發的混亂之治

    在掘力計劃系列活動第20場,《Flutter 開發實戰詳解》作者,掘金優秀作者,Github GSY 系列目負責人戀貓的小郭分享了Flutter 混合開發的混亂之治。Flutter 基于自研的 Skia 引擎
  • 分布式系統中的CAP理論,面試必問,你理解了嘛?

    對于剛剛接觸分布式系統的小伙伴們來說,一提起分布式系統,就感覺高大上,深不可測。而且看了很多書和視頻還是一臉懵逼。這篇文章主要使用大白話的方式,帶你理解一下分布式系統
  • 微信語音大揭秘:為什么禁止轉發?

    大家好,我是你們的小米。今天,我要和大家聊一個有趣的話題:為什么微信語音不可以轉發?這是一個我們經常在日常使用中遇到的問題,也是一個讓很多人好奇的問題。讓我們一起來揭開這
  • 三萬字盤點 Spring 九大核心基礎功能

    大家好,我是三友~~今天來跟大家聊一聊Spring的9大核心基礎功能。話不多說,先上目錄:圖片友情提示,本文過長,建議收藏,嘿嘿嘿!一、資源管理資源管理是Spring的一個核心的基礎功能,不
  • Python異步IO編程的進程/線程通信實現

    這篇文章再講3種方式,同時講4中進程間通信的方式一、 Python 中線程間通信的實現方式共享變量共享變量是多個線程可以共同訪問的變量。在Python中,可以使用threading模塊中的L
  • 支持aptX Lossless無損傳輸 iQOO TWS 1賽道版發布限時優惠價369元

    2023年7月4日,“無損音質,聲動人心”iQOO TWS 1正式發布,支持aptX Lossless無損傳輸,限時優惠價369元。iQOO TWS 1耳機率先支持端到端aptX Lossless無
  • 朋友圈可以修改可見范圍了 蘋果用戶可率先體驗

    近日,iOS用戶迎來微信8.0.27正式版更新,除了可更換二維碼背景外,還新增了多項實用功能。在新版微信中,朋友圈終于可以修改可見范圍,簡單來說就是已發布的朋友圈
  • DRAM存儲器10月價格下跌,NAND閃存本月價格與上月持平

    10月30日,據韓國媒體消息,自今年年初以來一直在上漲的 DRAM 存儲器的交易價格僅在本月就下跌了近 10%,此次是全年首次降價,而NAND 閃存本月價格與上月持平。市
Top