基于http的flash chat(实时通讯)

前两年发过基于socket的flash chat代码,但不是所有的情况都会选择(或者有条件)使用socket的服务器。基于http的实时通讯可以用在对即时性要求不是太高的程序。

原理是通过客户端获取信息的请求,如果没有需要的内容,后台程序会等待一段时间(反应速度),然后再看看有没有需要的结果。如果多次运行没有结果,返回超时信息。让客户端再次连接。

$times = 0;
function read($id)
{
	$link = getMySq();
	$rs = mysql_query("select id,msg,t from c where id>".$id);
	//返回json格式的结果
	$result = '[';
	$ns = true;
	while($row = mysql_fetch_object($rs))
	{
		$result = $result.'{"m":"'.$row->msg.'",'.'"i":"'.$row->id.'"},';
		$ns = false;
	}
	$result = $result.'{}]';
	if($ns)
	{
		mysql_close($link);
		$times++;
		//5次请求也没有反应,做超时判断,让客户端重新请求
		if($times >= 5)
		{	
			echo '[]';
			return;
		}
		//如果当前没有可读的数据,等待1秒再读,如果需要更短的时间(这样反应更快),使用usleep,单位是毫秒
		sleep(1);
		read($id);
	}
	else
	{
		echo $result;
		mysql_close($link);
	}
}

as代码:

//http://localhost/ajax/chat.php?type=r&id=1
var lv:LoadVars = new LoadVars();
lv.load('http://localhost/ajax/chat.php?type=r&id=2');
 
lv.onData = function(d)
{
	trace(d)
	var maxid = 0;
        //JSON请到json.org下载
	var data = (new JSON()).parse(d);
	//
	str = '';
	for(var i=0;i<data.length-1;i++)
	{
		str += data[i].m+'\n';
		maxid = data[i].i;
	}
	m.text += str;
	//
	m.scroll = m.maxscroll;
	//
	lv.load('http://localhost/ajax/chat.php?type=r&id='+maxid);
}
///
Key.addListener(this);
onKeyDown = function()
{
	if(Key.getAscii() == 13)
	{
		if(Selection.getFocus()== '_level0.smsg')
			sendMsg();
	}
}
 
 
send.onPress = function()
{
	sendMsg();
}
 
function sendMsg()
{
	if(smsg.text.length > 1)
	{
		var slv:LoadVars = new LoadVars();
		slv.load('http://localhost/ajax/chat.php?msg='+smsg.text);
		smsg.text = '';
	}
}

flash源文件下载:http://roading.net/res/blog/pic/httpchat.fla

完整的php代码:

<?php
 
/*
建立chat数据库
 
建立表:
-- 
-- 表的结构 `c`
-- 
 
CREATE TABLE `c` (
  `id` int(8) NOT NULL auto_increment,
  `msg` varchar(200) character set utf8 default NULL,
  `t` smallint(2) NOT NULL default '0',
  PRIMARY KEY  (`id`)
) ;
*/
 
$type=$_GET['type'];
if($_GET['type'] == 'r')
{
	$id = $_GET['id'] ;
	read($id);
}
else
{
	$msg = $_GET['msg'] ;
	write($msg);
}
function write($msg)
{
	$link = getMySq();
	//如果超过20条数据,清空一下
	$rs = mysql_query("select count(id) as num from c");
	$row = mysql_fetch_object($rs);
	if($row->num > 20)
	{
		$rs = mysql_query("delete from c");
	}
	//
	$rs = mysql_query("insert into c (msg,t)values('$msg',1)");
	//$id = mysql_insert_id();
	mysql_close($link);
}
//
$times = 0;
function read($id)
{
	$link = getMySq();
	$rs = mysql_query("select id,msg,t from c where id>".$id);
	//
	$result = '[';
	$ns = true;
	while($row = mysql_fetch_object($rs))
	{
		$result = $result.'{"m":"'.$row->msg.'",'.'"i":"'.$row->id.'"},';
		$ns = false;
	}
	$result = $result.'{}]';
	if($ns)
	{
		mysql_close($link);
		$times++;
		//5请求也没有反应,做超时判断,让客户端重新请求
		if($times >= 5)
		{	
			echo '[]';
			return;
		}
		//如果当前没有可读的数据,等待1秒再读
		sleep(1);
		read($id);
	}
	else
	{
		echo $result;
		mysql_close($link);
	}
}
///
function getMySq()
{
	$dbpw = '123456';
	$dbname = 'chat';
	//
	$link = mysql_connect("localhost", "root", $dbpw)
		or die("Could not connect: " . mysql_error());
	mysql_select_db($dbname); 
	return $link;
}
?>

