人生中第一次寫博客,寫的很差,各位大佬多多包涵。。。 話很少說,效果圖以下:css
我是用一個遊離的view標籤來作的,這個view採用fixed定位,默認top: 0; left: 0;css3
注:文中的遊離view均指動畫播放發生運動的view,即下面的圖片中紅色箭頭所指的元素git
當點擊加號的時候,會發生如下操做:github
獲取當前點擊加號的位置信息,計算出top值和left值,並將這個遊離的view定位到當前點擊的位置,這是動畫開始位置面試
計算出左下角購物車距離頂端的left, top值,這是動畫結束位置小程序
而後使用css3動畫,使其移動從開始位置移動到結束位置,left, top, opacity同時發生變化bash
Tips: 至於爲何不用小程序自帶的wx.createAnimation呢?是由於使用這個播放一次動畫以後,不能清除樣式,第二次加入購物車遊離view不能正確設置top, left值,好苦惱。。。css3動畫
這個飛入效果是css3實現的,因此其它的也能夠用,不侷限於小程序,就是獲取top, left的地方各有不一樣xss
接下來分佈介紹:工具
步驟一: 獲取當前點擊加號的top, left值
獲取當前點擊加號的top, left值
加入購物車按鈕綁定的點擊事件爲selectGoods
selectGoods(e) {
let that = this;
// 獲取當前點擊位置距離頂部的高度,即圖中標出來的,紅色字體寫的top值,left值
// top值和left值分別減去40, 是爲了使遊離的view定位到當前點擊位置的左上方,有一種先彈上去,再飛入購物車的感受,這裏懶就不用動畫了,哈哈
let top = e.detail.y - 40;
let left = e.detail.x - 40;
that.setData({
style: `top: ${top}px;left: ${left}px;`
})
that.playAnimation(e, left, top); // 播放動畫
},
複製代碼
遊離的view樣式以下:
<view class="animat" style="{{style}}">
<image class="icon" src="/resources/images/icon_add01.png"></image>
</view>
複製代碼
.animat{
position: fixed;
top: 0px;
left: 0px;
}
複製代碼
點擊加號的時候動態設置style值設置top, left
這一步結束後的效果圖以下:
步驟二: 計算出左下角購物車距離頂端的left, top值
小程序有提供獲取元素位置的方法,我大概封裝了只須要傳id的一個方法,方便使用,以下:
quertElementSize(id, callback) {
let query = wx.createSelectorQuery();
query.select('#' + id).boundingClientRect((rect) => {
callback && callback(rect);
}).exec()
}
複製代碼
/**
* 獲取左下角購物車圖標top, left值
*/
quertShoppingCarSize() {
let that = this;
this.quertElementSize('shoppingCar', function (rect) {
that.setData({
'shoppingCarSize.top': rect.top + (rect.height / 2),
'shoppingCarSize.left': rect.left + (rect.width / 2)
})
});
},
複製代碼
以下圖:
獲取元素中心點距離頂部top值,和距離左邊left值
因爲這個圖標的位置的固定的,因此這個位置信息能夠提早獲取,存儲到data中,不用每次加入購物車的時候再算
步驟三: 使用css3動畫,使其移動到左下角購物車的位置,left, top, opacity同時發生變化
步驟一和二已經拿到了動畫初始位置的top,left值,和結束位置的top, left值
如今只須要用animation,將這個遊離view從初始位置移動到結束位置就能夠了,代碼以下:
/**
* 小球飛入購物車動畫
*/
playAnimation(e, left, top) {
let that = this;
this.aniTimer = setTimeout(function () {
that.setData({
style: `--startLeft: ${left}px;--startTop: ${top}px;
--endLeft: ${that.data.shoppingCarSize.left}px;
--endTop: ${that.data.shoppingCarSize.top}px;
animation: runTop .3s cubic-bezier(.66,.1,1,.41), runLeft .3s linear;`
})
}, 5);
that.setDataAddShoppingCar(e);
},
複製代碼
這裏解釋一下:
setTimeout(function(){
console.log(1);
})
console.log(2);
// 輸入結果爲 2 1
複製代碼
CSS代碼: 動態獲取開始位置top, left值和結束位置top,left值
@keyframes runTop {
0%{
top: var(--startTop);
opacity: 1;
}
90%{
opacity: 1;
}
100%{
top: var(--endTop);
opacity: 0;
}
}
@keyframes runLeft {
0%{
left: var(--startLeft);
opacity: 1;
}
90%{
opacity: 1;
}
100%{
left: var(--endLeft);
opacity: 0;
}
}
複製代碼
/**
* 更新數據
*/
setDataAddShoppingCar(e) {
let that = this;
let index = e.currentTarget.dataset.index;
let data = that.data.nowShowData[index];
data.isSelect = true;
let nowSelectData = that.data.nowSelectData;
let tag = 'nowShowData[' + index + '].isSelect';
nowSelectData.push(data);
that.setData({
[tag]: true,
nowSelectData: nowSelectData
});
},
複製代碼
到這裏,飛入購物車效果就完成了,鼓掌👏
這裏就使用的是wx.createAnimation
代碼以下:
/**
* 購物車列表彈起
*/
transShoppingCar() {
let that = this;
if (this.data.nowSelectData.length === 0) {
wx.showToast({
title: '購物車內沒有商品哦~',
icon: 'none',
duration: 1500
})
return;
}
let shoppingCarIsShow = that.data.shoppingCarIsShow;
shoppingCarIsShow = !shoppingCarIsShow;
var animation = wx.createAnimation({
duration: 500,//動畫的持續時間 默認400ms 數值越大,動畫越慢 數值越小,動畫越快
timingFunction: 'ease',//動畫的效果 默認值是linear
});
this.animation = animation;
if (shoppingCarIsShow) {
this.setData({
shoppingCarIsShow: shoppingCarIsShow
});
that.fadeIn();//調用顯示動畫
} else {
that.fadeDown();//調用隱藏動畫
let time = setTimeout(function () {
this.setData({
shoppingCarIsShow: shoppingCarIsShow
});
clearTimeout(time);
}.bind(this), 500)//先執行下滑動畫,再隱藏模塊
}
},
//動畫集
// 進入
fadeIn: function () {
this.animation.translateY(0).opacity(1).step()
this.setData({
animationData: this.animation.export()
})
},
fadeDown: function () {
this.animation.translateY(300).opacity(0).step()
this.setData({
animationData: this.animation.export(),
})
},
複製代碼
WXML代碼
<view class="goodsList" animation="{{animationData}}"></view>
複製代碼
思路:
利用translateY實現,初始列表translateY(300),彈出動畫使translateY變爲0,隱藏時translateY又變爲300
因此樣式中要進行初始位置translateY(300),即:
.goodsList {
background-color: #fff;
transform: translateY(300px);
}
複製代碼
代碼github自取: github.com/orangleLi/o…
demo文件夾, 下載下來開發者工具直接導入就能夠了