我正在尝试创建一个带有文字的旋转轮。我创造了轮子,它根据我提供的颜色完美填充。现在我正在尝试将文本添加到方向盘的每个部分,但遇到了一些问题。我似乎无法在每种颜色中正确显示文本。我希望有人可以帮助我让它正常工作。我试图让文本工作的地方是_drawSlice函数。我试图找出让它正常工作的逻辑。任何帮助表示赞赏。这是我的代码:
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;
}
}
}
答案 0 :(得分:1)
为了简单起见,我使用嵌入字体,但你可以很容易地改变:)这是一个基于你的代码的快速解决方案,但思路与之前解释的相同,我赞成创建一个切片对象将文本放在正确的位置,然后添加切片对象以形成轮子。在我的代码中,我试图复制它,所以我为textfield设置了一个位置,然后将其添加到一个小容器中,该容器的旋转与幻灯片的数量成正比。这可以改进,但你应该有足够的元素把它变成更好的代码:
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;
}
}
}