AS3 Tween

前几天发了js tween,其实就是从这个as3 Tween改写的,这个类是2006年初写的,后来一直的完善,同时也一直封装一个常用的接口,增加管理tween的功能。

Tween代码下载

提供两种使用方式,常用的运动都已经封装过了,结果包括:
x2,y2,move2,w2,h2,size2,scale2,alpha2,rotate2,colorTransform2,brightness2,color2等功能,大多接口从名字上就能明白功能,如果没有需要的接口,ok,还有一个原始的方法:

/**
*
* @param	startProps 开始属性 array类型
* @param	endProps  结束属性 array类型
* @param	timeSeconds  持续时间  秒为单位
* @param	animType	 动作类型 有31种运动效果
* @param	delay		延迟时间 秒为单位
*/
var t:Tween = new Tween([1,2,3],[4,5,6],2,'liner',1);
t.addEventListener('tween',tweening);
function tweening(e:DataEvent):void
{
trace(e.data);//e.data也是array类型,在这里,可以给你需要改变的属性赋值
}
function complete(e:DataEvent):void
{
trace('over');
}

//————————实例——————————————
//

import net.roading.tween.*;
//----------------------------------------------
//随机动画效果和时间
function anmi()
{
	return Tween.animTypes[int(Math.random()*30)];
}
function time()
{
	return Math.random()+1;
}
//----------------------------------------------
c0(null);
//----------------
function c0(e)
{
	Tween.colorTransform2(mc,255*(Math.random()>.5?1:-1),255*(Math.random()>.5?1:-1),255*(Math.random()>.5?1:-1),1,time(),anmi()).addEventListener('complete',c);
}
function c(e)
{
	Tween.colorTransform2(mc,0,0,0,1,time(),anmi()).addEventListener('complete',c1);
}
function c1(e)
{
	Tween.size2(mc,100,100,time(),anmi()).addEventListener('complete',c2);
}
function c2(e)
{
	Tween.size2(mc,238,216,time(),anmi()).addEventListener('complete',c3);
}
function c3(e)
{
	Tween.move2(mc,150,120,time(),anmi()).addEventListener('complete',c4);
}
function c4(e)
{
	Tween.move2(mc,270,203,time(),anmi()).addEventListener('complete',c5);
}
function c5(e)
{
	Tween.rotate2(mc,360,time(),anmi()).addEventListener('complete',c0);
}

//

源文件下载
//——————————————————————

Tween测试的一个小工具:

//代码:

