ff: HTML5 Icon Generator
drawTrianglesから, displayObjectの3D APIに乗り換え. プレビューではぼやけてますが, 保存するといい感じでした.
色相・輝度いじり, ローカル画像の読み込み追加.
/**
* Copyright matacat ( http://wonderfl.net/user/matacat )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/36kN
*/
// forked from paq's HTML5 Icon Generator
package
{
import com.adobe.images.PNGEncoder;
import com.bit101.components.CheckBox;
import com.bit101.components.InputText;
import com.bit101.components.Label;
import com.bit101.components.PushButton;
import com.bit101.components.Style;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.GraphicsPathCommand;
import flash.display.GraphicsPathWinding;
import flash.display.Loader;
import flash.display.Shape;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.events.Event;
import flash.events.FocusEvent;
import flash.events.KeyboardEvent;
import flash.geom.Matrix;
import flash.net.FileFilter;
import flash.net.FileReference;
import flash.ui.Keyboard;
import frocessing.color.ColorHSV;
/**
* Twitter アイコンをHTML5っぽくするジェネレーター
* @author paq
*/
[SWF(width="465", height="465", backgroundColor="0xFFFFFF", frameRate="60")]
public class HTML5IconGen extends Sprite
{
private var _inputText:InputText;
private var _iconLoader:TwitterIconLoader;
private var _bitmapData:BitmapData;
private var _icon:Sprite;
private var _fileReference:FileReference;
private var _result:Sprite;
private var _iconHolder:Sprite;
private var _tweakHue:Boolean;
private var _darkenLeft:Boolean;
/**
* コンストラクタ.
*/
public function HTML5IconGen()
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
/**
*
* @param event
*/
private function init(event:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
Wonderfl.disable_capture();
_result = new Sprite();
addChild(_result);
// ステージの設定
stage.align = StageAlign.TOP_LEFT;
stage.quality = StageQuality.HIGH;
//stage.scaleMode = StageScaleMode.NO_SCALE;
var g:Graphics;
// 背景を作成
var bgShape:Shape = new Shape();
g = bgShape.graphics;
g.beginFill(ColorConst.BACKGROUND);
g.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
_result.addChild(bgShape);
// 集中線を描く
drawLineWork(g);
// マークを作成
var markShape:Shape = new Shape();
_result.addChild(markShape);
// マークを描く
drawMark(markShape.graphics);
// 文字を作成
var letterShape:Shape = new Shape();
_result.addChild(letterShape);
// 文字を描く
drawLetters(letterShape.graphics, "HTML");
Style.BACKGROUND = ColorConst.MARK_LIGHT;
Style.BUTTON_FACE = ColorConst.MARK_DARK;
Style.INPUT_TEXT = 0xFFFFFF;
Style.LABEL_TEXT = 0xFFFFFF;
// UI を作成
// ID 入力用テキスト
_inputText = new InputText(this);
_inputText.width = 100;
_inputText.addEventListener(FocusEvent.FOCUS_IN, function():void {
_inputText.removeEventListener(FocusEvent.FOCUS_IN, arguments.callee);
label.visible = false;
});
_inputText.addEventListener(KeyboardEvent.KEY_DOWN, function(event:KeyboardEvent):void {
if (event.keyCode == Keyboard.ENTER)
{
_iconLoader.load(_inputText.text);
_inputText.text = "";
}
});
// ラベル
var label:Label = new Label(this, 0, 0, "Twitter ID");
// ボタン
var genButton:PushButton = new PushButton(this, 0, 0, "GENERATE!", function():void {
_iconLoader.load(_inputText.text);
_inputText.text = "";
});
// 保存ボタン
var saveButton:PushButton = new PushButton(this, 0, 0, "SAVE ICON", save);
// 保存ダイアログ
_fileReference = new FileReference();
// Twitter アイコン読み込み用ローダー
_iconLoader = new TwitterIconLoader("html5", onTwitterIconLoaded);
// アイコン
_icon = new Sprite();
_icon.x = stage.stageWidth / 2 - 73*2.5 / 2;
_icon.y = stage.stageHeight / 2 - 73*2.5 / 2;
_icon.scaleX = _icon.scaleY = 2.5;
_result.addChild(_icon);
_iconHolder = new Sprite();
_iconHolder.x = stage.stageWidth >> 1;
_iconHolder.y = stage.stageHeight >> 1;
_result.addChild(_iconHolder);
_bitmapData = new BitmapData(73, 73, true, 0x00000000);
var b:Bitmap = new Bitmap(_bitmapData, "auto", true);
b.x = -73 >> 1;
b.y = -72 >> 1;
_iconHolder.addChild(b);
_iconHolder.scaleX = 2.5;
_iconHolder.scaleY = 2.5;
_iconHolder.rotationX = 18;
_tweakHue = false;
_darkenLeft = false;
Style.LABEL_TEXT = 0x666666;
var tc:CheckBox = new CheckBox(this, 0, 0, "TWEAK HUE", function():void { _tweakHue = tc.selected; onTwitterIconLoaded(null); } );
var dc:CheckBox = new CheckBox(this, 0, 0, "DARKEN LEFT", function():void { _darkenLeft = dc.selected; onTwitterIconLoaded(null); } );
var ff:FileFilter = new FileFilter("Image files (*.gif, *.jpg, *.png)", "*.jpg;*.gif;*.png");
var lo:FileReference = new FileReference();
lo.addEventListener(Event.SELECT, function():void { lo.load(); } );
lo.addEventListener(Event.COMPLETE, function():void { Loader(_iconLoader.getChildAt(0)).loadBytes(lo.data); onTwitterIconLoaded(null); } );
Style.LABEL_TEXT = 0xFFFFFF;
var lb:PushButton = new PushButton(this, 0, 0, "LOAD LOCAL IMAGE", function():void { lo.browse([ff]); } );
var w:int = stage.stageWidth;
var h:int = stage.stageHeight;
dc.x = 10; dc.y = h - dc.height - 10;
tc.x = dc.x; tc.y = dc.y - tc.height - 5;
genButton.x = w - genButton.width >> 1; genButton.y = h - genButton.height - 10;
_inputText.x = w - _inputText.width >> 1; _inputText.y = genButton.y - _inputText.height - 5;
label.x = w - label.width >> 1; label.y = _inputText.y;
saveButton.x = w - saveButton.width - 10; saveButton.y = h - saveButton.height - 10;
lb.x = saveButton.x; lb.y = saveButton.y - lb.height - 5;
}
/**
* 作成した画像を保存します.
*/
private function save(event:Event):void
{
var bmd:BitmapData = new BitmapData(stage.stageWidth / 2, stage.stageHeight / 2);
bmd.draw(_result, new Matrix(0.5, 0, 0, 0.5), null, null, null, true);
_fileReference.save(PNGEncoder.encode(bmd), "icon.png");
}
/**
* 指定した graphics に集中線を描きます.
*
* @param g
*/
private function drawLineWork(g:Graphics):void
{
var w:int = stage.stageWidth;
var h:int = stage.stageHeight;
var cx:int = w / 2;
var cy:int = h / 2;
var size:Number = h;
var commands:Vector.<int> = new Vector.<int>();
var data:Vector.<Number> = new Vector.<Number>();
commands.push(GraphicsPathCommand.MOVE_TO);
data.push(cx + size, cy);
for (var i:int = 0; i < 72; i++ )
{
var radian:Number = i * 5 * Math.PI / 180;
if (i % 2 == 0)
{
commands.push(GraphicsPathCommand.LINE_TO);
data.push(cx + Math.cos(radian) * size, cy + Math.sin(radian) * size);
}
else
{
commands.push(GraphicsPathCommand.LINE_TO);
data.push(cx + Math.cos(radian) * size * 0.15, cy + Math.sin(radian) * size * 0.15);
}
}
g.beginFill(ColorConst.LINE);
g.drawPath(commands, data);
g.endFill();
}
/**
* 指定した graphics にマークを描きます.
*
* @param g
*/
private function drawMark(g:Graphics):void
{
var w:int = stage.stageWidth;
var h:int = stage.stageHeight;
var cx:int = w / 2;
var cy:int = h / 2;
var size:Number = h - 110;
var padY:Number = size / 8;
var commands:Vector.<int> = new Vector.<int>();
var data:Vector.<Number> = new Vector.<Number>();
// 左半分
commands.push(GraphicsPathCommand.MOVE_TO);
data.push(cx, cy - size / 2 + padY);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(cx - size / 2.5, cy - size / 2 + padY);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(cx - size / 3, cy + size / 2 - size / 8);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(cx, cy + size / 2);
// 右半分
commands.push(GraphicsPathCommand.MOVE_TO);
data.push(cx, cy - size / 2 + padY);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(cx + size / 2.5, cy - size / 2 + padY);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(cx + size / 3, cy + size / 2 - size / 8);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(cx, cy + size / 2);
g.beginFill(ColorConst.MARK_DARK);
g.drawPath(commands, data);
commands = new Vector.<int>();
data = new Vector.<Number>();
// 明るい部分
commands.push(GraphicsPathCommand.MOVE_TO);
data.push(cx, cy - size / 2 + padY + size / 16);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(cx + size / 3, cy - size / 2 + padY + size / 16);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(cx + size / 3.5, cy + size / 2 - size / 6);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(cx, data[data.length-1] + size / 10);
g.beginFill(ColorConst.MARK_LIGHT);
g.drawPath(commands, data);
g.endFill();
}
/**
* 指定した graphics に文字を描きます.
*
* @param g
* @param letters
*/
private function drawLetters(g:Graphics, letters:String):void
{
var char:Array = letters.split("");
var sw:int = stage.stageWidth;
var w:Number = char.length * 70;
var x:Number = sw / 2 - w / 2 + 15;
for (var i:int = 0, len:int = char.length; i < len; i++ )
{
var span:Number = drawChar(g, char[i], x, 25);
x += span + 10;
}
}
/**
* 指定した graphics に文字を描きます.
*
* @param g
* @param char
* @param xpos
* @param ypos
* @param size
*/
private function drawChar(g:Graphics, char:String, xpos:int = 0, ypos:int = 0, size:Number = 55):Number
{
var commands:Vector.<int> = new Vector.<int>();
var data:Vector.<Number> = new Vector.<Number>();
var cx:Number = xpos + size / 2;
var cy:Number = ypos + size / 2;
var startX:Number, startY:Number;
var vw:Number, vh:Number;
var hw:Number, hh:Number;
var len:Number = size;
switch (char)
{
case "H":
vw = size / 2.9;
vh = size;
// *|*-|
startX = xpos;
startY = ypos;
commands.push(GraphicsPathCommand.MOVE_TO);
data.push(startX, startY);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX, startY + vh);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX + vw, startY + vh);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX + vw, startY);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX, startY);
// |-*|*
startX = xpos + size;
startY = ypos;
commands.push(GraphicsPathCommand.MOVE_TO);
data.push(startX, startY);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX, startY + vh);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX - vw, startY + vh);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX - vw, startY);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX, startY);
// |*-*|
startX = xpos + vw;
startY = cy - hh / 2;
hh = size / 3;
commands.push(GraphicsPathCommand.MOVE_TO);
data.push(startX, startY);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(xpos + size - vw, cy - hh / 2);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(xpos + size - vw, cy + size / 3- hh / 2);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(xpos + vw, cy + size / 3 - hh / 2);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX, cy - hh / 2);
break;
case "T":
var w:Number = size;
//  ̄
var topH:Number = size / 2.9;
startX = xpos;
startY = ypos;
commands.push(GraphicsPathCommand.MOVE_TO);
data.push(startX, startY);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX + w, startY);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX + w, startY + topH);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX, startY + topH);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX, startY);
// |
var bottomW:Number = size / 2.9;
var bottomH:Number = size - topH;
startX = xpos + w / 2 - bottomW / 2;
startY = ypos + topH;
commands.push(GraphicsPathCommand.MOVE_TO);
data.push(startX, startY);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX + bottomW, startY);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX + bottomW, startY + bottomH);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX, startY + bottomH);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX, startY);
break;
case "M":
vw = size / 3;
vh = size;
len = size + vw / 2;
// *|*\/|
startX = xpos;
startY = ypos;
commands.push(GraphicsPathCommand.MOVE_TO);
data.push(startX, startY);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX, startY + vh);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX + vw, startY + vh);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX + vw, startY);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX, startY);
// |*\*/|
startX = startX + vw;
startY = ypos;
commands.push(GraphicsPathCommand.MOVE_TO);
data.push(startX, startY);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(cx + vw / 4, cy - vw / 2);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(cx + vw / 4, cy + vw);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX, startY + vw * 1.5);
// |\*/*|
startX = xpos + size + vw / 2 - vw;
startY = ypos;
commands.push(GraphicsPathCommand.MOVE_TO);
data.push(startX, startY);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(cx + vw / 4, cy - vw / 2);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(cx + vw / 4, cy + vw);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX, startY + vw * 1.5);
// |\/*|*
startX = xpos + size + vw / 2;
startY = ypos;
commands.push(GraphicsPathCommand.MOVE_TO);
data.push(startX, startY);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX, startY + vh);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX - vw, startY + vh);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX - vw, startY);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX, startY);
break;
case "L":
len = size / 2.5;
vw = size / 3;
vh = size;
hw = size / 3;
hh = size / 3;
// *|*_
startX = xpos;
startY = ypos;
commands.push(GraphicsPathCommand.MOVE_TO);
data.push(startX, startY);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX, startY + vh);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX + vw, startY + vh);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX + vw, startY);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX, startY);
// |*_*
startX = xpos + vw;
startY = ypos + size - hh;
commands.push(GraphicsPathCommand.MOVE_TO);
data.push(startX, startY);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX, startY + hh);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX + size / 2.2, startY + hh);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX + size / 2.2, startY);
commands.push(GraphicsPathCommand.LINE_TO);
data.push(startX, startY);
break;
default:
break;
}
g.beginFill(ColorConst.LETTER);
g.drawPath(commands, data, GraphicsPathWinding.NON_ZERO);
g.endFill();
return len;
}
/**
* Twitter アイコンの読み込み完了時に呼び出されます.
*
* @param event
*/
private function onTwitterIconLoaded(event:Event):void
{
_bitmapData.lock();
var w:Number = _iconLoader.width, h:Number = _iconLoader.height;
var s:Number = 73 / (w > h ? w : h);
_bitmapData.fillRect(_bitmapData.rect, 0x00000000);
_bitmapData.draw(_iconLoader, new Matrix(s, 0, 0, s, (73 - w * s) / 2, (73 - h * s) / 2));
if (_tweakHue || _darkenLeft) {
var hsv:ColorHSV = new ColorHSV();
for (var i:int = 0; i < 73; i++) {
for (var j:int = 0; j < 73; j++) {
var c:uint = _bitmapData.getPixel(i, j);
hsv.rgb(c >> 16, c >> 8 & 0xFF, c & 0xFF);
if (_tweakHue) hsv.h = 18;
if (_darkenLeft && i < 37) {
hsv.h -= _tweakHue ? 6 : 0;
hsv.v -= 0.08;
}
_bitmapData.setPixel(i, j, hsv.value);
}
}
}
_bitmapData.unlock();
}
}
}
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLRequest;
import flash.system.LoaderContext;
/**
* Twitter のアイコンを読み込むためのクラス.
*
* <p>アイコン取得のために usericons.relucks.org を使用しています。</p>
*
* @author paq
*/
class TwitterIconLoader extends Sprite
{
private static const API_URL:String = "http://wonder-tools.appspot.com/api/proxy?url=http://usericons.relucks.org/twitter/";
private var _loader:Loader;
public var handler:Function;
/**
* 新しい TwitterIconLoader インスタンスを作成します.
*
* @param parent
* @param screenName ユーザーのスクリーンネーム
*/
public function TwitterIconLoader(screenName:String = null, handler:Function = null)
{
this.handler = handler;
_loader = new Loader();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
addChild(_loader);
if (screenName != null)
{
load(screenName);
}
}
/**
* 指定したスクリーンネームのアイコンを読み込みます.
*
* @param screenName ユーザーのスクリーンネーム
*/
public function load(screenName:String):void
{
_loader.load(new URLRequest(API_URL + screenName), new LoaderContext(true));
}
/**
* Loader の読み込み完了時に呼び出されます.
*
* @param event
*/
private function onComplete(event:Event):void
{
if (handler != null)
{
handler(event);
}
}
}
/**
* 色の定数をまとめたクラスです.
*
* @author paq
*/
class ColorConst
{
/** 文字の色 */
public static var LETTER:uint = 0x000000;
/** 背景色の色 */
public static var BACKGROUND:uint = 0xF2F2F2;
/** 集中線の色 */
public static var LINE:uint = 0xFFFFFF;
/** バッジの色 */
public static var MARK_LIGHT:uint = 0xF06529;
/** バッジの影 */
public static var MARK_DARK:uint = 0xE34C26;
}