原生js 加入购物车抛物线动画效果

抛物线:利用抛物线方程 y = ax^2 + bx + c   传入3点坐标(x1, y1)(x2, y2)(x3, y3)求解出参数 a, b, c

           a: (y3 - y1 + (y2 - y1) * (x1 - x3) / (x2 - x1)) / (x3 * x3 - x1 * x1 - (x3 - x1) * (x1 + x2))

           b: (y2 - y1 + a * x1 * x1 - a * x2 * x2) / (x2 - x1)

           c: y1 - a * x1 * x1 - b * x1

从起点到终点, x匀速增加, 将x 带入方程得到y值,(x, y)即为动画每一帧的坐标位置

原点位置默认为页面左上角

完整代码:

// 元素抛物线动画

// startPos 动画元素起始位置

// targetPos 动画元素结束位置

// animationDom 动画元素

// animationTime 动画执行时间

// time 动画执行间隔

// callback动画执行完回调函数

function parabolaAnimation(startPos, targetPos, animationDom, animationTime = 400, time = 10, callback) {

  const [x1, x2, y1, y2] = [parseInt(-startPos.x), parseInt(-targetPos.x), parseInt(-startPos.y), parseInt(-targetPos.y)]

  const x3 = (x1 + x2) * 3 / 5

  const y3 = y2 + 30

  const dom = document.createElement('img')

  dom.src = car

  dom.width = 30

  dom.height = 30

  const animationDoms = animationDom ? animationDom : dom

  const speedX = (x2 - x1) * time / animationTime

  let times = 0

  animationDoms.style.position = 'fixed'

  animationDoms.style.left = `${-x1}px`

  animationDoms.style.top = `${-y1}px`

  animationDoms.style.zIndex = '10000'

  document.body.appendChild(animationDoms)

  // 利用抛物线方程: y = ax^2 + bx + c 带入三点坐标求得抛物线方程系数 a, b, c 。再根据方程,传入X 求Y

  const a = (y3 - y1 + (y2 - y1) * (x1 - x3) / (x2 - x1)) / (x3 * x3 - x1 * x1 - (x3 - x1) * (x1 + x2))

  const b = (y2 - y1 + a * x1 * x1 - a * x2 * x2) / (x2 - x1)

  const c = y1 - a * x1 * x1 - b * x1

  const timer = setInterval(() => {

    times += 1

    const x = x1 + speedX * times

    const y = a * x * x + b * x + c

    if (times * time > animationTime) {

      clearInterval(timer)

      document.body.removeChild(animationDoms)

      callback && callback()

    } else {

      animationDoms.style.left = `${-x}px`

      animationDoms.style.top = `${-y}px`

    }

  }, time)

}


执行完抛物线动画,可以在让购物车按钮加点抖动动画效果,抖动动画:

// 元素抖动动画

// maxDistance 抖动偏移距离

// interval  抖动快慢,数字越小越快,太小DOM反应不过来,看不出动画

// quarterCycle 一次完整来回抖动的四分之一周期

export function shakingAnimation(el, maxDistance = 5, interval = 15, quarterCycle = 8) {

  let curDistance = 0

  let direction = 1

  const timer = setInterval(function () {

    if (direction > 0) {

      curDistance++

      if (curDistance === maxDistance) {

        direction = -1

        maxDistance -= 1

      }

    } else {

      curDistance--

      if (curDistance === -maxDistance) {

        direction = 1

      }

    }

    el.style.transform = `translateY(${curDistance}px)`;

  }, interval)

  setTimeout(function () {

    clearInterval(timer)

    el.style.transform = `translateY(0)`;

  }, maxDistance * interval * quarterCycle);

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容