Bläddra i källkod

新增购物车加入动画

shenjj 7 år sedan
förälder
incheckning
a59a4634c8
4 ändrade filer med 109 tillägg och 75 borttagningar
  1. 1 16
      components/common/buyOrCar/buyComponent.vue
  2. 98 30
      components/default/RightBar.vue
  3. 9 1
      layouts/main.vue
  4. 1 28
      store/option.js

+ 1 - 16
components/common/buyOrCar/buyComponent.vue

@@ -26,24 +26,9 @@
   export default {
     props: ['item', 'disabledFlag', 'btnColor'],
     methods: {
-      drop(el) {
-        this.$store.commit('option/SET_BALLSLIST_SUCCESS', el)
-      },
       buyNow: function (isBuy, event) {
-        this.drop(event.target)
-        // let $el = this.$refs.ballCard
-        // let transform = whichTransitionEvent()
-        // let _shopCar = document.getElementById('shopCar')
-        // let _eltop = event.currentTarget.getBoundingClientRect().top - 22
-        // let _elleft = event.currentTarget.getBoundingClientRect().left - 278
-        // // $el.style = `left: ${_elleft}px;top:${_eltop}px`
-        // $el.style[transform] = `translate3d(${_elleft}px,${_eltop}px,0)`
-        // $el.style.transition = 'all 0.5s'
-        // let _shopCarTop = _shopCar.getBoundingClientRect().top
-        // let _shopCarLeft = _shopCar.getBoundingClientRect().left
-        // $el.style[transform] = `translate3d(${_shopCarLeft}px,${_shopCarTop}px,0)`
+        this.$root.$emit('add_cart', event.target)
         event.stopPropagation()
-        return
         // if (!this.$store.state.option.user.logged) {
         //   this.$http.get('/login/page', {params: {returnUrl: window.location.href}}).then(response => {
         //     if (response.data) {

+ 98 - 30
components/default/RightBar.vue

@@ -77,17 +77,34 @@
       size="tiny">
       <message-board @pageEvent="listenPage" @openBoardEvent="listenOpen"/>
     </el-dialog>
-
-    <div v-for="(ball, index) in balls" v-bind:key="index">
-      <transition name="drop" @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter">
-        <div class="ball" v-show="ball.show">
-          <div class="inner inner-hook"></div>
-        </div>
-      </transition>
+    <div class="ball-container">
+      <div v-for="(ball, index) in balls">
+        <transition name="drop" v-on:before-enter="beforeEnter" v-on:enter="enter" v-on:after-enter="afterEnter">
+          <div class="ball" v-show="ball.show">
+            <div class="inner inner-hook"></div>
+          </div>
+        </transition>
+      </div>
     </div>
   </div>
 </template>
 <script>
+  function handler() {}
+  function whichTransitionEvent() {
+    let t,
+      el = document.createElement('surface'),
+      transitions = {
+        'transition': 'transitionend',
+        'OTransition': 'oTransitionEnd',
+        'MozTransition': 'transitionend',
+        'WebkitTransition': 'webkitTransitionEnd'
+      }
+    for (t in transitions) {
+      if (el.style[t] !== undefined) {
+        return transitions[t]
+      }
+    }
+  }
   import { scrollTo } from '~utils/scroll'
   import MessageBoard from '~components/default/MessageBoard.vue'
   export default {
@@ -101,7 +118,23 @@
         currentPage: 1,
         chatCount: 0,
         showMyshop: false,
-        // balls: [],
+        balls: [
+          {
+            show: false
+          },
+          {
+            show: false
+          },
+          {
+            show: false
+          },
+          {
+            show: false
+          },
+          {
+            show: false
+          }
+        ],
         dropBalls: []
       }
     },
@@ -109,9 +142,6 @@
       MessageBoard
     },
     computed: {
-      balls() {
-        return this.$store.state.option.ballsList
-      },
       user () {
         // console.log(this.$store.state.option)
         return this.$store.state.option.user
@@ -139,36 +169,73 @@
       }
     },
     methods: {
+      drop(el) {
+        for (let i = 0; i < this.balls.length; i++) {
+          let ball = this.balls[i]
+          if (!ball.show) {
+            ball.show = true
+            ball.el = el
+            this.dropBalls.push(ball)
+            return
+          }
+        }
+      },
       beforeEnter(el) {
         let count = this.balls.length
         while (count--) {
           let ball = this.balls[count]
           if (ball.show) {
+            // setTimeout(() => {
             let rect = ball.el.getBoundingClientRect()
             let x = -(rect.right - rect.left + 56)
-            let y = -(rect.top + window.innerHeight * 0.6)
+            // window.innerHeight * 0.6 - rect.top - rect.height
+            let y = -(window.innerHeight * 0.6 - rect.top)
+            el.style.display = '';
             el.style.webkitTransform = `translate3d(0, ${y}px,0)`
             el.style.transform = `translate3d(0, ${y}px,0)`
-            el.style.display = ''
-            let inner = el.getElementsByClassName("inner-hook")[0]
+            let inner = el.getElementsByClassName('inner-hook')[0]
             inner.style.webkitTransform = `translate3d(${x}px, 0, 0)`
             inner.style.transform = `translate3d(${x}px,0,0)`
+            // }, 10)
           }
         }
       },
       enter(el, done) {
-        let rf = el.offestHeight
+        let rf = el.offsetHeight // 触发浏览器重绘
+        // 这个地方为什么要写这个句话,才能第一次执行transition的结束动画
         this.$nextTick(() => {
           el.style.webkitTransform = 'translate3d(0, 0, 0)'
           el.style.transform = 'translate3d(0, 0, 0)'
           let inner = el.getElementsByClassName('inner-hook')[0]
           inner.style.webkitTransform = 'translate3d(0, 0, 0)'
           inner.style.transform = 'translate3d(0, 0, 0)'
-          el.addEventListener('transitionend', done)
+          let transitionEvent = whichTransitionEvent()
+            transitionEvent && el.addEventListener(transitionEvent, function() {
+              console.log('动画结束1')
+              done()
+            })
         })
       },
       afterEnter(el) {
-        this.$store.commit('option/SET_BALLSLIST_SUCCESS_DROP', el)
+        console.log(this.dropBalls)
+        // console.log('钩子函数收尾')
+        let ball = this.dropBalls.shift()
+        if (ball) {
+          ball.show = false
+          el.style.display = 'none'
+          let $el = document.getElementById('shopCar')
+          $el.className = $el.className + ' tranScale'
+          $el.addEventListener('animationend', () => {
+            let newClass = $el.className.split(' ')
+            let index = newClass.findIndex(function (value, index, arr) {
+              return value === 'tranScale'
+            })
+            if (index !== -1) {
+              newClass.splice(index, 1)
+              $el.className = newClass.join(' ')
+            }
+          })
+        }
       },
       listenPage: function (p) {
         this.page = p
@@ -298,20 +365,21 @@
             })
         }
       }
