About

<#TEMPLATE_INCLUDE_NINEPAGE_ABOUTME#>
  • Jun

    24

    基本描述

    2K、4K 等高分辨率屏幕(也被称为“高分屏”)越来越普及,当小尺寸的高分屏出现时就需要用到缩放,一些 Adobe AIR 应用在高分屏中缩放后变模糊(不仅是旧有的 Adobe AIR 应用程序,好多原有的应用程序都出现了这种问题)。

    如:https://tracker.adobe.com/#/view/AIR-3975136

    解决方法

    升级 Adobe AIR SDK 到 22.0 以上的版本,并在应用的 -app.xml 描述文件的 initialWindow 标签内新增一个子标签:<requestedDisplayResolution>high</requestedDisplayResolution>(与 iPhone 设置 Retina 屏那个标签一样)。

    https://helpx.adobe.com/cn/flash-player/release-note/fp_22_air_22_release_notes.html

    此时 Stage.contentScaleFactor 属性就能正确反应缩放系数的值了。

    Jun

    3

    笛箫简谱常见演奏符号说明。

    More...

    Jun

    3

    叠音表与打音表

    More...

    Jun

    3

    八孔洞箫指法表

    • 0 Comments
    • My Music

    第二张表是通过第一张表简化出来的最常用的筒音作5与2全音阶指法表。

    More...

    Apr

    22

    在安装 Adobe AIR 运行时程序过程中,会有一个界面显示应用程序的发行商身份,如果是自己创建的代码签名证书,在安装时会显示一个带有红色叉号的“未知”,如果要显示为绿色对号的“已验证”,需要购买第三方权威认证的代码签名证书,WoSign (沃通)提供了这种代码签名证书(使用前后的安装界面显示对比)。

    Apr

    19

    转载一个漂亮的 Flex4 Tooltips(其实我觉的它一点也不漂亮……好像就多了一个箭头么?):Flex4NiceTooltips.zip

    原文地址:http://www.hulstkamp.com/articles/flex-nicer-tooltips-and-balloon-help/srcview/index.html

    Apr

    19

    也许它们都并不是最好的……

    1、java 或 .NET 程序员可以利用开源的 itextsharp 库。另外,它也有独立的 dll 文件提供,使用方法参考《Extract Bookmark from PDF file》(相关资料《How to check if a pdf page has a bookmark?》)。

    2、一个基于命令行的 PDF Bookmark Print 小程序,但它是收费的,免费版会在抽出的书签中随机插入符号(可以自写脚本利用正则表达式去除这些符号),而且发现它并不能支持中文书签的抽出(不知道现在它的新版是否有更新过)。

    3、pdftk,它有 free、pro、以及 server 等不同的版本,它的免费版也能支持命令行导出书签,但我没有试用过它,所以不知道它是否能支持中文书签的导出……

    4、pdf2htmlEX 现在普遍用于 HTML5 网站中,为了适应移动端显示 PDF文件,许多文库类网站都放弃了 Flash 技术(因为 Flash 播放器无法使用于移动浏览器)。在它的功能简介中包含了支持转换导出链接、大纲(Bookmark)等。它提供了脚本和客户端命令行多种版本,并且放在 github 上授权方式是 GPLv3+(对于国人来说它就相当于是免费的了吧……)。

    没有下载试用过它,因为我是一个反 HTML5 技术的“异端”,我讨厌一却 HTML5 这种不够标准化的技术作为应用、游戏或网站的显示技术,至少现在是这样。然后看它的网页说明冒似原作者要放弃维护了,正在寻找新的维护者……我很开心:)

    Apr

    19

    许多 Web 端与客户端程在上传文件时都会利用到 Flash AS3 技术,在 ADOBE 官方提供的《ADOBE ® ACTIONSCRIPT® 3.0 编程》手册中有一篇完整的官方示例教程:《Adobe ActionScript 3.0 示例:上载和下载文件》。

    Feb

    4

    现在的新版 本 Feathers 为了改善开发者的体验,已经大大简化了外观、子组件相关部份的 API,虽然下面的这些旧资料并不一定适用于新版本(是 Feathers 1.0 开始提供的),但很多资料信息依旧完全适用于新版本,所以一并整理下来备注了。

    首先不用说的一点就是 Feathers 强烈推荐使用主题文件,主题类可以集中设置皮肤相关的代码,便于将来的维护和更新,以及替换新的主题而不影响旧有的功能业务。主题的另外最大的好处就是能自动化给组件添加皮肤(既便是相同类型的组件提供不同的皮肤)。

    但 Feathers 也同时提供了不使用主题、或在主题文件外直接设置组件外观以及子组件的 API。关于新版本的皮肤备注资料,已在博客中单独提供了备注。下面也整理了旧版的 Feathers 资料中一些通用的与皮肤外观、子组件相关的资料。

    子组件工厂:

    子组件可以通过一个“工厂”设置皮肤,这里的“工厂”只是一种设计模式的叫法,跟其它什么“事件侦听器”、“样式提供程序”一样,其实就是个普通的函数在不同情况下叫法不一样。当一个组件需要子组件时调用这个函数,但这个函数不接受参数,却会返回一个子组件对象。下面看个工厂的例子,就是生成 Slider 组件的 thumb 子组件工厂:

    slider.thumbFactory = function():Button
    {
        var thumb:Button = new Button();
        thumb.defaultSkin = new Scale9Image( upTextures );
        thumb.downSkin = new Scale9Image( downTextures );
        return thumb;
    };

    如上代码中,函数创建了一个 Button 实例,在返回之前给它添加了一些皮肤。

    子组件的子组件:

    有些子组件会复杂一些,自身也会带有一些子组件,则可以为这些子组件单独提供工厂函数,以引用的方式一层一层的传递工厂函数。如下代码,给一个 List 组件设置滚动条的皮肤:

    function simpleScrollBarThumbFactory():Button
    {
        var thumb:Button = new Button();
        thumb.defaultSkin = new Scale3Image( thumbTextures );
        return thumb;
    }

    function simpleScrollBarFactory():SimpleScrollBar
    {
        var scrollBar:SimpleScrollBar = new SimpleScrollBar();
        scrollBar.thumbFactory = simpleScrollBarThumbFactory;
        return scrollBar;
    }

    list.verticalScrollBarFactory = simpleScrollBarFactory;

    如上代码,其实也可以将 simpleScrollBarThumbFactory() 函数以嵌套函数的方式放在 simpleScrollBarFactory() 函数内,但子组件过多时可能会不方便阅读代码。

    重复使用(并联)的工厂:

    如果组件已经设置了外观,并且想要继续对它的子组件进行其它属性设置,可以重复使用工厂,如下代码,已经在一个工厂方法中设置了 Panel 的 header 的外观,但还想进一步设置或修改它的 title 属性:

    var headerWithSkinsFactory:Function = panel.headerFactory;
    panel.headerFactory = function():Button
    {
        var header:Header = headerWithSkinsFactory();
        header.title = "Tools";
        return header;
    };

    开发者虽然可以在一个工厂中设置所有的外观以及所有的属性,但有时候仅仅只是想要在后期动态的修改它的 title 属性,这种方法就必不可少了。

    子组件属性:

    开发者也可以不使用工厂,而是通过父组件的“子组件属性”来“引用”子对象设置属性,所有设置的值会在下一次渲染时生效。这种方式性能略差一点,大多数情况下推荐使用工厂方法。但这种方式适用于在创建子组件后很久才调整属性和皮肤。以上面的 slider 为例:

    slider.thumbProperties.defaultSkin = new Scale9Image( upTextures );
    slider.thumbProperties.downSkin = new Scale9Image( downTextures );

    如上代码通过 thumbProperties 属性设置的皮肤,并不会立即将设置传递给子组件,而是要等到下一帧的渲染时才会传递给子组件。一般来说开发者不能通过这种方式去获取子对象的属性值,只应该使用这种方式来设置属性的值。thumbProperties 对象并不知道它存储数据的实际 Button 实例的任何内容。所以以下代码将产生错误,除非开发者自己实际设置了 isSelected:

    var isSelected:Boolean = slider.thumbProperties.isSelected;

    这段话的主要意思就是指 “thumbProperties ”只是一个存储数据的对象,这个子组件属性并不是真正的引用到了子组件,而只是给出了用于下一次渲染时提供给 thumb 按钮需要的数据,所以 thumbProperties 本身并不是 thumb 子组件。所以上面的黄色字“子组件属性”与“引用”打了引号,只是看起来好像是子组件的引用,但实际上只是给子组件提供需要的属性数据(由于在下一帧渲染时需要传递给某个子组件,所以对应的子组件是需要被先创建好的)。

    嵌套的子组件属性:

    如上面的 slider 的 thumbProperties “伪引用”了子组件,这种伪引用可以嵌套的,听起来好凌乱(- -!),所以一般都推荐使用工厂方法,但如果有需要的话也可以作为一种可选的方法用于实际开发。

    再次以 list 组件的滚动条为例,但这次不使用工厂,而是使用嵌套的“子组件属性”:

    list.verticalScrollBarProperties.@thumbProperties.defaultSkin = new Scale3Image( thumbTextures );

    注意在这里使用了属性运算符(@)。属性运算符告诉系统在另一个“子组件属性”对象内创建“子组件属性”对象,但前提是它尚不存在。 它不能用于常规属性,所以这就是为什么 defaultSkin 不以@开头。

    但使用这种语法有一个好处,可以避免覆盖可能已经存在的对象。如果使用一个全新的对象设置 thumbProperties,如下面这样的代码,它将替换整个应用程序中全部的 thumbProperties:

    //警告:这可能会覆盖的东西!
    list.verticalScrollBarProperties.thumbProperties =
    {
       defaultSkin: new Scale3Image( thumbTextures )
    };

    在这里就可以使用 @thumbProperties 并单独传递属性,以便不会删除 thumbProperties 中已经存在的任何内容(这样就避免了替换整个对象,只是单个属性的替换)。

    Feb

    4

    3.0 版本的项目升级到 3.1 的版本时,项目本身不需要进行修改(只是一个次要版本的升级)。但有一些简化的 API,提高开发人员的体验,特别是在处理字体样式和皮肤方面。

    用 starling.text.TextFormat 设置字体样式:

    从 Starling 2.0 开始,引入了 starling.text.TextFormat 类,它定义了所有类型文本使用的常见字体样式,包括位图字体和TTF / OTF字体。以前,要在 Feathers 文本渲染器上使用自定义字体样式,需要使用不同的类并设置不同的属性,具体取决于使用的文本渲染器。例如,TextBlockTextRenderer 具有类型为flash.text.engine.ElementFormat 的 elementFormat 属性,而 TextFieldTextRenderer 具有类型为 flash.text.TextFormat 的 textFormat 属性。现在,所有文本渲染器都有统一的方式来支持 starling.text.TextFormat 类。

    事实上,现在的字体样式不需要直接设置在文本渲染器对象本身上,开发者可以直接在使用到文本组件的对象上直接设置就可以,比如 Label、Button 这些组件用到了文本渲染器,就可以直接对这些父组件设置字体样式,父组件会自动将设置好的字体样式传递给文本渲染器。以 Label 组件为例:

    var label:Label = new Label();
    label.text = "Hello World";
    label.fontStyles = new TextFormat( "_sans"20, 0xff0000 );
    this.addChild( label );

    就是如此简单。在绝大多数情况下,根本不需要通过文本渲染器工厂(text renderer factories)设置。

    如果想设置 Label 禁用时的字体样式,只需如下代码:

    label.disabledFontStyles = new TextFormat( "_sans"20, 0x999999 );

    现在含有文本渲染器的绝大多数组件都包含了 fontStyles、disabledFontStyles 属性。如果一个组件是可选择的(类似“开关”),也会包含 selectedFontStyles 属性。

    如果组件包含有更多的状态,如 Button 组件,还包含了 setFontStylesForState() 方法用于设置不同状态字体的样式,此方法可以传入一个状态名称和一个用于设置字体样式的 TextFormat  对象,如下代码可以设置更多的状态时字体样式:

    var button:Button = new Button();
    button.setFontStylesForState( ButtonState.DOWN, new TextFormat( "_sans"20, 0xffffff ) );
    button.setFontStylesForState( ButtonState.HOVER, new TextFormat( "_sans"20, 0xff9999 ) );

    样式属性与主题:

    在以前的 Feathers 版本中,单独的皮肤设置经常会与主题文件中的代码产生“冲突”。为了避免这种问题,过去可能需要通过使用 AddOnFunctionStyleProvider 类,设置组件的 styleProvider 属性为 null,等待组件的初始化,或者需要扩展主题,但有时候可能仅仅只是需要一些微小的调整,所以这些方法无论是哪一种,都会显示麻烦一点。

    从 Feathers 3.1 开始, 一些属性现在被定义为“样式属性”。如果在主题之外设置样式属性,不需要再担心会被主题替换掉,而且还会同时保留主题文件中其它的皮肤设置(其它样式不会受到影响)。例如,如果在自定义的主题文件之外设置按钮的字体样式,但保持主题的背景皮肤,可以很容易:

    var button:Button = new Button();
    button.label = "Click Me";
    //不会再被主题文件中替换
    button.fontStyles = new TextFormat( "_sans"20, 0xff0000 );
    this.addChild( button );

    如果想要知道 Button 类被单独分离出来的样式属性有哪些,可以查看 API 手册

    主题中的最小尺寸:

    如果在主题文件中设置了普通属性,那么依旧有可能与主题外的代码产生“冲突”。例如,不应该直接对主题中的组件本身设置 minWidth 和 minHeight 属性。这些属性不被视为“样式属性”,所以如果在主题外同时设置的话,就会产生冲突。

    //比如在主题内有如下代码
    private function setButtonStyles( button:Button ):void
    {
        button.defaultSkin = new ImageSkin( texture );
        button.minWidth = 40//在主题内最好不要对组件本身设置这种普通属性
    }

    取而代之的是应该设置组件的皮肤:

    //在主题内
    private function setButtonStyles( button:Button ):void
    {
        var skin:ImageSkin = new ImageSkin( texture );
        skin.minWidth = 40;//对组件的皮肤进行设置
        skin.minHeight = 20;
        button.defaultSkin = backgroundSkin;
    }

    如果组件没有显示的尺寸设置,组件就会用皮肤的尺寸用于测量步骤。所以如上代码在皮肤上设置尺寸,实际上跟在组件上设置尺寸基本上是一样的。

    如果有些组件不需要显示皮肤,可以使用一个全透明的背景皮肤,可以简单地传入一个starling.display.Quad,设 alpha 属性设置为 0:

    var backgroundSkin:Quad = new Quad( 4020 );
    backgroundSkin.alpha = 0;
    component.backgroundSkin = backgroundSkin;

    Starling 不会要求 GPU 渲染一个完全透明的显示对象,因此这个透明背景不会增加 GPU 绘制调用的次数,也不会影响 GPU 绘制的性能。但这个 Quad 的尺寸会被视为测量步骤中的最小尺寸。

    当一个显示对象没有 minWidth 与 minHeight 属性时(如上面的 Quad),它的普通 width 与 height 属性也会被当作最小值。如果一定需要有 minWidth 与 minHeight 的值比普通的 width 与 height 属性值还要小,可以考虑使用 ImageSkin。