前言
每次吃飯點(diǎn)外賣的時(shí)候(暴露了自己是個(gè)死肥宅逆皮,手動(dòng)滑稽),或者在淘寶購(gòu)物的時(shí)候柳譬,將商品加入購(gòu)物車時(shí)會(huì)有一個(gè)很炫酷的動(dòng)畫群扶,如下圖餓了么點(diǎn)餐動(dòng)畫:
所以百度了一下前端使用css實(shí)現(xiàn)這個(gè)效果,然后就自己就照葫蘆畫瓢的寫了一個(gè)小小的demo笨使,完全當(dāng)作學(xué)習(xí)了一把卿樱。
界面
在界面上,我是參考了圖片上的界面硫椰,寫的css繁调,然后在美團(tuán)上面扒的數(shù)據(jù)。完成后的界面如下圖:
開始想著只是做一個(gè)簡(jiǎn)單的實(shí)現(xiàn)效果靶草,界面上只有div框蹄胰,按鈕什么的這些,反正想著很丑的界面奕翔,但是自己看到餓了么這么好看的界面裕寨,自己就忍不住模仿著寫了一下下。
主要用到的是移動(dòng)端適配方案:flexible.js + rem的方案
動(dòng)畫實(shí)現(xiàn)
- 用戶在點(diǎn)擊圖片中
標(biāo)注1
的時(shí)候,創(chuàng)建一個(gè)div宾袜,插入到body中捻艳,改div暫且叫bar
吧 - 設(shè)置
bar
的css樣式為
其中,{ position: absolute; top: 點(diǎn)擊位置X坐標(biāo); left: 點(diǎn)擊位置Y坐標(biāo); width: 0.533333rem; height: 0.533333rem; border-radius: 50%; background: #02b6fd; transition: left .6s linear, top .6s cubic-bezier(0.5, -0.5, 1, 1) }
點(diǎn)擊位置的X坐標(biāo)
和點(diǎn)擊位置的Y坐標(biāo)
是通過點(diǎn)擊時(shí)js獲取到的 - 然后設(shè)置最終位移的位置到
標(biāo)注2
的位置
代碼實(shí)現(xiàn)
首先獲取到頁(yè)面上所有按鈕庆猫,然后給按鈕添加點(diǎn)擊事件认轨,獲取到點(diǎn)擊當(dāng)前按鈕的位置坐標(biāo)信息
var buttons = document.getElementsByClassName('ele_main_goods_add')
for (let i = 0; i < buttons.length; i++) {
buttons[i].onclick = function () {
let x = event.pageX - this.offsetWidth / 2;
let y = event.pageY - this.offsetWidth / 2;
// 方案一
// createBall01(x, y)
// 方案二
// createBall02(x, y)
}
}
方案一:使用定位+transition的方式實(shí)現(xiàn)
function createBall01(left, top) {
let bar = document.createElement('div');
bar.style.position = 'absolute'
bar.style.left = (left) + 'px'
bar.style.top = (top) + 'px'
bar.style.width = '0.533333rem'
bar.style.height = '0.533333rem'
bar.style.borderRadius = '50%'
bar.style.backgroundColor = '#02b6fd'
bar.style.transition = 'left .6s linear, top .6s cubic-bezier(0.5, -0.5, 1, 1)'
document.body.appendChild(bar)
// 添加動(dòng)畫屬性
setTimeout(() => {
let target = document.querySelector('.ele_car_icon')
bar.style.left = (target.offsetLeft + target.offsetWidth / 2) + 'px'
bar.style.top = (target.offsetTop) + 'px'
}, 0);
/**
* 動(dòng)畫結(jié)束后,刪除自己
*/
bar.ontransitionend = function () {
this.remove()
}
}
方案二:使用transform + transition的方式實(shí)現(xiàn)
function createBall02(x, y) {
const bar = document.createElement('div')
bar.style.position = 'absolute'
bar.style.left = '0'
bar.style.top = '0'
bar.style.width = '0.533333rem'
bar.style.height = '0.533333rem'
bar.style.borderRadius = '50%'
bar.style.backgroundColor = '#02b6fd'
// transform
bar.style.transform = 'translate(' + x + 'px,' + y + 'px)'
bar.style.transition = 'transform .5s linear'
document.body.appendChild(bar)
// 添加動(dòng)畫屬性
setTimeout(() => {
let target = document.querySelector('.ele_car_icon')
let targetX = (target.offsetLeft + target.offsetWidth / 2)
let targetY = (target.offsetTop)
bar.style.transform = 'translate(' + targetX + 'px,' + targetY + 'px)'
}, 0);
/**
* 動(dòng)畫結(jié)束后月培,刪除自己
*/
bar.ontransitionend = function () {
this.remove()
}
}
最終效果
其實(shí)還可以使用css的animate來實(shí)現(xiàn)嘁字,只不過由于需要?jiǎng)討B(tài)計(jì)算目標(biāo)位置的坐標(biāo),實(shí)現(xiàn)起來比較困難节视,所以我就沒有寫拳锚,如果目標(biāo)位置的坐標(biāo)值固定,那么可以通過animate改變top寻行、left或者translateX霍掺、translateY的值來實(shí)現(xiàn)這個(gè)效果,垂直方向的動(dòng)畫使用貝塞爾曲線的function-timing
拌蜘。