-    },
-    mounted() {
-      this.$nextTick(() => {
-        let length = document.getElementsByClassName('ball')
-        let _top = parseInt(window.innerHeight * 0.6) + 36
-        for (let i = 0; i < length.length; i++) {
-          length[i].style.top = _top + 'px'
-          length[i].style.left = window.innerWidth + 'px'
-        }
-      })
     }
   }
 </script>
 <style lang="scss" scoped>
+  @keyframes  tranScale{
+    0% { transform: scale(1)}
+    20% { transform: scale(1.4) }
+    40% { transform: scale(1.8) }
+    60% { transform: scale(1.4) }
+    80% { transform: scale(0.9) }
+    100% {transform: scale(1)}
+  }
+  .tranScale {
+    animation: tranScale 0.3s 1 forwards;
+  }
 a[disabled] {
   cursor: not-allowed;
 }
@@ -591,15 +659,15 @@ i {
 .ball {
   position: fixed;
   right: 0;
+  top: 60%;
   z-index: 200;
-  bottom: calc(100vh * 0.4);
-  transition: all 0.4s cubic-bezier(0.49,-0.29,0.75, 0.14);
+  transition: all 0.5s cubic-bezier(0.49,-0.29,0.75, 0.14);
 }
 .ball .inner {
   width: 16px;
   height: 16px;
   border-radius: 50%;
   background: rgb(0, 160, 220);
-  transition: all 0.4s linear
+  transition: all 0.5s linear
 }
 </style>

+ 9 - 1
layouts/main.vue

@@ -5,7 +5,7 @@
     <main-nav></main-nav>
     <nuxt/>
     <footer-view></footer-view>
-    <right-bar></right-bar>
+    <right-bar ref="rightBar"></right-bar>
   </div>
 </template>
 <script>
@@ -20,6 +20,14 @@
       MainHeader,
       MainNav
     },
+    created() {
+      this.$root.$on('add_cart', this.drop)
+    },
+    methods: {
+      drop(el) {
+        this.$refs.rightBar.drop(el)
+      }
+    },
     head () {
       return {
         title: this.title || '【优软商城】IC电子元器件现货采购交易平台商城',

+ 1 - 28
store/option.js

@@ -37,16 +37,7 @@ export const state = () => ({
     data: {}
   },
   messageType: '',
-  showMobileFooter: true,
-  // 定义小球数量为5个。如果遇到问题,这个地方需要重新处理
-  ballsList: [
-    {show: false},
-    {show: false},
-    {show: false},
-    {show: false},
-    {show: false}
-  ],
-  dropBalls: []
+  showMobileFooter: true
 })
 
 export const mutations = {
@@ -132,23 +123,5 @@ export const mutations = {
   },
   SET_SHOW_MOBILE_FOOTER (state, result) {
     state.showMobileFooter = result
-  },
-  SET_BALLSLIST_SUCCESS(state, result) {
-    for (let i = 0; i < state.ballsList.length; i++) {
-      let ball = state.ballsList[i]
-      if (!ball.show) {
-        ball.show = true
-        ball.el = result
-        state.dropBalls.push(ball)
-        return
-      }
-    }
-  },
-  SET_BALLSLIST_SUCCESS_DROP(state, result) {
-    let ball = state.dropBalls.shift()
-    if (ball) {
-      ball.show = false
-      result.style.display = 'none'
-    }
   }
 }