package 
{
	import flash.events.Event;
	import net.roading.tween.*;
	import net.roading.xml.*;
	import net.roading.skin.*;
	import net.roading.skin.base.*;
 
	import flash.display.MovieClip;
	public class TweenTool extends MovieClip
	{
 
		var ui:UI;
		var target:Pic;
		//
		BaseClasses
		public function TweenTool()
		{
			SkinManager.load(this,'flexskin.swf','rc.css',init);
		}
 
		protected function init():void
		{
			var xml:XML = <Container xid="app" width="800" height="500">
						<Container xid="tool" padding="5" border="line" height="70">
							<Container xid="tool1">
								<Label text="motion type:" />
								<ComboBox xid="mtype" dataProvider="[x2,y2,move2,w2,h2,size2,alpha2,rotate2,brightness2,color2,colorTransform2]" width="120" height="22" />
								<Label text="Parameters:" />
								<TextSlider xid="v1" width="60" height="22" />
								<TextSlider xid="v2" width="60" height="22"  />
								<TextSlider xid="v3" width="60" height="22"  />
								<TextSlider xid="v4" width="60" height="22"  />
								<layout type="FlowLayout" />
							</Container>
							<Container xid="tool2">
								<Label text="tween type:" />
								<ComboBox xid="atype" width="120" height="22" />
								<Label text="time:" />
								<TextSlider xid="time" width="60" height="22" data="{current:2,max:5,min:0.5,stepper:0.1}"  />
								<Label text="delay:" />
								<TextSlider xid="delay" width="60" height="22" data="{current:0,max:5,min:0,stepper:0.1}"  />
								<Button xid="run" text="run" width="80" height="30" />
								<layout type="FlowLayout" />
							</Container>
							<layout type="BoxLayout" axis="1" />
						</Container>
						<Box xid="content"   border="line" ></Box>
						<layout type="BorderLayout"><c Center="content" North="tool" /></layout>
					</Container>
			ui = new UI(xml);
			addChild(ui.app);
			//
			ui.atype.dataProvider = Tween.animTypes;
			//
			target = new Pic();
			target.x = 250;
			target.y = 150;
			//
			ui.content.content.addItem(target);
			//
			ui.mtype.addEventListener('change', mtypeChange);
			//
			ui.mtype.selectedIndex = 0;
			mtypeChange(null);
			//
			ui.run.addEventListener('click',runClick);
		}
 
		protected function runClick(e:Event):void
		{
			runTween();
		}
 
		private function  runTween()
		{
			//Tween[ui.mtype.selectedLabel](target,
			switch(ui.mtype.selectedLabel)
			{
				case 'x2':
					Tween.x2(target, ui.v1.value, ui.time.value, ui.atype.selectedLabel, ui.delay.value);
					break;
				case 'y2':
					Tween.y2(target, ui.v1.value, ui.time.value, ui.atype.selectedLabel, ui.delay.value);
					break;
				case 'move2':
					Tween.move2(target, ui.v1.value, ui.v2.value,ui.time.value, ui.atype.selectedLabel, ui.delay.value);
					break;
				case 'w2':
					Tween.w2(target, ui.v1.value, ui.time.value, ui.atype.selectedLabel, ui.delay.value);
					break;
				case 'h2':
					Tween.h2(target, ui.v1.value, ui.time.value, ui.atype.selectedLabel, ui.delay.value);
					break;
				case 'size2':
					Tween.size2(target, ui.v1.value, ui.v2.value, ui.time.value, ui.atype.selectedLabel, ui.delay.value);
					break;
				case 'alpha2':
					Tween.alpha2(target, ui.v1.value, ui.time.value, ui.atype.selectedLabel, ui.delay.value);
					break;
				case 'rotate2':
					Tween.rotate2(target, ui.v1.value, ui.time.value, ui.atype.selectedLabel, ui.delay.value);
					break;
				case 'brightness2':
					Tween.brightness2(target, ui.v1.value, ui.v2.value,ui.time.value, ui.atype.selectedLabel, ui.delay.value);
					break;
				case 'color2':
					Tween.color2(target, ui.v1.value,  ui.v2.value,ui.time.value, ui.atype.selectedLabel, ui.delay.value);
					break;
				case 'colorTransform2':
					Tween.colorTransform2(target, ui.v1.value,  ui.v2.value, ui.v3.value, ui.v4.value, ui.time.value, ui.atype.selectedLabel, ui.delay.value);
					break;
			}
		}
 
		protected function mtypeChange(e:Event):void
		{
			trace(ui.mtype.selectedLabel);
			ui.v2.visible = false;
			ui.v3.visible = false;
			ui.v4.visible = false;
			switch(ui.mtype.selectedLabel)
			{
				case 'x2':
					ui.v1.data = { current:500,max:800,min:0,stepper:1};
					break;
				case 'y2':
					ui.v1.data = { current:500,max:500,min:0,stepper:1};
					break;
				case 'move2':
					ui.v2.visible = true;
					ui.v1.data = { current:500, max:800, min:0, stepper:1 };
					ui.v2.data = { current:500,max:500,min:0,stepper:1};
					break;
				case 'w2':
					ui.v1.data = { current:500,max:800,min:100,stepper:1};
					break;
				case 'h2':
					ui.v1.data = { current:500,max:500,min:100,stepper:1};
					break;
				case 'size2':
					ui.v2.visible = true;
					ui.v1.data = { current:500, max:800, min:100, stepper:1 };
					ui.v2.data = { current:500,max:500,min:100,stepper:1};
					break;
				case 'alpha2':
					ui.v1.data = { current:1, max:1, min:0, stepper:0.01 };
					break;
				case 'rotate2':
					ui.v1.data = { current:360, max:360, min:0, stepper:1 };
					break;
				case 'brightness2':
					ui.v2.visible = true;
					ui.v1.data = { current:1, max:1, min:0, stepper:0.01 };
					ui.v2.data = { current:255, max:255, min:-255, stepper:1 };
					break;
				case 'color2':
					ui.v2.visible = true;
					ui.v2.data = { current:1, max:1, min:0, stepper:0.01 };
					ui.v1.data = { current:0, max:0xffffff, min:0, stepper:1 };
					break;
				case 'colorTransform2':
					ui.v2.visible = true;
					ui.v3.visible = true;
					ui.v4.visible = true;
					ui.v1.data = { current:255, max:255, min: -255, stepper:255 };
					ui.v2.data = { current:255, max:255, min:-255, stepper:255 };
					ui.v3.data = { current:255, max:255, min: -255, stepper:255 };
					ui.v4.data = { current:1, max:1, min:0, stepper:0.01 };
					break;
 
			//ui.v1
			}
			ui.tool1.doLayout();
		}
 
	}
 
 
}

 

