为了保障原创作者在本站发表文章的利益, 并维护本站原创的精神, 特声明: RIAShanghai对有以下任何情况之一的文章将不通知作者并直接进行快意删除:
- 非原创, 或者原创但一文多发;
- 各种形式的广告与吹擂;
- 不符合本站文章格式.
欢迎各位读者监督. 谢谢合作. 另: 作为Adobe正式的UG, 我们将把Adobe不定期分发的软件,书籍及各种纪念品赠送给发文活跃的作者, 共同进步.
从 The Joy of Flex 的博客上,看到了一则关于 Buzzword的视频介绍。Buzzword是Adobe官方的一个线上文档编辑器。功能强大。![]()
看到Buzzword的右键菜单很是好看,决定山寨一次,模仿一下。
通过模仿,我们可以了解如何制作一个Flex部件,自己来定义它的形状。
先上个Buzzword的右键菜单的视频截图,和模仿后的成品的截图。
左边的是视频截图,右边的是作者模仿。
Buzzword的那个Context Menu严格意义上来说,不是真正的,flash浏览器默认的那个右键菜单(就是有查看flash版本号选项的那个)。作者分析,那个Buzzword的这个context menu,不是基于flash.ui.ContextMenu来开发的。而是基于类似Canvas或者List一类的部件来进行开发的。作者是基于VBox来进行开发的。
这个Context Menu的特点就是,当鼠标沿着这个不规则的Context Menu四边游走的时候,被其盖在下面的部件,都能紧贴着Context Menu的边而被激活。也就是说,这个Context Menu的背景, 不是用一个这个不规则形状的截图来实现的。如果是这个形状的截图作为Context Menu的背景,那么作者放于这个Context Menu下面的Link Button 部件,就不会在鼠标放到该位置时,变成Mouse Over的状态。因为,这个按钮理应被正方形的截图所遮挡(之所以大家能看到它,是因为除了黑色的主体部分外,那个截图的画布背景是透明的)。
当然,如果不要求有上述这个功能,用截图也是可以的。但是这个部件的高度就不能方便地随意控制。
此次模仿的原理就是,自己写VBox的BorderSkin类。步骤如下,
1. 建立一个VBox的Border类,扩展mx.skins.Border类。覆盖 updateDisplayList方法。实现自己的graphics实例,也就是这个部件的外形了。
package com.chestnut.view
{
import flash.display.Graphics;
import flash.filters.DropShadowFilter;
import mx.skins.Border;
public class MyBorder extends Border
{
public function MyBorder()
{
super();
}
//覆盖updateDisplayList, 画自己所需要的图形
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
var g:Graphics = graphics;
drawBorder(unscaledWidth, unscaledHeight, g, -5);
}
//覆盖drawBorder,画自定义的边
public static function drawBorder(w:Number, h:Number, g:Graphics, inset:Number):void
{
var xSign:Number = 1;
var ySign:Number = 1;
var xShift:Number = 0;
var yShift:Number = 0;
var padding:Number = 20;
var upperLeftControlOffset:Number = 5;
var controlOffset:Number = 5;
g.clear();
g.beginFill(0x000000, 1);
g.lineStyle(1, 0x000000, 1);
//draw the menu
g.moveTo(xShift+xSign*upperLeftControlOffset, yShift+ySign*inset);
//..此处省略,这里就是Graphics,画出那个不规则图形的方法。代码因图形形状的不同而异,因此省略
g.endFill();
}
}
}
2. 在CSS定义中,定义自己的borderSkin类。
/* CSS file */
.contextMenu{
borderSkin: ClassReference("com.chestnut.view.MyBorder");
}
3. 加入自己的 menu item 部件。
private function onInit():void
{
menuArray = ["Open","Open in New Window","Seperator", "Share...", "Duplicate", "Rename", "Show Info", "Seperator", "Delete"];
for each(var str:String in menuArray)
{
//当关键字是sperator时,就插入一个横线,vb就是VBox
if(str == "Seperator")
{
var hr:HRule = new HRule();
hr.width = 150;
hr.setStyle("strokeColor", "#FFFFFF");
hr.height = 1;
vb.addChild(hr);
}
//其他时候,就插入自定义的menu item, 作者基于canvas来实现的
else
{
var mi:MenuItem = new MenuItem();
mi.menuStr = str;
vb.addChild(mi);
}
}
//加一个装饰阴影
var sf:DropShadowFilter = new DropShadowFilter();
sf.distance = 5;
sf.alpha = 0.4;
sf.angle = 45;
vb.filters = [sf];
var cm:ContextMenu = new ContextMenu();
}再说两句,是关于“山寨”文化的。现在中国的“山寨”文化盛行,好多人批评,中国人自己的创新能力都被“山寨”抹杀了。
作者,不反对“山寨”,但也不提倡“山寨”。这无非是个度的问题,过度和不足都不好。希望我们都能中性的看待“山寨”这个问题。师夷长技的时候,同时也要自省、创新。
Comments
vb和ContextMenu怎么联系起来呢
你好,我是flex初学者,你实现的右键菜单很炫呀, 可是看了你的代码,不太明白vb和ContextMenu怎么联系起来呢?var cm:ContextMenu = new ContextMenu(); 这句话后面还有代码吗?.contextMenu这个style class是用来修饰vb的吗?能把可以运行的代码都发给我看看吗?邮箱是tiao67@sohu.com, 谢谢啦!!
你好,能把你的这个例子发给我吗,谢谢! shangmw@1
你好,能把你的这个例子发给我吗,谢谢!
shangmw@163.com
漂亮!
漂亮!
谢谢
呵呵,看到你右边的那个广告了。在上海开张了没?
lw0110's Blog: http://chestnutjoelee.spaces.live.com/
有些有意向的, 但预算太少. 所以特地明码实价, 呵呵
有些有意向的, 但预算太少. 所以特地明码实价, 呵呵