实现抛物线运动
方式一:CSS3实现
我用原生js+css3实现了抛物线效果,查看效果请点击css3抛物线
同样的效果,下面代码是在vue中写的,我将用它来分析如何css3实现抛物线运动。
实现思路:
1)这里需要定一个球图片和一个包裹图片的球盒子,最终的位置是球盒子X轴移动300px,球图片相对于球盒子在Y轴移动了300px。
2)给样式变化加上transition,从而实现过渡效果,而不是瞬间完成。X轴方向是匀速的,所以采用了linear函数;Y轴上速度变化:负数-0-正数,所以你会看到小球先是负速度所以往上运动,然后是正速度就往下运动,而且速度原来越快。那么控制这个速度变化的函数长什么样呢?
这里就涉及到贝塞尔曲线,我们可以用css3里的贝塞尔函数来实现控制速度的效果,首先到这个网站上调出贝塞尔曲线,我调的曲线如下图所示:
对这张图片的理解,你可以理解成横轴是时间进度,斜率是速度,曲线最低处的速度就是0,左边是负速度,右边是正速度,速度是越来越大的。
vue中的代码:
<template>
<div :class="{'ball-box':true,'ball-box-translate':showAnimation}"
@click="start">
<img :class="{'ball-translate':showAnimation}" src="../../../images/icon-add.png" alt="">
</div>
</template>
<script>
export default {
data(){
return {
showAnimation: false
}
},
methods:{
start(e){
this.showAnimation = true
}
}
}
</script>
<style scoped>
.ball-box{
position: absolute;
top: 50px;
left: 10px;
/* background: #f80; */
background: transparent;
transition: transform 1s linear;
}
.ball-box-translate{
transform: translateX(300px);
}
.ball-translate{
transform: translateY( 300px);
transition: transform 1s cubic-bezier(.08,-0.35,.99,.33);
}
</style>
方式二:JS实现
我的目标是绘制出下面的抛物线,众所周知,三点可以确定一个抛物线,现在已经确定了抛物线过原点,那么抛物线的函数可以为
这样一来就可以确定一个二元一次方程组
接下来就是计算出参数a,b,这里可以利用线性代数中的行列式来计算,公式如下:
然后是用代码实现,实现的思路是:定义一个点,以这个点的位置为坐标原点,x轴向右,y轴向下,利用一个setInterval函数来不断改变位置坐标,这样就形成了连续的动画。
实现抛物线的核心代码:
<template>
<div class="ball"
:style="'transform: translate('+ x +'px,'+ y +'px);'"
@click="start">
<img class="ball-img" src="../../../images/icon-add.png" alt="">
</div>
</template>
<script>
// 计算平方函数
function pow(num){
return Math.pow(num, 2)
}
const intervalTime = 10
const topPoint = {x:50, y:-20}
const endPoint = {x:300, y:500}
//y=ax^2+bx (过原点的抛物线)
// 计算参数 a, b
// 利用行列式计算,先计算D
const D = pow(topPoint.x)*endPoint.x - pow(endPoint.x)*topPoint.x
console.log('D:'+D);
const a = (topPoint.y*endPoint.x - topPoint.x*endPoint.y)/D
const b = (pow(topPoint.x)*endPoint.y - pow(endPoint.x)*topPoint.y)/D
console.log(a, b);
export default {
data(){
return {
x: 0,
y: 0
}
},
methods:{
start(e){
const timer = setInterval(_=>{
this.x = this.x+2
this.y = a*pow(this.x) + b*this.x
if(this.x>300)
clearInterval(timer)
},intervalTime)
}
}
}
</script>
<style lang='scss' scoped>
.ball{
position: absolute;
top: 50px;
left: 10px;
}
</style>
这段代码的抛物线轨迹,我在绘图网站绘制出来后是下面这个样子(由于Y轴是向上的,请大家自行脑补把图像倒转过来,想像Y轴向下的图像)