显示具有 Flash 标签的文章。 显示所有文章
显示具有 Flash 标签的文章。 显示所有文章

2008年9月16日 星期二

Flash 技巧 - 字体资料转换与解析方式   [+/-]

相信大家应该都看过 fontpark 2.0 网站了吧
基本上,它是透过后端程序取得 font glyphs 矢量资料的
才能够做到随意缩放不失真

至于该如何从 TTF 取出资料呢?
资料格式又该使用哪一种呢?

其实网络上有不少工具可将 TTF 转为 PostScript、SVG、... 等等
相较起来,PostScript 语法需要自行去解析
而且 PostScript 有些绘图动作可能是 Flash 做不到的

AS3 有支持 E4X,同时 SVG 绘图的资料语法与 AS graphics API 比较相近
解析起来也更容易些
可以使用的工具有 Java Batik SVG ToolKit

不过后来又发现还有更好用的方式
那就是 ActionScript Viewer
千万不要以为它只是反编译程序的工具喔
它还可以将嵌入的字体输出 TTF、SWF、ActionScript Data
看到 ActionScript Data 了吧,意思就是连解析都不用!

那么事情就变得很简单了,只要制作一个 SWF
里面嵌入想要用的字体,输出 SWF,丢到 ASV 内
取出 Font Glyphs 资料
实际输出的资料格式如下:

利用 AS 将 Font Glyphs 资料重新画出来:

Ticore's Blog

因为是用标楷体,所以笔画重叠的地方会反白
相对有好有坏,这样可以做到把每一个笔画都拆成独立的对象呢!

最后,还有一个可能的方式,连 font glyphs 资料都不用转出来
请参考本 Blog 第一篇
利用 Flash Javascript API 作批次输出静态文字 swf
利用 Flash JavaScript API,多做一些动作:
打散文字、全选、分布到不同图层去、将每个图层的对象转为单独的 Sprite、....
到时候只要将这些 SWF 直接读入,就有分好的 Sprite 对象可以用
是不是更方便呢!

Read more...

2008年9月15日 星期一

Flash CS3 Compiler Bug   [+/-]

Ticore's Blog

这个问题其实去年就遇到了,只是最近又有人遇到类似的问题
再仔细探讨发生原因,顺便做的纪录

Bug 重现步骤如下:

  1. 使用 Flash CS3 创建一空白的 fla (as3) 文档
  2. 与 Cairngorm.swc (Cairngorm 2.2.1 or 2.2) 放在同一个资料夹下
  3. 影格一写一行 trace(123); 程序
  4. 编译测试影片就会得到以下的错误消息
1046: Type was not found or was not a compile-time constant: WebService.
1046: Type was not found or was not a compile-time constant: RemoteObject.
1046: Type was not found or was not a compile-time constant: HTTPService.

这个实在蛮诡异的,fla 文档内完全没有用到 Cairngorm 的类别
甚至连 ActionScript Classpath 都没设
Flash IDE 就自动去查找 Cairngorm.swc
然后自己挂在那边~~

Read more...

2008年9月12日 星期五

Flash TextField 选择性嵌入字型子集共享   [+/-]

Ticore's Blog

Flash 的文字字段可以选择性嵌入字集
但是当文字字段很多的时候
变的很不容易集中管理

其实在一个 swf 文件内由文字字段嵌入的字集是可以在不同文字字段之间共享的

前提是:

  • 文字字段的字体、文字样式 (Bold、Italic)、点阵风格与否要一致
  • 被分享字体的文字字段本身要具有 embedFonts 属性,可以藉由设置嵌入一个空白字符达到
  • 假如使用点阵风格的话,字集也必须要相同才可以共享

实际测试示范:

测试原始文件下载

Read more...

2008年9月9日 星期二

觉得 AS3 太困难?不妨试试看 SimpleAS3!   [+/-]

Ticore's Blog

SimpleAS3 提供了很简单的 function
让你可以做到读取外部资料、图片、跳页等等..

eg.

 var loader = this.loadChild( "images/button.png" );

loader.onClick(function()
{
        getURL( "http://www.example.com/", "_self" );

}); 

SimpleAS3 简介
SimpleAS3: It Doesn’t Get Any Easier Than This!
http://flashspeaksactionscript.com/simpleas3-it-doesnt-get-any-easier...

SimpleAS3 网站
http://simpleas3.com/

SimpleAS3 Documentation
http://simpleas3.com/documentation/

Read more...

2008年7月5日 星期六

AS3 - BitmapText 程序分享   [+/-]

Ticore's Blog

由于 Flash Player 一直以来都无法对系统字体的文字作旋转与不规则形状遮罩
可是到了 Flash Player 9 AS3,可以将文字绘制成位图
也可以自行继承内建类别 Sprite, TextField 等
于是想到做一个 TextField Wrapper,提供系统文字的点阵化功能
藉以达到文字可旋转、套用不规则遮罩

其实这个 BitmapText 程序去年就已经写了
主要是出于研究目的
专案一次也没有用到过
没想到最近新出的 Flash Player 10 beta 文字引擎
已经可以使用系统字体作旋转了
倘若再不把这程序拿出来使用一下,恐怕就这样永不见天日了~~><>

主要是包含两个类别 TextWrapper, BitmapText
TextWrapper 只是 TextField 的外覆类别
真正在做点阵绘图的是 BitmapText
由于 AS3 TextField 成员属性与方法相当多
我已经很尽量的复写大部分的方法了

TextWrapper Class:

/*
TextWrapper AS3 v0.0.2
 
Date: 2007.04.25
作者: Ticore Shih
Blog:http://ticore.blogspot.com
EMail: swl@ms53.url.com.tw
 
v0.0.1
继承 Sprite 包覆一个 TextField
 
v0.0.2
增加 TextField 一般性方法
*/

