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

色のトゥイーンの実験

http://ja.wikipedia.org/w/index.php?title=HSV%E8%89%B2%E7%A9%BA%E9%96%93 を見ながら色のトゥイーンの方法を探ってみた
Get Adobe Flash player
by kaikoga 05 Nov 2009
    Embed
// forked from kaikoga's ガンマ補正してみた
// forked from chaiyuttochai's how i can make movie clipe illastrate as a dot pixel?
// forked from hacker_7i4tn9on's forked from: The same brightness looks different.
// forked from borealkiss's The same brightness looks different.

// http://ja.wikipedia.org/w/index.php?title=HSV%E8%89%B2%E7%A9%BA%E9%96%93 を見ながら色のトゥイーンの方法を探ってみた

package {
	
	import flash.display.Sprite;
	
	import org.libspark.betweenas3.BetweenAS3;
	import org.libspark.betweenas3.easing.Custom;
	import org.libspark.betweenas3.tweens.ITween;
	
	[SWF(width=465, height=465, backgroundColor=0x0)]
	public class main extends Sprite{
		
		private static const STAGE_SIZE:int = 465;
		private static const RECT_SIZE:int = 100;
		
		private static const SCREEN_GAMMA:Number = 2.2;
		private static var SOURCE:Color;
		private static var TARGET:Color;
		
		private var rect1:RectSprite;
		private var rect2:RectSprite;
		private var rect3:RectSprite;
		private var rect4:RectSprite;
		
		public function main(){
			SOURCE = Color.rgb(255, 0, 0);
			TARGET = Color.rgb(0, 192, 64);
			this.addRects();
		}
		
		public function blend(a:Number, b:Number, pos:Number):Number {
			return a * (1 - pos) + b * pos;
		}
		public function set time(value:Number):void {
			//RGBの値ごとにトゥイーン
			this.rect1.color = Color.rgb(
					blend(SOURCE.red, TARGET.red, value),
					blend(SOURCE.green, TARGET.green, value),
					blend(SOURCE.blue, TARGET.blue, value)
					);
			//HSVの値ごとにトゥイーン
			this.rect3.color = Color.hsv(
					blend(SOURCE.hue, TARGET.hue, value),
					blend(SOURCE.saturation, TARGET.saturation, value),
					blend(SOURCE.value, TARGET.value, value)
					);
			//上二つをブレンド
			this.rect2.color = this.rect1.color.mix(this.rect3.color, 0.5);
			
			//HSV色空間を円柱と見て空間内をトゥイーン
			var x:Number = blend(
					Math.cos(SOURCE.hue / 180 * Math.PI) * SOURCE.saturation,
					Math.cos(TARGET.hue / 180 * Math.PI) * TARGET.saturation,
					value);
			var y:Number = blend(
					Math.sin(SOURCE.hue / 180 * Math.PI) * SOURCE.saturation,
					Math.sin(TARGET.hue / 180 * Math.PI) * TARGET.saturation,
					value);
			this.rect4.color = Color.hsv(
					Math.atan2(y, x) / Math.PI * 180,
					Math.sqrt(x * x + y * y),
					blend(SOURCE.value, TARGET.value, value)
					);
		}
		
		private function addRects():void{
			this.rect1 = new RectSprite(RECT_SIZE, RECT_SIZE, SOURCE.color);
			this.rect1.x = STAGE_SIZE * 0.2 - RECT_SIZE * 0.5;
			this.rect1.y = 50;
			this.addChild(this.rect1);
			this.rect2 = new RectSprite(RECT_SIZE, RECT_SIZE, SOURCE.color);
			this.rect2.x = STAGE_SIZE * 0.5 - RECT_SIZE * 0.5;
			this.rect2.y = 50;
			this.addChild(this.rect2);
			this.rect3 = new RectSprite(RECT_SIZE, RECT_SIZE, SOURCE.color);
			this.rect3.x = STAGE_SIZE * 0.8 - RECT_SIZE * 0.5;
			this.rect3.y = 50;
			this.addChild(this.rect3);
			
			this.rect4 = new RectSprite(RECT_SIZE, RECT_SIZE, SOURCE.color);
			this.rect4.x = STAGE_SIZE * 0.5 - RECT_SIZE * 0.5;
			this.rect4.y = 250;
			this.addChild(this.rect4);
			
			var tween:ITween = BetweenAS3.tween(this, {time: 1}, {time: 0}, 4);
			tween = BetweenAS3.serial(tween, BetweenAS3.reverse(tween));
			tween.stopOnComplete = false;
			tween.play();
		}
		
	}
}

import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;