//

flash9图文混排的高度设置

flash对文本支持一直不好,特别是对html文本,支持的更弱。这一问题直到flash10只才得到提升。可是我们的使用还主要集中在flash9。

在htmlText中,img标签不能独占文本的整个宽度,文本会和图片显示在一行,而且img只能设置左对齐和右对齐。每个图片就是一个Loader对象,通过给img标签设置id,可以用t.getImageReference (’id’)获取到img的容器。可以使用这个功能来批量的加载图片获取图片的Loader:)

在TextField里面有autoSize的属性,通过设置autoSize可以让文本自动使用内容的高度:
如果 autoSize 设置为 TextFieldAutoSize.NONE(默认值),则不会进行调整。

如果 autoSize 设置为 TextFieldAutoSize.LEFT,会将文本视为左对齐文本,这意味着该文本字段的左边距保持固定,在右边可调整单个文本字段行。 如果文本中包括换行符(例如 “\n” 或 “\r”),则会另外调整底边来适合文本的下一行。 如果 wordWrap 也设置为 true,则仅调整文本字段的底边,而右边距保持固定。

这样,设置autoSize 不为none,图片的高度就会字适应,但是,在图片在家完成之前,文本的高度不是最终高度,如果下面的内容是依赖文本位置的话,就需要侦听到文本高度的变化,可以使用change时间来侦听,每个图片加载完成,文本都会出发一个change事件,这样每次change的时候重新布局就可以了。

代码:

//舞台上添加一个文本框,设置名字为t
t.autoSize = 'center';
t.htmlText = '
<div id="blogMar">
<img src="http://img1.qq.com/blog/pics/15261/15261128.jpg" alt="" />
 <img src="http://img1.qq.com/blog/pics/15256/15256935.jpg" alt="" />
唯美小龙女惊艳写真
<img src="http://img1.qq.com/blog/pics/15250/15250542.jpg" alt="" />
 希拉里大学小样照</div>
';
//
t.addEventListener('change',htmlChange);
function htmlChange(e)
{
	trace('-----htmlChange-----')
        //可以看到,textHeight是不会改变的
	trace(t.textHeight);
	trace(t.height);
}

输出结果:

-----htmlChange-----
117
121
-----htmlChange-----
117
190
-----htmlChange-----
117
251

告别2008,flash之路的第6个年头

学习flash的第6个年头,在2002年,记得开始flash之路的原因竟然是因为大二时候宿舍有本讲flash的书,随手翻翻,然后很容易就能找到‘著名’的网页三剑客的光盘,觉得这是个很好玩的东西,然后花了一星期用它做了第一个flash游戏(Mario),很有成就感,关键的是它让我的想法很容易实现。

之后就有些着迷,看帮助,学习别人开源的代码,琢磨游戏算法的实现。。

再后来跟着一个老师做flash电子课件,做flash播放器,做音乐播放器,做flash网站,想一些很炫的效果。。

 

