首页 理论教育FlashCS6教程:自定义滚动文本框实例

FlashCS6教程:自定义滚动文本框实例

【摘要】:Flash CS6提供的滚动条组件已经可以完全胜任所有动态文本框的要求。选择绘图工具栏的文本工具,在这一层添加一个文本框。图9-43 添加边框回到主时间轴。修改文本框中文本的来源,从外部文件读取文本数据。固定文本框中的文本很容易,但是如果以后想改变文本框的内容的话,就必须要重新编辑源码,这太不方便了。把上面填入文本框里的文本复制到一个空的文本文件,使用记事本就可以完成要求。

Flash CS6提供的滚动条组件已经可以完全胜任所有动态文本框的要求。在本节中,将会介绍如何做一个动态文本框。安排这一个例子的目的,是为了让读者看看如何把影片剪辑和ActionScript结合起来综合运用,重点关注的是中间的方法和思想。

978-7-111-40639-6-Chapter09-182.jpg新建一个文档。按Ctrl+F8键创建一个影片剪辑,起名为containerMC。在元件编辑模式下,把containerMC的当前层该名为up button。然后从公用库里拖一个向上的箭头形状的按钮到这一层。

978-7-111-40639-6-Chapter09-183.jpg在containerMC的时间轴添加一个新层,起名为down button。从公用库里拖一个向下的箭头形状的按钮到这一层。

978-7-111-40639-6-Chapter09-184.jpg在containerMC的时间轴添加一个新层,起名为text box。选择绘图工具栏的文本工具,在这一层添加一个文本框。选中这个文本框,在属性面板的文本类型弹出式菜单中选择“动态文本”,实例名称为daTextBox,“行为”为“多行”。

978-7-111-40639-6-Chapter09-185.jpg选中舞台上向上的按钮,打开“动作”面板,添加如下的代码:

978-7-111-40639-6-Chapter09-186.jpg

978-7-111-40639-6-Chapter09-187.jpg选中舞台上向下的按钮,打开动作面板,添加如下的代码:

978-7-111-40639-6-Chapter09-188.jpg

978-7-111-40639-6-Chapter09-189.jpg

978-7-111-40639-6-Chapter09-190.jpg在containerMC的时间轴添加一个新层,命名为outline。选择绘图工具栏的矩形工具,选择边框颜色为黑色,填充颜色无,在舞台上画一个只有边框的矩形,如图9-43所示。

978-7-111-40639-6-Chapter09-191.jpg

图9-43 添加边框

978-7-111-40639-6-Chapter09-192.jpg回到主时间轴。在库面板中拖放一个containerMC实例到舞台上。

978-7-111-40639-6-Chapter09-193.jpg选中舞台上的containerMC实例,打开“动作”面板,添加如下的代码:

978-7-111-40639-6-Chapter09-194.jpg

978-7-111-40639-6-Chapter09-195.jpg

由于是在enterFrame中处理滚动,所以如果帧频太大的话,滚动会非常快,必须通过某种方式来控制它滚动的速度。比较好的方法是用一个变量frameCounter来计数当前所在帧,如果那个变量能被某个值speedFactor整除,那么就滚动,否则什么也不做。

然而,当第一次单击按钮的时候,希望能得到最快的响应,所以把frameCounter设置成speedFactor,下一次enterFrame消息就会被响应,这就是以上的比较难理解的代码。

978-7-111-40639-6-Chapter09-196.jpg修改文本框中文本的来源,从外部文件读取文本数据。

固定文本框中的文本很容易,但是如果以后想改变文本框的内容的话,就必须要重新编辑源码,这太不方便了。所以,将在Flash运行的时候,从外部文件读文本。

把上面填入文本框里的文本复制到一个空的文本文件,使用记事本就可以完成要求。读者的所有的文字应该都在一行里,除非读者使用了自动换行功能。现在,在所有文字的最前面添加上“daTextBox=”(注意没有引号)。保存这个文件为text.txt,放在和影片源文件同一个目录下面。

978-7-111-40639-6-Chapter09-197.jpg外部文件已经准备好了,现在需要修改containerMC的代码。选中舞台上的containerMC实例,打开“动作”面板,把脚本窗口中的代码用下面的代码替换:

978-7-111-40639-6-Chapter09-198.jpg

978-7-111-40639-6-Chapter09-199.jpg

