關於購物車添加按鈕的動畫(vue.js)

来源:http://www.cnblogs.com/Byme/archive/2017/12/18/8059395.html
-Advertisement-
Play Games

來自:https://segmentfault.com/a/1190000009294321 (侵刪) git 源碼地址 https://github.com/ustbhuangyi/vue-sell(侵刪) html代碼 生成一個動畫小球的div,並且生成五個小球,五個是為了生成一定數量的小球來作 ...


來自:https://segmentfault.com/a/1190000009294321 (侵刪)

git 源碼地址  https://github.com/ustbhuangyi/vue-sell(侵刪)

 

html代碼

  • 生成一個動畫小球的div,並且生成五個小球,五個是為了生成一定數量的小球來作為操作使用,按照小球動畫的速度,一般來說五個也可以保證有足夠的小球數量來運行動畫

  • 動畫的內容分別是外層和內層,外層控制動畫小球的軌道和方向,內層控制動畫小球的運行狀態

  • 動畫使用vue的js鉤子實現

  • 因為小球動畫只有一個方向(只執行單方向從上到下滾落),所以只用了before-enter,enter,after-enter

  • 用v-show控制小球的可見性,在動畫執行期間可見,其餘時候隱藏

 
    <div class="ball-container">
      <div v-for="ball in balls">
      //用了兩種方式的動畫,css和js鉤子
        <transition name="drop" @before-enter="beforeDrop" @enter="dropping" @after-enter="afterDrop">
        //外層動畫
          <div class="ball" v-show="ball.show">
          //內層動畫
            <div class="inner inner-hook"></div>
          </div>
        </transition>
      </div>
    </div>

