动画效果在地图产品中的运用

简介:

百度地图产品运用了大量的动画效果,比如:操作鱼骨或快捷键使地图移动、鹰眼控件的展开和收缩、滚动鼠标滚轮使地图进行缩放。PM对动画效果提出了平滑,流畅的要求,那么如何才能做到呢?

1 什么是动画

先来看看wiki上对动画一词的解释:动画是指由许多帧静止的画面,以一定的速度(如每秒16张)连续播放时,肉眼因视觉残象产生错觉,而误以为画面活动的作品。在网页中,可以将每一时刻的页面看做是一帧静止的画面,当每个时刻的画面产生差异时,就会产生动画效果了。网页中的动画形式很多,比如一副gif图像,一个flash或者是用脚本控制的页面元素的移动。这里,我们只关注js脚本控制的动画。这种动画的本质就是在每一时刻改变页面元素的属性。由此我们得到动画的两个关键组成部分:

  1. 属性:在每个时刻,只有元素的某些属性发生了变化才会有动画产生,比如元素位置的变化。
  2. 时间:动画是在一定时间内产生的连续效果,脱离了时间动画也就不存在了。可以将动画起始的时间点视为0。

2 属性作为时间的函数

在动画效果中,属性是随着时间变化的,且在某一时刻内属性的值是唯一的,属性和时间有着一对一的对应关系,因此可以用函数来表达这种对应关系。
令p表示属性,t表示时间,那么有:p=f(t)。 在JavaScript中,我们很容易写出这样一个函数:

 
  1. var f = function(t){    return t; }  

函数参数为时间t,返回值是元素的某个属性。当t值不同时,函数的返回值也不同。那么在JavaScript中如何得到一组不同的时刻t呢?

3 在JavaScript中实现动画

在JS中,setTimeout和setInterval这两个函数可用来在特定时间间隔执行某些操作,从而帮助我们实现动画,它们都可以产生不同时刻值t供上面的函数使用。方法如下:

 
  1. var startAnimationByTimeout = function(){  var beginTime = new Date().getTime();  setTimeout(function(){    var now = new Date().getTime();    var t = now - beginTime;    f(t);    setTimeout(arguments.callee, 50);  }, 50); }  

 
  1. <pre>var startAnimationByInterval = function(){  var beginTime = new Date().getTime();  setInterval(function(){    var now = new Date().getTime();    var t = now - beginTime;    f(t);  }, 50); }  

 

这样,每隔50ms动画函数f就被调用一次,时间参数t也被传递进来,从而产生动画。