添加的第一句代码就是loadVariables语句。它从text.txt文件里读取变量。当Flash打开文本文件,看见了daTextBox=text.txt中的文本,它就把内部变量daTextBox设置成text.txt中的文本。注意,使用了“this”操作符,代表当前的影片剪辑,这就是告诉Flash想把文本文件中的内容读入containerMC里,而不是主时间轴或者其他的影片剪辑里。

LoadVariable这行让Flash从一个文件读数据到影片中。当文本文件在远程的一个服务器上的时候,Flash必须首先和它建立连接,然后开始接收数据,这需要一定的时间。希望有一种途径可以知道文件什么时候被全部读进来。当完成读文件的任务后,可以做一些其他的工作,比如说显示“ready”。

所以,要介绍另一个影片剪辑事件,data。当一个文本文件用loadVariables函数读完之后,data事件就被触发。所以当data事件被触发的时候,就知道文件已经读进Flash里了。

但是光有这些机制知道文件已经读进来还不够,当Flash把一个文件读进一个影片以后,它要分析这个文件,分析文件也需要时间,所以说尽管文本文件已经读进来了,但是Flash可能会延迟一到两帧把这些文本内容填充到文本框里。

所以,加入了另外一个方法。首先,把needInit变量设置为false。当文本文件读进来之后,data事件被触发,变量needInit被设置为true。在enterFrame clip事件里,引发了一个if判断语句的执行,这个if语句检查文本框的maxscroll属性是否已经被更新,如果已经被更新的话,它一定大于1,这就意味这文本文件已经被读进来,而且也已经分析完了。

图9-44表示了这个过程。

978-7-111-40639-6-Chapter09-200.jpg

图9-44 读取文件的过程

978-7-111-40639-6-Chapter09-201.jpg去掉小手图标978-7-111-40639-6-Chapter09-202.jpg

可能读者已经发现,在Flash中使用按钮的时候,每当鼠标移到按钮上的时候,鼠标指针就会变为小手的形状。在某些情况下,这个功能很有用,因为它指示出了什么区域是可以单击的。然而,在这个例子里,这个小手非但没有用反而会出问题。首先,用户已经知道有一个滚动条可以单击,所以没有必要显示这种指示信息。其次,小手指针不是很精确,最终要模拟每天使用的Windows滚动条,从没有见过Windows滚动条里显示小手指针的。

不幸的是,Flash里没有某项设置可以隐藏按钮上的小手指针,需要自己想办法去掉它。

978-7-111-40639-6-Chapter09-203.jpg使用影片剪辑来代替向上和向下的按钮,进入containerMC影片剪辑,删除掉up和down按钮。

978-7-111-40639-6-Chapter09-204.jpg现在按Ctrl+F8键创建一个影片剪辑,起名为scroll button up。在元件编辑模式下,在第1帧放一张按钮普通状态(没有按下)的图片,如图9-45所示。

978-7-111-40639-6-Chapter09-205.jpg选中第2帧,按下F6键插入一个关键帧。在第2帧放一张按钮被按下的图片,如图9-46所示。

978-7-111-40639-6-Chapter09-206.jpg

图9-45 没有按下

978-7-111-40639-6-Chapter09-207.jpg

图9-46 按钮按下

978-7-111-40639-6-Chapter09-208.jpg选中第1帧,打开“动作”面板,添加一行代码:

978-7-111-40639-6-Chapter09-209.jpg

978-7-111-40639-6-Chapter09-210.jpg按照与上面相同的步骤,创建另外一个影片剪辑,命名为scroll button down。当然,第1帧和第2帧的两幅图片要换成箭头向下的按钮图片。

978-7-111-40639-6-Chapter09-211.jpg双击库面板中的containerMC,回到containerMC的时间轴。单击up button层,然后在库面板中拖一个scroll button up实例到containerMC的舞台上。选中这个scroll button up的实例,在属性面板的实例名称文本框中输入up。

978-7-111-40639-6-Chapter09-212.jpg单击down button层,然后在库面板中拖一个scroll button down实例containerMC的舞台上。选中这个scroll button down的实例,在属性面板的实例名称文本框中输入down。此时的containerMC如图9-47所示。

978-7-111-40639-6-Chapter09-213.jpg

图9-47 containerMC

978-7-111-40639-6-Chapter09-214.jpg回到主时间轴,在库面板中拖一个containerMC到舞台上。

978-7-111-40639-6-Chapter09-215.jpg选中舞台上的containerMC实例,打开“动作”面板,添加下面的代码:

978-7-111-40639-6-Chapter09-216.jpg

