2010-08-14 2 views
1

Я пытаюсь создать вращающееся колесо с текстом на нем. Я создал колесо, и оно прекрасно заполняется на основе цветов, которые я им предлагаю. Теперь я пытаюсь добавить текст к каждой из частей колеса, но у меня проблемы. Кажется, я не могу правильно отобразить текст в каждом из цветов. Я надеялся, что кто-то поможет мне заставить это работать правильно. Место, где я пытаюсь получить текст для работы, находится в функции _drawSlice. Я пытаюсь понять логику, чтобы заставить ее работать правильно. Любая помощь приветствуется. Вот мой код:Flash as3 прялка

package { 
import flash.display.MovieClip; 
import flash.display.Sprite; 
import flash.text.TextFormat; 
import flash.text.TextField; 
import flash.display.BitmapData; 
import flash.display.Bitmap; 

public class PieChart extends MovieClip{ 
    //settings 
    private var _radius:Number = new Number(100); 

    //storage 
    private var slices:Array = new Array(); 
    private var _startAngle:Number = new Number(0); 

    public function PieChart() { 
     this._setup(_radius); 

     for(var i:int=0;i<2;i++){ 
      this.addSlice(0xCF5351,'Maroon'); //maroon 
      this.addSlice(0x3DA261,'Green'); //green 
      this.addSlice(0x4485C3,'Blue'); //blue 
      this.addSlice(0xF8F66D,'Yellow'); //yellow 
      this.addSlice(0x9D499B,'Purple'); //purple 
      this.addSlice(0xF99F44,'Orange'); //orange 
     } 
     this.x = 150; 
     this.y = 150; 
     this.draw(); 
    } 

    public function addSlice(color:Number,text:String):void { 
     var slice:Array = ["slice"+slices.length,color,text]; 
     slices.push(slice); 
    } 

    public function draw():void { 
     var angle:Number=((100/slices.length)*360)/100; 

     for(var i:int=0;i<slices.length;i++){ 
      this._drawSlice(_radius,_startAngle,slices[i][1],1,angle,slices[i][2]);       
      _startAngle-=angle; 
     } 
    } 

    private function _drawSlice(radius:Number,angle:Number,color:Number,alpha:Number,arc:Number,txt:String):void { 
     var sprite:Sprite = new Sprite(); 

     sprite.graphics.beginFill(color,alpha); 

     //setup the variables 
     var segAngle:Number, theta:Number, angle:Number, angleMid:Number, segs:Number, ax:Number, ay:Number, bx:Number, by:Number, cx:Number, cy:Number; 

     //start at point 0,0 
     sprite.graphics.moveTo(0, 0); 
     //get the number of segments 
     segs = Math.ceil(Math.abs(arc)/45); 
     // Now calculate the sweep of each segment. 
     segAngle = arc/segs; 
     // The math requires radians rather than degrees. To convert from degrees 
     // use the formula (degrees/180)*Math.PI to get radians. 
     theta = -(segAngle/180)*Math.PI; 
     // convert angle _startAngle to radians 
     angle = -(_startAngle/180)*Math.PI; 
     // draw the curve in segments no larger than 45 degrees. 
     if (segs>0) { 
      // draw a line from the center to the start of the curve 
      ax = Math.cos(_startAngle/180*Math.PI)*radius; 
      ay = Math.sin(-_startAngle/180*Math.PI)*radius; 
      sprite.graphics.lineTo(ax, ay); 

      // Loop for drawing curve segments 
      for (var i:int = 0; i<segs; i++) { 
       angle += theta; 
       angleMid = angle-(theta/2); 
       bx = Math.cos(angle)*radius; 
       by = Math.sin(angle)*radius; 
       cx = Math.cos(angleMid)*(radius/Math.cos(theta/2)); 
       cy = Math.sin(angleMid)*(radius/Math.cos(theta/2)); 
       sprite.graphics.curveTo(cx, cy, bx, by); 
      } 

      // close the wedge by drawing a line to the center 
      sprite.graphics.lineTo(0, 0); 
     } 

     var txtFormat:TextFormat = new TextFormat(); 
     txtFormat.color = 0xFFFFFF; 
     txtFormat.size = 16; 

     var txtField:TextField = new TextField; 
     txtField.text = txt; 
     txtField.setTextFormat(txtFormat); 

     var bmpData:BitmapData = new BitmapData(sprite.width,sprite.height,true,0x000000); 
     bmpData.draw(txtField); 

     var bmp:Bitmap = new Bitmap(bmpData,"auto",true); 
     bmp.rotation = (_startAngle*-1)-20; 
     bmp.y -= 20; 

     sprite.addChild(bmp); 
     this.addChild(sprite); 
    } 

    private function _setup(radius:Number):void { 
     this._radius = radius; 
    } 

} 

}

ответ

1

Для простоты, я использую встраивать шрифты, но вы можете легко изменить это :) Это быстрое решение на основе вокруг вашего кода, но мышление так же, как объяснялось ранее, я бы предпочел создать объект среза с текстом в правильном положении, а затем добавить объекты среза для формирования колеса. Внутри кода я попытался реплицировать это, поэтому я установил позицию для текстового поля, которое затем добавляется в маленький контейнер, оборот которого пропорционален количеству слайдов. Это может быть улучшено, но вы должны иметь достаточное количество элементов, чтобы превратить это в более хороший код:

