Flash中使用原生鼠标指针

Posted on Jul 11, 2012

Flash 10.2 版本有很多值得注意的新功能,StageVideo,多屏幕支持,原生鼠标指针等等。其中原生鼠标指针是一个非常引人注目的新特性。可以直接通过操作系统指针机制实现基于位图的原生鼠标指针,此方式比使用显示对象来显示自定义指针图像更有效。

image

理解原生位图指针

自Flash Player 5开始,一直使用 InteractiveObject.startDrag 和 Mouse.hide 来自定义光标外形。但是之前的这种实现有以下几个限制:

  • 显示对象实现的光标受限于舞台的维度。当用户把光标在舞台边界处,自定义光标会显示不完全。
  • 显示对象光标在Flash Player 渲染时非常消耗资源,因为整个舞台必须在很高的帧数下重新渲染。updateAfterEvent 方法的使用会导致高CPU占用。
  • 如果SWF因为某些原因停顿了几毫秒,光标动画也会停顿,用户会误认为程序不响应了。
  • 总体上看,相比原生光标,显示对象实现的光标比较迟缓,不够流畅,用户体验不好。

实现原生鼠标光标

实现原生鼠标光标只需要 MouseCursorData 类的几个属性,非常简洁高效。

flash.ui.MouseCursorData 的三个属性:

  • data:BitmapData 对象的 Vector 包含光标图像或图像。可提供多个图像,并将 frameRate 属性设置为使光标具有动画效果。但是位图大小有限制,最大光标大小为 32×32 像素。
  • frameRate:使光标具有动画效果的帧速率,在 data 属性中提供多个图像并将帧速率设置为大于 0 的值,以便为指针添加动画效果。光标帧速率可能不同于当前的 SWF 帧速率,就是说调整帧率后光标动画帧率不会变化。
  • hotSpot:以像素表示的光标热点,热点是指在光标上注册鼠标单击所在的点。默认情况下位于左上角 (0,0)。

代码示例

动态光标和静态光标的实现方式差不多,只需要在data中存入多个位图并设置frameRate。代码如下:

private function createFakeCursor():void
{
	this.fakeCursor = new Shape();
	var bmp:BitmapData = this.generateCursorBmp(8);
	fakeCursor.graphics.beginBitmapFill(bmp);
	fakeCursor.graphics.drawRect(0,0,bmp.width,bmp.height);
	fakeCursor.graphics.endFill();
	fakeCursor.visible = false;
	this.addChild(fakeCursor);
}
 
private function createStaticNativeCursor():void
{
	var cursorData:MouseCursorData = new MouseCursorData();
	cursorData.hotSpot = new Point(0,0);
	var bitmapDatas:Vector. = new Vector.();
 
	//static
	bitmapDatas.push( this.generateCursorBmp(8) );
	// we assign the bitmap to the MouseCursor object
	cursorData.data = bitmapDatas;
	// we register the MouseCursorData to the Mouse
	Mouse.registerCursor(MY_STATIC_CURSOR, cursorData);
}
 
private function createAnimatedNativeCursor():void
{
	var cursorData:MouseCursorData = new MouseCursorData();
	cursorData.hotSpot = new Point(0,0);
	var bitmapDatas:Vector. = new Vector.();
	//animated
	bitmapDatas.push( this.generateCursorBmp(5) );
	bitmapDatas.push( this.generateCursorBmp(7) );
	bitmapDatas.push( this.generateCursorBmp(8) );
	bitmapDatas.push( this.generateCursorBmp(9) );
	bitmapDatas.push( this.generateCursorBmp(10) );
 
	// we assign the bitmap to the MouseCursor object
	cursorData.data = bitmapDatas;
	// we register the MouseCursorData to the Mouse
	Mouse.registerCursor(MY_ANIMATED_CURSOR, cursorData);
	// we just pas a frame rate
	cursorData.frameRate = 10;
}
 
//设置光标:只须赋值注册的光标名称即可
//set a cursor 
//Mouse.cursor = MY_STATIC_CURSOR;

Demo

说明:

  • Static 和 Animated 都采用基于位图的原生光标。Static是静态的,Animated是一个5帧的动态光标,Oldfashioned 是利用显示对象实现的光标,System为系统光标。
  • 在选择Oldfashioned光标,然后点击ComboBox的时候,明显可以看到层次不对的问题。类似的情况还发生在TextInput以及相似的组件上,而且鼠标指针离开舞台时,光标不能隐藏。使用原生光标这类问题统统没有。
  • 为方便得到不同大小光标,位图是用代码生成的。
  • 左键按住画图,右键清屏。右键菜单屏蔽是利用11.3 里 MouseEvent.RIGHT_CLICK 实现的,纯属娱乐。

总体上看,原生光标完全超越传统的“冒牌”光标,无论是在性能和代码编写,以及用户体验上,都是让人满意的。

Source: 点击下载


参考资料

  1. http://help.adobe.com/zh_CN/FlashPlatform/reference/actionscript/3/flash/ui/MouseCursorData.html
  2. http://www.adobe.com/devnet/flashplayer/articles/native-mouse-cursors.html
  3. http://www.bytearray.org/?p=2373
  4. http://www.cnblogs.com/ddw1997/archive/2011/04/11/2013061.html