饿了么购物车动画
前言
之前用餓了么印象最深刻的是聯(lián)動(dòng)菜單和小球飛入購(gòu)物車動(dòng)畫,所以想看看別人是怎么實(shí)現(xiàn)的,但是看了很多仿餓了么的demo都是實(shí)現(xiàn)了一個(gè)完整的大的項(xiàng)目,要找到那個(gè)小模塊很麻煩,所以自己將聯(lián)動(dòng)菜單和動(dòng)畫提取出來寫了一個(gè)demo,方便學(xué)習(xí)。
目的只是想突出功能所以界面細(xì)節(jié)很relax,大家也relax的看看吧~
效果圖
?
實(shí)現(xiàn)功能
1. 聯(lián)動(dòng)菜單
1.1 用戶點(diǎn)擊左側(cè)導(dǎo)航欄會(huì)跳轉(zhuǎn)到相應(yīng)的內(nèi)容
這個(gè)很簡(jiǎn)單,給導(dǎo)航欄的每一個(gè)元素加一個(gè)點(diǎn)擊事件,其實(shí)也可以通過a標(biāo)簽的錨點(diǎn)來實(shí)現(xiàn)
<li v-for="(item, index) in navs" :key="index" :class="{click: selector==index}"@click="toHash(item, index)">{{item}} </li> // 點(diǎn)擊右側(cè)導(dǎo)航欄 toHash(item, index) {this.selector = index;window.location.hash = item; // 導(dǎo)航欄向上滾動(dòng)相應(yīng)距離,一個(gè)li的高度為54pxthis.$refs.left.scrollTop = (index > 7 ? index-7 : 0)*54; }1.2 用戶滑動(dòng)右側(cè)的內(nèi)容左側(cè)的導(dǎo)航欄會(huì)響應(yīng)式改變
右側(cè)內(nèi)容監(jiān)聽一個(gè)scroll事件,當(dāng)觸發(fā)滑動(dòng)事件的時(shí)候獲取粘性定位在頂部的標(biāo)題,根據(jù)標(biāo)題使導(dǎo)航欄定位到相應(yīng)的li
var obj = element.getBoundingClientRect();上述api返回一個(gè)對(duì)象obj,該對(duì)象有l(wèi)eft、top等屬性,可以根據(jù)該屬性獲得element元素在頁(yè)面的位置
listScroll() {// 為了達(dá)到聯(lián)動(dòng)效果,右側(cè)滑動(dòng)則改變左側(cè)導(dǎo)航欄樣式var titles = document.getElementsByClassName('goodTitle');for(var i = 0; i < titles.length; i++) {var style = titles[i].getBoundingClientRect();if(style.top == 107) {this.toHash(titles[i].innerHTML, i);}} }1.3 標(biāo)題欄粘性定位
#el {position: sticky;top: 0; }該元素定位表現(xiàn)為在跨越特定閾值前為相對(duì)定位,之后為固定定位。這也實(shí)現(xiàn)了內(nèi)容區(qū)標(biāo)題欄始終在頂部的效果。關(guān)于粘性定位更多的可以看這里
2. 按鈕緩慢彈出
當(dāng)我們點(diǎn)擊添加按鈕的時(shí)候其他的內(nèi)容會(huì)緩慢彈出,這個(gè)是靠css的動(dòng)畫實(shí)現(xiàn)的。
我們先將個(gè)數(shù)減少按鈕和被選中物品個(gè)數(shù)num的left設(shè)為48px,使其被隱藏。點(diǎn)擊添加按鈕時(shí)選擇物品個(gè)數(shù)大于0則讓left變?yōu)?達(dá)到一個(gè)緩慢彈出的動(dòng)畫效果。
<div :class="{pop: true, mov: item.num>0}"><!----></div> .pop {display: inline-block;position: relative;left: 48px;opacity: 0;transition: all ease .5s; } .mov {left: 0;opacity: 1; }3.小球飛入購(gòu)物車動(dòng)畫
先準(zhǔn)備n個(gè)小球,為什么不是一個(gè)呢?因?yàn)槿绻脩暨B續(xù)點(diǎn)擊添加可能會(huì)出現(xiàn)小球不夠的情況,所以需要多個(gè)小球。
<!-- 運(yùn)動(dòng)的小球 --> <div id="points"><div class="pointOuter pointPre"><div class="point-inner"></div></div> <!--其他n個(gè)小球--> </div>令小球?yàn)榻^對(duì)定位這樣可以改變它的left和top。
動(dòng)畫實(shí)現(xiàn)思路:用戶點(diǎn)擊添加時(shí)將一個(gè)小球的位置設(shè)置為被點(diǎn)擊元素的位置,且獲取目的地位置(購(gòu)物車位置),當(dāng)小球拋出時(shí)使其運(yùn)動(dòng)方式按照貝塞爾曲線過渡。
increase(index1, index2, event) { // some code...// 小球動(dòng)畫 var top = event.clientY, // 小球降落起點(diǎn)left = event.clientX,endTop = window.innerHeight - 30, // 小球降落終點(diǎn)endLeft = 20; // // 小球到達(dá)起點(diǎn)并去掉小球的display: none;var outer = $('#points .pointPre').first().removeClass("pointPre").css({left: left + 'px',top: top + 'px'});var inner = outer.find(".point-inner"); setTimeout(function() { // 將jquery對(duì)象轉(zhuǎn)換為DOM對(duì)象outer[0].style.webkitTransform = 'translate3d(0,' + (endTop - top) + 'px,0)';inner[0].style.webkitTransform = 'translate3d(' + (endLeft - left) + 'px,0,0)';// 小球運(yùn)動(dòng)完畢恢復(fù)到原點(diǎn)setTimeout(function() {outer.removeAttr("style").addClass("pointPre");inner.removeAttr("style");}, 1000); //這里的延遲值和小球的運(yùn)動(dòng)時(shí)間相關(guān)}, 1); }注意點(diǎn):
- 嵌套的setTimeout中的時(shí)間之所以設(shè)置為1s,是因?yàn)閏ss中規(guī)定的小球運(yùn)動(dòng)時(shí)間為1s,所以在小球1s運(yùn)動(dòng)完以后會(huì)令它恢復(fù)到原來的位置,你想想,小球一共就只有那么幾個(gè),如果不恢復(fù)的話下次用戶點(diǎn)擊了小球就不夠啊...
總結(jié)
以上是餓了么購(gòu)物車模塊主頁(yè)面的幾個(gè)主要技術(shù)點(diǎn),這個(gè)demo注重功能所以UI什么的沒有完全copy餓了么,大家也可以把項(xiàng)目fork下來自己添加組件來擴(kuò)充成一個(gè)高仿的餓了么購(gòu)物車模塊。
源碼地址:vue-eleme-shoppingCart
轉(zhuǎn)載于:https://www.cnblogs.com/wind-lanyan/p/8964545.html
總結(jié)
- 上一篇: [C#] DataTable 操作汇总(
- 下一篇: 当年的程序员,如今已是父母,七个方法让孩