2004年暑假,一个偶然的机会,一个写电脑书籍的工作室要出版flash方面书籍,给他们做程序方面的实例,然后用自己挣的第一笔钱买了第一个手机(这个手机陪伴了我4年,现在还在好好工作)。

然后认识了aol(当时比较有名的flasher,很佩服的一个高手),介绍我跟老古(古墓)认识,开始跟闪吧结缘。

2004年10月,给闪吧开发几个小游戏。

2004年11月,开始开发闪吧音乐FM,从这开始改变了我后来的发展方向。

在此之前,我学习flash,觉得很酷,很好玩,能实现我的想法,偶尔挣点小钱也很幸福,但是还没有考虑以后靠flash吃饭。还在用c++写程序,还在学习C#。

经过两个多月,闪吧音乐FM第一版开发完成,中间得到aol的不少帮忙。

 

2005年3月,应老古邀请,第一次来到闪吧,开发闪吧音乐FM第二版,顺便完成毕业实习。期间,确定了毕业后来闪吧工作。

2005年7月14日,第二次来闪吧,开始正式工作。和aol,kissall,rui,uu,小海…成了同事。

然后开发闪吧图库和闪吧收藏夹。

然后10月,经历一次动荡。。。

10月开始开发闪吧涂鸦,研究swf文件格式,查找字符串64k的问题,研究C#读写swf文件的方法,2006年1月16日第一版上线。

2005年就这样过去了。

 

2006年,之后一直的完善功能中,到7月份,发布了闪吧涂鸦第二版,增加了图层,实现了用涂鸦做动画的功能,把后台从c#换成php,使用amfphp,让一切变的更好更简单。同时,在后台开发上,我也从c#转到php。

在这中间,2月开始,研究了flash video的东西,研究flv的结构,制作视频的上传、转制成flv、播放flv的程序

3月份,开始写一套自己的flash组件(as2.0版本的)

8月份,开始开发闪吧音乐FM第三版

然后,9月份,使用C#制作了闪吧涂鸦的本地版

10月份,使用fms开发闪吧涂鸦的联机版

然后,2006悄然而逝,中间研究几种后台的flash socket应用,写过flash chat实例。

 

2007年,1月5日,发布了闪吧flash动画播放器,使用flash加载flash动画控制播放,因为之前的js版本经常报错。

1月,开始开发flash as3组件框架

4月,闪吧音乐FM第三版发布,这次采用新的模式,通过iframe方式,多个flash互相通讯,完成程序的交互。

3-7月,研究模式识别,想做人脸的自动卡通形象的装换,开始捡起c语言,研究人脸识别和提取,研究openCV,实现了人脸识别和粗量器官提取,因为一些原因,项目搁置。

10月,封装flash访问webservice的as3类(针对.net版本的),从4月发现问题,7月找到解决方法,10月才把功能封装起来。

10月18日,花费3个多月的闪吧影像发布。

12月,增加了涂鸦、图像自由裁剪、高级效果设置等功能的闪吧影像发布。

2007匆匆的离去。

 

2008年flash as3组件和闪吧影像不断的完善。

3月,在闪吧坚持了3年后,开始想换个环境学点新的东西,开始找新工作之旅。

4月24日,在离开闪吧,离开上海的最后的时间,发布了闪吧涂鸦第三版

4月26日,来到广东,来到深圳,来到腾讯。 开始新的工作历程。

就这样,2008也离我们而去了。

 

2009年,祝平安,祝幸福…你和我

在flash as3中使用嵌入字体embedFonts

flash一直对字体渲染支持不好,特别是中文,存在锯齿、模糊、失真等等问题。而且系统的字体不能旋转,不能设置alpha(作为bitmap处理除外)。

因此在有些时候,就不得不考虑使用嵌入字体。

 

使用之前必须定义字体类,在library面板选择新建字体(new font),为新建的字体设置链接,制定Class的值,这个Class就要要注册的字体类。比如你为你新建字体的Class设置为Comic ,下面代码就外这种字体注册到全局字体库里面:Font.registerFont(Comic);  这样就可以在本文件或者所有加载这个文件的程序使用这种字体了。

在flash as3中,使用嵌入字体有两种方式,一种是通过TextFormat.font属性设置,另外一种通过StyleSheet设置样式,文本使用class来应用。

