JS implementa animación parabólica

author: 陈家宾
email: [email protected]
date: 2018/2/24

En un proyecto de programa pequeño, debe agregar una animación de bola parabólica cuando agrega un carrito de compras.

Primero le mostraremos la imagen del efecto (de hecho, el efecto ya se ha logrado, por cierto, anuncio mi empresa jaja)

Análisis

Este tipo de animación sin una posición de inicio fija, naturalmente, no puede usar imágenes gif, por lo que solo se puede implementar con código nativo

Entonces, ¿qué herramientas tenemos para implementar la animación?

  • El applet proporciona JS API createAnimationpara crear animación.
  • Transición CSS

Con la herramienta, echemos un vistazo a lo que es una parábola.

Aquí sólo se discute el nivel de parábola, parábola desde el nivel de principio, es matemáticamente [uniforme nivel, la aceleración vertical del movimiento], en el nivel de código es en la animación timingFunction, la animación usando la horizontal linearuso y vertical de la animaciónease-in

Así tenemos que poner esta animación parábola divide en dos a la vez llevado a cabo, pero diferentes efectos de animación animación.

Lograr

(1) La realización de applets

JS :

cartAnimation(x, y) { // x y 为手指点击的坐标,即球的起始坐标
    let self = this,
        cartY = app.globalData.winHeight - 50, // 结束位置(购物车图片)纵坐标
        cartX = 50, // 结束位置(购物车图片)的横坐标
        animationX = flyX(cartX, x), // 创建球的横向动画
        animationY = flyY(cartY, y) // 创建球的纵向动画
    this.setData({
          ballX: x,
          ballY: y,
          showBall: true
    })
    setTimeoutES6(100).then(() => { // 100 ms 延时,确保球已经到位并显示
        self.setData({
            animationX: animationX.export(),
            animationY: animationY.export(),
        })
        return setTimeoutES6(400) // 400 ms 是球的抛物线动画时长
    }).then(() => { // 400 ms 延时后隐藏球
        this.setData({
            showBall: false,
        })
    })
}

function setTimeoutES6(sec) { // Promise 化 setTimeout
    return new Promise((resolve, reject) => {
        setTimeout(() => {resolve()}, sec)
    })
}

function flyX(cartX, oriX) { // 水平动画
    let animation = wx.createAnimation({
        duration: 400,
        timingFunction: 'linear',
    })
    animation.left(cartX).step()
    return animation
}

function flyY(cartY, oriY) { // 垂直动画
    let animation = wx.createAnimation({
        duration: 400,
        timingFunction: 'ease-in',
    })
    animation.top(cartY).step()
    return animation
}

HTML:

<view animation="{{animationY}}" style="position:fixed;top:{{ballY}}px;" hidden="{{!showBall}}">
    <view class="ball" animation="{{animationX}}" style="position:fixed;left:{{ballX}}px;"></view>
</view>

optimización de traducción

Por lo que yo sé, el uso de transform: translate()la animación a lograr será mejor que la parte superior izquierda y el rendimiento, pero no tan fácil de lograr ligeramente hacia abajo.

Investigue para estudiar, y descubrió que el método de traslación es un paso más que el método de arriba y a la izquierda, es decir, el desplazamiento de traslación de la bola necesita ser restaurado (de lo contrario, la traslación tiene valor todo el tiempo) para garantizar que el próximo desplazamiento comience desde la posición en la que se hizo clic.

cartAnimation(x, y) {
    let self = this,
        cartY = app.globalData.winHeight - 50,
        cartX = 50,
        animationX = flyX(cartX, x),
        animationY = flyY(cartY, y)
    this.setData({
        leftNum: x,
        topNum: y,
        showBall: true
    })
    setTimeoutES6(100).then(() => {
        self.setData({
            animationDataX: animationX.export(),
            animationDataY: animationY.export(),
        })
        return setTimeoutES6(400)
    }).then(() => {
        this.setData({
            showBall: false,
            animationX: flyX(0, 0, 0).export(), // 还原小球位置,即 translate 恢复默认值
            animationY: flyY(0, 0, 0).export(),
        })
    })
}

function flyX(cartX,oriX,duration) {
    let animation = wx.createAnimation({
        duration: duration||400,
        timingFunction: 'linear',
    })
    animation.translateX(cartX-oriX).step()
    return animation
}
function flyY(cartY,oriY,duration) {
    let animation = wx.createAnimation({
        duration: duration||400,
        timingFunction: 'ease-in',
    })
    animation.translateY(cartY-oriY).step()
    return animation
}

Parte HTML sin cambios

(2) Implementación de H5

Además de pequeños programas, el desarrollo diario front-end es, por supuesto, más H5, a continuación utilizaré el método de transición CSS3 para lograr

<!DOCTYPE html>
<html lang="en" style="width:100%;height:100%;">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width">
    <style>
        * {
            padding: 0;
            margin: 0;
        }
        #ball {
            width:12px;
            height:12px;
            background: #5EA345;
            border-radius: 50%;
            position: fixed;
            transition: left 1s linear, top 1s ease-in;
        }
    </style>
    <title>CSS3 水平抛物线动画</title>
</head>
<body style="width:100%;height:100%;">
    <div id="ball"></div>
</body>
<script>
    var $ball = document.getElementById('ball');
    document.body.onclick = function (evt) {
        console.log(evt.pageX,evt.pageY)
        $ball.style.top = evt.pageY+'px';
        $ball.style.left = evt.pageX+'px';
        $ball.style.transition = 'left 0s, top 0s';
        setTimeout(()=>{
            $ball.style.top = window.innerHeight+'px';
            $ball.style.left = '0px';
            $ball.style.transition = 'left 1s linear, top 1s ease-in';
        }, 20)
    }
</script>
</html>

También hay un enlace de experiencia, haga clic en mí.

Hasta ahora, la realización de la animación parabólica horizontal está casi introducida, ¡jeje! !

Este artículo se reproduce en: Ape 2048 https://www.mk2048.com/blog/blog.php?id=h0ij1k2hjcb

Supongo que te gusta

Origin www.cnblogs.com/baimeishaoxia/p/12722629.html
Recomendado
Clasificación