package com.ticore.text {
 
 import flash.geom.*;
 import flash.display.*;
 import flash.text.*;
 import flash.events.*;
 
 public class TextWrapper extends Sprite {
  //
  // Protected Property
  //
  protected var _txt_:TextField;
  //
  // Constructor
  //
  public function TextWrapper() {
   init();
  }
  protected function init():void {
   _txt_ = new TextField();
   this.addChild(_txt_);
  }
  //
  // Override DisplayObject Property and Method
  //
  public override function set width(w:Number):void {
   _txt_.width = w;
  }
  public override function get width():Number {
   return _txt_.width;
  }
  
  public override function set height(h:Number):void {
   _txt_.height = h;
  }
  public override function get height():Number {
   return _txt_.height;
  }
  //
  // Proxy Common TextField Property
  //
  public function set antiAliasType(value:String):void {
   _txt_.antiAliasType = value;
  }
  public function get antiAliasType():String {
   return _txt_.antiAliasType;
  }
  
  public function set autoSize(value:String):void {
   _txt_.autoSize = value;
  }
  public function get autoSize():String {
   return _txt_.autoSize;
  }
  
  public function set gridFitType(value:String):void {
   _txt_.gridFitType = value;
  }
  public function get gridFitType():String {
   return _txt_.gridFitType;
  }
  
  public function set htmlText(value:String):void {
   _txt_.htmlText = value;
  }
  public function get htmlText():String {
   return _txt_.htmlText;
  }
  
  public function set restrict(value:String):void {
   _txt_.restrict = value;
  }
  public function get restrict():String {
   return _txt_.restrict;
  }
  
  public function set text(txt:String):void {
   _txt_.text = txt;
  }
  public function get text():String {
   return _txt_.text;
  }
  
  public function set type(type:String):void {
   _txt_.type = type;
  }
  public function get type():String {
   return _txt_.type;
  }
  
  
  public function set backgroundColor(value:uint):void {
   _txt_.backgroundColor = value;
  }
  public function get backgroundColor():uint {
   return _txt_.backgroundColor;
  }
  
  public function set borderColor(value:uint):void {
   _txt_.borderColor = value;
  }
  public function get borderColor():uint {
   return _txt_.borderColor;
  }
  
  public function set textColor(value:uint):void {
   _txt_.textColor = value;
  }
  public function get textColor():uint {
   return _txt_.textColor;
  }
  
  
  public function get bottomScrollV():int {
   return _txt_.bottomScrollV;
  }
  
  public function get caretIndex():int {
   return _txt_.caretIndex;
  }
  
  public function get length():int {
   return _txt_.length;
  }
  
  public function get maxChars():int {
   return _txt_.maxChars;
  }
  
  public function get maxScrollH():int {
   return _txt_.maxScrollH;
  }
  
  public function get maxScrollV():int {
   return _txt_.maxScrollV;
  }
  
  public function get numLines():int {
   return _txt_.numLines;
  }
  
  public function get selectionBeginIndex():int {
   return _txt_.selectionBeginIndex;
  }
  
  public function get selectionEndIndex():int {
   return _txt_.selectionEndIndex;
  }
  
  
  public function set sharpness(value:Number):void {
   _txt_.sharpness = value;
  }
  public function get sharpness():Number {
   return _txt_.sharpness;
  }
  
  public function set thickness(value:Number):void {
   _txt_.thickness = value;
  }
  public function get thickness():Number {
   return _txt_.thickness;
  }
  
  public function get textHeight():Number {
   return _txt_.textHeight;
  }
  public function get textWidth():Number {
   return _txt_.textWidth;
  }
  
  
  public function set alwaysShowSelection(value:Boolean):void {
   _txt_.alwaysShowSelection = value;
  }
  public function get alwaysShowSelection():Boolean {
   return _txt_.alwaysShowSelection;
  }
  
  public function set border(value:Boolean):void {
   _txt_.border = value;
  }
  public function get border():Boolean {
   return _txt_.border;
  }
  
  public function set condenseWhite(value:Boolean):void {
   _txt_.condenseWhite = value;
  }
  public function get condenseWhite():Boolean {
   return _txt_.condenseWhite;
  }
  
  public function set displayAsPassword(value:Boolean):void {
   _txt_.displayAsPassword = value;
  }
  public function get displayAsPassword():Boolean {
   return _txt_.displayAsPassword;
  }
  
  public function set embedFonts(value:Boolean):void {
   _txt_.embedFonts = value;
  }
  public function get embedFonts():Boolean {
   return _txt_.embedFonts;
  }
  
  public function set mouseWheelEnabled(value:Boolean):void {
   _txt_.mouseWheelEnabled = value;
  }
  public function get mouseWheelEnabled():Boolean {
   return _txt_.mouseWheelEnabled;
  }
  
  public function set multiline(value:Boolean):void {
   _txt_.multiline = value;
  }
  public function get multiline():Boolean {
   return _txt_.multiline;
  }
  
  public function set selectable(value:Boolean):void {
   _txt_.selectable = value;
  }
  public function get selectable():Boolean {
   return _txt_.selectable;
  }
  
  public function set useRichTextClipboard(value:Boolean):void {
   _txt_.useRichTextClipboard = value;
  }
  public function get useRichTextClipboard():Boolean {
   return _txt_.useRichTextClipboard;
  }
  
  public function set wordWrap(value:Boolean):void {
   _txt_.wordWrap = value;
  }
  public function get wordWrap():Boolean {
   return _txt_.wordWrap;
  }
  //
  // Proxy Common TextField Method
  //
  public function appendText(text:String):void {
   _txt_.appendText(text);
  }
  
  public function getCharBoundaries(charIndex:int):Rectangle {
   return _txt_.getCharBoundaries(charIndex);
  }
  
  public function getCharIndexAtPoint(x:Number, y:Number):int {
   return _txt_.getCharIndexAtPoint(x,y);
  }
  
  public function getFirstCharInParagraph(charIndex:int):int {
   return _txt_.getFirstCharInParagraph(charIndex);
  }
  
  public function getImageReference(id:String):DisplayObject {
   return _txt_.getImageReference(id);
  }
  
  public function getLineIndexAtPoint(x:Number, y:Number):int {
   return _txt_.getLineIndexAtPoint(x,y);
  }
  
  public function getLineIndexOfChar(charIndex:int):int {
   return _txt_.getLineIndexOfChar(charIndex);
  }
  
  public function getLineLength(lineIndex:int):int {
   return _txt_.getLineLength(lineIndex);
  }
  
  public function getLineMetrics(lineIndex:int):TextLineMetrics {
   return _txt_.getLineMetrics(lineIndex);
  }
  
  public function getLineOffset(lineIndex:int):int {
   return _txt_.getLineOffset(lineIndex);
  }
  
  public function getLineText(lineIndex:int):String {
   return _txt_.getLineText(lineIndex);
  }
  
  public function getParagraphLength(charIndex:int):int {
   return _txt_.getParagraphLength(charIndex);
  }
  
  public function replaceSelectedText(value:String):void {
   _txt_.replaceSelectedText(value);
  }
  
  public function replaceText(beginIndex:int, endIndex:int, newText:String):void {
   _txt_.replaceText(beginIndex,endIndex,newText);
  }
  
  public function setTextFormat(format:TextFormat, beginIndex:int = -1, endIndex:int = -1):void {
   _txt_.setTextFormat(format,beginIndex,endIndex);
  }
  public function getTextFormat(beginIndex:int = -1, endIndex:int = -1):TextFormat {
   return _txt_.getTextFormat(beginIndex,endIndex);
  }
  
  public function set defaultTextFormat(format:TextFormat):void {
   _txt_.defaultTextFormat = format;
  }
  public function get defaultTextFormat():TextFormat {
   return _txt_.defaultTextFormat;
  }
  
 }
}