在使用字体之前,最好使用Font.enumerateFonts();得到的字体的fontName来用,因为有些字体名字跟看到的不一样,特别是只用粗体和斜体的时候。

使用这两种方法前,都要设置文本的embedFonts = true;,这样文本就会按照嵌入字体进行渲染。

 效果:

embedFonts

源文件:

下载

具体使用的代码:

//-----------------------------------------------------------------------
//使用嵌入字体
//Arial
//var a = Font.enumerateFonts();
//trace(a[0].fontName);
//
//Font.registerFont(Arial);
//a = Font.enumerateFonts();
//trace(a);
//trace(a[0].fontName);
//trace(a[1].fontName);
//把库里面的字体注册到全局字体库里面,如果在本文件内使用,可以不注册,但是如果作为字体库供其他文件调用,必须要注册到全局
//Font.registerFont(Birch);
//
var l:Loader = new Loader();
//加载字体库
l.load(new URLRequest('fontlib.swf'));
l.contentLoaderInfo.addEventListener('complete',lc);
//
function lc(e)
{
//获取嵌入的字体数组
var a = Font.enumerateFonts();
trace(a);
//嵌入字体的名字
trace(a[0].fontName);
trace(a[1].fontName);
//使用TextFormat.font设置字体
var tf:TextFormat = new TextFormat();
tf.font = a[0].fontName;
t.embedFonts = true;
t.text = 'asdas dasdas';
t.setTextFormat(tf);
//
//
//使用StyleSheet设置字体
var css:StyleSheet = new StyleSheet();
css.setStyle('.font',{fontFamily:a[1].fontName});
//
t1.embedFonts = true;
t1.styleSheet = css;
t1.htmlText = '&lt;p class="font"&gt;asdas dasdas&lt;/p&gt;';
//
 
}
 

JS Tween

从我写的as tween改写的,基本功能跟as里面写的一样,只是没有扩展特定功能的接口(比如alpha2,move2,size2,color2等接口,这些在as tween里面都有实现)。

