In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

スパイラルカレンダー

操作方法:
*		ドラッグ上下:拡大・縮小
*		ドラッグ左右:回転
*		Spaceキー:初期化/表示変更
*		Shift or Ctrl+ドラッグ:?
Get Adobe Flash player
by talte 10 Jan 2010
/**
 * Copyright talte ( http://wonderfl.net/user/talte )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/m6PQ
 */

/*
 *	操作方法:
 *		ドラッグ上下:拡大・縮小
 *		ドラッグ左右:回転
 *		Spaceキー:初期化/表示変更
 *		Shift or Ctrl+ドラッグ:?
*/
package
{
	import flash.display.Sprite
	import flash.events.Event
	import flash.events.MouseEvent
	import flash.events.KeyboardEvent
	import org.papervision3d.objects.DisplayObject3D
	import org.papervision3d.scenes.Scene3D
	import org.papervision3d.typography.Font3D
	import org.papervision3d.view.Viewport3D
	import org.papervision3d.cameras.Camera3D
	import org.papervision3d.render.BasicRenderEngine
	import org.papervision3d.core.geom.Lines3D
	import org.papervision3d.materials.special.LineMaterial
	import org.papervision3d.core.math.Number3D
	import org.papervision3d.typography.Text3D
	import org.papervision3d.materials.special.Letter3DMaterial
	import org.papervision3d.core.proto.MaterialObject3D
	import org.papervision3d.typography.fonts.HelveticaBold
	import org.papervision3d.core.math.Matrix3D
	
	public class Calender extends Sprite
	{
		// 3D関連
		private var object:DisplayObject3D
		private var scene:Scene3D
		private var camera:Camera3D
		private var viewport:Viewport3D
		private var render:BasicRenderEngine
		
		// 操作関連
		private var mouse_down:Boolean = false
		private var mouse_x:int
		private var mouse_y:int
		
		private var key_shift:Boolean = false
		private var key_ctrl:Boolean = false
		private var key_space:Boolean = false
		
		// 日付関連
		private var now:Date = new Date
		private var today:Date = new Date
		private var firstweek:int
		private var lastday:int
		
		public function Calender()
		{
			this.addEventListener(Event.ADDED_TO_STAGE, this.onInit) // 初期化
		}
		
		// 初期設定
		public function onInit(event:Event):void 
		{
			// 3D関連初期化
			this.viewport = new Viewport3D(0, 0, true)
			this.viewport.opaqueBackground = 0x000000
			this.addChild(this.viewport)
			
			this.render = new BasicRenderEngine
			this.camera = new Camera3D
			
			this.scene = new Scene3D
			
			// 初期化
			this.initObject() // 描画
			this.initDisplay() // 表示
			
			// 動作登録
			stage.addEventListener(Event.ENTER_FRAME, this.onEnterFrame)
			stage.addEventListener(MouseEvent.MOUSE_DOWN, this.onMouseDown)
			stage.addEventListener(MouseEvent.MOUSE_UP, this.onMouseUp)
			stage.addEventListener(MouseEvent.MOUSE_MOVE, this.onMouseMove)
			stage.addEventListener(MouseEvent.MOUSE_WHEEL, this.onMouseWheel)
			stage.addEventListener(KeyboardEvent.KEY_DOWN, this.onKeyDown)
			stage.addEventListener(KeyboardEvent.KEY_UP, this.onKeyUp)
		}
		// 描画初期化
		private function initObject():void
		{
			// 初期化
			var obj:DisplayObject3D = new DisplayObject3D
			if(this.object != null) {
				this.scene.removeChild(this.object) // クリア
				obj.copyTransform(this.object.transform) // 表示情報を引き継ぐ
			}
			this.scene.addChild(obj)
			this.object = obj
			
			// 日付関連計算
			var date:Date = new Date(now)
			date.date -= date.date - 1
			this.firstweek = date.day // 月初めの曜日
			date.month += 1
			date.date -= 1
			this.lastday = date.date // 月終わりの日
			
			// 日付描画
			var letter_day:Letter3DMaterial = new Letter3DMaterial(0xaaaaaa)
			var letter_sun:Letter3DMaterial = new Letter3DMaterial(0xff4444)
			var letter_sat:Letter3DMaterial = new Letter3DMaterial(0x4444ff)
			var font:Font3D = new HelveticaBold
			for(var i:int = 1; i <= lastday; i++) {
				// 文字色
				var mat:MaterialObject3D
				if((i + firstweek) % 7 == 1) { // 日曜
					mat = letter_sun
				}
				else if ((i + firstweek) % 7 == 0) { // 土曜
					mat = letter_sat
				}
				else {
					mat = letter_day
				}
				var text:Text3D = new Text3D(i.toString(), font, mat)
				
				var ang:Number = ((i - 1) / 7 + 0.25) * Math.PI * 2
				text.x = 500 * -Math.cos(ang)
				text.y = 500 * Math.sin(ang)
				text.z = -1520 + i * 100
				text.rotationX = -90
				text.rotationZ = -360 * ((i - 1) / 7)
				this.object.addChild(text)
			}
			
			// 枠線
			var line_today:LineMaterial = new LineMaterial(0xffff00)
			var line_other:LineMaterial = new LineMaterial(0xff0000)
			
			// 横線描画
			var lines:Lines3D = new Lines3D
			var pos_from:Number3D = null
			for(i = 0; i <= (lastday + 7) * 10; i++) { // 曲線にするため細かく
				// 文字色
				if (this.now.fullYear == this.today.fullYear && this.now.month == this.today.month && ((i > (this.today.date - 1) * 10 && i <= this.today.date * 10) || (i > (this.today.date + 6) * 10 && i <= (this.today.date + 7) * 10))) { // 今日
					lines.material = line_today
				}
				else {
					lines.material = line_other
				}
				
				var pos_to:Number3D = new Number3D
				ang = ((i / 10 - 0.5) / 7 + 0.25) * Math.PI * 2
				pos_to.x = 500 * -Math.cos(ang)
				pos_to.y = 500 * Math.sin(ang)
				pos_to.z = -1600 + i  * 10
				if (pos_from != null) {
					lines.addNewLine(1, pos_from.x, pos_from.y, pos_from.z, pos_to.x, pos_to.y, pos_to.z)
				}
				pos_from = pos_to // 前回の位置を保存して次回に使う
			}
			this.object.addChild(lines)
			
			// 縦線描画
			for(i = 0;  i <= lastday; i++) { // 線の片側が画面外だと消えるので分けて描画
				lines = new Lines3D
				// 文字色
				if(this.now.fullYear == this.today.fullYear && this.now.month == this.today.month && (i == this.today.date - 1 || i == this.today.date)) { // 今日
					lines.material = line_today
				}
				else {
					lines.material = line_other
				}
				
				ang = (((i - 0.5) / 7 + 0.25) * Math.PI * 2)
				pos_from = new Number3D(500 * -Math.cos(ang), 500 * Math.sin(ang), -1600 + (i / 7 * 7) * 100)
				pos_to = new Number3D(500 * -Math.cos(ang), 500 * Math.sin(ang), -1600 + ((i / 7 + 1) * 7) * 100)
				lines.addNewLine(1, pos_from.x, pos_from.y, pos_from.z, pos_to.x, pos_to.y, pos_to.z)
				this.object.addChild(lines)
			}
		}
		// 表示初期化
		private function initDisplay():void
		{
			this.object.transform = new Matrix3D
			if(this.key_space) {
				this.object.moveUp(this.now.date * 100 - 1300)
				this.object.pitch(90)
				this.camera.z = -600
				this.key_space = false
			}
			else {
				this.camera.z = -2200
				this.key_space = true
			}
			this.object.roll((this.now.day - this.firstweek) / 7 * 360)
		}
		
		// 更新
		private function onEnterFrame(event:Event):void
		{
			// 再描画
			this.render.renderScene(this.scene, this.camera, this.viewport)
		}
		// マウス移動
		private function onMouseMove(event:MouseEvent):void 
		{
			// クリック時
			if(this.mouse_down) {
				if(this.key_shift && !this.key_ctrl) { // shiftのみ
					this.object.transform = Matrix3D.multiply(Matrix3D.translationMatrix((event.stageX - this.mouse_x) * 3, 0, 0), this.object.transform) // 横:X軸移動
					this.object.transform = Matrix3D.multiply(Matrix3D.translationMatrix(0, -(event.stageY - this.mouse_y) * 3, 0), this.object.transform) // 縦:Y軸移動
				}
				else if(!this.key_shift && this.key_ctrl) { // ctrlのみ
					this.object.transform = Matrix3D.multiply(Matrix3D.rotationY((event.stageX - this.mouse_x) / 60), this.object.transform) // 横:Y軸回転
					this.object.transform = Matrix3D.multiply(Matrix3D.rotationX( -(event.stageY - this.mouse_y) / 60), this.object.transform) // 縦:X軸回転
				}
				else if(this.key_shift && this.key_ctrl) { // shiftとctrl
					this.object.transform = Matrix3D.multiply(Matrix3D.rotationZ(-(event.stageX - this.mouse_x) / 60), this.object.transform) // 横:Z軸回転
					this.camera.z -= (event.stageY - this.mouse_y) * 10 // 縦:ズーム
				}
				else { // キーなし
					this.object.roll(-(event.stageX - this.mouse_x)) // 横:カレンダー回転
					this.object.moveForward((event.stageY - this.mouse_y) * 3) // 縦:カレンダー上下
				}
				
				// マウス位置更新
				this.mouse_x = event.stageX
				this.mouse_y = event.stageY
			}
		}
		// マウス押す
		private function onMouseDown(event:MouseEvent):void 
		{
			this.mouse_down = true // クリック
			
			// マウス位置更新
			this.mouse_x = event.stageX
			this.mouse_y = event.stageY
		}
		// マウス離す
		private function onMouseUp(event:MouseEvent):void 
		{
			this.mouse_down = false // クリック解除
		}
		// マウスホイール
		private function onMouseWheel(event:MouseEvent):void 
		{
			this.now.month += event.delta > 0 ? 1 : -1
			this.now.date = 1
			this.initObject()
		}
		// キー押す
		private function onKeyDown(event:KeyboardEvent):void
		{
			switch(event.keyCode) {
				case 16: // shift
					this.key_shift = true
					break
				case 17: // ctrl
					this.key_ctrl = true
					break
			}
		}
		// キー離す
		private function onKeyUp(event:KeyboardEvent):void
		{
			switch(event.keyCode) {
				case 16: // shift
					this.key_shift = false
					break
				case 17: // ctrl
					this.key_ctrl = false
					break
				case 32: // space
					this.initDisplay()
					break
			}
		}
	}
}