2009年08月6日

【練習】3D標籤雲實作

  看到有些部落格裡開始出現3D造型的標籤雲(3D tag cloud), 感覺滿有趣的, 於是模仿動態做一個, 當作PV3D的練習, 原始檔附於文末。

延伸閱讀:
3D標籤雲不再是WordPress獨有 » 樂多也可以


結果:

為了方便下載和使用, 直接寫在fla檔裡

import org.papervision3d.view.BasicView;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.primitives.Sphere;
import org.papervision3d.materials.ColorMaterial;
import org.papervision3d.materials.special.BitmapParticleMaterial;
import org.papervision3d.core.geom.Particles;
import org.papervision3d.core.geom.renderables.Particle;
import org.papervision3d.events.InteractiveScene3DEvent;

var scale:Number = 5; // 字的縮放
var radius:Number = 300; // 圓半徑
var smoothing:Boolean = true; // 材質平滑化
var minAlpha:Number = 0.3; // 最遠處alpha
var glow:GlowFilter = new GlowFilter (0x003366, 1, 8, 8, 2, BitmapFilterQuality.LOW, true, false); // 移上換色

var i:uint; // 迴圈變數

// tag設定及圓的參數
var tags:Array = ["免費","新聞","Cookie","Toshiba","練習","JavaScript","玩具","人生","作品","TAMAMA","LocalConnection","備忘","MSN大頭","星爺","Loader","XML","創作","轉載","事件","加菲貓","Silverlight","3D","全螢幕"];
var tag_num:uint = tags.length;
var tag_num_sqrt:Number = Math.sqrt (tag_num);
var segW:uint = Math.ceil (tag_num_sqrt) + 1;
var segH:uint = Math.ceil (tag_num_sqrt);

// 3D變數
var bv:BasicView = new BasicView (stage.stageWidth, stage.stageHeight, true, true);
var tagArray:Array = [];
var tagContainer:DisplayObject3D = new DisplayObject3D ("tag_container");
	tagContainer.x = -radius * 0.25;
	tagContainer.y =  radius * 0.25;
var sphere:Sphere = new Sphere (new ColorMaterial(), radius, segW, segH);

// 由sphere取得節點資訊
var vertices_choose:Array = [];
var vertices_num:uint = sphere.geometry.vertices.length;

// 裁員(避免tag量超過點的量)
if (tag_num > vertices_num)
	tag_num = tags.length = vertices_num;

// 取一次亂數
for (i = 0; i < tag_num; i++) {
	var chooseId:int = sphere.geometry.vertices.length * Math.random();
	
	vertices_choose.push (sphere.geometry.vertices [chooseId]);
	sphere.geometry.vertices.splice (chooseId, 1);
}

// 生成3D tag
for (i = 0; i < tag_num; i++) {
	// 2D
	var txt:TextField = new TextField ();
		txt.text = tags[i];
		txt.filters = [new BlurFilter(1.1, 1.1)];
	var txtW:Number = txt.textWidth + 4;
	var txtH:Number = txt.textHeight + 4;
	var bitmap:BitmapData = new BitmapData (txtW, txtH, true, 0x01FFFFFF);
		bitmap.draw (txt);
	
	// 3D
	var material:BitmapParticleMaterial = new BitmapParticleMaterial (bitmap);
		material.interactive = true;
		material.smooth = smoothing;
	var v = vertices_choose[i];
	var tag:Particle = new Particle (material, scale, 0, 0, 0); // 使用粒子以使面永遠朝向鏡頭
	var tagHolder:Particles = new Particles ("tag_");
		tagHolder.addParticle (tag);
		tagHolder.x = v.x; // 放到圓的點上
		tagHolder.y = v.y;
		tagHolder.z = v.z;
		tagHolder.extra = {key:tags[i]};
		tagHolder.useOwnContainer = true; // 個別化layer以套用效果
		tagHolder.autoCalcScreenCoords = true; // 啟動screen計算(求深度)
		tagHolder.addEventListener (InteractiveScene3DEvent.OBJECT_OVER, objectOverHandler);
		tagHolder.addEventListener (InteractiveScene3DEvent.OBJECT_OUT, objectOutHandler);
		tagHolder.addEventListener (InteractiveScene3DEvent.OBJECT_PRESS, objectPressHandler);
	
	tagContainer.addChild (tagHolder);
	tagArray.push (tagHolder);
}

function objectOverHandler (e):void {
	bv.viewport.buttonMode = true;
	e.target.filters = [glow];
}

function objectOutHandler (e):void {
	bv.viewport.buttonMode = false;
	//e.target.filters = [];
	for (var j:uint = 0; j < tag_num; j++) {
		tagArray [j].filters = [];
	}
}

function objectPressHandler (e):void {
	trace (e.target.extra.key);
}

bv.viewport.interactive = true;
bv.scene.addChild (tagContainer);
bv.camera.z = -2 * radius;
bv.camera.zoom = 20;
// 開始render
bv.startRendering ();
addChild (bv);

addEventListener (Event.ENTER_FRAME, enterFrameHandler);
function enterFrameHandler (e):void {
	// 隨滑鼠移動
	tagContainer.rotationX += (mouseY - stage.stageHeight * 0.5) * 0.02;
	tagContainer.rotationY += (mouseX - stage.stageWidth * 0.5) * 0.02;
	
	for (var j:uint = 0; j < tag_num; j++) {
		// 依深度設定alpha
		tagArray[j].alpha = minAlpha + (1 - minAlpha) * (1 - (tagArray[j].screen.z - radius) / (2 * radius));
	}
}
原始檔下載:(需搭配PaperVision3D服用)
.fla

Posted by esabear at 樂多Roodo! │22:12 │回應(0)引用(0)Flash筆記
樂多分類:網路/3C 共同主題:Flash筆記 工具:編輯本文
標籤:3D,練習,濾鏡,pv3d,flash,ActionScript3
Ads by Roodo! 

引用URL

http://cgi.blog.roodo.com/trackback/9692349