有31中缓动算法,实现了颜色的自动转换(#f00 #ff0000 rgb(255,0,0)格式到颜色运算格式,最后返回#ff0000格式)、px单位的自动转换。

调用接口:

/**
 * 对外接口
 * Tween的示例
 * @param startProps 开始属性,单个属性或者数组
 * @param endProps  结束属性,单个属性或者数组
 * @param timeSeconds 运动消耗时间,单位秒
 * @param animType 动作类型,字符串型,内部自己转换算子
 * @param delay  延迟时间,多长时间后开始运动,单位秒
 */
window.rtween = function(startProps, endProps, timeSeconds, animType, delay)
{
var tw = new Tween();
tw.start(startProps, endProps, timeSeconds, animType, delay);
return tw;
}

示例如下:

http://roading.net/work/jstween/tween.htm

选择列表里面的缓动算法,点前面的按钮,就会以想对的缓动算法运动

源代码:

http://roading.net/js/rtween.js

核心代码:

 

function Tween()
{
this._frame=20;
//
this._animType = linear;
this._delay = 0;
//
this.run = function(){}
this.complete = function(){}
}
//
Tween.prototype.getValue = function(prop)
{
this._valueType = ”;
if(prop.constructor == Array) return prop;
//
if(typeof(prop) == ’string’)
{
if(isColor(prop))
{
this._valueType = ‘color’;
return c2a(prop);
}
if(prop.split(’px’).length>1)
{
this._valueType = ‘px’;
return [prop.split('px')[0]];
}
}
return [prop];
}
Tween.prototype.setValue = function(prop)
{
if(this._valueType == ‘color’)return a2c(prop);
if(this._valueType == ‘px’)return prop[0]+’px’;
return prop;
}

Tween.prototype.start = function(startProps, endProps, timeSeconds, animType, delay)
{
if(animType != undefined)this._animType = this.animTypes[animType];
if(delay != undefined)this._delay = delay;
//
this._timeSeconds = timeSeconds;
this._startTimer = new Date().getTime() + this._delay * 1000;
//
this._endProps = this.getValue(endProps);
this._startProps = this.getValue(startProps);
this._currentProps = [];
//
var $this = this;
clearInterval(this._runID);
this._runID = setInterval(
function(){$this._run();}
,this._frame);
}

Tween.prototype.stop = function(state)
{
for(var i in this._startProps)
{
if(Number(state)>0)
this._currentProps[i] = this._endProps[i];
else if(Number(state)<0)
this._currentProps[i] = this._startProps[i];
}
this.callListener();
this.complete();
//
clearInterval(this._runID);
}
Tween.prototype.callListener = function()
{
this.run(this.setValue(this._currentProps));
}
Tween.prototype._run = function()
{
if ( new Date().getTime()- this._startTimer< 0) return;
var isEnd = false;
//
for(var i in this._startProps)
{
this._currentProps[i] = this._animType( new Date().getTime()-this._startTimer,Number(this._startProps[i]),Number(this._endProps[i])-Number(this._startProps[i]),this._timeSeconds * 1000);
//
if(this._startTimer + (this._timeSeconds * 1000) <= new Date().getTime())
{
this._currentProps[i] = this._endProps[i];
isEnd = true;
}
}
//
if(isEnd)this.stop();
else this.callListener();
}
 

 

google reader的新皮肤

google reader new look and feel

睡一觉起来就发现google reader的皮肤换了,昨晚看到的还是旧的样式。

从gmail开始自定义theme的时候就在想为什么google reader没有提供更换皮肤的功能呢,也就一直在等这个功能。

马上就到setting里面去找,可是有点所望,再回来看看它的说明(http://googlereader.blogspot.com/):Updated look and feel。

不过还好,有进步总是好的:)

flash lite3无法播放fms录制的flv音频?

播放flv音频视频的功能是从flash lite3.0开始支持的,在此之前,flash lite只能播放midi,mp3,3gp,mp4之类的音频视频文件。

在使用flash lite3开发播放flv功能的时候,使用fms2/3录制的flv音频怎么也播放不了,代码如下:

var nc:NetConnection = new NetConnection();

nc.connect(null);

nc.onStatus = function(info:Object):Void {

  status_txt.text+=info.code+”\n”;

}

 var ns:NetStream = new NetStream(nc);

  ns.play(”test.flv”);

  ns.onStatus = function(info:Object):Void {

   status_txt.text+=info.code+”\n”;

  }

 

一直提示:

NetConnection.Connect.Success

NetStream.Play.Start

NetStream.Play.Stop

NetStream.Buffer.Flush

刚开始start就stop了,但是可以获取到metadata信息。(其实,在这里就能大概想到是编码问题了,因为ns能够读取的数据,但是立即停止应该是说明不能解析具体数据)

 

一开始一直以为是代码有问题,检查也没有发现问题,然后把版本设置成flash player7可以正常播放。那么应该不是代码的问题。

可是为什么不能播放呢?

开始考虑是不是文件的问题。从youk和tudou分别抓个flv测试,发现用此程序播放没问题。

那就应该是测试文件的问题了。

可是使用FMS录制的文件,flash lite3竟然不支持?

使用as3的ns.audioCodec属性,可以获取到flv的音频编码格式,经过验证,fms2录制的文件的音频编码是6,也就是Nellymoser(参考:flv文件格式解读之音频tags),其他的flv(包括用flash video encoder转制的)的音频编码一般是2,也就是mp3格式的。这就说明flash lite3支持的flv的音频编码只能播放mp3格式编码的?

但是使用flash media encoder2(http://download.macromedia.com/pub/flashmediaserver/flashmediaencoder/installer/flashmediaencoder-v2.0.1.1114.msi)来调用fms录制的音频却可以播放(是选择format为mp3的时候才行,如果选择format为NellyMoser时候录制的内容也不可以播放)。

以上内容都是在手机测试的。

可是,怎么设置fms的音频编码呢?  或者是我哪个地方考虑的不周导致不能正常播放呢?  有熟悉的朋友麻烦指点一下:)

 

 

 

 

 

 

js-图片轮播

图片轮播

http://roading.net/work/picPlayer/picplay.htm

用js来做图片轮播比flash就简单的多了

 

js-tween-切换移动效果

鼠标在左边和右边点点试试

http://roading.net/work/jstween/move.htm

有时候用js来处理一下效果,反而比flash更舒服一点。