978-7-111-40639-6-Chapter09-217.jpg(www.chuimin.cn)

当鼠标按下和释放的时候,分别触发mouseDown和mouseUp消息。现在读者可能会想,难道onClipEvent(mouseDown)和on(press)不是一样的吗?当然是不一样的。

第一,onClipEvent(mouseDown)只适用于影片剪辑;而on(press)只适用于按钮。

第二,当读者在一个按钮区域外面单击鼠标的话,按钮的on(press)不会被触发,然而,对于onClipEvent(mouseDown)来说,即使读者在离影片剪辑1000像素远处单击鼠标,它也会被触发。

所以onClipEvent(mouseDown)有一个很大的优点,只需要一段代码,就可以控制几个影片剪辑的击键动作。onClipEvent(mouseUp)也是一样的道理。

代码的第二行是:

978-7-111-40639-6-Chapter09-218.jpg

hitTest函数检查某个坐标点是否在调用的影片剪辑内部,如果在,那么返回true,否则返回false,这里的调用者就是影片剪辑Up,被检查的坐标是鼠标在主时间轴里的坐标值,mouseDown和hitTest函数联合起来,完成了和on(press)同样的功能。

接下来的两行和前面按钮里写的代码是一样的,它们的作用也是和在按钮里一样。变量scrolling被设置成up,通知onClipEvent(enterFrame)函数向上滚动;变量frameCounter设置成speedFactor,就可以得到即时的响应,这和在滚动时使用求余数来跳过某些帧是相关的。接下来的一行让影片剪辑up跳到它的第二帧,显示它被按下的状态。

第二个if语句和第一个的作用是一样的,只不过是为影片剪辑down写的。mouseDown事件的消息处理函数以updateAfterEvent()函数结束。通常,每一帧都会刷新屏幕,使用updateAfterEvent()函数,鼠标一按下屏幕就立刻被刷新。这就可以给一个即时响应的效果。

接下来,就是onClipEvent(mouseUp)函数,每当鼠标被释放,就会触发这个事件处理函数。所做的首先是重置scrolling变量,然后把两个影片剪辑按钮的状态跳到它们相应的鼠标释放的状态。又一次使用了updateAfterEvent()函数来即时刷新屏幕。

正如读者所看到的,把以前的按钮的代码都取出来,并把它们都放到containerMC里,由于影片剪辑不是按钮,所以在鼠标滑过它们的时候小手指针不会出现。

一个滚动条如果要工作,那么它必须具有以下的一些机制:首先,它必须在某些限制条件下可以拖动,它的位置必须可以指示文本框的滚动;它还必须根据文本的长度来缩放,通过这个方法告诉使用者文本有多长。比如说,如果文本的长度是文本框可视区域的两倍,那么滚动条应该正好是它的最大高度的一半高度。一个滚动条高度越小,证明有更多的文本内容;最后,在用户单击向上和向下按钮的时候,它还必须可以滚动。

978-7-111-40639-6-Chapter09-219.jpg绘制滚动条。按Ctrl+F8键创建一个影片剪辑,起名为scrollbar。在元件编辑模式下,在scrollbar的舞台上放一张滚动条的图片。

978-7-111-40639-6-Chapter09-220.jpg选中这个图片,一定要确保滚动条的顶端放在坐标为(0,0)的位置,也就是那个十字所在的位置,如图9-48所示。这样,缩放影片剪辑scrollbar的时候,只有scrollbar的底端缩放,而顶端不动。

978-7-111-40639-6-Chapter09-221.jpg双击库面板中的containerMC,回到containerMC的时间轴。添加一个新层,起名为scrollbar。在库面板中拖一个scrollbar到containerMC的scrollbar层。

978-7-111-40639-6-Chapter09-222.jpg选中scrollbar的实例,在属性面板的实例名称文本框中输入scrollbar。并在containerMC里把scrollbar放在y坐标为0的位置,让containerMC和scrollbar的两个表示原点的十字符号在同一条水平线上,如图9-49所示。

978-7-111-40639-6-Chapter09-223.jpg

图9-48 滚动条

978-7-111-40639-6-Chapter09-224.jpg

图9-49 添加滚动条后的containerMC

978-7-111-40639-6-Chapter09-225.jpg回到主时间轴。选中舞台上的containerMC实例,然后打开“动作”面板,用下面的代码替换原来的代码:

978-7-111-40639-6-Chapter09-226.jpg

978-7-111-40639-6-Chapter09-227.jpg