js代碼

  • 設置了balls數組來代表五個小球

  • 設置了dropBalls數組正在運行的小球

  •  data(){
          return {
            balls: [
              {show: false},
              {show: false},
              {show: false},
              {show: false},
              {show: false}
            ],
            dropBalls: []
          }
        },
    • 只要觸發了drop事件,不止是drop事件裡面的代碼會執行,另外幾個vue的js監聽鉤子也會一起按順序執行

      • 觸發了drop事件

      • beforeDrop開始執行

      • dropping開始執行

      • afterDrop開始執行

    • drop事件的觸發可以通過點擊cartcontrol組件的添加小球按鈕addCart事件觸發使用$emit,也可以父組件this.$refs.shopcart.drop(target);直接觸發

      • 這麼做的目的是實現,在子組件cartcontrol點擊之後,可以將該dom傳給父組件goods然後再傳給子組件shopcart,(因為目前他們之間的通道就是這樣,shopcart子組件並沒有導入cartcontrol子組件,所以沒有直接通訊)這樣就實現了多個組件之間的通訊,從而可以實現需求,例如這裡就是實現點擊子組件cartcontrol後添加一個動畫,將小球滑落到另外一個組件shopcart

    • $emit是觸發當前實例上的事件。附加參數都會傳給監聽器回調。

    • methods: {
            drop(el) { 
            //觸發一次事件就會將所有小球進行遍歷
              for (let i = 0; i < this.balls.length; i++) {
                let ball = this.balls[i];
                if (!ball.show) { //將false的小球放到dropBalls
                  ball.show = true;
                  ball.el = el; //設置小球的el屬性為一個dom對象
                  this.dropBalls.push(ball); 
                  return;
                }
              }
            },
      
            beforeDrop(el){ //這個方法的執行是因為這是一個vue的監聽事件
              let count = this.balls.length;
              while (count--) {
                let ball = this.balls[count];
                if (ball.show) {
                  let rect = ball.el.getBoundingClientRect(); //獲取小球的相對於視口的位移(小球高度)
                  let x = rect.left - 32;
                  let y = -(window.innerHeight - rect.top - 22); //負數,因為是從左上角往下的的方向
                  el.style.display = ''; //清空display
                  el.style.webkitTransform = `translate3d(0,${y}px,0)`; 
                  el.style.transform = `translate3d(0,${y}px,0)`;
                  //處理內層動畫
                  let inner = el.getElementsByClassName('inner-hook')[0]; //使用inner-hook類來單純被js操作
                  inner.style.webkitTransform = `translate3d(${x}px,0,0)`;
                  inner.style.transform = `translate3d(${x}px,0,0)`;
                }
              }
            },
      
            dropping(el, done) { //這個方法的執行是因為這是一個vue的監聽事件
              /* eslint-disable no-unused-vars */
              let rf = el.offsetHeight; //觸發重繪html
              this.$nextTick(() => { //讓動畫效果非同步執行,提高性能
                el.style.webkitTransform = 'translate3d(0,0,0)';
                el.style.transform = 'translate3d(0,0,0)';
                //處理內層動畫
                let inner = el.getElementsByClassName('inner-hook')[0]; //使用inner-hook類來單純被js操作
                inner.style.webkitTransform = 'translate3d(0,0,0)';
                inner.style.transform = 'translate3d(0,0,0)';
                el.addEventListener('transitionend', done); //Vue為了知道過渡的完成,必須設置相應的事件監聽器。
              });
            },
      
            afterDrop(el) { //這個方法的執行是因為這是一個vue的監聽事件
              let ball = this.dropBalls.shift(); //完成一次動畫就刪除一個dropBalls的小球
              if (ball) {
                ball.show = false;
                el.style.display = 'none'; //隱藏小球
              }
            }
          }
      • 關於transitionend

      • 關於drop方法,是實現每一個ball的show屬性和el屬性處理,並且點擊一次會自動將一個小球放到dropBalls數組裡面,放到裡面就代表的是一個小球已經被開始執行動畫,但是由於動畫是非同步的,所以先主動設置.

      • 關於getBoundingClientRect(位移的計算是從左上角開始)

        • 使用getBoundingClientRect獲取到當前元素的坐標,然後需要位移的left減去元素的寬獲取真正的最終位移x坐標

        • 使用getBoundingClientRect獲取到當前元素的坐標,然後需要當前屏幕的高度減去元素的top再減去元素本身的高度獲取到真正的最終位移y坐標,並且這個是負數,因為是從左上角往下的方向

      • 關於html重繪

        • 因為瀏覽器對於重繪是有要求並且是有隊列完成的,這是主要為了性能,雖然動畫隱藏了小球display none,但沒有觸發html重繪,或者說沒有立即觸發html重繪,所以需要手動

        • let rf = el.offsetHeight; 這是一個手動觸發html重繪的方法

        • 網頁性能管理詳解

        • 高性能JavaScript 重排與重繪

      css代碼

    • .ball-container
            .ball
              position: fixed //小球動畫必須脫離html佈局流
              left: 32px
              bottom: 22px
              z-index: 200 
              transition: all 0.4s cubic-bezier(0.49, -0.29, 0.75, 0.41)
              .inner
                width: 16px
                height: 16px
                border-radius: 50%
                background: rgb(0, 160, 220)
                transition: all 0.4s linear

      關於cubic-bezier(0.49, -0.29, 0.75, 0.41),是動畫拋物曲線(貝塞爾曲線)的配置,基於css3實現,http://cubic-bezier.com/#.17,.67,.83,.67,參考貝塞爾曲線與CSS3動畫、SVG和canvas的基情 ,至於拋物線放在外層就是為了控制內層的元素的軌道和方向的.


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 小時候懷念的貪吃蛇游戲~~啦啦啦 ...
  • 所謂的清除浮動實際上就是清除浮動帶來的影響。那麼浮動會帶來什麼影響呢?下麵先看一個正常的例子: 定義一個父div1和子div2,將子div2設置成左浮動。 現象為: 當把div1的height=200px這句話註釋之後就會出現浮動的影響這個問題: 我們發現div1的背景顏色(粉色)沒有了。這個現象可 ...
  • 如圖所示,就是一個5*5的螺旋矩陣 我的思路如下: 第一步:拆分“層”數組 把矩陣根據層數分成N個連續的自然數組,根據如果每一層寬度為n的話,那麼每一層一共就有4(n-1)個數字,且當n=1時個數為1 拆分數字代碼 迴圈調用,n每次減2 第二部:將其組裝為一個“沙漏”數組 將第一步拆分好的數組取第1 ...
  • 原文鏈接:https://www.cnblogs.com/itbainianmei/p/6062249.html 1.每個組件模板template,不再支持片段代碼 之前: <template> <h3>vue-router+vue-loader</h3> <p>hshsh</p> </templa ...
  • 在把微信自定義菜單編輯工具加上又拍雲CDN嘗嘗鮮時,發現頁面上的JS莫名的報錯了。在排查許久無果後,突然想起CDN有個頁面壓縮功能。 菜單編輯器頁面部分JS腳本使用到了頁面註釋進行了語法綁定,CDN開啟壓縮後,直接去除了語法綁定代碼導致程式報錯。 ...
  • IE瀏覽器下的漸變背景 IE瀏覽器下漸變背景的使用需要使用IE的漸變濾鏡。如下代碼: filter: progid:DXImageTransform.Microsoft.gradient(startcolorstr=red,endcolorstr=blue,gradientType=1); 相關說明 ...
  • 萬事開頭難,一個好的Hello World程式可以節省我們好多的學習時間,幫助我們快速入門。Hello World程式之所以是入門必讀必會,就是因為其代碼量少,簡單易懂。但我覺得,還應該做到功能豐富,涉及的知識點多。這樣才是一個好的初學者入門指引程式。 之所以選擇Vue,不僅因為其流行,還因為其輕量 ...
  • 前話 好久沒寫教程了(可能會誤導新手的菜鳥教程( ̄▽ ̄)")。 這是我的github,歡迎前端大大們和我一起學習交流 "https://github.com/pwcong" 最近入職公司做前端實習,這幾個星期來學到了移動端H5頁面適配。(以前根本沒做過移動端網頁/(ㄒoㄒ)/~~,還是微信端的) 所 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...