3分钟学会在小程序开发纸飞机动画

来这里找志同道合的小伙伴!

作 者 简 介

姜泰——前端架构工程师

14年以上开发经验,对client和server开发都有着深刻认知,现在依然每周都在学习数学。

>>>> 需求来源

最近京东二手拍拍团队制作了一个小程序,叫“附近有闲”

发布求购信息叫“纸飞机”,发送信息完毕之后,屏幕会出现一个纸飞机的飞行轨迹。

动画设计需求为:

1、纸飞机需要平滑的运动

2、有多种飞行方式

>>>> 纸飞机飞翔动画

>>>> css3动画

动画的实现方式有很多种,大部分人想到jq的amination,css3的amination和transition

1、position vs transform

对比一下,左边是布局方式的left和top,右边是transform的translate,尤其是绘画和渲染简直天差地别。看了chrome的专业介绍,transform会走硬件加速,就是机器的显卡越好,这个差距越明显。

2、运动动画

回过来继续说飞机,我们写个飞机飞行的css3,让飞机从0px飞到1000px

@keyframes move {
  from {transform: translateX(0px)}
  to {transform: translateX(1000px)}
}

然后给标签应用动画,让标签播放动画,10秒播放完毕。

#plane {
    animation: move 10s linear;
    width: 100px;
    height: 500px;
}

动画虽然播放了,可是设计的要求肯定不是让你这么直直的飞,效果太差了。但是css3只能这么弄,我们加上translateY就可以斜着飞了,貌似这是极限了。

@keyframes move {
  from{transform: translate(0px, 0px)}
  to{transform: translate(1000px, 500px)}
}

3、运动合成

实际上,我们的思维不能这么局限,回想一下中学的物理和数学。

速度是可以分解的,v等于v1和v2的合成。

再想想著名的平抛运动——x轴做匀速直线运动,y轴做自由落体运动(重力加速运动),因此,我们也可以分两个div,一个大div套着小div。

<div id="plane">

    <div id="entity"></div>

</div>

设置一个y的运行0px到500px

@keyframesfalling {

    from{transform: translateY(0px)}

    to{transform: translateY(500px)}

}

注意动画这里,虽然还是10秒完成动画,但是用了淡入,就是先慢后快。

#entity {

    animation: falling 10s ease-in;

    width: 50px;

    height: 50px;

}

我们也可以改变一下这个动画方式,比如改成5秒执行两次并且反弹。

animation: falling 5s ease-in alternate 2;

其他的方式就更多了,总之,就看你怎么组合了。

>>>> canvas动画

但是我们的纸飞机不能就这么一种飞法啊!

设计小姐姐给我们提出了要多几种飞行方式,可是每一种方式要调整到设计满意的样子都很难,更别说是那么多种飞行方式了。如果设计妥协,那我们的产品精致程度就要大打折扣。

这时候,我们重新捋一遍,设计做的效果肯定是有各种软件,其实软件也是把数据做了渲染。我们是否可以把设计做好的东西里面直接把数据应用到我们的开发中呢?这样肯定是还原了设计,并且修改成本非常低。

其实,设计就是画了一条线,然后拉成曲线,就是我们常说的贝塞尔曲线。

是不是听了很懵逼?

不用想那么多了!我封装了一个game.class.js类,你只需要在引用就行了。以后我们也多多这种类,别人初始化用一下就行了,根本不用去理解你怎么完成的。(这个类是小程序专用,h5需要修改)

var context = wx.createCanvasContext('aeroplane', this);//构造画布

var game = new Game.main(context);//构造game类

game.setPlane(plane);

game.launch(bezier);//启动

Context就是canvas的context,你可以随意创建一个;Plane是飞机的数据有地址和宽高。

plane: {

  url:"/static/images/3.png",

  width:80,

  height:77.6

}

Bezier就是一个数组,里面放三个坐标就是二次贝塞尔,四个坐标就是三次贝塞尔。

cube: [ //三次贝塞尔

  {

   x: -20,

   y:600,

   z:1

  },

  {

   x:200,

   y:500,

   z:1

  },

  {

   x:250,

   y:300,

   z:.5

  },

  {

   x:300,

   y:50,

   z:.5

  }

],

square: [ //二次贝塞尔

  {

   x:0,

   y:200

  },

  {

   x:100,

   y:0

  },

  {

   x:200,

   y:200

  }

],

有了这些,就可以随意的生成小飞机动画了。

>>>> 动画解析

但是有些童鞋,表示“我就喜欢刨根问底,告诉我怎么做的!”好,我们一步步来。

>>>> 二次贝塞尔曲线

其实,就是给起始点和结束点中间加了一个控制点。

公式为:

>>>> 三次贝塞尔曲线

其实,就是给起始点和结束点中间加了两个控制点。

公式为:

由于有了两个控制点,可以更随意的绘制路径。

>>>> 函数解析

所谓的公式其实就是函数(function),比如这个公式,就是一个叫B的函数,参数为t,t的取值范围是0~1,p0~3这里其实是常数,因为在变化过程中他是不变的。

