我们在学习Degrafa之前首先应该了解Flex和Flash画图之间的异同:
下面是Flex 和Flash 的类继承结构,他们都是继承自Sprite,然后在子类上 Flex 简化或去除了时间轴的感念。
Flex 中的 UI元素 大都继承自 UIComponent类
UIComponent>FlexSprite>Sprite >DisplayObjectContainer>InteractiveObject >Displayobject
Flash 中的架构 (Sprite类的继承关系)
MovieClip > Sprite > DisplayObjectContainer > InteractiveObject >Displayobject
Flex 中无法直接使用Flash 中的MovieClip元件。只能通过工具 将Flash MovieClip 转成 UIMovieClip, UIMovieClip 继承自 MovieClip, MovieClip 类用于实现其使用方式与普通 Flex 组件一样的某个 Flash 组件的必要接口。因此,MovieClip 的子类可以用作 Flex 容器的子项或外观,它可以响应事件、定义视图状态和转换,还可以像所有 Flex 组件一样使用效果。
所有的Flex的图形必须添加到UIComponent的对象中才能在Application中被显示出来。
接下来我们开始讲Degrafa
Degrafa是一套很强大的图形算法类库,并且开源,他为我们封装好了一些图形原件和容器,开发人员可以直接使用这些图形原件,并修改内部属性。
在Degrafa库中图形的属性修改会自动影响到图形的显示。
这里我们拿圆形来了解Degrafa是怎么一个原理来画图的:
系统默认的画圆方式是(如下图):
var circle2:Sprite = new Sprite();
circle2.graphics.beginFill(0x00CCFF);
circle2.graphics.drawCircle(80, 40, 40);
而Degrafa的画圆方式是通过线来实现的,他有两个属性stroke和fill来控制内部填充和外部环绕。
我们看一下geometry.Circle的preDraw函数,里面的addMoveTo是设置起点,addCurveTo是设置弧度,由此来画图
commandStack.addMoveTo(
centerX+Math.cos(anchorAngle)*radius,
centerY+Math.sin(anchorAngle)*radius);
var i:int=0;
//loop through and add the curve commands
for (i; i<accuracy; ++i) {
controlAngle = anchorAngle+span;
anchorAngle = controlAngle+span;
commandStack.addCurveTo(
centerX + Math.cos(controlAngle)*controlRadius,
centerY + Math.sin(controlAngle)*controlRadius,
centerX + Math.cos(anchorAngle)*radius,
centerY + Math.sin(anchorAngle)*radius)
};
个人觉得,Degrafa的内部运行机制就是提供了诸如addCurveTo之类的一套很强大的图形算法类库。
这里我写了一个硬编码的画圆形方式:
package {
import com*.IGeometry;
import com.*.geometry.Geometry;
import flash.display.Graphics;
import flash.geom.Rectangle;
//--------------------------------------
// Other metadata
//--------------------------------------
[Bindable]
public class Hec extends Geometry implements IGeometry{
public function Hec(){
super();
}
override public function preDraw():void{
commandStack.source.length = 0;
commandStack.addMoveTo(150,100);
commandStack.addCurveTo(150,150,100,150);
commandStack.addCurveTo(50,150,50,100);
commandStack.addCurveTo(50,50,100,50);
commandStack.addCurveTo(150,50,150,100);
//commandStack.addLineTo(200,200);
invalidated = false;
}
override public function draw(graphics:Graphics,rc:Rectangle):void{
preDraw();
//apply the fill retangle for the draw
super.draw(graphics,(rc)? rc:bounds);
}
}
}
调用的类:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="1024" height="900" minWidth="955" minHeight="600" creationComplete="init()">
<s:layout>
<s:BasicLayout/>
</s:layout>
<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import com.annpro.base.geometry.Circle;
import com.annpro.base.geometry.CubicBezier;
import com.annpro.base.paint.SolidStroke;
import mx.containers.Canvas;
import mx.graphics.Stroke;
public function init():void{
import com.annpro.base.GeometryGroup;
import com.annpro.base.Surface;
var su:Surface=new Surface();
var gg:GeometryGroup=new GeometryGroup();
var _graphObjects1:Array=new Array;
_graphObjects1.push(gg);
su.graphicsData=_graphObjects1;
var line:Hec=new Hec();
//line.data="125 0 375";
var stroke:SolidStroke=new SolidStroke(0x444444,1,5);
line.stroke=stroke;
var _graphObjects:Array=new Array;
_graphObjects.push(line);
gg.geometry=_graphObjects;
var can:Canvas=new Canvas();
can.addChild(su);
this.addElement(can);
}
]]>
</fx:Script>
</s:Application>
是不是也获得了一个圆形,可能不是很圆,大家谅解。。。。。。。。