购物车图标动画

314 阅读2分钟

背景

最近在做电商的h5项目,会有这个一个东西,商品列表添加到购物车的动画。emmm 作为一个优秀的前端工程师,说干就干

思路

拿到这个问题,正常的思维就是做一个动画,设置好位置,left,top,然后移动到购物车的位置就好了。

实现

好的,基本思路有了。写一个js文件,创建一个class,emmm名字就叫shoppingBall,我可真是个取名鬼才

class ShoppingBall{}

好,那我们来想想,这个ball需要什么属性,emmm 需要起始点坐标,终止点坐标,需要挂载的元素。我们记录下这些属性。

construtor(target,position,destination){
    this.target = target[0]
    this.position = position
    this.destination = destination
}

接下来我们创建一个ball的dom元素,设置好高度宽度颜色,插入到我们的target元素中

 createBall () {
    this.node = document.createElement('div')
    this.node.style.height = '10px'
    this.node.style.width = '10px'
    this.node.style.position = 'absolute'
    this.node.style.borderRadius = '50%'
    this.node.style.backgroundColor = '#00B058'
    this.node.style.top = this.position.top + 'px'
    this.node.style.zIndex = '2'
    this.node.style.left = this.position.left + 'px'
    this.target.appendChild(this.node)
    this.move()
    }

我们的开始移动元素:通过改变我们的ball的位置来实现这个动画,递归调用这个move方法

move () {
    if (this.position.top > this.destination.top) {
      this.target.removeChild(this.node)
      return
    }
    this.position.top += 10
    this.position.left += 10
    requestAnimationFrame(() => {
      this.node.style.top = this.position.top + 'px'
      this.node.style.left = this.position.left + 'px'
      this.move()
    })
  }

emmmmmm初版的代码已经写完了。不过效果好像不是很好,小球的走路线是斜着的,而且毫无美感。作为一个优秀的前端工程师是不允许自己的页面这么丑的。

优化

开始优化,加入时间的概念和加速度概念,让我们的小球走一个抛物线。增加了横向速度和纵向速度

 this.xSpeed = (this.destination.left - this.position.left) / (this.duration * 10)
    this.ySpeed = -10

然后更改我们的move方法:

move () {
    if (this.position.top > this.destination.top) {
      this.target.removeChild(this.node)
      return
    }
    this.position.top += this.ySpeed + this.time
    if (this.position.left > this.destination.left) {
      this.position.left += this.xSpeed
    }
    requestAnimationFrame(() => {
      this.node.style.top = this.position.top + 'px'
      this.node.style.left = this.position.left + 'px'
      this.time++
      this.move()
    })
  }
    

看看效果

看着还行撒。再试试别的方法,诶 是不是有这么一个东西transition

transition

transition是在属性变化中起到过度的动画,好,我直接设置终点的坐标位置,然后设置transition,通过改变这个的bezier 曲线来去改变。我改一下这个创建ball的方法

    if (this.heightPart) {
      this.node.style.transition = `left 1.5s cubic-bezier(0,2.3, 1, 2.6),top 1.5s cubic-bezier(0,-0.1, 0.5, 0.5)`
    } else {
      this.node.style.transition = `left 1s cubic-bezier(0,1, 1, 1),top 1s cubic-bezier(0,-1, 0.5, 0.5)`
    }
    setTimeout(() => {
      this.node.style.left = this.destination.left + 'px'
      this.node.style.top = this.destination.top + 'px'
    }, 100)
    setTimeout(() => {
      this.target.removeChild(this.node)
    }, this.heightPart ? 1600 : 1000)

我区分了一下高位和低位,可以以不同的动画。来,展示

这个方法可以更好的实现不同的曲线的改变,而且没有第一种方法的闪烁感,当然也有自己的问题,就是兼容性的问题。

总结

刚做完,组长过来说 这是需求之外的东西,可以上,但是后期的bug全是我的。