書道してみる

| 1 Comment | No TrackBacks

株式会社 バスキュールさんのところにある「SODO」のようなのをやってみようとおもい、いろいろと考えて作ってみました。



ソースはこんな感じ

package 
{
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	/**
	書道クラス
	*/
	public class Shodo extends Sprite
	{
		//半紙
		private var paper:Sprite;
		//一つ前の座標
		private var oldX1:Number;
		private var oldY1:Number;
		//二つ前の座標
		private var oldX2:Number;
		private var oldY2:Number;
		//一つ前の幅
		private var oldW:Number;
		//筆の太さ
		private var strength:Number = 20;
		//筆の太さの幅(太さ-太さの幅=最小の太さ)
		private var range:Number = 12;
		//筆の変化幅
		private var limitDistance:Number = 30;

		public function Shodo(w:Number = 100,h:Number = 100) 
		{
			initPaper(w,h);
		}
		// **************************************** 表示領域の初期化
		private function initPaper(w,h):void
		{
			//半紙を配置する
			paper = new Sprite();
			addChild(paper);
			paper.graphics.beginFill(0xffffff);
			paper.graphics.drawRect(0, 0, w, h);
			//マウスが半紙上で押されるのを検知
			paper.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
		}
		
		// **************************************** マウスが押された。
		private function mouseDownHandler(e:MouseEvent):void 
		{
			//マウスの動きを検知
			addEventListener(MouseEvent.MOUSE_MOVE,mouseMoveHandler)
			//ステージにマウスボタンが離されるリスナーを配置
			stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
			//筆を置いたときのイメージを置いた座標に配置
			var hajime:Hajime = new Hajime();
			hajime.x = paper.mouseX;
			hajime.y = paper.mouseY;
			paper.addChild(hajime);
			//座標の履歴をとりあえず格納
			oldX1 = paper.mouseX;
			oldY1 = paper.mouseY;
			oldX2 = paper.mouseX;
			oldY2 = paper.mouseY;
			oldW = strength;
		}
		// **************************************** マウスが離された。
		private function mouseUpHandler(e:MouseEvent):void 
		{
			//リスナーを削除
			removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler)
			//前座標と前々座標の距離、角度、拡大率を求める。
			var distance:Number = Math.sqrt((oldX1 - oldX2) * (oldX1 - oldX2) + (oldY1 - oldY2) * (oldY1 - oldY2));
			var deg:Number = Math.atan2(oldY1 - oldY2, oldX1 - oldX2) * 180 / Math.PI;
			var scale:Number = oldW / strength;
			//マウスボタンを離す前の2座標の距離に応じて、トメやハライのイメージを配置する。
			var postfix:Sprite;
			if (distance > 25) {
				postfix = new Harai();
			} else if (distance > 10) {
				postfix = new Hane();
			} else {
				postfix = new Tome();
			}
			postfix.x = oldX1;
			postfix.y = oldY1;
			postfix.scaleX = postfix.scaleY = scale;
			postfix.rotation = deg;
			paper.addChild(postfix);
		}
		// **************************************** マウスが動いた
		private function mouseMoveHandler(e:MouseEvent):void 
		{
			//前座標との距離、角度を求める。幅wも適当に求める。(変化幅以上に移動していたら最大細さ。それ以内はそれに比例した細さ。)
			var distance:Number = Math.sqrt((paper.mouseX - oldX1) * (paper.mouseX - oldX1) + (paper.mouseY - oldY1) * (paper.mouseY - oldY1));
			var w:Number = distance > limitDistance?(strength - range):(strength - range * distance / limitDistance);
			var deg:Number = Math.atan2(paper.mouseY - oldY1, paper.mouseX - oldX1) * 180 / Math.PI;
			//原点に下底前幅、上底現幅、高さ現距離の台形を描き(エルボーとして前幅の円も原点に配置)、
			var s:Sprite = new Sprite();
			s.graphics.beginFill(0, 1);
			s.graphics.drawCircle(0, 0, oldW / 2);
			s.graphics.endFill()
			s.graphics.beginFill(0, 1);
			s.graphics.moveTo(0, -oldW / 2)
			s.graphics.lineTo(distance, -w / 2);
			s.graphics.lineTo(distance, w / 2);
			s.graphics.lineTo(0, oldW / 2);
			s.graphics.lineTo(0, -oldW / 2)
			s.graphics.endFill()
			//前座標に求めた角度に回転させて配置する。
			s.rotation = deg;
			s.x = oldX1;
			s.y = oldY1;
			paper.addChild(s);
			//履歴を格納
			oldX2 = oldX1;
			oldY2 = oldY1;
			oldX1 = paper.mouseX;
			oldY1 = paper.mouseY;
			oldW = w;
		}
		// **************************************** 半紙クリアのメソッド
		public function clearPaper() {
			for (var i:int = paper.numChildren; i > 0; i--)
			{
				paper.removeChildAt(i - 1);
			}
		}
	}
}

使い方は

//Shodoを作成
shodo = new Shodo(480,330);
addChild(shodo);
//枠を描く
var f:Sprite = new Sprite();
f.graphics.lineStyle(0,0x666666);
f.graphics.drawRect(0,0,480,330);
addChild(f);
//ボタンを配置
var clearBtn:Button = new Button()
clearBtn.y = 336;
clearBtn.label = 'clear';
clearBtn.addEventListener(MouseEvent.CLICK,onClickHandler)
addChild(clearBtn);

function onClickHandler(e:MouseEvent):void {
	shodo.clearPaper();
}

こんな感じです。筆圧感知ができないと思うので(マウスが前提ですし...)移動した距離によって(すなわちマウスの速さによって)線の太さを決めています。早く動かすと細くなるイメージで、そこは適当に計算して決めています。

イメージだけのクラスの作成に悩んでしまったので、トメ、ハネ、ハライ、ハジメのイメージはFLA内でそれぞれTome,Hane,Harai,Hajimeの名前でActionScriptに書き出ししています。

No TrackBacks

TrackBack URL: http://www.norisuke.jp/mt/mt-tb.cgi/11

1 Comment

Your publishis an inspiration for me to study more about this topic. I must concede your lucidity widened my views and I will forthwith snatch your rss feed to remain up to date on any incoming articles you might publish.

Leave a comment

About this Entry

This page contains a single entry by ノリスケ published on April 6, 2009 11:00 PM.

FileReference でうまくダウンロードできない was the previous entry in this blog.

Find recent content on the main index or look in the archives to find all content.

Categories

Pages

Powered by Movable Type 4.21-en