我们拿个实际例子吧:

  • 开始位置为(-20,600)
  • 第一个控制点为(200,500)
  • 第二个控制点为(250,300)
  • 结束点为(300,50)

我们用公式算出点

t=0.1

x = -20*(1-0.1)3 + 3*200 * 0.1*(1-0.1)2 +3* 250*0.12*(1-0.1)+300*0.13

y = 600*(1-0.1)3 + 3*500 * 0.1*(1-0.1)2 +3* 300*0.12*(1-0.1)+50*0.13

t=0.5

x = -20*(1-0.5)3 + 3*200 * 0.1*(1-0.5)2 +3* 250*0.12*(1-0.5)+300*0.13

y = 600*(1-0.5)3 + 3*500 * 0.1*(1-0.5)2 +3* 300*0.12*(1-0.5)+50*0.13

……

这样,所有点的集合为这样的一条贝塞尔曲线。

既然画线知道了,我们把所有点做为飞机的做标来设置就可以了,并且t与时间相匹配,比如setinterval,设置300毫秒执行一次飞机定位,并且t+=0.1,于是就完成了一个动画,如果想让动画更连贯,最好用requestAnimationFrame,并且分段更细一点。

这样设计只要做出满意的动画轨迹,然后把关键点的做标给技术,马上动画就完成了。并且t最好也用缓动来完成,因为飞机开始起飞慢,中间快,最后停下又慢。

>>>> 反三角函数

但是飞机飞行的时候不是一直水平的,它是按照曲线的切线运动的。这个怎么实现呢?就要用我们的反三角函数了。

不对,是反→

我们知道当前的坐标,又知道上一个坐标,然后yt-y0和xt-x0就是三角函数的值,把这个用反三角函数就可以求出角度(其实是弧度)了,然后让其旋转。

let r = Math.atan2(p.y - yt, p.x - xt);

_context.rotate(r);

记住,一定要用atan2不要用atan,那个只能算出π/2之内的值。

>>>> 总结

总的来说,我们的思维要开阔一些。其实自己深度不够没事,我们可以增加我们的深度;最怕的是都不知道可以往某个方面去想,所以我们要多增加点交流,技术储备就会越来越多。

原文发布于微信公众号 - 京东技术(jingdongjishu)

原文发表时间:2018-08-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏牛客网

美团点评:前端工程师-实习面经 2018.03.231. 投递信息来源2. 投递及面试时间3. 面试过程4. 感受

1. 投递信息来源 感谢牛客网以及牛客网网友的帮助,招聘信息来自牛客网上美团点评的免笔试内推二维码。 2. 投递及面试时间 2018.03.09 - 网申(来...

3977
来自专栏CDA数据分析师

【零一】#操作教程贴#从0开始,教你如何做数据分析#初阶#第三篇

大家好,我是零一。我的公众微信号是start_data,欢迎大家关注。今天接着第一篇的内容,我们继续利用excel来做分析。 首先,回应派友的疑问。 我这系列文...

1946
来自专栏企鹅号快讯

三年后,人工智能将彻底改变前端开发?

关键时刻,第一时间送达! 近几天,因为阮一峰老师的一条微博,我们看到了这样一个项目:https://weibo.com/1400854834/FE1Tz8TIB...

2856
来自专栏iOSDevLog

iOS ARKit教程:用裸露的手指在空中画画

最近,Apple公布了名为ARKit的新增强现实(AR)库。对于许多人来说,它看起来只是另一个优秀的AR库,而不是一个值得关注的技术破坏者。但是,如果你看一下过...

1633
来自专栏天天P图攻城狮

终端图像处理实践:AR全景动态贴纸方案简介

全景动态贴纸主要包含三部分技术要点,本文将进行详细阐述。

6525
来自专栏Android机动车

Android用MediaExtractor和MediaMuxer合成音视频

最近在做类似小咖秀的视频录制功能,也就是俗称的对嘴型表演,录制视频我用的是三方SDK,但是视频合成就需要自己搞了,在网上搜了挺多资料,国内国外网站看了不少,踩了...

2573
来自专栏大数据文摘

人类对随机数的探索:如何才能生成一个均匀的随机数列

2567
来自专栏AI科技大本营的专栏

没有地图也能导航?DeepMind用街景来认路

译者 | 王柯凝 【AI科技大本营导读】在童年记忆中,你是如何沿着路线去朋友家、学校或者商店的?那时候没有地图,只是简单的记住街景和沿途转向。随着开始尝试新的越...

3979
来自专栏数据小魔方

think-cell chart系列16——树状分布图

今天跟大家分享think-cell chart系列的第16篇——树状分布图。 大家不要困惑于该图表的名称——树状分布图,其实它用的技巧非常简单(就是基本图表的组...

5244
来自专栏ThoughtWorks

一张漂亮的可视化图表背后|洞见

可视化之根 多年前读过一篇非常震撼的文章,叫《Lisp之根》(英文版:The roots of Lisp),大意是Lisp仅仅通过一种数据结构(列表)和有限的几...

3667

扫码关注云+社区

领取腾讯云代金券