flash on 2013-11-17
-1~1の幅の折れ線グラフを描く。
ドラッグ終了ごとにテキストとしてクリップボードに出力。
@author Moriwaki Yuuya
/**
* Copyright kazuki ( http://wonderfl.net/user/kazuki )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/qSi1
*/
package
{
import flash.events.*;
import flash.display.*;
import flash.geom.*;
import flash.system.*;
import flash.text.*;
/**
* -1~1の幅の折れ線グラフを描く。
* ドラッグ終了ごとにテキストとしてクリップボードに出力。
* @author Moriwaki Yuuya
*/
public class Main extends Sprite
{
//-------------consts-----------------
/// 線の数(点の数 -1)
private const LINECOUNT :int = 24;
/// 縦方向の罫線数。正負+0位置 = ROW * 2 + 1
private const ROW :int = 10;
//-------------props------------------
private var view :Sprite;
private var bg :Shape;
private var line :Shape;
private var marks :Vector.<Marker>;
private var caption :TextField;
//-------------general---------------
public function Main():void { if (stage) { init(); } else { addEventListener(Event.ADDED_TO_STAGE, init); }}
private function init(ev:Event = null) :void {
view = new Sprite();
bg = new Shape();
line = new Shape();
view.addChild(bg);
view.addChild(line);
addChild(view);
captionInit();
addEventListener(Event.CHANGE, drawLine);
addEventListener(Event.COMPLETE, setClipboard);
renew(LINECOUNT);
}
private function setClipboard(ev:Event = null) :void {
var i :int, ar :Array = [];
for (i = 0; i < marks.length; i++) {
ar.push(marks[i].value);
}
System.setClipboard(ar.join("\t"));
captionBeginAnime();
}
//--------------draw------------------
private function renew(count :int) :void {
var i :int, n :Number, rct :Rectangle;
rct = new Rectangle(24, 12, stage.stageWidth - 48, stage.stageHeight - 100);
view.x = rct.x;
view.y = rct.y;
//bg---------
var g :Graphics = bg.graphics;
g.clear();
g.beginFill(0x333333);
g.drawRect( -rct.x, -rct.y, stage.stageWidth, stage.stageHeight);
g.endFill();
g.beginFill(0x0);
g.drawRect(0, 0, rct.width, rct.height);
g.endFill();
for (i = 0; i <= ROW * 2; i++) {
n = i * rct.height / (ROW * 2);
g.lineStyle(1, i == ROW? 0xFFFFFF: 0x666666);
g.moveTo(0, n);
g.lineTo(rct.width , n);
}
for (i = 0; i <= count; i++) {
n = i * rct.width / count;
g.lineStyle(1, i % count == 0? 0xFFFFFF: 0x666666);
g.moveTo(n, 0);
g.lineTo(n, rct.height);
}
//marker----------------
var m :Marker;
if (marks) {
for each(m in marks) view.removeChild(m);
}
marks = new Vector.<Marker>();
for (i = 0; i <= count; i++){
m = new Marker(i, i * rct.width / count, 0, rct.height);
marks.push(m);
view.addChild(m);
}
drawLine();
}
private function drawLine(ev:Event = null) :void {
var i :int, g :Graphics = line.graphics;
g.clear();
g.lineStyle(2, 0x0099FF);
g.moveTo(marks[0].x, marks[0].y);
for (i = 1; i < marks.length; i++) {
g.lineTo(marks[i].x, marks[i].y);
}
}
//----------caption----------------
private function captionInit() :void {
caption = new TextField();
caption.width = 0;
caption.height = 12;
caption.x = 24;
caption.y = stage.stageHeight - 50;
caption.autoSize = TextFieldAutoSize.LEFT;
caption.mouseEnabled = false;
caption.selectable = false;
caption.multiline = true;
caption.textColor = 0xFFFFFF;
caption.alpha = 0.5;
caption.htmlText = "<b>Oresen2Clipboard</b><br />点の移動を終えるたび、グラフの状態をテキストとしてクリップボードに出力します。";
addChild(caption);
}
private function captionBeginAnime() :void {
caption.alpha = 1.0;
addEventListener(Event.ENTER_FRAME, captionAnime);
}
private function captionAnime(ev:Event) :void {
caption.alpha -= 0.1;
if (caption.alpha > 0.5) return;
caption.alpha = 0.5;
removeEventListener(Event.ENTER_FRAME, captionAnime);
}
}
}
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.text.*;
//---------------Marker--------------------
class Marker extends Sprite {
//---------consts-----------
private const MODE_DEF :int = 1;
private const MODE_DRAG :int = 2;
private const ROUNDBASE :int = 1000;
//---------props------------
private var id :int;
private var mode :int;
private var dRect :Rectangle;
private var txId :TextField;
private var txValue :TextField;
//--------general-------------
public function Marker(id :int, x :Number, ymin :Number, ymax :Number) {
this.id = id;
this.x = x;
this.y = (ymax - ymin) / 2;
mode = MODE_DEF;
dRect = new Rectangle(x, Math.min(ymin, ymax), 0, Math.abs(ymax - ymin));
txId = addTextField();
txId.text = id.toString();
txId.y = -8;
txValue = addTextField();
txValue.background = true;
txValue.backgroundColor = 0x666666;
txValue.text = "0";
txValue.y = 16;
useHandCursor = true;
addEventListener(MouseEvent.ROLL_OVER, onRollOver);
addEventListener(MouseEvent.ROLL_OUT, onRollOut);
addEventListener(MouseEvent.MOUSE_DOWN, onDragBegin);
addEventListener(Event.REMOVED_FROM_STAGE, onRemoved);
onRollOut(null);
}
/// Y座標から、-1~1の値を算出。yを変えれば即座に反映
public function get value() :Number {
return Math.round(((y - dRect.y) * -2 / dRect.height + 1) * ROUNDBASE) / ROUNDBASE;
}
private function onRemoved(ev:Event) :void {
removeEventListener(MouseEvent.ROLL_OVER, onRollOver);
removeEventListener(MouseEvent.ROLL_OUT, onRollOut);
removeEventListener(MouseEvent.MOUSE_DOWN, onDragBegin);
removeEventListener(Event.ENTER_FRAME, onDragUpdate);
parent.removeEventListener(MouseEvent.MOUSE_UP, onDragEnd);
//stage.removeEventListener(Event.MOUSE_LEAVE, onDragEnd);
removeEventListener(Event.REMOVED_FROM_STAGE, onRemoved);
}
//--------mouse---------
private function onRollOver(ev:Event) :void {
if (mode == MODE_DRAG) return;
drawButton(0xFFFFFF, 0x0066FF, 12);
}
private function onRollOut(ev:Event) :void {
if (mode == MODE_DRAG) return;
drawButton(0xCCCCCC, 0x006699, 8);
}
//--------drag----------
private function onDragBegin(ev:Event) :void {
if (mode == MODE_DRAG) return;
drawButton(0xFFFFFF, 0xCC6666, 12);
mode = MODE_DRAG;
addEventListener(Event.ENTER_FRAME, onDragUpdate);
parent.addEventListener(MouseEvent.MOUSE_UP, onDragEnd);
//stage.addEventListener(Event.MOUSE_LEAVE, onDragEnd);
}
private function onDragUpdate(ev:Event) :void {
y = Math.min(dRect.bottom, Math.max(dRect.top, parent.mouseY));
txValue.text = value.toString();
dispatchEvent(new Event(Event.CHANGE, true));
}
private function onDragEnd(ev:Event) :void {
removeEventListener(Event.ENTER_FRAME, onDragUpdate);
parent.removeEventListener(MouseEvent.MOUSE_UP, onDragEnd);
//stage.removeEventListener(Event.MOUSE_LEAVE, onDragEnd);
mode = MODE_DEF;
onRollOut(null);
onDragUpdate(null);
dispatchEvent(new Event(Event.COMPLETE, true));
}
//--------draw-----------
private function drawButton(fillcol :Number, linecol:Number, radius :Number) :void {
graphics.clear();
graphics.lineStyle(2, linecol);
graphics.beginFill(fillcol);
graphics.drawCircle(0, 0, radius);
graphics.endFill();
}
private function addTextField() :TextField {
var tx :TextField = new TextField();
tx = new TextField();
tx.width = 0;
tx.height = 12;
tx.x = 0;
tx.y = 0;
tx.autoSize = TextFieldAutoSize.CENTER;
tx.mouseEnabled = false;
tx.selectable = false;
tx.multiline = false;
tx.textColor = 0x0;
addChild(tx);
return tx;
}
}