如果给定了动画的运行时间,则可将函数调整为如下形式(仅给出使用setTimeout函数的情况,setInterval类似):

 

 
  1. var startAnimationByTimeout = function(duration){  var beginTime = new Date().getTime(); // 开始时间  var endTime = beginTime + duration;   // 结束时间  startAnimationByTimeout._timerId = setTimeout(function(){    var now = new Date().getTime();    if (now &gt;= endTime){clearTimeout(startAnimationByTimeout._timerId);f(1);return}  // 动画结束    var schedule = (now - beginTime) / duration;    f(schedule);    startAnimationByTimeout._timerId = setTimeout(arguments.callee, 50);  }, 50); }  

参数schedule是一个0到1之间的数,它的含义已不再是真正的时间t了,而表示当前时刻动画执行到了哪个阶段。相当于把时间t映射到了[0, 1]区间,告知运动函数当前动画运行了百分之多少。这时函数f也需要做相应的调整:

 
  1. var f = function(schedule){  var initialValue = 10;  var final = 100;  return 10 + final * schedule; }  

由于参数schedule取值为0到1,那么我们就需要知道元素属性在动画初始时刻和结束时刻的属性值。

 

4 时间间隔多少合适?

 

时间间隔的多少影响着动画另一个关键因素——帧率。帧率表示动画每秒钟显示多少个不同的画面,单位是帧/秒(fps)或者赫兹(Hz)。由于人眼会有视觉停留的现象,一般动画的帧率超过16,人眼就会认为是连贯的。电影胶片的帧率是24,对多数人而言已经足够流畅,而像CS这样的第一人称射击游戏,则要求帧率达到30或者更高。平衡性能和效果,网页中动画的帧率在20到30之间就已经足够了。假如我们希望动画采用24fps,那么时间间隔应取值约为 1000 / 24 = 42毫秒。

 

5 通过运动函数优化动画效果

 

为了方便问题的讨论,先将调整后的函数f进行如下拆分:

 

 
  1. var f = function(schedule){  var initialValue = 10;  var final = 100;  return 10 + final * motion(schedule); }  var motion = function(schedule){  return schedule; }  

函数motion仅仅将schedule原封不动的return了,这么做有什么意义呢?假定函数f返回的是元素的位置,那么位置就是schedule的一次函数,因此可看作元素是在做匀速运动。匀速动画效果往往显得比较呆板、生硬,考虑到PM提出的需求,为了更好的满足使用体验,我们仅需要提供更丰富的motion函数(以下函数仅考虑[0, 1]区间),函数f再去调用它们即可。

 

匀加速直线运动的物体的运动公式为:s = (a * t * t) / 2,即位置是时间的二次函数。运动函数可写为:

 

 
  1. var motion2 = function(t){  return t * t; }  

函数曲线:

 

 

 

 

有过Flash动画开发经验的同学知道,这种效果称为easein,运动的物体有一种加速的效果。 类似的,我们可以给出一个减速运动效果(easeout)的函数:

 

 
  1. var motionEaseOut = function(t){  return - (t * (t - 2)); }  

函数曲线:

 

 

 

 

将加速和减速效果结合在一起的函数(是一个分段函数,要保证在t=0.5时两个函数的斜率一致):

 

 
  1. var motionEaseInOutQuad = function(t){  if (t &lt; 0.5){    return t * t * 2;  }  else{    return - 2 * (t - 2) * t - 1;  } }  

函数曲线:

 

 

 

 

6 结论和后续工作

 

使用JavaScript实现动画效果没有什么技术难度,但是要想在保证性能的前提下实现那些看起来很酷、很炫的效果就不是轻而易举的事情了。开发人员需要自己尝试不同的参数设置,比如动画间隔、时长、动画函数等。只要我们在处理动画时多考虑一些东西,实现起来就不困难了。

 

无论是地图自己的Animation,都须提供duration参数,也就是说动画的持续时间必须是已知的。在每个时刻我们得到的是一个运行百分比值,只有知道了动画结束时的终止值才能计算出当前时刻值。而在地图产品中,用户操作键盘的上、下、左、右键会导致地图的移动,这种移动的持续时间和结束时刻的移动位置都是未知的,那么采用这种方式实现动画就比较繁琐。希望以后动画基础库能够对此种情况提供更友好的支持。

 

参考文献:

 

1. 动画效果演示(Easing Deme)

2. 10个超炫的JavaScript动画框架(10 Impressive JavaScript Animation Frameworks)

3. 16个可与Flash匹敌的炫酷JavaScript动画灵感、教程和插件(16 Impressive Flash-like JavaScript Animation Inspirons, Tutorials and Plugins)

 
















本文转自百度技术51CTO博客,原文链接:http://blog.51cto.com/baidutech/747233,如需转载请自行联系原作者
相关文章
|
9月前
Echarts手机端无刷新实现图表自适应横屏和竖屏的解决方案
Echarts手机端无刷新实现图表自适应横屏和竖屏的解决方案
210 0
|
9月前
|
搜索推荐 定位技术
百度地图开发mapStyle个性化地图styleJson的配色解决方案
百度地图开发mapStyle个性化地图styleJson的配色解决方案
435 0
|
7月前
|
JavaScript 前端开发 开发者
|
4月前
|
数据可视化 定位技术 数据格式
Tableau可视化设计案例-07 多边形地图和背景图地图
Tableau可视化设计案例-07 多边形地图和背景图地图
|
9月前
|
定位技术
高德地图进阶开发实战案例(6):添加自定义图片覆盖物图层获取可视范围经纬度的解决方案
高德地图进阶开发实战案例(6):添加自定义图片覆盖物图层获取可视范围经纬度的解决方案
165 0
|
6月前
|
前端开发 数据可视化 定位技术
GIS前端-地图标绘与动画
GIS前端-地图标绘与动画
76 0
|
8月前
|
JavaScript 前端开发
低代码必备!带标尺和缩略图的画板
低代码平台经常要用到标尺和缩略图操作同步的画板,点进来就能定制你的专属低代码画板!还等什么!快看我!
|
9月前
|
定位技术
Echarts实战案例代码(39):地理坐标整体地图背景色渐变效果和字体随地图缩放的解决方案
Echarts实战案例代码(39):地理坐标整体地图背景色渐变效果和字体随地图缩放的解决方案
180 0
|
12月前
|
JavaScript
制作移动端整页滚动动画
制作移动端整页滚动动画
81 0
|
定位技术
制作地图的布局、元素和设计介绍
制作地图的布局、元素和设计介绍
181 0
制作地图的布局、元素和设计介绍