package { 
import flash.display.Bitmap; 
import flash.display.BitmapData; 
import flash.display.MovieClip; 
import flash.display.Sprite; 
import flash.text.TextField; 
import flash.text.TextFormat; 

public class PieChart extends MovieClip{ 
//settings 
private var _radius:Number = new Number(100); 


[Embed(source="fonts/Arial.ttf", 
    fontName="PCArial", 
    mimeType="application/x-font-truetype", 
    embedAsCFF= "false")] 
public var PCArial:Class; 

//storage 
private var slices:Array = new Array(); 
private var _startAngle:Number = new Number(0); 

public function PieChart() { 
    this._setup(_radius); 

    for(var i:int=0;i<2;i++){ 
     this.addSlice(0xCF5351,'Maroon'); //maroon 
     this.addSlice(0x3DA261,'Green'); //green 
     this.addSlice(0x4485C3,'Blue'); //blue 
     this.addSlice(0xF8F66D,'Yellow'); //yellow 
     this.addSlice(0x9D499B,'Purple'); //purple 
     this.addSlice(0xF99F44,'Orange'); //orange 
    } 
    this.x = 150; 
    this.y = 150; 
    this.draw(); 
} 

public function addSlice(color:Number,text:String):void { 
    var slice:Array = ["slice"+slices.length,color,text]; 
    slices.push(slice); 
} 

public function draw():void { 
    var angle:Number=((100/slices.length)*360)/100; 

    for(var i:int=0;i< slices.length;i++){ 
     this._drawSlice(_radius,_startAngle,slices[i][1],1,angle,slices[i][2] , i);       
     _startAngle-=angle; 
    } 
} 

private function _drawSlice(radius:Number,angle:Number,color:Number,alpha:Number,arc:Number,txt:String , j:int):void { 
    var sprite:Sprite = new Sprite(); 

    sprite.graphics.beginFill(color,alpha); 

    //setup the variables 
    var segAngle:Number, theta:Number, angle:Number, angleMid:Number, segs:Number, ax:Number, ay:Number, bx:Number, by:Number, cx:Number, cy:Number; 

    //start at point 0,0 
    sprite.graphics.moveTo(0, 0); 
    //get the number of segments 
    segs = Math.ceil(Math.abs(arc)/45); 
    // Now calculate the sweep of each segment. 
    segAngle = arc/segs; 
    // The math requires radians rather than degrees. To convert from degrees 
    // use the formula (degrees/180)*Math.PI to get radians. 
    theta = -(segAngle/180)*Math.PI; 
    // convert angle _startAngle to radians 
    angle = -(_startAngle/180)*Math.PI; 
    // draw the curve in segments no larger than 45 degrees. 
    if (segs>0) { 
     // draw a line from the center to the start of the curve 
     ax = Math.cos(_startAngle/180*Math.PI)*radius; 
     ay = Math.sin(-_startAngle/180*Math.PI)*radius; 
     sprite.graphics.lineTo(ax, ay); 

     // Loop for drawing curve segments 
     for (var i:int = 0; i<segs; i++) { 
      angle += theta; 
      angleMid = angle-(theta/2); 
      bx = Math.cos(angle)*radius; 
      by = Math.sin(angle)*radius; 
      cx = Math.cos(angleMid)*(radius/Math.cos(theta/2)); 
      cy = Math.sin(angleMid)*(radius/Math.cos(theta/2)); 
      sprite.graphics.curveTo(cx, cy, bx, by); 
     } 

     // close the wedge by drawing a line to the center 
     sprite.graphics.lineTo(0, 0); 
    } 

    var txtFormat:TextFormat = new TextFormat("PCArial"); 
    txtFormat.color = 0xFFFFFF; 
    txtFormat.size = 16; 

    var txtField:TextField = new TextField; 
    txtField.text = txt; 
    txtField.x = 30; 
    txtField.y = -18; 
    txtField.rotation = -18 ; 
    txtField.embedFonts = true; 
    txtField.setTextFormat(txtFormat); 

    var txtSprite:Sprite = new Sprite(); 

    txtSprite.rotation = (360/slices.length * j); 
    txtSprite.addChild(txtField); 

    sprite.addChild(txtSprite); 
    this.addChild(sprite); 
} 

private function _setup(radius:Number):void { 
    this._radius = radius; 
} 
    } 

} 
+0

Я не хочу использовать встроенные шрифты, потому что они раздувают программу от того, что я читал. Он отлично работает, и текст отображается и вращается. Проблема, с которой я сталкиваюсь, заключается в том, что я не могу получить углы с текстом. Цвета прекрасно, но текст не в нужном месте. Любая помощь в этом? – ngreenwood6

+0

Некоторые шрифты не такие большие, может быть, 30kb-50kb, но опять же это зависит от того, что вам нужно достичь. Правильно или нет в правильном месте слишком неопределенно для меня, чтобы дать вам ответ, можете ли вы сузить его? Можно ли увидеть, что у вас есть до сих пор? – PatrickS

+0

Текст не отображается в нужном месте. Он должен быть в цветовой области под углом, подобным цветам. Если вы создаете новый флеш-файл, а затем связываете его с классом (назовите его PieChart), вы можете скопировать и вставить код из моего сообщения в этот класс, переопределяя то, что там есть. Он покажет вам, с чем я работаю. – ngreenwood6