BitmapText Class:

/*
BitmapText AS3 v0.0.4
 
Date: 2007.04.25
作者: Ticore Shih
Blog:http://ticore.blogspot.com
EMail: swl@ms53.url.com.tw
 
v0.0.1
利用 BitmapData draw TextFIeld
达到可以呈现旋转文字的效果
 
v0.0.2
增加 TextField 一般性方法与属性控制
增加 validate 属性,减少不必要 draw 次数
 
TextField.autoSize 功能会有一些问题
TextField 大小会一直跳动,重复 draw 会发生多重图象
 
v0.0.3
增加 TextField 一般性方法与属性控制
 
v0.0.4
重构将 TextWrapper 功能独立为单一 Class
*/

package com.ticore.text {
 
 import flash.geom.*;
 import flash.display.*;
 import flash.text.*;
 import flash.events.*;
 import flash.filters.*;
 
 public class BitmapText extends TextWrapper {
  
  // Private Property
  private var _validate_:Boolean = true;
  private var magniFactor:Number = 3;
  private var blurFilter:BlurFilter;
  private var _useBitmapText_:Boolean = true;
  
  private var bmpData:BitmapData;
  private var bmp:Bitmap;
  
  public function BitmapText() {
   init();
  }
  protected override function init():void {
   super.init();
   _txt_.addEventListener(Event.CHANGE, onChange);
   bmp = new Bitmap();
   bmp.smoothing = true;
   bmp.scaleX = bmp.scaleY = 1 / magniFactor;
   this.addChild(bmp);
   _txt_.visible = false;
   this.addChild(_txt_);
   blurFilter = new BlurFilter(1 + magniFactor / 6, 1 + magniFactor / 6, BitmapFilterQuality.MEDIUM);
   validate = false;
   addEventListener(Event.ENTER_FRAME, onEnterFame);
  }
  //
  // Private Method
  //
  private function updateBmpData():void {
   if (bmpData) {
    bmpData.dispose();
   }
   bmpData = new BitmapData((width + 1) * magniFactor, (height + 1) * magniFactor, true, 0x00000000);
   bmp.bitmapData = bmpData;
   bmp.smoothing = true;
   validate = false;
  }
  
  private function onChange(eventObj:Event):void {
   validate = false;
  }
  
  private function onEnterFame(eventObj:Event):void {
   if (!validate) {
    draw();
   }
  }
  
  private function draw():void {
   if (bmpData == null) {
    updateBmpData();
   }

   if (bmpData.width < (width + 1) * magniFactor || bmpData.height < (height + 1) * magniFactor) {
    updateBmpData();
   }
   var rect:Rectangle = new Rectangle(_txt_.x, _txt_.y, _txt_.width, _txt_.height);
   bmpData.fillRect(bmpData.rect, 0x00000000);
   var xOffset:Number = -_txt_.x;

   var dev:Number = magniFactor / 3;
   bmpData.draw(_txt_, new Matrix(magniFactor, 0, 0, magniFactor, xOffset * magniFactor + 0, 0));
   bmpData.draw(_txt_, new Matrix(magniFactor, 0, 0, magniFactor, xOffset * magniFactor + dev, 0));
   bmpData.draw(_txt_, new Matrix(magniFactor, 0, 0, magniFactor, xOffset * magniFactor + 0, dev));
   bmpData.applyFilter(bmpData, bmpData.rect, new Point(0, 0), blurFilter);
   bmpData.draw(_txt_, new Matrix(magniFactor, 0, 0, magniFactor, xOffset * magniFactor + dev / 2, dev / 2));

   bmp.x = _txt_.x;
   bmp.y = _txt_.y;
   validate = true;
  }
  
  //
  // Public Method
  //
  public function set validate(value:Boolean):void {
   _validate_ = value;
  }
  public function get validate():Boolean {
   return _validate_;
  }
  
  public function set useBitmapText(value:Boolean):void {
   _useBitmapText_ = value;
   _txt_.visible = !value;
   bmp.visible = value;
  }
  public function get useBitmapText():Boolean {
   return _useBitmapText_;
  }
  //
  // Override Method
  //
  public override function set width(w:Number):void {
   super.width = w;
   validate = false;
  }
  public override function set height(h:Number):void {
   super.height = h;
   validate = false;
  }
  public override function appendText(text:String):void {
   super.appendText(text);
   validate = false;
  }
  public override function replaceSelectedText(value:String):void {
   super.replaceSelectedText(value);
   validate = false;
  }
  public override function replaceText(beginIndex:int, endIndex:int, newText:String):void {
   super.replaceText(beginIndex,endIndex,newText);
   validate = false;
  }
  public override function setTextFormat(format:TextFormat, beginIndex:int = -1, endIndex:int = -1):void {
   super.setTextFormat(format,beginIndex,endIndex);
   validate = false;
  }
  public override function set defaultTextFormat(format:TextFormat):void {
   super.defaultTextFormat = format;
   validate = false;
  }
  
  public override function set antiAliasType(value:String):void {
   super.antiAliasType = value;
   validate = false;
  }
  public override function set autoSize(value:String):void {
   super.autoSize = value;
   validate = false;
  }
  public override function set gridFitType(value:String):void {
   super.gridFitType = value;
   validate = false;
  }
  public override function set htmlText(value:String):void {
   super.htmlText = value;
   validate = false;
  }
  public override function set restrict(value:String):void {
   super.restrict = value;
   validate = false;
  }
  public override function set text(value:String):void {
   super.text = value;
   validate = false;
  }
  
  public override function set backgroundColor(value:uint):void {
   super.backgroundColor = value;
   validate = false;
  }
  public override function set borderColor(value:uint):void {
   super.borderColor = value;
   validate = false;
  }
  public override function set textColor(value:uint):void {
   super.textColor = value;
   validate = false;
  }
  
  public override function set sharpness(value:Number):void {
   super.sharpness = value;
   validate = false;
  }
  public override function set thickness(value:Number):void {
   super.thickness = value;
   validate = false;
  }
  
  public override function set alwaysShowSelection(value:Boolean):void {
   super.alwaysShowSelection = value;
   validate = false;
  }
  public override function set border(value:Boolean):void {
   super.border = value;
   validate = false;
  }
  public override function set condenseWhite(value:Boolean):void {
   super.condenseWhite = value;
   validate = false;
  }
  public override function set displayAsPassword(value:Boolean):void {
   super.displayAsPassword = value;
   validate = false;
  }
  public override function set embedFonts(value:Boolean):void {
   super.embedFonts = value;
   validate = false;
  }
  public override function set multiline(value:Boolean):void {
   super.multiline = value;
   validate = false;
  }
  public override function set selectable(value:Boolean):void {
   super.selectable = value;
   validate = false;
  }
  public override function set wordWrap(value:Boolean):void {
   super.wordWrap = value;
   validate = false;
  }
  
 }
}

