AS3中的DisplayObject有一个render事件,他会在重绘DisplayList之前触发,这给我们提供了在重绘之前最后一次操作的机会。每次需要DisplayObject触发render事件时,都要调用一次 stage.invalidate();
下面用一个小例子来说明一下具体用法吧。
假设我们现在要写一个list组件,该组件有addItem()方法用于添加list项目,和remvoeItem() 方法用于删除list项目,当然还可能有addItemAt(),removeItemAt()等方法,这些方法调用后,都需要对list内的显示对象进行重新排列。
我们先实现一个List类,用于显示列表项目List类中,有addItem() 和 removeItem() 这两个方法提供给外部调用,用于添加和删除list项目,这两个方法中除了将列表项目添加/删除,还要调用一个方法来重新对list中的项目进行排列,layoutContents()。关键就是,这个layoutContents()的调用,他的调用次数越少,那效率当然就越高啦,如果是常规的做法,就是类似这样:
代码:
public function addItem ( item : DisplayObject ) : void {
addChild ( item ) ;
layoutContents () ;
}
将item加入后,重新排列列表
下面是List类的源代码:
代码:
package {
import flash . display . DisplayObject ;
import flash . display . Sprite ;
import flash . events . Event ;
public class List extends Sprite {
public function addItem ( item : DisplayObject ) : void {
addChild ( item ) ;
layoutContents () ;
}
public function removeItem ( item : DisplayObject ) : void {
if ( contains ( item )) {
removeChild ( item ) ;
layoutContents () ;
}
}
//对内部项目进行排列,可以是任意的排列算法
protected function layoutcontents () : void {
trace ( " do layout " ) ;
var y : Number = 0 ;
var num : int = numChildren ;
for ( var i : int = 0 ; i < num ; i ++ ) {
var child : DisplayObject = getChildAt ( i ) ;
child . x = 0 ;
child . y = y ;
y += child . height + 2 ;
}
}
}
这个程序粗看似乎没什么问题,但却存在一个效率问题,如果只调用一次addItem,没问题,如果调用10次呢? 前9次的layoutcontents()都不是必须的,只有第十次才是真正需要的这样程序的效率就降低了。
我们可以试一下,先需要一个简单的ListItem
代码:
package {
import flash . display . Shape ;
public class ListItem extends Shape {
public function ListItem () {
super () ;
graphics . beginFill ( 0 xFF6600 ) ;
graphics . drawRect ( 0 , 0 , 30 , 16 ) ;
graphics . endFill () ;
}
}
}
然后测试
代码:
package {
import flash . display . Sprite ;
public class ListTest extends Sprite {
public function ListTest () {
var list : List = new List () ;
addChild ( list ) ;
list . addItem ( new ListItem ()) ;
list . addItem ( new ListItem ()) ;
list . addItem ( new ListItem ()) ;
}
}
}
我们可以看到,输出了3次 do layout 说明layoutcontents执行了3次,前两次都是多余的。现在,解决办法就是利用render事件啦。因为当前帧内,显示列表更新前会触发render事件,所以在render事件触发后来排列列表项目,就可以保证排列方法在做了任意次的添加或删除操作后只需调用一次,从而提高效率。
这么做只需要对List类稍做一些改动,首先肯定是要监听render事件,我们可以仅监听stage对象的render事件即可,因为这样以后可以做一个独立的RepaintManger来管理所有组件的重绘(可以参考AsWing的RepaintManager类)。
在render事件触发后,做我们需要的调整,由于要render事件触发,就必须先调用stage.invalidate() ,所以每次添加或删除list项目后,都要执行一次该方法,即:
代码:
public function addItem(item:DisplayObject):voide { ...... stage.invalidate() } 由于是监听的stage的render事件, 所以在添加删除操作后,要做一个标记,表示list有改动,需要在render事件后重新排列,如果该标记为false,那么即使render触发了也不 做排列,因为stage的render事件也有可能是由于该stage内的其他child需要重绘而造成stage的render触发。
下面是改过后的List代码
package {
import flash . display . DisplayObject ;
import flash . display . Sprite ;
import flash . events . Event ;
public class List extends Sprite {
private var changed : Boolean ;
public function List () {
super () ;
addEventListener ( Event . ADDED_TO_STAGE , __addToStage ) ;
}
public function addItem ( item : DisplayObject ) : void {
addChild ( item ) ;
requireLayout () ;
}
public function removeItem ( item : DisplayObject ) : void {
if ( contains ( item )) {
removeChild ( item ) ;
requireLayout () ;
}
}
private function requireLayout () : void {
changed = true ;
if ( stage != null ) stage . invalidate () ;
}
//对内部项目进行排列,可以是任意的排列算法
protected function layoutContents () : void {
trace ( " do layout " ) ;
var y : Number = 0 ;
var num : int = numChildren ;
for ( var i : int = 0 ; i < num ; i ++ ) {
var child : DisplayObject = getChildAt ( i ) ;
child . x = 0 ;
child . y = y ;
y += child . height + 2 ;
}
}
private function __addToStage ( e : Event ) : void {
stage . addEventListener ( Event . RENDER , __render ) ;
if ( changed ) stage . invalidate () ;
}
private function __render ( e : Event ) : void {
if ( changed ) {
layoutContents () ;
changed = false ;
}
}
}
}
当我们再次运行ListTest的时候,do layout 只输出了一次。就是这些内容,当然,你可能会说,需要做到这些根本不需要这么复杂,只要公开layoutContents方法,在所有操作调用之后让调用者自行调用一次layoutContents()。
在这个例子中当然可以,但是当情况很复杂的时候,使用者每进行一次操作都要自行调用更新的方法,这样做并不是好的解决方案。试想,如果 flashplayer不会为我们处理显示DisplayObject的工作,而是每次addChild/removeChild之后,我们都需要自行调 用flashplayer底层的方法来让我们需要的东西显示出来,这样做显然很不好。
分享到:
相关推荐
Unity Render Streaming相关的webserver服务运行文件
通过探索和学习PG3Render,用户不仅可以提升对3D渲染技术的理解,还能掌握如何利用物理渲染来提升项目的视觉质量。无论是游戏开发者、视觉艺术家还是3D建模爱好者,都能从中获益。不过,要充分利用这个工具,需要...
【标题】"mfc directx3d old error render.rar"涉及到的是使用Microsoft Foundation Classes (MFC)库在DirectX ...同时,保持系统和驱动程序的更新,以及利用有效的错误处理和日志记录机制,能够有效地排查和解决问题。
Render-and-Compare loss that allows 3D shape and pose to be learned with 2D supervision. We evaluate our method on the challenging real-world datasets of Pascal3D+ and KITTI, where we achieve state-of...
**JSRender:强大的JavaScript模板引擎** JSRender是一个轻量级但功能强大的JavaScript模板引擎,它由Microsoft的MVC...无论你是初学者还是经验丰富的开发人员,学习并掌握JSRender都能提升你的开发效率和代码质量。
Direct3D 11,简称D3D11,是微软开发的一个图形应用程序接口(API),它是Windows操作系统上用于实现高级3D图形渲染的核心组件。D3D11 Render,我们可以理解为基于Direct3D 11的渲染系统,它包含了进行高效、高质量3D...
3D-render.zip,一个简单的web服务,它使用自定义文本呈现搅拌机3d场景。,3D建模使用专门的软件来创建物理对象的数字模型。它是3D计算机图形的一个方面,用于视频游戏,3D打印和VR,以及其他应用程序。
PV3D通过利用硬件加速,提高了在Flash Player中的3D性能。 在"flash as3 pv3d实现的魔方效果源文件"中,我们重点关注的核心技术有: 1. **3D对象建模**:魔方是由多个立方体组成的,每个立方体在3D空间中都有自己...
综上所述,Render Frame是一个包含众多复杂特性和技术的渲染工具,旨在简化3D图形编程,提高开发效率,并为用户提供高质量的视觉体验。通过对上述知识点的深入理解和应用,开发者可以利用Render Frame构建出令人惊叹...
RenderDoc 是一款免费的开源实时图形调试器,可快速轻松地捕获帧,并对使用Vulkan、Direct3D 11、Direct3D 12、OpenGL和OpenGL ES的任何应用程序进行详细检查。这些绑定要求在目标机器上安装 RenderDoc,并且从您的 ...
**jQuery-jsrender.js** 是一个基于...总的来说,jQuery-jsrender.js 为前端开发者提供了一个强大的工具,帮助他们构建响应式、高性能的用户界面,特别是在处理动态数据和复杂视图时,能够显著提高开发效率和用户体验。
这篇内容将深入探讨基于ActionScript 3(AS3)的Stage3D技术,这是一种在Flash平台上实现高效2D渲染的框架,其工作原理与OpenGL相似,能够充分利用GPU(图形处理单元)的强大计算能力,为游戏和复杂交互式应用提供...
在本文中,我们将详细探讨`render`属性在RichFaces 4中的使用,特别是如何利用它来更新页面上的特定区域。 `render`属性通常用于AJAX(异步JavaScript和XML)操作,它允许我们在用户与页面交互时,只更新页面的某些...
**JSRender:强大的前端模板引擎** JSRender是一个轻量级但功能强大的JavaScript模板引擎,它在前端项目中被广泛...通过深入学习和实践,开发者可以充分利用JSRender的强大功能,提升Web应用的用户体验和开发效率。
Octane Render 4.0是一款高效且先进的3D渲染插件,专为各种3D建模软件设计,如Cinema 4D、3D Max和Maya等。它以其无与伦比的真实感渲染能力而备受赞誉,尤其在电影、电视、游戏、建筑可视化和产品设计等领域中广泛...
标题中的“DEMO_2_RENDER.rar”是一个压缩文件,它包含了一个3D GDI(Graphics Device Interface)演示程序,主要用于展示如何在Windows环境下使用C++和GDI技术来实现3D地形的渲染。"3D GDI_DEMO_render_terrian_...
在Windows Presentation Foundation(WPF)中,渲染是应用程序界面显示的关键部分。WPF使用一种基于XAML(Extensible Application ...通过深入理解这些概念,开发者能够充分利用WPF的强大功能,打造出色的应用程序。
在"RenderEngine(Assets资源文件)"这个主题中,我们主要关注的是如何管理和利用资源来创建高效的3D渲染引擎。这个压缩包可能包含了用于教学或示例的资源文件,如模型、纹理、着色器等,这些都存储在"Assets"目录下...
5. **性能优化**: JsRender 通过编译模板为JavaScript函数,提高了渲染效率,减少了DOM操作,从而提升页面性能。 **JsRender的循环迭代** 在提供的"JsRender的应用,提供一个循环迭代的例子"中,我们可以看到如何...