抛出小球加到地方对应元素晃动(加入购物车动画)
/** *
* 横向抛小球到购物车
* @param addBtnDom 增加按钮的dom元素或者选择器,初始位置
* @param shopCarDom 购物车的dom元素或选择器,结束位置
* @param shopImg 购物车需要晃动的元素
*/
export default function controllPath(addBtn, shopCar, shopImg) {
// 获取小球初始元素和最终到达元素
let addBtnDom = null
let shopCarDom = null
if (typeof addBtn === 'string') {
addBtnDom = document.querySelector(addBtn)
} else if (addBtn instanceof HTMLElement) {
addBtnDom = addBtn
} else {
console.error('加入购物车动画传入的参数错误: 第一个参数应为增加按钮的dom元素或该元素的选择器。')
return
}
if (typeof shopCar === 'string') {
shopCarDom = document.querySelector(shopCar)
} else if (shopCar instanceof HTMLElement) {
shopCarDom = shopCar
} else {
console.error('加入购物车动画传入的参数错误: 第二个参数应为增加按钮的dom元素或该元素的选择器。')
return
}
// 获取两个dom的位置
const addBtnposition = addBtnDom.getBoundingClientRect()
const shopCarPosition = shopCarDom.getBoundingClientRect()
const addBtnCenterX = (addBtnposition.left + addBtnposition.right) / 2
const addBtnCenterY = (addBtnposition.top + addBtnposition.bottom) / 2
const shopCarCenterX = (shopCarPosition.left + shopCarPosition.right) / 2
const shopCarCenterY = (shopCarPosition.top + shopCarPosition.bottom) / 2
// 计算增加按钮 是在 相对于购物车的 左边还是右边(用于控制后面的移动方向)
const relativePosition = addBtnCenterX > shopCarCenterX ? -1 : 1
// 获取连个dom之间的横向和纵向距离
const xDistance = Math.abs(addBtnCenterX - shopCarCenterX)
const yDistance = Math.abs(addBtnCenterY - shopCarCenterY)
// 绘制小球并设置其初始位置
const ballDom = drawBall()
ballDom.style.top = addBtnCenterY + 'px'
ballDom.style.left = addBtnCenterX + 'px'
document.body.appendChild(ballDom)
// 小球的横纵坐标,需要加上的偏移
let xAbscissa = 0; let yAbscissa = 0
const addCount = xDistance / 10 // 计算变化次数
let curCount = 0 // 当前变化次数
const onceY = 40 / (addCount / 2) // 每次Y轴移动大小
// 设置移动路径
const ballTimer = setInterval(function() {
curCount += 1
// 每次重新坐标
xAbscissa += 10 * relativePosition
// if ()
// 实际应该除以2,但为了动画效果更好,改为1.8
if (curCount <= addCount / 1.8) {
yAbscissa -= onceY
} else {
yAbscissa += onceY
}
ballDom.style.top = addBtnCenterY + yAbscissa + 'px'
ballDom.style.left = addBtnCenterX + xAbscissa + 'px'
// 检查是否到达终点
const surplusDistance = parseInt(ballDom.style.left) - shopCarCenterX
// const surplusDistanceY = parseInt(ballDom.style.top) - shopCarCenterY
if (Math.abs(surplusDistance) <= 10) {
clearInterval(ballTimer)
document.body.removeChild(ballDom)
}
}, 50)
let shopImgDom = null // 购物车图片
if (typeof shopImg === 'string') {
shopImgDom = document.querySelector(shopImg)
} else if (shopImg instanceof HTMLElement) {
shopImgDom = shopImg
} else {
console.log('加入购物车动画传入的参数错误: 第三个参数应为增加按钮的dom元素或该元素的选择器。')
return
}
let rotateCount = 4 // 购物车图片左右晃动次数
let rotateVal = 0 // 晃动角度
const rotateInterval = setInterval(() => {
if (rotateCount < 0) clearInterval(rotateInterval)
else rotateCount--
if (rotateCount === -1) rotateVal = 0 // 结束时摆正
else rotateVal = 10 * Math.pow(-1, rotateCount) // 晃动角度10,一正一负
shopImgDom.style.transform = 'rotate(' + rotateVal + 'deg)' // 设置css样式
}, 100)
}
/*
* 绘制小球
* */
function drawBall() {
const ballDom = document.createElement('div')
ballDom.style.width = '20px'
ballDom.style.height = '20px'
ballDom.style.border = '1px solid #ccc'
ballDom.style.background = '#fa5151'
ballDom.style.borderRadius = '50%'
ballDom.style.position = 'absolute'
ballDom.style.zIndex = 99999
return ballDom
}
- 传入的dom参数的样式需要自己先写好,抛出的路线和晃动次数与角度可以自己调整