测试程序如下:

import com.ticore.text.*;

var bmpTxt:BitmapText = new BitmapText();
this.addChild(bmpTxt);
bmpTxt.border = true;
bmpTxt.multiline = true;
bmpTxt.rotation = 0;
bmpTxt.wordWrap = true;
bmpTxt.rotation = 15;
bmpTxt.width = 320;
bmpTxt.height = 250;
bmpTxt.x = 170;
bmpTxt.y = 30;

var format:TextFormat = bmpTxt.getTextFormat();
format.font = "新细明体";
format.align = "center";

for (var i:Number = 6; i <= 22; format.size=i; bmpTxt.defaultTextFormat=format; bmpTxt.appendText("Font Size format.size 新细明体\n");>

原始文件下载

实际运行效果撷图:

看起来应该还不错吧!
即使在旋转状态下也没有很严重的锯齿
我特别在绘制位图步骤提升了分辨率
并且作了偏移绘制,套用滤镜
当然这些动作是会消耗效能的
所以只有在必要时才会进行重绘的动作

Read more...

2008年6月17日 星期二

Adobe AIR 1.1 出了   [+/-]

Ticore's Blog

Adobe AIR 1.1 出了,HTML Input Text 终于支持双位元文字输入法了

Download Adobe AIR SDK
Adobe AIR extension for Dreamweaver CS3
Installing Adobe Air 1.1 Update for Flash CS3 Professional

Read more...

2008年6月14日 星期六

AS 技巧 - Layer BlendMode 的用处   [+/-]

Ticore's Blog

Flash Player 8 新增的混合模式功能中的图层模式 (Layer)
一般使用起来或许觉得没有什么特别的用处
说明文档上写得更是令人雾茫茫
简单的说,只是让 DisplayObject 子对象预先混和颜色而已

基本上,除了 Normal 之外的混合模式,都会强迫预先混和子对象颜色
但是其它混合模式都是有特殊效果的
假如不需要那些效果,但是又要强迫预先混合颜色时
就要用 Layer 混合模式了

对于像是 Flex 这样由大量的 DisplayObject 组合而成的组件
遇到需要淡入、淡出效果时
即使是在最外层设置 Alpha 透明度
每个子对象仍会先被单独套用 Alpha 效果再叠合成一张图
这样就会有某些位置颜色特别突兀不透明

此时 Layer 混合模式就非常好用了
它可以让整个表单先叠合成一张图再进行 Alpha 效果
可以确保组件颜色看起来不会特别突兀

以下是用 Flex 作的简单测试
可以容易观察到多层嵌套组件在不同 Alpha, BlendMode 的效果

<?xml version="1.0"?>
<mx:Application layout="vertical" fontSize="12" backgroundColor="#FFFFFF"
   xmlns:mx="http://www.adobe.com/2006/mxml">
 <mx:Style>
  HBox.whiteBox {
   paddingTop: 15px;
   paddingBottom: 15px;
   paddingLeft: 15px;
   paddingRight: 15px;
   backgroundColor: #000000;
  }
 </mx:Style>
 <mx:HBox styleName="whiteBox" alpha="{alphaSlider.value}"
    blendMode="{blendModeCb.value ? blendModeCb.value : 'normal'}">
  <mx:HBox styleName="whiteBox">
   <mx:HBox styleName="whiteBox">
    <mx:HBox styleName="whiteBox" />
   </mx:HBox>
  </mx:HBox>
 </mx:HBox>
 
 <mx:HRule width="100%" />
 <mx:HBox verticalAlign="middle">
  <mx:Label text="BlendMode: " />
  <mx:ComboBox id="blendModeCb">
   <mx:dataProvider>
    ["normal", "layer", "darken", "invert", "hardlight"]
   </mx:dataProvider>
  </mx:ComboBox>
 </mx:HBox>
 <mx:HBox verticalAlign="middle">
  <mx:Label text="Alpha: " />
  <mx:HSlider id="alphaSlider" value="0.5"
    tickValues="[0, 0.5, 1]" labels="[0, 0.5, 1]"
    minimum="0" maximum="1" liveDragging="true" />
 </mx:HBox>
</mx:Application>
<!-- Ticore's Blog - http://ticore.blogspot.com/ -->

线上测示示范:

相关连结:
Flex Label, TextField 半透明小技巧
Flash 8 半透明输入、动态文字字段

Read more...

2008年6月3日 星期二

Flash 内嵌动态文字与样式的问题   [+/-]

Ticore's Blog

问题出处:动态文字字段的问题

问题描述:

于 Flash 舞台上
放置两个动态文字字段,选择相同的字体
第一个不嵌入任何字集,样式设为 regular
第二个嵌入数字字符集,样式设为 bold
于运行期动态重设第二个文字字段内容
该文字字段将无法表现新的文字内容

简化过后的问题 Demo 程序如下:

注意,测试的时候不要先选定 txt2 内的文字
只要一选定过,就不过出现问题了

原始文件下载

这个问题其实还挺复杂的,由许多的特性共同影响,分述如下~

Flash TextField 与 Embed Font 特性:

特性 1.
基本上,Flash 的内嵌字体,即使是相同的字体名称
不同的样式 (regular, bold, italic) 会被当作完全不同的字体处理

特性 2.
Flash 内所有时间轴预置 TextField 内嵌字体都是可以共用的

依据特性 1. 2.,可以做一个简单的测试
于 Flash 舞台上放置两个动态文字字段
第一个文字字段仅嵌入 Airal regular 数字字集
第二个文字字段仅嵌入 Airal bold 英文字母字集
动态将第二个文字字段样式设为 regular 之后
那么该文字字段只能表现数字了~~

特性 3.
一个 SWF 内仅嵌入单一字体样式 (eg. Arial regular) 时
动态使用同一字体但是不同样式 (eg. Arial bold) 的文字字段
将会使用该字体唯一嵌入样式 (eg. Arial regular) 作为替代字体

特性 4.
将 TextField.text 内容重设时
TextField 内的文字样式 bold, italic 也会被重设为默认的样式
AS3 TextField.appendText 则不会重设样式

ActionScript 3.0 测试程序:

package {
 import flash.display.*;
 import flash.text.*;

 public class Main1 extends MovieClip {

  public function Main1() {

   var txt:TextField = new TextField();
   var tf:TextFormat = new TextFormat();
   tf.bold = true;
   tf.italic = true;


   // TextField 内不含文字内容时,无法套用 bold, italic 样式
   txt.text = "";
   txt.setTextFormat(tf);
   tf = txt.getTextFormat();
   trace("tf.bold :",tf.bold,", tf.italic :",tf.italic);
   // tf.bold : null , tf.italic : null

   txt.text = "123";
   txt.setTextFormat(tf);
   tf = txt.getTextFormat();
   trace("tf.bold :",tf.bold,", tf.italic :",tf.italic);
   // tf.bold : true , tf.italic : true


   // 改变 TextField.text 内容时,bold, italic 样式被重设
   txt.text="123";
   tf = txt.getTextFormat();
   trace("tf.bold :",tf.bold,", tf.italic :",tf.italic);
   // tf.bold : false , tf.italic : false

   tf.bold = true;
   tf.italic = true;
   txt.setTextFormat(tf);
   txt.text += "123";
   tf = txt.getTextFormat();
   trace("tf.bold :",tf.bold,", tf.italic :",tf.italic);
   // tf.bold : false , tf.italic : false


   // 使用 appendText 改变 TextField.text 内容时,bold, italic 样式会被保留
   tf.bold = true;
   tf.italic = true;
   txt.setTextFormat(tf);
   txt.appendText("456");
   tf = txt.getTextFormat();
   trace("tf.bold :",tf.bold,", tf.italic :",tf.italic);
   // tf.bold : true , tf.italic : true
   
   
   // 指定 TextField.text 内容前,调用 setSelection,bold, italic 样式会被保留
   tf.bold = true;
   tf.italic = true;
   txt.setTextFormat(tf);
   txt.setSelection(0, 1);
   txt.text = "456";
   tf = txt.getTextFormat();
   trace("tf.bold :",tf.bold,", tf.italic :",tf.italic);
   // tf.bold : true , tf.italic : true
   
   
   // 改变 TextField.text 内容时,bold, italic 会被重设为 defaultTextFormat
   tf.bold = true;
   tf.italic = false;
   txt.setTextFormat(tf);
   tf.bold = false;
   tf.italic = true;
   txt.defaultTextFormat = tf;
   txt.text = "456";
   tf = txt.getTextFormat();
   trace("tf.bold :",tf.bold,", tf.italic :",tf.italic);
   // tf.bold : false , tf.italic : true
   
  }
 }
}
// Ticore's Blog - http://ticore.blogspot.com/

了解上述特性之后,答案就很明显了~~

解决方式:
1. 对于同一字体不同的样式,均嵌入相同的字集
2. 当 TextField.text 内容重设时,自行回设正确的 Bold, Italic 样式
3. 利用 TextField.defaultTextFormat 设置 Bold, Italic 设置样式
4. 于 TextField.text 内容重设之前,调用 TextField.setSelection(0, 1);

相关连结:
Flash 技巧 - 预先编译嵌入字体

Read more...

2008年5月23日 星期五

Flash Player 10 beta - 新的影格事件   [+/-]

Ticore's Blog

Flash Player 10 beta 文档出来了
要观察新的 API 更方便一些

新的 AS3 API 多了两个影格事件
分别是 Event.FRAME_CONSTRUCTED, Event.EXIT_FRAME
看起来有点像 Director 的影格事件
以往 Flash 从来没有离开影格的相关事件

Event.FRAME_CONSTRUCTED 事件按照文档上所述
是发生在影格上的 DisplayObject 创建之后
运行影格程序之前

看起来像是用来补足 Flash Player 9 影格事件的不足
之前听到不少人抱怨 AS3 作影格跳跃之后
无法直接取用该影格的时间轴预置对象 (Timeline-Placed Object)
必须要等一个影格左右的时间...
非常不方便!

不过新的 frameConstructed 事件也只是将等待一个影格的时间缩短而已
好像没有方便到哪去
至于正式版情况怎样,就拭目以待了!

以下为 Flash Player 10 beta 新影格事件测试程序:
(需要自行准备一个具有三个影格的空白 fla 文档)

package {
    import flash.display.*;
    import flash.text.*;
    import flash.events.*;

    public class Main extends MovieClip {

        public function Main() {
            this.addEventListener(Event.ENTER_FRAME, onEvent);
            this.addEventListener(Event.EXIT_FRAME, onEvent);
            this.addEventListener(Event.FRAME_CONSTRUCTED, onEvent);
            this.addFrameScript(0, onFrame, 1, onFrame, 2, onFrame);
        }

        private function onFrame():void {
            trace(currentFrame, "FrameAction");
        }

        private function onEvent(evtObj:Event):void {
            trace(currentFrame, evtObj.type);
        }

    }
}
// Ticore's Blog - http://ticore.blogspot.com/

以下是输出结果:

1 frameConstructed
1 FrameAction
1 exitFrame
2 enterFrame
2 frameConstructed
2 FrameAction
2 exitFrame
3 enterFrame
3 frameConstructed
3 FrameAction
3 exitFrame
1 enterFrame
1 frameConstructed
1 FrameAction
1 exitFrame
..
.

除了第一影格之外,大致上可以看得出来运行顺序是
enterFrame, frameConstructed, FrameAction, exitFrame

相关连结:
Flash Player 10 beta - MouseCursor 功能
Flash Player 10 beta - JPEGLoaderContext 介绍
Flash 9 AS3 时间性事件混合测试
Flash Player 8 AS2 影格程序运行顺序

Read more...

2008年5月17日 星期六

AIR - 如何区分 JavaScript 与 ActionScript 对象   [+/-]

Ticore's Blog

Adobe AIR 虽然可以让 ActionScript 与 JavaScript 对象互相传递调用
但是除了基础对象以外,复杂对象是不会被转换的
某些情况下,仍需要注意所持有的对象到底是 AS Object 还是 JS Object
以下介绍如何区分 JavaScript 与 ActionScript 对象

于 AIR ActionScript runtime 中辨别对象是否为 AS Object

import flash.html.*;
import flash.events.*;
import flash.utils.*;
import flash.system.*;

var htmlLdr:HTMLLoader = new HTMLLoader();
var jsRuntime:Object = htmlLdr.window;

var asObj:Object = new Object();
var asAry:* = new Array();
var asDate:* = new Date();
var asSprite:* = new flash.display.Sprite();
var asXML:* = new XML();
var asXMLList:* = new XMLList();
var asRegExp:* = new RegExp();
var asNS:* = new Namespace();
var asFun:* = function():void{};
var asNo:* = new Number();
var asStr:* = new String();
var asBol:* = new Boolean();

var jsObj:Object = new jsRuntime.Object();
var jsAry:Object = new jsRuntime.Array();
var jsDate:Object = new jsRuntime.Date();
var jsFun:Object = new jsRuntime.Function("", "");
var jsNo:Object = new jsRuntime.Number();
var jsStr:Object = new jsRuntime.String();
var jsBol:Object = new jsRuntime.Boolean();

function isASObject(o:*):Boolean{
 //return o.constructor is Class;
 return getQualifiedClassName(o).indexOf("flash.html::__HTMLScript") < 0;
}

trace(isASObject(asObj)); // true
trace(isASObject(asAry)); // true
trace(isASObject(asDate)); // true
trace(isASObject(asSprite)); // true
trace(isASObject(asXML)); // true
trace(isASObject(asXMLList)); // true
trace(isASObject(asRegExp)); // true
trace(isASObject(asNS)); // true
trace(isASObject(asFun)); // true
trace(isASObject(asNo)); // true
trace(isASObject(asStr)); // true
trace(isASObject(asBol)); // true

trace(isASObject(jsObj)); // false
trace(isASObject(jsAry)); // false
trace(isASObject(jsDate)); // false
trace(isASObject(jsFun)); // false
trace(isASObject(jsNo)); // true
trace(isASObject(jsStr)); // true
trace(isASObject(jsBol)); // true

// Ticore's Blog - http://ticore.blogspot.com/

于 AIR JavaScript runtime 中辨别对象是否为 JS Object


var asObj = new runtime.Object();
var asAry = new runtime.Array();
var asDate = new runtime.Date();
var asSprite = new runtime.flash.display.Sprite();
var asXML = new runtime.XML();
var asXMLList = new runtime.XMLList();
var asRegExp = new runtime.RegExp();
var asFun = runtime.trace;
var asNo = new runtime.Number();
var asStr = new runtime.String();
var asBol = new runtime.Boolean();

var jsObj = new Object();
var jsAry = new Array();
var jsDate = new Date();
var jsFun = function(){};
var jsNo = 10;
var jsStr = "str";
var jsBol = true;

function isJSObject(o) {
 return o.constructor instanceof Function;
}

runtime.trace(isJSObject(asObj)); // false
runtime.trace(isJSObject(asAry)); // false
runtime.trace(isJSObject(asDate)); // false
runtime.trace(isJSObject(asSprite)); // false
runtime.trace(isJSObject(asXML)); // false
runtime.trace(isJSObject(asXMLList)); // false
runtime.trace(isJSObject(asRegExp)); // false
runtime.trace(isJSObject(asFun)); // false
runtime.trace(isJSObject(asStr)); // true
runtime.trace(isJSObject(asNo)); // true
runtime.trace(isJSObject(asBol)); // true

runtime.trace(isJSObject(jsObj)); // true
runtime.trace(isJSObject(jsAry)); // true
runtime.trace(isJSObject(jsDate)); // true
runtime.trace(isJSObject(jsFun)); // true
runtime.trace(isJSObject(jsStr)); // true
runtime.trace(isJSObject(jsNo)); // true
runtime.trace(isJSObject(jsBol)); // true

// Ticore's Blog - http://ticore.blogspot.com/

以上的方式,除了 Number, String, Boolean 会自动转换的对象以外
应该都可以辨别大部分的 AS or JS Object

其实之前尝试过各种不同的方式
像是 __proto__, constructor is Class 等等
但是都无法用在所有的对象判别上

相关连结:
AIR - ActionScript, JavaScript 混搭技巧
Adobe AIR Namespace Bug
AIR - JavaScript 与 ActionScript 之间对象的传递

Read more...

2008年5月4日 星期日

一行 AS3 程序让 Flash Player 9 死机 Part 4   [+/-]

Ticore's Blog

Bug 又来了,以下任一行 AS3 程序都会造成 Flash Player Crash

Object['isPrototypeOf']();
Object['hasOwnProperty']();
Object['propertyIsEnumerable']();
Object['setPropertyIsEnumerable']();

实在是太诡异了,这么平常的 Class - Object
居然可以轻易让 Flash Player 挂掉
其实该 Bug 是在测试 Adobe AIR JavaScript 时发现的
连带的导致 AIR 也 Crash
因为 JavaScript 没有型别检查功能
不小心就会调用到不属于该对象的方法
平常 Flash 多亏了 AS3 型别检查
才会让该问题这么久没有浮上台面

正常情况下,对 Class 调用 non-static member 虽然是错误的动作
但是也不至于会造成 Flash Player Crash
只要捕捉例外就好
但是对于以上这四行 AS3 程序
try...catch 例外捕捉完全没用,Flash Player 照样 Crash

以上 Bug 至少会在以下的 Flash Player 版本发生
Flash Player 9.0.47.0
Flash Player 9.0.115.0
Flash Player 9.0.124.0

相关连结:
一行 AS3 程序让 Flash Player 9 死机 Part 3
一行 AS3 程序让 Flash Player 9 死机 Part 2
一行 AS3 程序让 Flash Player 9 死机
用 @* 指定 Attributes 造成 Flash Player 9 Crash

Read more...

2008年5月1日 星期四

Flash AS3 No Border Scale Background Image   [+/-]

Ticore's Blog

利用 ActionScript 3.0 简单实作 No Border 等比例缩放的 Background Image

这只有背景图满版而已
假如还有其它需要自动调整位置的对象
全部都要个别加以控制
程序码比起用 Flex 实作多出很多

使用时,须要先准备一个 MovieClip 指定 Class Name 为 MC
作为满版背景图之用

ActionScript 3.0 Code:

/*
 Ticore's Blog
 http://ticore.blogspot.com/
*/
package {
 import flash.display.*;
 import flash.events.*;
 
 public class Main extends MovieClip {
  
  public var bg:MovieClip = new MC();
  
  public function Main () {
   
   if (stage) {
    stage.scaleMode = StageScaleMode.NO_SCALE;
    stage.align = "TL";
    stage.addEventListener(Event.RESIZE, onStageResize);
   }
   
   this.addChild(bg);
   onStageResize();
  }
  
  public function onStageResize (evtObj:Event = null):void {
   bg.scaleX = bg.scaleY = 1;
   
   if (!stage) {
    return;
   }
   
   var bgWidth:Number = bg.width;
   var bgHeight:Number = bg.height;
   var stageWidth:Number = stage.stageWidth;
   var stageHeight:Number = stage.stageHeight;
   
   var ratioFlag:Boolean = (stageWidth / stageHeight) > (bgWidth / bgHeight);
   bg.width = ratioFlag ? stageWidth : stageHeight * (bgWidth / bgHeight);
   bg.height = !ratioFlag ? stageHeight : stageWidth * (bgHeight / bgWidth);
   
   bg.x = (stageWidth - bg.width) / 2;
   bg.y = (stageHeight - bg.height) / 2;
  }
  
 }
}

Online Demo

相关连结:
Flex - 简单实作 No Border Image

Read more...

2008年4月21日 星期一

让 Flex 内不可选择的文字超连结生效   [+/-]

Ticore's Blog

在 Flash 内,不可选择的 (unselectable) TextField 仍可保留 HTML 超连结功能
但是 Flex 却不行
查文档上也有写到 Label.selectable

其实不光是 Label, Text 组件不行
任何一个在 Flex App 下的 unselectable TextField 超连结都会失效
这样需要用到不可选择的超连结文字时就很不方便

Flex 超连结失效测试程序:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
   fontSize="12" backgroundColor="#F0F0F0">
 <mx:Script>
  <![CDATA[
   import flash.events.*;
   import mx.managers.FocusManager;
   
   public function onTxtLink(evtObj:Event):void{
    textArea.text += evtObj + "\n";
   }
  ]]>
 </mx:Script>
 <mx:Label selectable="false" link="onTxtLink(event)">
  <mx:htmlText>
   <![CDATA[Flex Label : <a href='event:linkEvent'>Link Event Text</a> | ]]>
   <![CDATA[<a href='http://ticore.blogspot.com' target='_blank'>Ticore's Blog</a>]]>
  </mx:htmlText>
 </mx:Label>
 
 <mx:Text selectable="false" link="onTxtLink(event)">
  <mx:htmlText>
   <![CDATA[Flex Text : <a href='event:linkEvent'>Link Event Text</a> | ]]>
   <![CDATA[<a href='http://ticore.blogspot.com' target='_blank'>Ticore's Blog</a>]]>
  </mx:htmlText>
 </mx:Text>
 
 <mx:Button label="Clear Log" click="textArea.text = '';" />
 <mx:TextArea id="textArea" width="100%" height="100%" />
</mx:Application>

于是花了不少力气去追踪原因
终于发现是 Flex 内的 FocusManager 刻意拦截下 unselectable TextField Focus 事件
这也间接造成超连结失效

既然知道问题是出在 FocusManager 上
问题就比较好处理了
以下是变通方式,让 FocusManager 短暂失效一下~

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
   fontSize="12" backgroundColor="#F0F0F0">
 <mx:Script>
  <![CDATA[
   import flash.events.*;
   import mx.managers.FocusManager;
   
   public function onTxtLink(evtObj:Event):void{
    textArea.text += evtObj + "\n";
   }
  ]]>
 </mx:Script>
 <mx:Label selectable="false" link="onTxtLink(event)"
   rollOver="focusManager.deactivate()" rollOut="focusManager.activate()">
  <mx:htmlText>
   <![CDATA[Flex Label : <a href='event:linkEvent'>Link Event Text</a> | ]]>
   <![CDATA[<a href='http://ticore.blogspot.com' target='_blank'>Ticore's Blog</a>]]>
  </mx:htmlText>
 </mx:Label>
 
 <mx:Text selectable="false" link="onTxtLink(event)"
   rollOver="focusManager.deactivate()" rollOut="focusManager.activate()">
  <mx:htmlText>
   <![CDATA[Flex Text : <a href='event:linkEvent'>Link Event Text</a> | ]]>
   <![CDATA[<a href='http://ticore.blogspot.com' target='_blank'>Ticore's Blog</a>]]>
  </mx:htmlText>
 </mx:Text>
 
 <mx:Button label="Clear Log" click="textArea.text = '';" />
 <mx:TextArea id="textArea" width="100%" height="100%" />
</mx:Application>

Online Demo:

Read more...

2008年3月11日 星期二

Flash ActionScript 2 Pre-Compiler Bug   [+/-]

Ticore's Blog

从 MXNA 看到一篇有趣的文章
Why SOMETIMES … (String == Number) ….
在 ActionScript 直接比较意义相同的数值与字串
居然有的会得到 ture,有的会得到 false
真是诡异

于是也来测试看看
ActionScript 2.0 测试程序

trace('0.90' == 0.90); // true
trace('0.91' == 0.91); // true
trace('0.92' == 0.92); // true
trace('0.93' == 0.93); // true
trace('0.94' == 0.94); // false
trace('0.95' == 0.95); // false
trace('0.96' == 0.96); // true
trace('0.97' == 0.97); // true
trace('0.98' == 0.98); // true
trace('0.99' == 0.99); // true

后来想到用 AS Decompiler 去看看
结果如下:

    trace(true);
    trace(true);
    trace(true);
    trace(true);
    trace(false);
    trace(false);
    trace(true);
    trace(true);
    trace(true);
    trace(true);

原来是 Flash IDE Pre-Compiler (前处理器) 的 Bug
实际用 ActionScript 比较的结果还是正确的

Read more...

2008年3月10日 星期一

AS 技巧 - 强迫更新 DisplayObject.scrollRect 尺寸   [+/-]

Ticore's Blog

AS 技巧 - 强迫 DisplayObject.scrollRect 更新尺寸

上一篇提到 DisplayObject.scrollRect 特性
更改过 scrollRect 之后,需要一点时间,才会影响到对象的尺寸

另外,假如该 DisplayObject 对象没有放置在 Stage 之下
scrollRect 就不会影响到对象的尺寸
这就更诡异了

以上两种诡异特性
对于需要做对象缩放排版的功能时,很容易生成潜在的 Bug
尤其是需要开发或是更改 Flex UI Component 时

就算知道了,对于需要时间反映在对象尺寸特性
还是很难避免
难道每次更改过 scrollRect 之后,都要使用 setTimeout or callLater 吗?

以下分享一个小技巧
可以让你在变动过 scrollRect 之后,立即强迫 DisplayObject 更新尺寸相关属性

AS3 示范程序:

/*
 Ticore's Blog
 http://ticore.blogspot.com
*/

package {
 import flash.display.*;
 import flash.geom.*;
 import flash.utils.*;
 
 public class Main extends MovieClip {
  
  var mc:MovieClip;
  
  public function Main() {
   doTest();
  }

  public function doTest() {
   mc = new MovieClip();
   this.addChild(mc);
   
   var g:Graphics = mc.graphics;
   g.beginFill(0xFF0000);
   g.drawRect(0, 0, 100, 100);
   g.endFill();
   traceSize("After draw rectangle graphic", mc);

   mc.scrollRect = new Rectangle(0, 0, 50, 50);
   traceSize("After assign scrollRect", mc);
   
   //*/
   // Force DisplayObject update dimensions
   var bmpData:BitmapData = new BitmapData(1, 1);
   bmpData.draw(mc);
   traceSize("After draw by BitmapData", mc);
   //*/
   
   setTimeout(traceSize, 0, "0 ms later", mc);
   setTimeout(traceSize, 10, "10 ms later", mc);
   setTimeout(traceSize, 500, "500 ms later", mc);
  }
  
  public function traceSize(msg:String, target:DisplayObject):void{
   trace("----------------------------------------------------");
   trace(msg, ", time:" + getTimer());
   trace("width:", mc.width, ", height:", mc.height,
      ", bounds:", mc.getBounds(mc.parent));
  }
  
 }
}

输出结果:

----------------------------------------------------
After draw rectangle graphic , time:7
width: 100 , height: 100 , bounds: (x=0, y=0, w=100, h=100)
----------------------------------------------------
After assign scrollRect , time:13
width: 100 , height: 100 , bounds: (x=0, y=0, w=100, h=100)
----------------------------------------------------
After draw by BitmapData , time:45
width: 50 , height: 50 , bounds: (x=0, y=0, w=50, h=50)
----------------------------------------------------
0 ms later , time:85
width: 50 , height: 50 , bounds: (x=0, y=0, w=50, h=50)
----------------------------------------------------
10 ms later , time:92
width: 50 , height: 50 , bounds: (x=0, y=0, w=50, h=50)
----------------------------------------------------
500 ms later , time:571
width: 50 , height: 50 , bounds: (x=0, y=0, w=50, h=50)

相关连结:
AS - scrollRect 与 Mask 差异
What you should know about DisplayObject’s mask and scrollRect

Read more...

2008年3月9日 星期日

AS - scrollRect 与 Mask 差异   [+/-]

Ticore's Blog

自从 Flash 8 开始添加了 scrollRect 功能
让开发者可以指定一块矩形区域限制表现的范围
功能上有点类似 Mask,程序写起来也比 Mask 简单一些
几乎所有需要卷轴区块的组件都是用 scrollRect 实作的

很明显的一个差异是,Mask 可以做任何形状的遮罩,scrollRect 只能用矩形

另外,还有一个特性是比较不为人知的
Mask 并不会影响到 DisplayObject 对象的 width, height, bounds 等尺寸属性
可是 scrollRect 会影响到 DisplayObject 对象的尺寸

以下分别用 Mask 与 scrollRect 做测试
以 ActionScript 创建 100*100 大小的 MovieClip
套用 50*50 的 Mask or scrollRect

AS3 DisplayObject with Mask:

package {
 import flash.display.*;
 import flash.geom.*;
 import flash.utils.*;
 
 public class Main  extends MovieClip {
  
  var mc:MovieClip;
  var maskMC:MovieClip;
  
  public function Main() {
   doTest();
  }

  public function doTest() {
   mc = new MovieClip();
   mc.cacheAsBitmap = true;
   maskMC = new MovieClip();
   this.addChild(mc);
   mc.addChild(maskMC);
   
   mc.mask = maskMC;
   
   var g:Graphics = mc.graphics;
   
   g.beginFill(0xFF0000);
   g.drawRect(0, 0, 100, 100);
   g.endFill();
   
   g = maskMC.graphics;
   g.beginFill(0xFF0000);
   g.drawRect(0, 0, 50, 50);
   g.endFill();
   
   setTimeout(traceSize, 500, mc);
  }
  
  public function traceSize(target:DisplayObject):void{
   trace("time:" + getTimer());
   trace("width:", mc.width, ", height:", mc.height,
      ", bounds:", mc.getBounds(mc.parent));
  }
  
 }
}

//  Ticore's Blog http://ticore.blogspot.com/

输出结果:

time:553
width: 100 , height: 100 , bounds: (x=0, y=0, w=100, h=100)

AS3 DisplayObject with scrollRect:

package {
 import flash.display.*;
 import flash.geom.*;
 import flash.utils.*;
 
 public class Main  extends MovieClip {
  
  var mc:MovieClip;
  
  public function Main() {
   doTest();
  }

  public function doTest() {
   mc = new MovieClip();
   this.addChild(mc);
   
   var g:Graphics = mc.graphics;
   g.beginFill(0xFF0000);
   g.drawRect(0, 0, 100, 100);
   g.endFill();

   mc.scrollRect = new Rectangle(0, 0, 50, 50);
   
   setTimeout(traceSize, 500, mc);
  }
  
  public function traceSize(target:DisplayObject):void{
   trace("time:" + getTimer());
   trace("width:", mc.width, ", height:", mc.height,
      ", bounds:", mc.getBounds(mc.parent));
  }
  
 }
}

//  Ticore's Blog http://ticore.blogspot.com/

输出结果:

time:535
width: 50 , height: 50 , bounds: (x=0, y=0, w=50, h=50)

由输出结果可以看出,Mask 对被遮罩对象尺寸没有影响
至于为什么要延迟一小段时间
这是因为被套用 scrollRect 之后,需要一点时间,才会对尺寸发生作用
真是诡异的特性

相关连结:
AS 技巧 - 强迫更新 DisplayObject.scrollRect 尺寸

Read more...

2008年2月12日 星期二

2003 Flash 6 AS 1 旋转时钟作品   [+/-]

Ticore's Blog

好几年前,网络上很流行 JavaScript 作的旋转时钟
那时候还是 Flash 6 而已,当初为了练习 ActionScript
将旋转时钟改成 ActionScript 版
现在分享给大家看看

ActionScript 1.0 旋转时钟