`
天梯梦
  • 浏览: 13730688 次
  • 性别: Icon_minigender_2
  • 来自: 洛杉矶
社区版块
存档分类
最新评论

flex 扇形菜单

阅读更多

在继 auzn经典Flex教程–KingnareStyle皮肤制作简介 后 ,auzn又出品了经典作品–扇形菜单。本文英文


版:Tutorials: Step by Step to Create your Sector Menu 。 下面我们就来做个扇形菜单,首先来看看效果吧:


[PieMenu.swf ]


只要设定好起始位置和总角度,似乎可以画出很多种组合.


Search-256x256Demo | DownloadDownload Full Project


这样:

clip_image004

这样:

clip_image006

或者这样:

clip_image008

 

菜单的重点是如何画空心弧及过渡动画的控制.

很明显,菜单是由多个空心弧组成的,菜单形成也就是多个空心弧的产生并进行动画过渡的过程,所以我们先从单个空心弧入手.空心弧在过渡动画 中可能是在任意一个角度开始绘制,任意一个角度结束绘制,我们随意取一个状态:

 

clip_image010

 

上图是从-30度起始画图,画到-135度结束,空心弧角度为-105度,内圆半径50,外圆半径100,中心圆坐标(x,y).

 

可以看出这个图形边线由两条直线和两条弧组成,按逆时针为直线P1P2, 弧P2P3, 直线P3P4, 弧P4P1. 只要画好边线再进行填充即可.

 

我们先来计算四个点的坐标:

P1: (x+r*cos(start), y+r*sin(start))

P2: (x+R*cos(start), y+R*sin(start))

P3: (x+r*cos(start+angle), y+r*sin(start+angle))

P4: (x+R*cos(start+angle), y+R*sin(start+angle))

 

接下来的问题就是圆弧的算法了,可以知道,在圆心角小于45度的范围内是可以画出圆弧的.我们把圆弧的圆心角以小于 45 度 为单位 均分,对每个部分进行画弧,这样拼接起来就是完整的圆弧了.

 

目前已经有比较成熟的程序代码了.

修改了Geordi的DrawSector方法(如果知道作者及出处,请留言):

 

//angle为圆心角的大小,startA为起始角度

//以45度为最大角度值均分,取得可以划分数值

var n:Number = Math.ceil(Math.abs(angle) / 45);

//计算每份圆弧的圆心角(均小于45度)

var angleA:Number=angle / n;

angleA = angleA * Math.PI / 180;

startA = startA * Math.PI / 180

//循环绘制圆弧

for (var i=1; i <= n; i++)

{

startA += angleA;

var angleMid1:Number=startA – angleA / 2;

var bx:Number = x + R / Math.cos(angleA / 2) * Math.cos(angleMid1);

var by:Number = y + R / Math.cos(angleA / 2) * Math.sin(angleMid1);

var cx:Number = x + R * Math.cos(startA);

var cy:Number = y + R * Math.sin(startA);

sector.graphics.curveTo(bx, by, cx, cy);

}

 

如果理解上有些困难,可参见下图:

[tween_with_angle.swf ]

clip_image012

 

切点P就是画曲线方法curveTo的控制点.

 

OK,理论部分结束.我们在Flash cs3中新建Flash文件,在第一帧的动作面版写上如下代码:

 

var sector:Sprite = new Sprite();

addChild(sector);

drawSector(200, 200, 50, 100, -105, -30);

function drawSector( x:Number, y:Number, r:Number, R:Number, angle:Number, startA:Number)

{

sector.graphics.clear();

sector.graphics.lineStyle (1, 0, 1, true);

sector.graphics.beginFill(0, 0.5);

if (Math.abs(angle) > 360)

{

angle=360;

}

var n:Number = Math.ceil(Math.abs(angle) / 45);

var angleA:Number=angle / n;

angleA = angleA * Math.PI / 180;

startA = startA * Math.PI / 180;

var startB:Number = startA;

//起始边

sector.graphics.moveTo(x + r * Math.cos(startA), y + r * Math.sin(startA));

sector.graphics.lineTo(x + R * Math.cos(startA), y + R * Math.sin(startA));

//外圆弧

for (var i=1; i <= n; i++)

{

startA += angleA;

var angleMid1:Number=startA – angleA / 2;

var bx:Number = x + R / Math.cos(angleA / 2) * Math.cos(angleMid1);

var by:Number = y + R / Math.cos(angleA / 2) * Math.sin(angleMid1);

var cx:Number = x + R * Math.cos(startA);

var cy:Number = y + R * Math.sin(startA);

sector.graphics.curveTo(bx, by, cx, cy);

}

//内圆起点

sector.graphics.lineTo(x + r * Math.cos(startA),y + r * Math.sin(startA));

//内圆弧

for (var j = n; j >= 1; j–)

{

startA-= angleA;

var angleMid2:Number=startA + angleA / 2;

var bx2:Number=x + r / Math.cos(angleA / 2) * Math.cos(angleMid2);

var by2:Number=y + r / Math.cos(angleA / 2) * Math.sin(angleMid2);

var cx2:Number=x + r * Math.cos(startA);

var cy2:Number=y + r * Math.sin(startA);

sector.graphics.curveTo(bx2, by2, cx2, cy2);

}

//内圆终点

sector.graphics.lineTo(x + r * Math.cos(startB),y + r * Math.sin(startB));

//完成

sector.graphics.endFill();

}

CTRL+ENTER测试(坐标系为笔者自行加入,坐标中心点为(200, 200)).

 

[draw_sector.swf ]

clip_image014

 

这样就可以完成我们的空心弧了.

至此,绘制空心弧完成.

 

接下来我们将介绍如何生成过渡动画.

通过上面的程序可知,只要改变空心弧的起始角度和圆心角角度,就能达到“展开并旋转”这一效果了.

 

首先是展开效果.所谓展开,就是起始角度不变,只改变圆心角角度.以前面的数据为例,起始角度为-30度,圆心角数值由0过渡到-105 度.加入以下代码:

 

import fl.transitions.Tween;

import fl.transitions.TweenEvent;

import fl.transitions.easing.Strong;

var obj:Object = {};

obj.angle = 0;

var tween:Tween=new Tween(obj, “angle”, Strong.easeInOut, 0, -105, 5, true);

tween.addEventListener(TweenEvent.MOTION_CHANGE, changeHandler);

function changeHandler(event:TweenEvent):void

{

drawSector(200, 200, 50, 100, obj.angle, -30);

}

 

使用了Flash CS3内置的Tween类,除此之外还可以用TweenMax 代替.

CTRL+ENTER测试,[tween_with_angle.swf ].

 

可以观查到程序不断的在改变圆心角角度.

展开没问题了,接下来是改变起始角度.这次设定圆心角夹角仍为105度,起始角度75度, 旋转到-30停止.

 

对刚才的展开代码稍加改动,缓部分代码如下:

 

import fl.transitions.Tween;

import fl.transitions.TweenEvent;

import fl.transitions.easing.Strong;

var obj:Object = {};

obj.start = 0;

var tween:Tween=new Tween(obj, “start”, Strong.easeInOut, 75, -30, 5, true);

tween.addEventListener(TweenEvent.MOTION_CHANGE, changeHandler);

function changeHandler(event:TweenEvent):void

{

drawSector(200, 200, 50, 100, -105, obj.start);

}

CTRL+ENTER测试,[tween_with_start.swf ].

 

可以观查到程序不断的在改变起始角度.

 

由上面两个过程,可以推导出子菜单的生成过程:首先起始角度固定,不断变化的只有圆心角,当圆心角达到目标值后,开始改变起始角度,这个时 候圆心角是固定不变的,空心弧此时是在以围绕圆心做旋转运动,起始角度达到目标值后,整个过程结束.

 

但是有一个重要的问题:如果先展开再旋转,两个动画中间的衔接是个问题.那么如何产生比较流畅的动画?我们现在用另一种方法重新分析一下:

 

我们设定圆心角度数值为正值,那么这时起始边应该在结束边的逆时针方向上,起始边逆时针旋转一定的角度 angle(angle>0),此时将其圆心角数值也更新为angle,这样看起来结束边不动,角度在变大.可以模拟展开效果.当圆心角角度达到目 标值后,将圆心角角度固定,而此时起始边继续旋转,最后旋转到目标值,整个过程结束.

 

根据以上分析,我们修改刚才的代码:

 

import fl.transitions.Tween;

import fl.transitions.TweenEvent;

import fl.transitions.easing.Strong;

var obj:Object = {};

obj.start = 0;

obj.angle = 0;

var tween:Tween;

//begin:起始角度初始值

// end:起始角度终止值

// angle:圆心角绝对值

function create (begin:Number, end:Number, angle:Number, tweenTime:Number):void

{

var oldStart:Number=0;

tween=new Tween(obj, “start”, Strong.easeInOut, begin, end, tweenTime, true);

tween.addEventListener(TweenEvent.MOTION_CHANGE, changeHandler);

function changeHandler(event:TweenEvent):void

{

if (Math.abs(obj.angle) >= angle)

{

drawSector(200, 200, 50, 100, angle, obj.start);

}

else

{

obj.angle = Math.abs(oldStart – obj.start)

drawSector(200, 200, 50, 100, obj.angle, obj.start);

}

}

}

//由0开始,起始边转到-135度,动画时间为5秒

create (0, -135, 105, 5);

 

CTRL+ENTER测试.[tween_without_filters.swf ].

OK,剩下的工作就是加上合适的滤镜,让菜单看上去更加美观.

 

可以选择BevelFilter及DropShadowFilter增加立体效果.

增加两个方法:

 

function getBevelFilter():BitmapFilter

{

var distance:Number = 6;

var angleInDegrees:Number = 45;

var highlightColor:Number = 0xFFFFFF;

var highlightAlpha:Number = 0.6;

var shadowColor:Number = 0xFFFFFF;

var shadowAlpha:Number = 0;

var blurX:Number = 10;

var blurY:Number = 10;

var strength:Number = 0.8;

var quality:Number = BitmapFilterQuality.LOW;

var type:String = BitmapFilterType.INNER;

var knockout:Boolean = false;

return new BevelFilter(distance,angleInDegrees,highlightColor,highlightAlpha,shadowColor,shadowAlpha,blurX,blurY,strength,quality,type,knockout);

}

//获取DropShadow滤镜

function getDropShadowFilter():BitmapFilter

{

var color:Number = 0×000000;

var angle:Number = 45;

var alpha:Number = 0.9;

var blurX:Number = 5;

var blurY:Number = 5;

var distance:Number = 5;

var strength:Number = 0.9;

var inner:Boolean = false;

var knockout:Boolean = false;

var quality:Number = BitmapFilterQuality.LOW;

return new DropShadowFilter(distance,angle,color,alpha,blurX,blurY,strength,quality,inner,knockout);

}

 

然后给sector设定滤镜.

sector.filters = [getBevelFilter(), getDropShadowFilter()];

最后把create方法中的填充换为更醒目的色彩:

sector.graphics.beginFill(0×0066FF, 0.8);

 

CTRL+ENTER测试,[tween_with_filters.swf ].

 

接下来就是由总角度及菜单数确定各个菜单的起始角度值变化范围及圆心角数值,然后分别“启动”他们的create方法.我们已经把这部分编 写完成了,大家可以在文章尾部的链接下载到所有示例程序源代码.

若要改用到FLEX中,需要替换代码中的Tween类,因为Flash CS3和FLEX中的Tween是不同的.

 

伪代码如下:

 

import mx.effects.Tween;

import mx.effects.easing.*;

private var tween:Tween;

public function create (value:Number ,delta:Number, tweenTime:Number):void

{

//…

var listener:Object = {};

listener.onTweenUpdate = function(val:Object):void

{

//更新圆心角度

}

listener.onTweenEnd = function(val:Object):void

{

//

}

tween = new Tween(listener, obj.start, value, tweenTime*1000);

tween.easingFunction = Quadratic.easeInOut;

}

 

这样就可以应用到FLEX程序中了.

 

OK,菜单的核心部分就讲到这里,希望能对大家有些许帮助.

 

可以在here 下 载全部源文件.

分享到:
评论
3 楼 415695053 2013-03-08  
lz在么,有问题请教。。。
2 楼 天梯梦 2011-11-28  
lianxia114112 写道
项目里正好想要用到这种效果 非常感谢

有用就好~
1 楼 lianxia114112 2011-11-25  
项目里正好想要用到这种效果 非常感谢

相关推荐

    FLEX 鱼眼菜单,点击菜单3D旋转效果切换页面

    在这个场景中,我们讨论的是一个使用FLEX实现的具有3D旋转效果的鱼眼菜单,当用户点击菜单项时,页面会以3D旋转的方式进行切换。 首先,我们需要了解FLEX布局的基础知识。FLEX布局允许开发者设置容器内的子元素如何...

    Flex 扇形Loading

    Flex扇形Loading是一种在Flex应用中实现的自定义加载指示器,它提供了更加美观和动态的用户体验,替代了默认的加载动画。这种加载效果通常采用扇形或环形的进度条设计,使得用户能够直观地看到加载过程的进度。本文...

    利用flex画一个扇形区域

    在本文中,我们将深入探讨如何使用Flex来绘制一个扇形区域。Flex是一个强大的开发框架,主要用于构建富互联网应用程序(RIA)。在Flex中,我们可以利用ActionScript编程语言和MXML标记来实现图形绘制。 首先,我们...

    Flex创建菜单栏

    本文将详细讲解如何使用Flex来创建一个菜单栏,这是一项基础但重要的用户界面设计任务。 首先,我们需要理解Flex中的菜单栏组件。在Flex中,`MenuBar`类是用于创建顶部水平菜单的组件,它提供了类似于传统桌面应用...

    flex常用动态菜单

    动态添加菜单项是Flex动态菜单的核心特性,可以根据用户操作或数据变化实时更新菜单内容。例如,我们可以根据服务端返回的数据动态生成菜单: ```actionscript for each (var item:Object in serverData) { var ...

    Flex4绘制扇形

    在Flex4中,开发人员可以使用图形类库来创建各种自定义形状,其中包括扇形。Flex4引入了ActionScript3的强大力量,使得绘制图形变得更加灵活和高效。本篇文章将详细探讨如何在Flex4中绘制具有指定角度和背景颜色的...

    flex 鱼眼菜单项目下载

    flex 鱼眼菜单flex 鱼眼菜单flex 鱼眼菜单flex 鱼眼菜单

    Flex右键菜单 flex tree 右键菜单 源码

    在Flex中,右键菜单是用户交互的重要组成部分,特别是在数据可视化和树形结构的数据展示中,如Flex Tree组件。本文将深入探讨如何在Flex中实现右键菜单,并结合提供的源码进行分析。 1. Flex右键菜单: Flex中的...

    flex3D菜单

    这个"flex3D菜单"项目显然利用了Flex的强大功能来创建一个具有三维效果的交互式菜单,该菜单能够跟随用户的鼠标移动,提供流畅的用户体验。在Flex中,3D效果通常通过Stage3D API实现,这是一个底层的硬件加速图形...

    Flex4 滑动菜单案例

    在这个"Flex4 滑动菜单案例"中,我们将探讨如何利用Flex4的组件和特效来实现一个动态的滑动菜单。 滑动菜单是用户界面设计中的常见元素,它可以提供更高效的导航,特别是在内容丰富的应用中。在Flex4中,我们可以...

    Flex自定义右键菜单

    在Flex开发中,自定义右键菜单是一项常见的需求,它能为用户界面提供更丰富的交互体验。Flex是一款基于ActionScript 3.0的开源框架,主要用于构建富互联网应用程序(RIA)。在这里,我们将深入探讨如何在Flex中实现...

    flex自定义多级系统菜单

    这个“flex自定义多级系统菜单”的话题,主要是关于如何在Flex中通过XML配置实现动态、多层次的菜单结构。 在Flex中,菜单通常由`Menu`或`MenuBar`组件来创建。然而,为了实现自定义的多级菜单,我们需要更深入地...

    flex实现右键菜单

    本话题我们将探讨如何使用Flex技术来实现一个自定义的右键菜单。Flex是一种基于ActionScript 3.0的开放源码框架,主要用于构建富互联网应用程序(RIA)。 首先,我们需要理解Flex的基本架构。Flex使用MXML和...

    Flex右键菜单例子

    "Flex右键菜单例子"是一个专门针对Flex技术的右键菜单自定义解决方案。Flex是一种用于构建富互联网应用程序(RIA)的开放源代码框架,由Adobe公司开发。它基于ActionScript编程语言和MXML标记语言,主要用于创建交互式...

    flex右键菜单代码

    在Flex编程中,右键菜单(Context Menu)是一种常见的用户交互功能,允许用户在点击鼠标右键时显示自定义的菜单选项。这个“flex右键菜单代码”分享提供了一个实现Flex中右键菜单的示例,这对于提升用户体验和增强...

    Flex 导航菜单 绝非一般 cool

    在本教程中,我们将深入探讨“Flex 导航菜单 绝非一般 cool”这一主题,这是一个使用Flex技术创建的独特且吸引人的菜单导航系统。通过覆盖提供的`src`文件夹,您可以轻松地将这个酷炫的菜单集成到您的Flex项目中。 ...

    自定义Flex右键菜单

    在IT行业中,自定义Flex右键菜单是一项常见的需求,它涉及到用户交互体验的优化和界面定制化。Flex是一个基于ActionScript 3.0的开源框架,用于构建富互联网应用程序(RIA)。在这里,我们主要探讨如何在Flex项目中...

    Flex 实现右键菜单

    本文将深入探讨如何在Flex环境中实现自定义的右键菜单,包括屏蔽浏览器的默认右键菜单,创建XML格式的多级菜单,以及设置菜单出现位置的自适应策略。 首先,我们需要了解Flex屏蔽浏览器系统右键的基本方法。在...

    2分钟教你实现环形/扇形菜单(基础版)

    在本文中,我们将探讨如何使用React来实现一个基础版的环形或扇形菜单。环形菜单是一种交互式UI设计,常用于展示多个操作选项,这些选项围绕着一个中心图标呈环状或扇形分布。以下是你需要了解的关键概念和技术: 1...

    flex-menu.rar_Flex 4_Menu_flex_flex Menu_flex 菜单

    这个"flex-menu.rar"压缩包包含了一个使用Flex 4构建的菜单组件,专为Flash Builder 4设计。Flash Builder 4是基于Eclipse IDE的开发工具,用于创建、测试和调试Flex和ActionScript项目。 Flex 4中的菜单系统是用户...

Global site tag (gtag.js) - Google Analytics