使用CSS3硬件加速的拖动小示例
示例如下图:

可直接访问:http://easymorse.googlecode.com/svn/tags/WebBook-0.2/test.html,需要注意只能跑在有webkit浏览器的触摸设备上。
为什么会抖动
在iPad上,如果用传统的改变html元素的左上顶点坐标(left、top),会有可被用户察觉的抖动现象。
这是因为,浏览器不确定是否要使用GPU硬件加速,也许这个操作只是移动一个元素到某个位置。
这种指定顶点的做法,在鼠标操作设备上不会出现抖动现象,是因为鼠标的轨迹是连续的。而触摸设备的手指移动是离散的。
另外,浏览器是假定可用可不用硬件加速的地方,就不用硬件加速,这是因为,对于移动设备来说,硬件加速更消耗电池。
使用CSS3的translate,浏览器将使用硬件加速,手指移动的坐标离散量,会自动形成动画,这样看起来就不会抖动了。
另外,translate的另一个好处是和css布局无关,坐标是针对元素自己的,也就是从(0,0)开始。
怎样编写translate代码
首先要有一个可供移动的html元素:
<div id=’dragContent’>本示例只能用触摸设备使用</div>
然后,有一个css文件,其实和translate关系不大,不过要注意到没有绝对定位:
#dragContent{
top:100px;
left:200px;
height: 200px;
width: 400px;
background: rgba(0,0,0,0.2);
margin: 0px auto;
}
javascript代码部分(使用到jquery简化代码编写),这是关键,首先要监控touch事件:
$(‘#dragContent’).on(‘touchstart touchmove touchend’, function(e) {
在touch开始(touchstart)的时候,记录touch的点坐标:
obj.lastX=touch.pageX;
obj.lastY=touch.pageY;
另外,初始化move变量,刚开始是0,在多次移动操作后,它就不会还是0了:
if(!obj.moveX){
obj.moveX=0;
obj.moveY=0;
}
关键的关键在move事件的处理,分两部分,第一,要记录当前touch后的move累计值,并通过css3做translate:
obj.moveX += (touch.pageX – obj.lastX);
obj.moveY += (touch.pageY – obj.lastY);
$(‘#dragContent’).css(
‘-webkit-transform’,
‘translate(‘ + obj.moveX + ‘px,’ + obj.moveY
+ ‘px)’);
第二,记录当前touch坐标,供以后计算累计值:
obj.lastX = touch.pageX;
obj.lastY = touch.pageY;
在Android设备下的测试
在Android平板(Xoom,已经升级到Android4.0.3)下做了测试,效果不好,主要表现在:
- 拖动的元素和手指有明显滞后
- 拖动元素的抖动
虽然Android也使用webkit浏览器,但是动画要port到本地系统的对应功能上,可能是这方面Android有不足。
这篇文章上的评论的 RSS feed TrackBack URI