class RectSprite extends Sprite {
	
	private var rectWidth:Number;
	private var rectHeight:Number;
	private var textField:TextField;
	private var _colorValue:uint;
	
	public function set caption(value:String):void {
		this.textField.text = value;
	}
	
	public function get colorValue():uint {
		return this._colorValue;
	}
	public function set colorValue(value:uint):void {
		this._colorValue = value;
		this.graphics.clear();
		this.graphics.beginFill(value);
		this.graphics.drawRect(0, 0, this.rectWidth, this.rectHeight);
		this.caption = value.toString(16);
	}
	
	public function get color():Color {
		return new Color(this._colorValue);
	}
	public function set color(value:Color):void {
		this.colorValue = value.color;
	}
	
	public function RectSprite(width:Number, height:Number, color:uint) {
		this.rectWidth = width;
		this.rectHeight = height;
		var textFormat:TextFormat = new TextFormat();
		textFormat.size = 16;
		textFormat.color = 0xFFFFFF;
		textFormat.align = TextFormatAlign.CENTER;
		
		this.textField = new TextField();
		this.textField.width = width * 2;
		this.textField.height = 100;
		this.textField.x = -width * 0.5;
		this.textField.y = height + 20;
		this.textField.defaultTextFormat = textFormat;
		this.addChild(this.textField);
		
		this.colorValue = color;
	}
	
}
class Color {
	
	public var color:uint;
	
	public function Color(color:uint) {
		this.color = color;
	}
	
	public function get red():uint {
		return (this.color >> 16) & 255;
	}
	
	public function get green():uint {
		return (this.color >> 8) & 255;
	}
	
	public function get blue():uint {
		return (this.color) & 255;
	}
	
	public function set red(value:uint):void {
		this.color = (this.color & 0xff00ffff) | ((value & 255) << 16);
	}
	
	public function set green(value:uint):void {
		this.color = (this.color & 0xffff00ff) | ((value & 255) << 8);
	}
	
	public function set blue(value:uint):void {
		this.color = (this.color & 0xffff00ff) | ((value & 255));
	}
	
	public static function rgb(r:int, g:int, b:int):Color {
		return new Color(((r & 255) << 16) | ((g & 255) << 8) | ((b & 255) << 0));
	}
	
	private function get maxRGB():uint {
		return Math.max(this.red, this.green, this.blue);
	}
	
	private function get minRGB():uint {
		return Math.min(this.red, this.green, this.blue);
	}
	
	private function get dynRGB():uint {
		return this.maxRGB - this.minRGB;
	}
	
	public function get hue():Number {
		switch (this.maxRGB) {
			case this.red:
			return 60 * (this.green - this.blue) / this.dynRGB + 0;
			case this.green:
			return 60 * (this.blue - this.red) / this.dynRGB + 120;
			case this.blue:
			return 60 * (this.red - this.green) / this.dynRGB + 240;
		}
		return 0;
	}
	
	public function get saturation():Number {
		return this.dynRGB / this.maxRGB;
	}
	
	public function get value():Number {
		return this.maxRGB / 255;
	}
	
	public function set hue(value:Number):void {
		this.color = hsv(value, this.saturation, this.value).color;
	}
	
	public function set saturation(value:Number):void {
		this.color = hsv(this.hue, value, this.value).color;
	}
	
	public function set value(value:Number):void {
		this.color = hsv(this.hue, this.saturation, value).color;
	}
	
	public static function hsv(h:Number, s:Number, v:Number):Color {
		v *= 255;
		if (s == 0) {
			return rgb(v, v, v);
		}
		
		if (h < 0) {
			h = 360 + (h % 360);
		}
		var Hi:int = Math.floor(h / 60) % 6;
		var f:Number = h / 60 - Hi;
		var p:Number = v * (1 - s);
		var q:Number = v * (1 - f * s);
		var t:Number = v * (1 - (1 - f) * s);
		switch (Hi) {
			case 0:
			return rgb(v, t, p);
			case 1:
			return rgb(q, v, p);
			case 2:
			return rgb(p, v, t);
			case 3:
			return rgb(p, q, v);
			case 4:
			return rgb(t, p, v);
			case 5:
			return rgb(v, p, q);
		}
		return rgb(0, 0, 0);
	}
	
	public function mix(target:Color, rate:Number = 0.5):Color {
		var nr:Number = 1 - rate;
		return rgb(this.red * nr + target.red * rate, this.green * nr + target.green * rate, this.blue * nr + target.blue * rate);
	}
	
	private function gamma(a:int, g:Number):int {
		return 255 * Math.pow(a / 255, 1 / g);
	}
	
}