978-7-111-40639-6-Chapter09-228.jpg

Load事件是第一个被触发的事件。唯一需要改变的就是numLines变量,它定义了文本框中的可见文本的行数。也把scrollbar最初的高度X和坐标保存起来,因为以后要用到它们。

一旦文本文件被读进来,而且分析完毕,就可以根据文本的长度来指定scrollbar的高度。所以,当一切工作完成之后,调用了一个自定义的函数initScrollBar()。

现在来一行一行地看看initScrollBar函数:

978-7-111-40639-6-Chapter09-229.jpg

978-7-111-40639-6-Chapter09-230.jpg

第二行很简单,把总的文本行数存在一个变量totalLines里。

第三行开始做真正有用的工作,把scrollbar的Y坐标设置成和文本的行数成比例。假设有20行文本,而文本框的可视区域只有10行,这样,scrollbar的高度应该是它最大高度的一半,那样的话,numLines等于10,maxScroll等于11,所以totalLines=10+11-1=20;_yscale应该是100*10/20=50,这样就把scrollbar的Y坐标设置为原来的50%。

第四行定义了一个deltaHeight变量,它代表可以拖动的区域,可拖动的高度是scrollbar原来的高度和经过调整以后的新的高度的高度差。

为了知道滚动文本的哪一部分和scrollbar相关联,需要定义一个变量lineHeight,这个lineHeight变量是当那滚动一行文本对应的应该移动scrollbar多少像素的总像素值。

在mouseDown事件处理函数里,添加了几行代码来处理对于scrollbar的单击事件。

978-7-111-40639-6-Chapter09-231.jpg

第一行就是一个简单的hitTest,用来确定是scrollbar正在被单击。

如果单击了scrollbar,那么应该开始拖动它,所以使用了startDrag()方法,startDrag的参数按顺序是:上,左,下,右;分别是调用这个方法的movieclip的可以拖动范围的坐标值。垂直方向,可以从0拖到deltaHeight,deltaHeight是scrollbar和上下箭头之间的区域,scrollbar水平方向应该不变的,因为这个是垂直滚动条,所以它的拖动范围是原来的X坐标到原来的X坐标,水平方向是锁定不动的。最后,把scrolling变量设置成“scrollbar”,这样其他的代码就知道正在拖动的是scrollbar。

文本框的更新操作是通过mouseMove事件的处理函数完成的。

978-7-111-40639-6-Chapter09-232.jpg

每当鼠标移动的时候,mouseMove事件就被触发,当想根据当前鼠标的位置来调整某个movieclip的属性时,这个事件处理函数就很有用。

第二行,检查拖动的是否是scrollbar。如果不是,就没有必要更新文本框。

第三行是真正的scrollbar的核心,它根据scrollbar的y坐标设置文本框的scroll属性。

比如说,假设lineHeight等于10,scrollbar的y坐标是30,那就意味着应该滚动三行文本。由于scroll属性是从1开始的,所以应该在这三行文本的基础上加最终的scroll属性应该是4。使用Math.round()函数对结果取整,因为读者猜都可以猜到,scroll属性只允许整数值。

在这个函数的最后,使用了updateAfterEvent()。在mouseMove处理函数里使用updateAfterEvent是非常有用的,每当鼠标移动的时候,屏幕就会被刷新,如果读者有一个拖动的动作,在mouseMove事件处理函数里加上updateAfterEvent()可以使效果变得很平滑。

在mouseUp处理函数里,加了一句stopDrag(),当用户释放鼠标,scrollbar停止拖动。

现在需要的就是当用户单击up和down按钮的时候,scrollbar也跟着移动。读者已经注意到了,在enterFrame处理函数里,当要滚动的时候,添加了一个对于函数updateScrollbarPos()函数的调用。下面就来看看这个自定义函数:

978-7-111-40639-6-Chapter09-233.jpg

这里用到的方法和在mouseMove处理函数里用到的方法恰好相反,前面从scrollbar的Y坐标算出文本框的scroll属性,这里,反过来,从文本框的scroll属性算出scrollbar的Y坐标。这两个等式在数学上是完全等价的。

978-7-111-40639-6-Chapter09-234.jpg按Ctrl+Enter键,打开滚动文本框。用右边的滚动条可以浏览左边文本框的内容了,如图9-50所示。这样整个滚动文本框就做好了。

978-7-111-40639-6-Chapter09-235.jpg

图9-50 自定义滚动文本框外观