• R/O
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

JavaScriptを色々あれこれしようとするがひたすら失敗を繰り返している


Commit MetaInfo

Revision1 (tree)
Time2016-11-12 07:36:43
Authortakoyaki_umaaaa

Log Message

File Drop, Browser上での要素の操作まで
Edgeでの確認のみ

Change Summary

Incremental Difference

--- HtmlDrawApp/src/CommandMgr.js (nonexistent)
+++ HtmlDrawApp/src/CommandMgr.js (revision 1)
@@ -0,0 +1,146 @@
1+// Worker thread
2+// Command処理を実行する
3+// ・Queuing command.
4+// ・To process the command sequentially.
5+// ・And stack to undo list.
6+
7+// cmdAddress宛先に対応するcmd送信処理関数
8+// DispObj GroupObj CommandMgr ObjIDMgr DispField Dialog InputMgr SaveLoadMgr
9+const eachDestOfFuncTbl = [cmdSendUiThread, cmdSendUiThread, cmdSendCommandMgr, cmdSendUiThread, cmdSendUiThread, cmdSendUiThread, cmdSendUiThread, cmdSendSaveLoadMgr];
10+
11+// UI threadにcmd情報を送信
12+// (InstanceがUI threadにあるobjに対して使用する)
13+function cmdSendUiThread(cmdObj){
14+ // 宛先の実体がUI thread側にあるものは、一律postMessageでcommandを送り付ける
15+ self.postToUI.post(cmdObj);
16+}
17+function cmdSendCommandMgr(cmdObj){
18+}
19+function cmdSendSaveLoadMgr(cmdObj){
20+}
21+
22+
23+
24+// commandごとに undo commandの作成処理関数を登録
25+const cmdUndoFunc = [];
26+cmdUndoFunc[cmdCmd.createTextbox] = undoCreateTextbox;
27+cmdUndoFunc[cmdCmd.createImagebox] = undoCreateImagebox;
28+cmdUndoFunc[cmdCmd.movebox] = undoMovebox;
29+cmdUndoFunc[cmdCmd.scalebox] = undoScalebox;
30+cmdUndoFunc[cmdCmd.rollbox] = undoRollbox;
31+cmdUndoFunc[cmdCmd.deleteTextbox] = undoDeleteTextbox;
32+cmdUndoFunc[cmdCmd.deleteImagebox] = undoDeleteImagebox;
33+
34+
35+// Undoコマンド作成関数
36+function undoCreateTextbox (cmd) {
37+ debuglog("undoCreateTextbox");
38+ var undoCmd = new CCommandObj();
39+ undoCmd.createCommand( cmdType.request, cmd.from, cmd.to, cmdCmd.deleteTextbox, cmd.param1, cmd.param2, cmd.msgID );
40+ return undoCmd;
41+}
42+function undoCreateImagebox (cmd) {
43+}
44+function undoMovebox (cmd) {
45+ debuglog("undoMovebox");
46+ var undoCmd = new CCommandObj();
47+ // dummy
48+ undoCmd.createCommand( cmdType.request, cmd.from, cmd.to, cmdCmd.deleteTextbox, cmd.param1, cmd.param2, cmd.msgID );
49+ return undoCmd;
50+}
51+function undoScalebox (cmd) {
52+ debuglog("undoScalebox");
53+ var undoCmd = new CCommandObj();
54+ // dummy
55+ undoCmd.createCommand( cmdType.request, cmd.from, cmd.to, cmdCmd.deleteTextbox, cmd.param1, cmd.param2, cmd.msgID );
56+ return undoCmd;
57+}
58+function undoRollbox (cmd) {
59+ debuglog("undoRollbox");
60+ var undoCmd = new CCommandObj();
61+ // dummy
62+ undoCmd.createCommand( cmdType.request, cmd.from, cmd.to, cmdCmd.deleteTextbox, cmd.param1, cmd.param2, cmd.msgID );
63+ return undoCmd;
64+}
65+function undoDeleteTextbox (cmd) {
66+}
67+function undoDeleteImagebox (cmd) {
68+}
69+
70+
71+
72+
73+
74+class CCommandMgr {
75+ constructor(){
76+ this.cmdProcessTbl = {};
77+ this.cmdQue = new Queue();
78+ this.undoQue = new Queue();
79+ }
80+
81+ debuglog (str) {
82+ debuglog("【CommandMgr】 " + str);
83+ }
84+
85+
86+ // コマンド要求してもらうためのI/F関数
87+ requestCommand (cmdObj) {
88+ this.debuglog( "requestCommand()" );
89+
90+ // 処理予約queueにコマンド インスタンスを登録
91+ this.cmdQue.enqueue( cmdObj );
92+
93+ return true;
94+ }
95+
96+ // cmdQueにある Commandを処理
97+ processCommands () {
98+ // Queに cmdが溜まっている場合はここで処理
99+ // その間 UI threadから要求があった場合は threadの Msg queに溜まる
100+ // (Receiveできないため)
101+ while( 0 < this.cmdQue.size() ){
102+ this.processSingleCommand();
103+ }
104+ }
105+ // cmdQueに積まれた commandを1回処理
106+ // (worker thread の onmessage event handlerから呼び出される)
107+ processSingleCommand () {
108+ if( this.cmdQue.size() < 1 ){
109+ this.debugLog("processCommand() cmdQue is empty!");
110+ return;
111+ }
112+
113+ let cmdObj = null;
114+ cmdObj = this.cmdQue.dequeue();
115+ this.debuglog( "processCommand() dequeue." );
116+
117+ // cmd内部処理実行
118+ this.cmdProcess( cmdObj );
119+
120+ // 応答cmd作成
121+ this.cmdCreateResponse( cmdObj );
122+
123+ // Undo情報作成
124+ this.createUndoInfo( cmdObj );
125+
126+ // cmdの宛先によりcmd送信処理分け
127+ eachDestOfFuncTbl[ cmdObj.to ]( cmdObj );
128+ }
129+
130+
131+ // 以降、private method -----------------
132+ cmdProcess ( cmd ) {
133+ // 必要ならここでcmdごとに必要な計算を行う
134+ }
135+
136+ cmdCreateResponse ( cmd ) {
137+ cmd.type = cmdType.result;
138+ }
139+
140+ // 処理するcmdから逆操作情報を作成し、Undo queに積む
141+ createUndoInfo ( cmd ) {
142+ this.debuglog("createUndoInfo");
143+ var undoCmd = cmdUndoFunc[ cmd.cmd ]( cmd );
144+ this.undoQue.enqueue( undoCmd );
145+ }
146+} // class CCommandMgr
--- HtmlDrawApp/src/CommandObj.js (nonexistent)
+++ HtmlDrawApp/src/CommandObj.js (revision 1)
@@ -0,0 +1,135 @@
1+const cmdType = {
2+ request : 0,
3+ response : 1,
4+ result : 2,
5+};
6+// commandの送信元,送信先オブジェクト
7+const cmdAddress = {
8+ DispObj : 0,
9+ GroupObj : 1,
10+ CommandMgr : 2,
11+ ObjIDMgr : 3,
12+ DisplayField : 4,
13+ Dialog : 5,
14+ InputMgr : 6,
15+ SaveLoadMgr : 7,
16+ Focus: 8,
17+};
18+const cmdCmd = {
19+ createTextbox : 0,
20+ createImagebox : 1,
21+ movebox : 10,
22+ scalebox: 11,
23+ rollbox: 12,
24+ deleteTextbox : 100,
25+ deleteImagebox : 101,
26+};
27+
28+
29+
30+// Command本体定義
31+// Command処理 および postMessageでのデータやり取りに使用
32+// postMessageでは methodは送れないためここに methodは定義しないこと (必要ならtext変換してparamで渡し、evalで復元すること)
33+class CCommandObj {
34+ // constructorでは真偽値を返せないので createCommand関数で作成する
35+ constructor(){
36+ const undoList = [];
37+ }
38+
39+ // toには最終到達 moduleを指定する。CommandMgrに要求するわけではないため
40+ createCommand(type, from, to, cmd, param1, param2, param3, msgID){
41+ this.type = type; // 'Request', 'Response', 'Result'
42+ this.msgID = msgID; // msgID from postMessage (1~) 2つ以上のsequenceが同時に走るとき、処理が識別できれば(重複IDにならなければ)なんでもOK
43+ this.from = from;
44+ this.to = to;
45+ this.cmd = cmd;
46+ this.param1 = param1;
47+ this.param2 = param2;
48+ this.param3 = param3;
49+
50+// return checkCommandInfo();
51+
52+ debuglog( "createCommand" );
53+ debuglog( this );
54+ return true;
55+ }
56+
57+ outputLog () {
58+ debuglog("commandObj data ------------\ntype=" + this.type + ", msgID=" + this.msgID + ",\nfrom=" + this.from +", to=" + this.to + ",\ncmd=" + this.cmd + ", praram1=" + this.param1 + ", param2=" + this.param2 + ", param3=" + this.param3 + "\n---------------------------------");
59+ }
60+
61+ // 設定されたコマンド情報の正当性チェック
62+ // 先に内部変数に値を入れてから呼び出すこと
63+ checkCommandInfo(){
64+ let retFrom = checkInfoFrom();
65+ let retTo = checkInfoTo();
66+ let retCmd = checkInfoCmd();
67+ let retParam1 = checkInfoParam1();
68+ let retParam2 = checkInfoParam2();
69+
70+ if( true == retFrom
71+ && true == retTo
72+ && true == retCmd
73+ && true == retParam1
74+ && true == retParam2 )
75+ {
76+ return true;
77+ }
78+ else {
79+ return false;
80+ }
81+ }
82+ checkInfoFrom(){
83+ let ret = checkCmdFromTo(this.from);
84+ if( false == ret ){
85+ // 指定された Command発行元ID誤り
86+ console.log("Cmd From ID Error.");
87+ console.log( this );
88+ return false;
89+ }
90+ return true;
91+ }
92+ checkInfoTo(){
93+ let ret = checkCmdFromTo(this.to);
94+ if( false == ret ){
95+ // 指定された Command発行元ID誤り
96+ console.log("Cmd To ID Error.");
97+ console.log( this );
98+ return false;
99+ }
100+ return true;
101+ }
102+ // 送信先,送信元確認用
103+ checkCmdFromTo(str){
104+ let fromto = getFromToStr(str);
105+ if( null == fromto ){
106+ console.log("cmdmgr error. fromto=" + str);
107+ return false;
108+ }
109+ // 抽出文字が送信先ごと関数tblに要素として存在するか確認
110+ if( !fromto in eachDestOfFuncTbl ){
111+ console.log("cmdmgr error. 要素がFuncTblにない fromto=" + str);
112+ return false;
113+ }
114+ if( null == eachDestOfFuncTbl[fromto] ){
115+ console.log("cmdmgr error. FuncTblにfunc未登録 fromto=" + str);
116+ return false;
117+ }
118+ return true;
119+ }
120+ checkInfoCmd(){
121+ return true;
122+ }
123+ checkInfoParam1(){
124+ return true;
125+ }
126+ checkInfoParam2(){
127+ return true;
128+ }
129+ getFromToStr(str){
130+ // 数字部分以外を抽出
131+ let index = /[^0-9]/.exec(str);
132+ if( index.index < 1 ) return null;
133+ return index;
134+ }
135+} // class CCommandObj
--- HtmlDrawApp/src/Common.js (nonexistent)
+++ HtmlDrawApp/src/Common.js (revision 1)
@@ -0,0 +1,39 @@
1+// 汎用処理定義
2+// この sourceは UI thread, Worker threadのそれぞれから呼び出される
3+
4+var DEBUGLOG = true;
5+debuglog = (true==DEBUGLOG)? debugLog : logQuiet;
6+
7+function debugLog(str) {
8+ console.log(str);
9+}
10+function logQuiet(str) {
11+ // 処理なし
12+}
13+
14+
15+
16+function rectData( left, top, right, bottom ) {
17+ this.setData( left, top, right, bottom );
18+};
19+rectData.prototype.setData = function ( left, top, right, bottom ) {
20+ this.left = parseInt(left);
21+ this.top = parseInt(top);
22+ this.right = parseInt(right);
23+ this.bottom = parseInt(bottom);
24+};
25+rectData.prototype.setLTWH = function ( left, top, width, height ) {
26+ this.left = parseInt(left);
27+ this.top = parseInt(top);
28+ this.right = this.left + parseInt(width);
29+ this.bottom = this.top + parseInt(height);
30+}
31+
32+
33+function angle (x1, y1, x2, y2) {
34+ let theta = Math.atan2( y2 - y1, x2 - x1 );
35+ if( theta < 0 ) {
36+ theta = theta + 2 * Math.PI;
37+ }
38+ return (theta * 360 / (2 * Math.PI)-90); // atan2は X軸基準での角度を出すため、画面表示系の Y軸基準に合わせるため 90を減算する
39+}
--- HtmlDrawApp/src/DispObj.js (nonexistent)
+++ HtmlDrawApp/src/DispObj.js (revision 1)
@@ -0,0 +1,263 @@
1+
2+class CDispObj {
3+ constructor(){
4+ this.ObjID = 0;
5+ this.GroupID = 0;
6+ this.type = 0;
7+ this.x = 0.0;
8+ this.y = 0.0;
9+ this.width = 0.0;
10+ this.height = 0.0;
11+ this.opacity = 1.0;
12+ this.degree = 0;
13+ this.text = null;
14+ this.transformStr = null;
15+ this.DOMobject = null;
16+ this.renderFunc = new Queue();
17+
18+ this.dropinitsize = 100.0;
19+ }
20+
21+ debuglog (str) {
22+ debuglog("【DispObj " + this.ObjID + "】" + str);
23+ }
24+
25+
26+
27+ // ブラウザ上への描画 -------------------------
28+
29+ // コマンド要求実行後の描画共通処理
30+ // requestAnimationFrameのcallbackから呼び出される
31+ render () {
32+ while( 0 < this.renderFunc.size() ){
33+ this.debuglog("render() renderFunc size=" + this.renderFunc.size());
34+ let renderFunction = this.renderFunc.dequeue();
35+ renderFunction();
36+ }
37+ }
38+
39+ // コマンド実行処理 -----------------------------
40+
41+ // DIV Box作成
42+ // 作成 ObjIDMgrへの登録も行う
43+ create (type, rect, opt1) {
44+ this.debuglog( "DispObj.Create() called. type=" + type + ", left=" + rect.left + ", top=" + rect.top + ", right=" + rect.right + ", bottom=" + rect.bottom );
45+ let ret = this.checkType( type );
46+ if( false == ret ){
47+ console.error("【CDispObj XX】 create() object type error. type = " + type);
48+ return false;
49+ }
50+ this.type = type;
51+
52+ // ObjIDMgrへ 自身の登録
53+ this.ObjID = window.ObjIDMgr.registerDispObj(this);
54+ if( this.ObjID < 0 ){
55+ console.error("【CDispObj XX】 create() ObjID error. ObjID = " + this.ObjID);
56+ return false;
57+ }
58+ // サイズ設定
59+ this.x = rect.left;
60+ this.y = rect.top;
61+ this.width = rect.right - rect.left;
62+ this.height = rect.bottom - rect.top;
63+
64+ // 画面に影響しない範囲で作成できるところまで Dom objectを作成する
65+ let elType = ( null != type.match( /imagebox/ ) )? 'img': 'div';
66+ this.DOMobject = document.createElement(elType);
67+ this.DOMobject.dataset.objid = this.ObjID;
68+ this.DOMobject.addEventListener('mousedown', this.onMouseDown.bind(this), false);
69+ if( null != type.match( /imagebox/ ) ){
70+ // imageの場合、画像読み込み完了後に描画する必要がある
71+ this.loadImage( opt1 );
72+ }
73+ else {
74+ if( null != opt1 ){
75+ this.loadText( opt1 );
76+ }
77+ else {
78+ // 描画呼び出し時に呼び出す関数を登録
79+ this.renderFunc.enqueue( this.renderCreate.bind(this) );
80+ }
81+ }
82+ return true;
83+ }
84+ loadText(file) {
85+ let reader = new FileReader();
86+ // fileを読み込み
87+ reader.readAsText( file ); // UTF-8として読み込み
88+ reader.onload = function (evt) {
89+ this.text = evt.target.result;
90+ // 描画呼び出し時に呼び出す関数を登録
91+ this.renderFunc.enqueue( this.renderCreate.bind(this) );
92+ }.bind(this);
93+ }
94+ loadImage (file) {
95+ let reader = new FileReader();
96+ // fileを読み込み
97+ reader.readAsDataURL( file );
98+ reader.onload = function (evt) {
99+ // src属性にURLをセットして、画像として再度読み込み
100+ this.DOMobject.src = evt.target.result;
101+ this.DOMobject.onload = function (evt) {
102+ // 画像としての読み込み完了後に幅と高さが取れる
103+ //
104+ let rect = this.calcImageWH(parseInt(evt.target.naturalWidth), parseInt(evt.target.naturalHeight));
105+ this.width = rect.right - rect.left;
106+ this.height = rect.bottom - rect.top;
107+ // 表示サイズ取得完了したので画面に表示
108+ this.renderFunc.enqueue( this.renderCreate.bind(this) );
109+ }.bind(this);
110+ }.bind(this);
111+ }
112+ calcImageWH (srcW, srcH) {
113+ let destW = 0;
114+ let destH = 0;
115+ let isLongWidth = (srcW < srcH) ? false : true;
116+ if (isLongWidth) {
117+ let ratio = this.dropinitsize / srcW;
118+ destW = this.dropinitsize;
119+ destH = srcH * ratio;
120+ }
121+ else {
122+ let ratio = this.dropinitsize / srcH;
123+ destH = this.dropinitsize;
124+ destW = srcW * ratio;
125+ }
126+ return new rectData(0, 0, destW, destH);
127+ }
128+ renderCreate () {
129+ this.DOMobject.style.position = "absolute"; // 決め打ち
130+ this.DOMobject.style.left = this.x.toString() + "px";
131+ this.DOMobject.style.top = this.y.toString() + "px";
132+ this.DOMobject.style.width = this.width.toString() + "px";
133+ this.DOMobject.style.height = this.height.toString() + "px";
134+ this.DOMobject.style.border = "1px solid black"; // 指定するI/Fが必要
135+ this.DOMobject.style.backgroundColor = "#cdcdcd";
136+ if( null != this.text ) this.DOMobject.innerHTML = this.text;
137+
138+ document.getElementById('DispField').appendChild(this.DOMobject);
139+
140+ this.debuglog( "renderCreate() left=" + this.DOMobject.style.left
141+ + ", top=" + this.DOMobject.style.top
142+ + ", width=" + this.DOMobject.style.width
143+ + ", height=" + this.DOMobject.style.height
144+ + ", border=" + this.DOMobject.style.border);
145+ }
146+
147+ // DIV box 移動 (移動先確定後の移動)
148+ // ※ Drag中の表示は別で行っている
149+ movebox ( x, y ) {
150+ this.x = x;
151+ this.y = y;
152+ this.renderFunc.enqueue( this.rendermove.bind(this) );
153+
154+ this.debuglog("movebox() x=" + this.x + ", y=" + this.y + ", renderFunc size=" + this.renderFunc.size());
155+ }
156+ rendermove () {
157+ this.DOMobject.style.left = this.x.toString() + "px";
158+ this.DOMobject.style.top = this.y.toString() + "px";
159+ this.DOMobject.style.opacity = this.opacity.toString();
160+
161+ this.debuglog( "rendermove() left=" + this.DOMobject.style.left
162+ + ", top=" + this.DOMobject.style.top
163+ + ", width=" + this.DOMobject.style.width
164+ + ", height=" + this.DOMobject.style.height
165+ + ", border=" + this.DOMobject.style.border);
166+ }
167+
168+ scalebox ( rect ) {
169+ this.x = rect.left;
170+ this.y = rect.top;
171+ this.width = rect.right - rect.left;
172+ this.height = rect.bottom - rect.top;
173+ this.renderFunc.enqueue( this.renderscalebox.bind(this) );
174+ }
175+ renderscalebox () {
176+ this.DOMobject.style.left = this.x.toString() + "px";
177+ this.DOMobject.style.top = this.y.toString() + "px";
178+ this.DOMobject.style.width = this.width.toString() + "px";
179+ this.DOMobject.style.height = this.height.toString() + "px";
180+ this.DOMobject.style.opacity = this.opacity.toString();
181+ }
182+
183+ rollbox (degree) {
184+ this.degree = degree;
185+ this.renderFunc.enqueue( this.renderrollbox.bind(this) );
186+ }
187+ renderrollbox () {
188+ this.DOMobject.style.transform = 'rotateZ(' + this.degree + 'deg);';
189+ }
190+
191+
192+
193+ checkType ( str ) {
194+ return true;
195+ }
196+
197+
198+
199+  
200+
201+ // イベント処理関数 ---------------------------
202+ onMouseDown (evt) {
203+ this.debuglog("onMouseDown");
204+ if( 0 == (evt.buttons & 0x0001) ){ // 左クリックチェック
205+ return;
206+ }
207+ // Mouse eventをDisplayFieldからScalerに渡してもらうように設定
208+ window.displayField.setMouseEventObj( this.mouseMove.bind(this), this.mouseUp.bind(this) );
209+
210+
211+ // Focus設定
212+ evt.target.dataset.focus = "true";
213+ // 移動元として座標を保持
214+ this.startDragX = evt.clientX;
215+ this.startDragY = evt.clientY;
216+
217+ // Focus表示
218+ window.partsFocus.setClingingPartner(this.DOMobject);
219+
220+ }
221+ mouseMove (evt) {
222+ // 画像の仮移動
223+ this.endDragX = evt.clientX;
224+ this.endDragY = evt.clientY;
225+ // 移動量取得
226+ let moveX = this.endDragX - this.startDragX;
227+ let moveY = this.endDragY - this.startDragY;
228+ // dispObjがあった位置からマウス移動分移動させた後の位置取得
229+ moveX = this.x + moveX;
230+ moveY = this.y + moveY;
231+ this.renderFunc.enqueue( this.renderMoveDragging.bind(this, moveX, moveY) );
232+ }
233+ renderMoveDragging (x, y) {
234+ this.DOMobject.style.left = x + "px";
235+ this.DOMobject.style.top = y + "px";
236+ this.DOMobject.style.opacity = 0.4;
237+ }
238+ mouseUp (evt) {
239+ this.debuglog("mouseUp");
240+ // Mouse event処理対象をクリア
241+ window.displayField.setMouseEventObj( null, null );
242+
243+
244+ // 移動元として座標を保持
245+ this.endDragX = evt.clientX;
246+ this.endDragY = evt.clientY;
247+ // 移動量取得
248+ let moveX = this.endDragX - this.startDragX;
249+ let moveY = this.endDragY - this.startDragY;
250+ // dispObjがあった位置からマウス移動分移動させた後の位置取得
251+ let rect = new rectData( this.x + moveX, this.y + moveY, 0, 0 );
252+
253+ // 移動 Command発行
254+ let cmd = new CCommandObj();
255+ cmd.createCommand( cmdType.request, cmdAddress.ObjIDMgr, cmdAddress.ObjIDMgr, cmdCmd.movebox, rect, this.ObjID, 4 );
256+ this.debuglog("postToWorker");
257+ window.postToWorker.post( cmd );
258+ }
259+
260+
261+} // class CDispObj
262+
263+
--- HtmlDrawApp/src/DisplayField.js (nonexistent)
+++ HtmlDrawApp/src/DisplayField.js (revision 1)
@@ -0,0 +1,137 @@
1+
2+
3+class CDisplayField {
4+ constructor (dom) {
5+ this.DOMobject = dom;
6+ this.renderFunc = new Queue();
7+ this.mouseMoveFunc = null;
8+ this.mouseUpFunc = null;
9+ }
10+
11+ debuglog (str) {
12+ debuglog("【DisplayField】" + str);
13+ }
14+
15+ // ■ 初期化
16+ initialize () {
17+ if( null == this.DOMobject ){
18+ console.log("【DisplayField】 initialize() DOMobject is null.");
19+ return false;
20+ }
21+ this.debuglog( "initialize" );
22+ this.DOMobject.addEventListener('mousemove', this.onMouseMove.bind(this), false);
23+ this.DOMobject.addEventListener('mousedown', this.onMouseDown.bind(this), false);
24+ this.DOMobject.addEventListener('mouseup', this.onMouseUp.bind(this), false);
25+ this.DOMobject.addEventListener('dragstart', this.onDragStart.bind(this), false);
26+ this.DOMobject.addEventListener('dragover', this.onDragover.bind(this), false);
27+ this.DOMobject.addEventListener('drop', this.onDrop.bind(this), false);
28+ }
29+
30+ // Mouse eventを処理するObj
31+ setMouseEventObj( mouseMove, mouseUp ){
32+ this.debuglog('setMouseEventObj');
33+
34+ this.mouseMoveFunc = mouseMove;
35+ this.mouseUpFunc = mouseUp;
36+ }
37+
38+ // ブラウザ上への描画 -------------------------
39+ render () {
40+ while( 0 < this.renderFunc.size() ){
41+// this.debuglog("render() renderFunc size=" + this.renderFunc.size());
42+ let renderFunction = this.renderFunc.dequeue();
43+ renderFunction();
44+ }
45+ }
46+
47+
48+
49+ // Event handler -------------------
50+
51+ // ■マウス左ボタン押下 (Drag処理)
52+ onMouseDown (evt) {
53+ }
54+ // ■ マウス移動 (ドラッグ中)
55+ onMouseMove (evt) {
56+ if( null != this.mouseMoveFunc ){
57+ this.mouseMoveFunc(evt);
58+ return;
59+ }
60+ }
61+ // ■ ドロップ処理
62+ onMouseUp (evt) {
63+ if( null != this.mouseUpFunc ){
64+ this.mouseUpFunc(evt);
65+ return;
66+ }
67+ }
68+
69+ // 表示要素の drag & drop禁止
70+ onDragStart (evt) {
71+ evt.preventDefault();
72+ }
73+ onDragover (evt) {
74+// this.debuglog('onDragover');
75+ evt.preventDefault();
76+ evt.dataTransfer.dropEffect = "move";
77+ }
78+ onDrop (evt) {
79+ this.debuglog('onDrop');
80+ evt.stopPropagation(); // event伝播を自分のところで止める(上位に行かなくなる)
81+ evt.stopImmediatePropagation(); // 処理中要素の他のevent listenerを止める
82+ evt.preventDefault(); // 要素既定のdefault動作を止める
83+ let files = evt.dataTransfer.files;
84+ if( !files ) {
85+ console.error('dropされた file listが取得できない' );
86+ return;
87+ }
88+ if( files.length <= 0 ){
89+ this.debuglog( 'drop fileの file list length == 0' );
90+ return;
91+ }
92+ let dropfile = null;
93+ for(var cnt=0; cnt < files.length; cnt++) {
94+ dropfile = files[cnt];
95+ if( null != dropfile.type.match(/image/) ){
96+
97+ // 画像box 作成 command要求
98+ let rect = new rectData( 205, 205, 255, 255 );
99+ var cmd = new CCommandObj();
100+ // Image box 新規作成 command(新規なので objidを指定する箇所はない) 出力先rect, img blob
101+ cmd.createCommand( cmdType.request, cmdAddress.DisplayField, cmdAddress.ObjIDMgr, cmdCmd.createImagebox, rect, dropfile, null, 6 );
102+ window.postToWorker.post( cmd );
103+
104+ break;
105+ }
106+ else if( null != dropfile.type.match(/text\/plain/) ){
107+
108+ // Textbox作成 command要求
109+ let rect = new rectData( 205, 205, 255, 255 );
110+ var cmd = new CCommandObj();
111+ // Text box 新規作成 command(新規なので objidを指定する箇所はない) 出力先rect, txt blob
112+ cmd.createCommand( cmdType.request, cmdAddress.DisplayField, cmdAddress.ObjIDMgr, cmdCmd.createTextbox, rect, dropfile, null, 6 );
113+ window.postToWorker.post( cmd );
114+
115+ break;
116+ }
117+ }
118+ }
119+
120+
121+
122+
123+
124+
125+
126+ // DOM obj → 対応する dispObjへ変換
127+ getDOMtoDispObj( dom ){
128+ if( true == /^DisplayField/.test(dom.dataset.objid ) ) return null; // DisplayFieldを指しているのでreturn
129+ var dispObj = window.ObjIDMgr.getIDtoDispObj( dom.dataset.objid );
130+ if( null == dispObj ){
131+ console.log("dispObj取得失敗 dom.dataset.objid=" + dom.dataset.objid);
132+ return null;
133+ }
134+ return dispObj;
135+ }
136+
137+} // class CDisplayField
--- HtmlDrawApp/src/ObjIDMgr.js (nonexistent)
+++ HtmlDrawApp/src/ObjIDMgr.js (revision 1)
@@ -0,0 +1,74 @@
1+class CObjIDMgr {
2+ constructor () {
3+ this.ObjIDLen = 0;
4+ this.ObjIDarray = {'0':null};
5+ }
6+
7+ debuglog (str) {
8+ debuglog("【ObjIDMgr】 " + str);
9+ }
10+
11+
12+ // DispObj.createから呼び出される
13+ registerDispObj( DispObj ){
14+ if( null == DispObj ){
15+ console.error("RegisterDispObj error. DispObj == null.");
16+ return -1;
17+ }
18+ // 今回作成するDispObjのNumberを保存
19+ let objNumber = this.ObjIDLen;
20+ this.ObjIDarray[objNumber] = DispObj;
21+ // 1件分の登録が完了したら、登録済みObjID数を更新
22+ this.ObjIDLen++;
23+
24+ // 返すのは登録されているNumberになる
25+ return objNumber;
26+ }
27+
28+ renderAll(){
29+ for( let i=0; i < this.ObjIDLen; i++ ){
30+ this.ObjIDarray[i].render();
31+ }
32+ }
33+
34+ // 指定されたIDの実体(への参照)を返す
35+ getIDtoDispObj( id ){
36+ let numId = parseInt( id );
37+ if( this.ObjIDLen <= numId ){
38+ console.error("getIDtoDispObj() 指定されたIDが範囲外 id=" + id + ", numId=" + numId + ", this.ObjIDLen=" + this.ObjIDLen);
39+ return null;
40+ }
41+ return this.ObjIDarray[numId];
42+ }
43+
44+
45+
46+
47+ // Command処理 ----------------------
48+ createDispObj (type, rect, opt) {
49+ this.debuglog("createDispObj");
50+ var obj = new CDispObj();
51+ obj.create( type, rect, opt );
52+ }
53+
54+ movebox (id, rect) {
55+ this.debuglog("movebox id=" + id);
56+ if( id < this.ObjIDLen ) {
57+ this.ObjIDarray[id].movebox( rect.left, rect.top );
58+ }
59+ }
60+
61+ scalebox (id, rect) {
62+ this.debuglog("scalebox id=" + id);
63+ if( id < this.ObjIDLen ) {
64+ this.ObjIDarray[id].scalebox( rect );
65+ }
66+ }
67+
68+ rollbox (id, degree) {
69+ this.debuglog('rollbox id=' + id + ', deg=' + degree );
70+ if( id < this.ObjIDLen ) {
71+ this.ObjIDarray[id].rollbox( degree );
72+ }
73+ }
74+} // class CObjIDMgr
--- HtmlDrawApp/src/Queue.js (nonexistent)
+++ HtmlDrawApp/src/Queue.js (revision 1)
@@ -0,0 +1,29 @@
1+// http://keicode.com/script/scr25.php
2+// からの貰い物 ;´Д`)
3+
4+//
5+// Queue (FIFO)
6+//
7+
8+function Queue() {
9+ this.__a = new Array();
10+}
11+
12+Queue.prototype.enqueue = function(o) {
13+ this.__a.push(o);
14+}
15+
16+Queue.prototype.dequeue = function() {
17+ if( this.__a.length > 0 ) {
18+ return this.__a.shift();
19+ }
20+ return null;
21+}
22+
23+Queue.prototype.size = function() {
24+ return this.__a.length;
25+}
26+
27+Queue.prototype.toString = function() {
28+ return '[' + this.__a.join(',') + ']';
29+}
--- HtmlDrawApp/src/ThreadMessage.js (nonexistent)
+++ HtmlDrawApp/src/ThreadMessage.js (revision 1)
@@ -0,0 +1,51 @@
1+// importScripts()での読み込みは、先に定義がないとエラーになるためこのファイルを作成
2+// (JavaScriptは実行時 型チェックのため定義が前後しても基本的には問題ないが
3+// worker thread用 import関数は読み込みと同時に実行も行うため)
4+
5+
6+// UI thread用 定義
7+// Worker thead起動, post message
8+function postToWorker () {
9+ this.src = "worker_thread.js";
10+ this.workerMain = new Worker(this.src);
11+ this.workerMain.onmessage = null;
12+};
13+postToWorker.prototype.setMessageHandler = function (func) {
14+ this.workerMain.onmessage = func;
15+};
16+postToWorker.prototype.post = function (cmd) {
17+ if( null == cmd ){
18+ console.error("postToUI.post() cmd == null.");
19+ return;
20+ }
21+ if( null == this.workerMain.onmessage ){
22+ console.error("■■ Workerからの Msg handler未設定のまま Workerへ postMessage");
23+ }
24+ debuglog("== UI --> Worker =============\ntype=" + cmd.type + ", msgID=" + cmd.msgID + ",\nfrom=" + cmd.from +", to=" + cmd.to + ",\ncmd=" + cmd.cmd + ", praram1=" + cmd.param1 + ", param2=" + cmd.param2 + ", param3=" + cmd.param3 + "\n=========================");
25+ this.workerMain.postMessage(cmd);
26+};
27+
28+
29+// Worker thread用 定義
30+// Post to UI thread
31+function postToUI () {
32+ self.onmessage = null;
33+}
34+postToUI.prototype.setMessageHandler = function (func) {
35+ self.onmessage = func;
36+}
37+postToUI.prototype.post = function (cmd) {
38+ if( null == cmd ){
39+ console.log("postToUI.post() cmd == null.");
40+ return;
41+ }
42+ if( undefined == cmd ){
43+ console.log("★★ postToUI.post() cmd == undefined");
44+ return;
45+ }
46+ if( null == self.onmessage ){
47+ debuglog("■■ UI threadからの Msg handler未設定のまま UI threadへ postMessage");
48+ }
49+ debuglog("__ Worker --> UI ________________" + "\ntype=" + cmd.type + ", msgID=" + cmd.msgID + ",\nfrom=" + cmd.from +", to=" + cmd.to + ",\ncmd=" + cmd.cmd + ", praram1=" + cmd.param1 + ", param2=" + cmd.param2 + ", param3=" + cmd.param3 + "\n_______________________________");
50+ self.postMessage(cmd);
51+}
\ No newline at end of file
--- HtmlDrawApp/src/UI_parts.js (nonexistent)
+++ HtmlDrawApp/src/UI_parts.js (revision 1)
@@ -0,0 +1,330 @@
1+
2+// [data-focus="true"] の場合のみ CSSで borderを変更したかったが
3+// DOMに直接 style指定するとその指定が最優先となるため CSSで上書きできない
4+// また、図形として borderを指定したい場合もあるため border: noneにもできない
5+// そのため Focus図形を描く専用の DOMを用意する
6+class CPartsFocus {
7+ constructor () {
8+ this.lineWidth = 2;
9+ this.markWidth = 10;
10+ this.num2str = ['focusleft', 'focustop', 'focusright', 'focusbottom'];
11+ this.clingingPartner = null;
12+ this.DOM = [null, null, null, null]; // focus表示用
13+ this.domScaler = null;
14+ this.domRoller = null;
15+ this.renderFunc = new Queue();
16+ }
17+
18+ debuglog (str) {
19+ var focused = (null == this.clingingPartner)? "null" : this.clingingPartner.dataset.objid;
20+ debuglog("【PartsFocus】 focused objid=" + focused + ", " + str);
21+ }
22+
23+
24+ // ブラウザ上への描画 -------------------------
25+
26+ // domの淵を囲むように Focus lineを表示する
27+ // requestAnimationFrameからの呼び出しを想定
28+ render () {
29+ while( 0 < this.renderFunc.size() ){
30+// this.debuglog("render() renderFunc size=" + this.renderFunc.size());
31+ let renderFunction = this.renderFunc.dequeue();
32+ renderFunction();
33+ }
34+
35+ // Drag & Dropを追いかけるための処理
36+ this.renderClinging();
37+ }
38+ renderClinging () {
39+ if( null == this.clingingPartner ) return;
40+
41+ let originX = parseInt(this.clingingPartner.style.width) / 2;
42+ let originY = parseInt(this.clingingPartner.style.height) / 2;
43+
44+ this.renderClingingSetPosition( this.DOM[0], this.getRectLeft(), (originX + this.lineWidth / 2) + 'px', '50%' );
45+ this.renderClingingSetPosition( this.DOM[1], this.getRectTop(), '50%', (originY + this.lineWidth / 2) + 'px' );
46+ this.renderClingingSetPosition( this.DOM[2], this.getRectRight(), (originX - this.lineWidth / 2) * -1 + 'px', '50%' );
47+ this.renderClingingSetPosition( this.DOM[3], this.getRectBottom(), '50%', (originY - this.lineWidth / 2) * -1 + 'px' );
48+ this.renderClingingSetPosition( this.domScaler, this.getRectScaler(), (originX - this.markWidth / 2) * -1 + 'px', (originY - this.markWidth / 2) * -1 + 'px' );
49+// this.renderClingingSetPosition( this.domRoller, this.getRectRoller(), (originX - this.markWidth / 2) * -1 + 'px', (originY + this.markWidth / 2) + 'px');
50+ this.renderClingingSetPosition( this.domRoller, this.getRectRoller(), '50%', (originY + this.markWidth / 2) + 'px');
51+ }
52+ renderClingingSetPosition(dom, rect, ox, oy) {
53+ dom.style.left = rect.left.toString() + "px";
54+ dom.style.top = rect.top.toString() + "px";
55+ dom.style.width = (rect.right - rect.left).toString() + "px";
56+ dom.style.height = (rect.bottom - rect.top).toString() + "px";
57+// dom.style.border = "1px solid blue";
58+ dom.style.transform = this.clingingPartner.style.transform;
59+ dom.style.transformOrigin = ox + ' ' + oy + ';'; // 回転の中心を focus対象の中心点に合わせる
60+ }
61+
62+
63+
64+ // Elementの描画 size取得関数 -------------------------
65+
66+ // Focusとして描画する4つのbar それぞれの サイズ取得
67+ getRectLeft () {
68+ if( null == this.clingingPartner ) return new rectData(0,0,0,0);
69+ let rect = new rectData();
70+ rect.setLTWH(this.clingingPartner.style.left, this.clingingPartner.style.top, this.clingingPartner.style.width, this.clingingPartner.style.height);
71+ rect.left -= this.lineWidth / 2; rect.top -= this.lineWidth / 2;
72+ rect.right = rect.left + this.lineWidth; rect.bottom += this.lineWidth / 2;
73+ return rect;
74+ }
75+ getRectTop () {
76+ if( null == this.clingingPartner ) return new rectData(0,0,0,0);
77+ let rect = new rectData();
78+ rect.setLTWH( this.clingingPartner.style.left, this.clingingPartner.style.top, this.clingingPartner.style.width, this.clingingPartner.style.height );
79+ rect.left += this.lineWidth / 2; rect.top -= this.lineWidth / 2;
80+ rect.right -= this.lineWidth / 2; rect.bottom = rect.top + this.lineWidth;
81+ return rect;
82+ }
83+ getRectRight () {
84+ if( null == this.clingingPartner ) return new rectData(0,0,0,0);
85+ let rect = new rectData();
86+ rect.setLTWH( this.clingingPartner.style.left, this.clingingPartner.style.top, this.clingingPartner.style.width, this.clingingPartner.style.height );
87+ rect.right +=this.lineWidth /2; rect.bottom += this.lineWidth / 2;
88+ rect.left = rect.right - this.lineWidth; rect.top -= this.lineWidth / 2;
89+ return rect;
90+ }
91+ getRectBottom () {
92+ if( null == this.clingingPartner ) return new rectData(0,0,0,0);
93+ let rect = new rectData();
94+ rect.setLTWH( this.clingingPartner.style.left, this.clingingPartner.style.top, this.clingingPartner.style.width, this.clingingPartner.style.height );
95+ rect.right -= this.lineWidth / 2; rect.bottom += this.lineWidth / 2;
96+ rect.left += this.lineWidth / 2; rect.top = rect.bottom - this.lineWidth;
97+ return rect;
98+ }
99+ // 拡大縮小用 右下マーカーの rect取得
100+ getRectScaler () {
101+ if( null == this.clingingPartner ) return new rectData(0,0,0,0);
102+ let centerX = parseInt(this.clingingPartner.style.left) + parseInt(this.clingingPartner.style.width);
103+ let centerY = parseInt(this.clingingPartner.style.top) + parseInt(this.clingingPartner.style.height);
104+ let rect = new rectData();
105+ rect.left = centerX - this.markWidth / 2; rect.top = centerY - this.markWidth / 2;
106+ rect.right = centerX + this.markWidth / 2; rect.bottom = centerY + this.markWidth / 2;
107+ return rect;
108+ }
109+ // 回転用 上辺中心部 マーカーの rect取得
110+ getRectRoller () {
111+ if( null == this.clingingPartner ) return new rectData(0,0,0,0);
112+ let centerX = parseInt(this.clingingPartner.style.left) + parseInt(this.clingingPartner.style.width) / 2;
113+ let centerY = parseInt(this.clingingPartner.style.top);
114+ let rect = new rectData();
115+ rect.left = centerX - this.markWidth / 2; rect.top = centerY - this.markWidth / 2;
116+ rect.right = centerX + this.markWidth / 2; rect.bottom = centerY + this.markWidth / 2;
117+ return rect;
118+ }
119+
120+ // 表示関数-----------------------------------
121+ // Focus作成
122+ create () {
123+ let getRectProperty = [this.getRectLeft.bind(this), this.getRectTop.bind(this), this.getRectRight.bind(this), this.getRectBottom.bind(this)];
124+ for( let cnt=0; cnt < this.num2str.length; cnt++ ) {
125+ this.DOM[cnt] = document.createElement('div');
126+ this.DOM[cnt].dataset.objid = this.num2str[cnt];
127+ this.DOM[cnt].classList.add( 'focusimage' );
128+ this.DOM[cnt].classList.add( this.num2str[cnt] );
129+ this.renderFunc.enqueue( this.renderCreateOneFocusbar.bind(this, this.DOM[cnt], getRectProperty[cnt]()) );
130+ }
131+// this.debuglog("create() renderFunc size=" + this.renderFunc.size());
132+
133+ this.createScaler();
134+ this.createRoller();
135+ }
136+ renderCreateOneFocusbar (dom, rect) {
137+ dom.style.display = (null == this.clingingPartner)? "none" : "block";
138+ dom.style.position = "absolute";
139+ dom.style.left = rect.left.toString() + "px";
140+ dom.style.top = rect.top.toString() + "px";
141+ dom.style.width = (rect.right - rect.left).toString() + "px";
142+ dom.style.height = (rect.bottom - rect.top).toString() + "px";
143+// dom.style.border = "1px solid blue";
144+ document.getElementById('DispField').appendChild(dom);
145+ }
146+
147+
148+ // 拡大縮小操作マーカー作成
149+ createScaler () {
150+ this.domScaler = document.createElement('div');
151+ this.domScaler.dataset.objid = 'scaler';
152+ this.domScaler.classList.add( 'scaler' );
153+ this.domScaler.addEventListener('mousedown', this.onMouseDownScale.bind(this), false);
154+ this.renderFunc.enqueue( this.renderScaler.bind(this,this.getRectScaler()) );
155+ }
156+ renderScaler (rect) {
157+ this.domScaler.style.display = (null == this.clingingPartner)? "none" : "block";
158+ this.domScaler.style.position = 'absolute';
159+ this.domScaler.style.left = rect.left.toString() + "px";
160+ this.domScaler.style.top = rect.top.toString() + "px";
161+ this.domScaler.style.width = (rect.right - rect.left).toString() + "px";
162+ this.domScaler.style.height = (rect.bottom - rect.top).toString() + "px";
163+// this.domScaler.style.border = "1px solid blue";
164+ document.getElementById('DispField').appendChild(this.domScaler);
165+ }
166+
167+ // 回転操作マーカー作成
168+ createRoller () {
169+ this.domRoller = document.createElement('div');
170+ this.domRoller.dataset.objid = 'roller';
171+ this.domRoller.classList.add( 'roller' );
172+ this.domRoller.addEventListener('mousedown', this.onMouseDownRoll.bind(this), false);
173+ this.renderFunc.enqueue( this.renderRoller.bind(this,this.getRectRoller()) );
174+ }
175+ renderRoller (rect) {
176+ this.domRoller.style.display = (null == this.clingingPartner)? "none" : "block";
177+ this.domRoller.style.position = 'absolute';
178+ this.domRoller.style.left = rect.left.toString() + "px";
179+ this.domRoller.style.top = rect.top.toString() + "px";
180+ this.domRoller.style.width = (rect.right - rect.left).toString() + "px";
181+ this.domRoller.style.height = (rect.bottom - rect.top).toString() + "px";
182+// this.domRoller.style.border = "1px solid blue";
183+ document.getElementById('DispField').appendChild(this.domRoller);
184+ }
185+
186+ // 操作関数-----------------------------------
187+ // Forcus先 クリア
188+ clearClingingPartner () {
189+ this.debuglog("setClingingPartner() clear focus.");
190+ this.clingingPartner = null;
191+ // requestAnimationFrameでの描画タイミング中は DOM.outerHTMLを変更できないため
192+ // 処理ロジック上のまま削除処理を実行する
193+// this.renderFunc.enqueue( this.renderClearClingingPartner.bind(this) );
194+ this.debuglog("clearClingingPartner() renderFunc size=" + this.renderFunc.size());
195+
196+ this.renderClearClingingPartner();
197+ }
198+ renderClearClingingPartner () {
199+ this.debuglog("renderClearClingingPartner()");
200+
201+ for( let cnt=0; cnt < this.num2str.length; cnt++ ) {
202+ if( null != this.DOM[cnt] ){
203+ this.DOM[cnt].outerHTML = "";
204+ delete this.DOM[cnt];
205+ this.DOM[cnt] = null;
206+ }
207+ }
208+
209+ if( null != this.domScaler ) {
210+ this.domScaler.outerHTML = "";
211+ delete this.domScaler;
212+ this.domScaler = null;
213+ }
214+ if( null != this.domRoller ) {
215+ this.domRoller.outerHTML = "";
216+ delete this.domRoller;
217+ this.domRoller = null;
218+ }
219+ }
220+
221+ // Forcus先設定
222+ setClingingPartner (dom) {
223+ this.debuglog("setClingingPartner()");
224+
225+ // Focus先 クリア
226+ if( null == dom ){
227+ this.clearClingingPartner();
228+ return;
229+ }
230+ // Focus先 変更
231+ else if( this.clingingPartner != dom) {
232+ // 現在の情報をクリア
233+ this.clearClingingPartner();
234+ // 新しいFocus先に変更
235+ this.clingingPartner = dom;
236+ this.create();
237+ }
238+ }
239+
240+
241+ // Event handler -------------------------
242+ onMouseDownScale (evt) {
243+ this.debuglog('onMouseDownScale');
244+
245+ // Mouse eventをDisplayFieldからScalerに渡してもらうように設定
246+ window.displayField.setMouseEventObj( this.mouseMoveScale.bind(this), this.mouseUpScale.bind(this) );
247+
248+ // 移動元として座標を保持
249+ this.scaleStartWidth = parseInt(this.clingingPartner.style.width);
250+ this.scaleStartHeight = parseInt(this.clingingPartner.style.height);
251+ this.startDragX = evt.clientX;
252+ this.startDragY = evt.clientY;
253+ }
254+ mouseMoveScale (evt) {
255+ // 画像の仮変形
256+ this.endDragX = evt.clientX;
257+ this.endDragY = evt.clientY;
258+ // 移動量取得
259+ let moveX = this.endDragX - this.startDragX;
260+ let moveY = this.endDragY - this.startDragY;
261+ this.renderFunc.enqueue( this.renderMouseMoveScale.bind(this, this.scaleStartWidth + moveX, this.scaleStartHeight + moveY) );
262+ }
263+ renderMouseMoveScale (width, height) {
264+ this.clingingPartner.style.width = width + "px";
265+ this.clingingPartner.style.height = height + "px";
266+ this.clingingPartner.style.opacity = 0.4;
267+ }
268+ mouseUpScale (evt) {
269+ this.debuglog('mouseUpScale');
270+ // Mouse event callback設定をクリア
271+ window.displayField.setMouseEventObj( null, null );
272+
273+ // 画像の仮変形
274+ this.endDragX = evt.clientX;
275+ this.endDragY = evt.clientY;
276+ // 移動量取得
277+ let moveX = this.endDragX - this.startDragX;
278+ let moveY = this.endDragY - this.startDragY;
279+
280+ let rectFrom = new rectData();
281+ let rectTo = new rectData();
282+ rectFrom.setLTWH( parseInt(this.clingingPartner.style.left), parseInt(this.clingingPartner.style.top), this.scaleStartWidth, this.scaleStartHeight);
283+ rectTo.setLTWH( rectFrom.left, rectFrom.top, this.scaleStartWidth + moveX, this.scaleStartHeight + moveY);
284+
285+ // Scale Command発行
286+ let cmd = new CCommandObj();
287+ cmd.createCommand( cmdType.request, cmdAddress.Focus, cmdAddress.ObjIDMgr, cmdCmd.scalebox, this.clingingPartner.dataset.objid, rectFrom, rectTo, 5 );
288+ this.debuglog("postToWorker");
289+ window.postToWorker.post( cmd );
290+ }
291+
292+ onMouseDownRoll (evt) {
293+ this.debuglog('onMouseDownRoll');
294+
295+ // Mouse eventをDisplayFieldからRollerに渡してもらうように設定
296+ window.displayField.setMouseEventObj( this.mouseMoveRoll.bind(this), this.mouseUpRoll.bind(this) );
297+ }
298+ mouseMoveRoll (evt) {
299+ let x1 = parseInt(this.clingingPartner.style.left) + parseInt(this.clingingPartner.style.width) / 2;
300+ let y1 = parseInt(this.clingingPartner.style.top) + parseInt(this.clingingPartner.style.height) / 2;
301+ let x2 = evt.clientX;
302+ let y2 = evt.clientY;
303+ let degree = angle( x2, y2, x1, y1 );
304+
305+ this.renderFunc.enqueue( this.renderMouseMoveRoll.bind(this, degree) );
306+ }
307+ renderMouseMoveRoll (degree) {
308+ this.clingingPartner.style.transform = 'rotateZ(' + degree + 'deg);';
309+ }
310+ mouseUpRoll (evt) {
311+ this.debuglog('mouseUpRoll');
312+ // Mouse event callback設定をクリア
313+ window.displayField.setMouseEventObj( null, null );
314+
315+ let x1 = parseInt(this.clingingPartner.style.left) + parseInt(this.clingingPartner.style.width) / 2;
316+ let y1 = parseInt(this.clingingPartner.style.top) + parseInt(this.clingingPartner.style.height) / 2;
317+ let x2 = evt.clientX;
318+ let y2 = evt.clientY;
319+ let degree = angle( x2, y2, x1, y1 );
320+// this.debuglog('■■ x1=' + x1 + ', y1=' + y1 + ',\nx2=' + x2 + ', y2=' + y2 + '\nangle=' + degree);
321+// window.ObjIDMgr.rollbox( this.clingingPartner.dataset.objid, degree ); // debug用 設定情報で直接表示
322+
323+ // Rotate command発行
324+ let cmd = new CCommandObj();
325+ cmd.createCommand( cmdType.request, cmdAddress.Focus, cmdAddress.ObjIDMgr, cmdCmd.rollbox, this.clingingPartner.dataset.objid, degree, null, 6);
326+ this.debuglog("postToWorker");
327+ window.postToWorker.post( cmd );
328+ }
329+
330+} // class CPartsFocus
--- HtmlDrawApp/src/UI_thread.js (nonexistent)
+++ HtmlDrawApp/src/UI_thread.js (revision 1)
@@ -0,0 +1,149 @@
1+
2+(function () {
3+ "use strict";
4+
5+
6+ // onLoadイベントも待つ
7+ document.addEventListener('load', onLoadStartHTML, false);
8+ function onLoadStartHTML(){
9+ console.log("onload");
10+ }
11+
12+
13+
14+ // worker_main thread起動
15+ window.postToWorker = new postToWorker();
16+ window.postToWorker.setMessageHandler( receiveWorkerMessage );
17+
18+
19+ // UI thread初期化
20+
21+ // Mgr obj生成
22+ // Create Mgr---
23+ var dom = document.getElementById( "DispField" );
24+ window.displayField = new CDisplayField(dom);
25+ window.displayField.initialize();
26+ window.ObjIDMgr = new CObjIDMgr();
27+ // -------------
28+ // 選択 itemの focus状態表示用
29+ // MouseDownで Focus移動
30+ window.partsFocus = new CPartsFocus();
31+
32+ // 固定設置 palette button ------------------
33+ let palButtonlist = document.getElementsByClassName( 'pal' );
34+ for( let cnt=0; cnt < palButtonlist.length; cnt++ ){
35+ palButtonlist[cnt].addEventListener( 'click', onClickPalButton, false );
36+ }
37+
38+
39+
40+ // --- test code -------
41+ var rect = new rectData( 105, 105, 155, 155 );
42+ var obj1 = new CCommandObj();
43+ obj1.createCommand( cmdType.request, cmdAddress.ObjIDMgr, cmdAddress.ObjIDMgr, cmdCmd.createTextbox, rect, null, 1 );
44+ window.postToWorker.post( obj1 );
45+ // ----------------------
46+ rect.setData( 110, 110, 160, 160 );
47+ var obj3 = new CCommandObj();
48+ obj3.createCommand( cmdType.request, cmdAddress.ObjIDMgr, cmdAddress.ObjIDMgr, cmdCmd.createTextbox, rect, null, 1 );
49+ window.postToWorker.post( obj3 );
50+
51+ // ----------------------
52+ rect.setData( 150, 150, 0, 0 );
53+ var obj4 = new CCommandObj();
54+ obj4.createCommand( cmdType.request, cmdAddress.ObjIDMgr, cmdAddress.ObjIDMgr, cmdCmd.movebox, rect, 0, 2 );
55+ window.postToWorker.post( obj4 );
56+
57+
58+
59+
60+
61+
62+
63+ // 画像読み込み等は待たずに実行開始
64+ window.startTime = window.performance.now();
65+ window.frameLength = 6.0;
66+ // 描画用無限ループ
67+ (function renderLoop () {
68+ let nowTime = window.performance.now();
69+// let frame = Math.floor((nowTime - window.startTime) / (1000.0 / 60.0) % window.frameLength);
70+
71+ window.displayField.render();
72+ window.ObjIDMgr.renderAll();
73+
74+ window.partsFocus.render();
75+
76+ requestAnimationFrame( renderLoop );
77+ })();
78+
79+
80+
81+
82+ // worker threadからの Message受信関数
83+ // UI threadで処理が必要な commandが送られてくる
84+ function receiveWorkerMessage (evt) {
85+ debuglog("receiveWorkerMessage() cmdReceive.");
86+ debuglog( evt.data );
87+
88+ // commandの宛先ごとにcommand処理関数をテーブル化
89+ // DispObj GroupObj CommandMgr ObjIDMgr DispField Dialog InputMgr SaveLoadMgr
90+ const executeCmdFunc = [executeCmdErr, executeCmdErr, executeCmdErr, executeCmdObjIdMgr, executeCmdDispField, executeCmdDialog, executeCmdInputMgr, executeCmdSaveLoadMgr];
91+ executeCmdFunc[ evt.data.to ]( evt.data );
92+ }
93+
94+ // command宛先の実体が worker thread側にあるにも関わらず、commandが UI threadに送られてきた場合のエラー出力
95+ function executeCmdErr (cmd) {
96+ console.log("[UI thread] cmd error.");
97+ console.log( cmd );
98+ }
99+ function executeCmdObjIdMgr (cmd) {
100+ debuglog("executeCmdObjIdMgr");
101+
102+ switch(cmd.cmd){
103+ case cmdCmd.createTextbox: // Text box新規作成 (新規作成なので ObjIDは指定しない)
104+ // type, rect text blob
105+ window.ObjIDMgr.createDispObj("textbox", cmd.param1, cmd.param2);
106+ break;
107+ case cmdCmd.createImagebox: // Image box新規作成 (新規作成なので ObjIDは指定しない)
108+ // type, rect image blob
109+ window.ObjIDMgr.createDispObj("imagebox", cmd.param1, cmd.param2);
110+ break;
111+ case cmdCmd.movebox: // 移動
112+ // objid rect
113+ window.ObjIDMgr.movebox(cmd.param2, cmd.param1);
114+ break;
115+ case cmdCmd.scalebox: // 拡大縮小
116+ // objid rect
117+ window.ObjIDMgr.scalebox(cmd.param1, cmd.param3);
118+ break;
119+ case cmdCmd.rollbox: // 回転
120+ // objid degree
121+ window.ObjIDMgr.rollbox(cmd.param1, cmd.param2);
122+ break;
123+ case cmdCmd.deletebox:
124+ break;
125+ default:
126+ console.error('未定義のコマンド cmd=' + cmd.cmd);
127+ break;
128+ }
129+ }
130+ function executeCmdDispField (cmd) {
131+ debuglog("executeCmdDispField");
132+ }
133+ function executeCmdDialog (cmd) {
134+ debuglog("executeCmdDialog");
135+ }
136+ function executeCmdInputMgr (cmd) {
137+ debuglog("executeCmdInputMgr");
138+ }
139+ function executeCmdSaveLoadMgr (cmd) {
140+ debuglog("executeCmdSaveLoadMgr");
141+ }
142+
143+
144+
145+
146+
147+
148+
149+})();
--- HtmlDrawApp/src/index.html (nonexistent)
+++ HtmlDrawApp/src/index.html (revision 1)
@@ -0,0 +1,98 @@
1+<!DOCTYPE html>
2+<html lang="ja">
3+<head>
4+ <meta charset="UTF-8">
5+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
6+ <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1.5, minimum-scale=0.1, width=device-width, height=device-height">
7+ <title></title>
8+ <!--script type="text/javascript" src="js/Splash.js"></script-->
9+
10+ <!--link rel="stylesheet" href="style.css"-->
11+ <style>
12+ *, *:before, *:after {
13+ -webkit-box-sizing: border-box;
14+ -moz-box-sizing: border-box;
15+ -o-box-sizing: border-box;
16+ -ms-box-sizing: border-box;
17+ box-sizing: border-box;
18+ -webkit-user-select: none;
19+ -khtml-user-select: none;
20+ -moz-user-select: none;
21+ user-select: none;
22+ }
23+/*
24+ [data-objid] {
25+ transition: transform 2s linear 0s;
26+ }
27+*/
28+
29+ #DispField{
30+ display:block;
31+ width:400px; height:300px;
32+ border:1px solid black;
33+ }
34+
35+ .scaler {
36+ border: 2px solid black;
37+ border-radius: 50%;
38+ background-color: orange;
39+ }
40+ .roller {
41+ border: 2px solid black;
42+ border-radius: 50%;
43+ background-color: green;
44+ }
45+
46+ .focusimage {
47+ background-image: linear-gradient(
48+ -45deg,
49+ rgba(255,255,255,0.5),
50+ rgba(255,255,255,0.5) 25%,
51+ rgba(0,0,0,0.5) 26%,
52+ rgba(0,0,0,0.5) 50%,
53+ rgba(255,255,255,0.5) 51%,
54+ rgba(255,255,255,0.5) 75%,
55+ rgba(0,0,0,0.5) 76%,
56+ rgba(0,0,0,0.5) 100%
57+ );
58+ background-size: 8px 8px;
59+ }
60+ .focusleft { animation: animForcus1 3s linear infinite; }
61+ .focusright { animation: animForcus2 3s linear infinite; }
62+ .focustop { animation: animForcus2 3s linear infinite; }
63+ .focusbottom { animation: animForcus1 3s linear infinite; }
64+ @keyframes animForcus1 {
65+ 0% { background-position:0% 0%}
66+ 100% {background-position:100% 100%}
67+ }
68+ @keyframes animForcus2 {
69+ 0% { background-position:100% 100%}
70+ 100% {background-position:0% 0%}
71+ }
72+
73+
74+
75+
76+ </style>
77+</head>
78+<body>
79+ <div id="DispField" data-objid="DisplayField" data-focus="true">
80+ </div>
81+ <button type=button class="pal" data-objid="pal" data-palid="0" data-value="ff000001">button1</button>
82+ <button type=button class="pal" data-objid="pal" data-palid="1" data-value="00ff0001">button2</button>
83+ <button type=button class="pal" data-objid="pal" data-palid="2" data-value="0000ff01">button3</button>
84+ <button type=button class="pal" data-objid="pal" data-palid="3" data-value="ffffff01">button4</button>
85+ <button type=button class="pal" data-objid="pal" data-palid="4" data-value="00000000">button5</button>
86+
87+
88+ <script type="text/javascript" src="Common.js"></script>
89+ <script type="text/javascript" src="Queue.js"></script>
90+ <script type="text/javascript" src="CommandObj.js"></script>
91+ <script type="text/javascript" src="UI_parts.js"></script>
92+ <script type="text/javascript" src="DispObj.js"></script>
93+ <script type="text/javascript" src="ObjIDMgr.js"></script>
94+ <script type="text/javascript" src="ThreadMessage.js"></script>
95+ <script type="text/javascript" src="DisplayField.js"></script>
96+ <script type="text/javascript" src="UI_thread.js"></script>
97+</body>
98+</html>
--- HtmlDrawApp/src/worker_thread.js (nonexistent)
+++ HtmlDrawApp/src/worker_thread.js (revision 1)
@@ -0,0 +1,48 @@
1+
2+// worker threadでのcommand処理に必要な class fileの読み込みと実行
3+// (引数のjs内容の実行も行われる)
4+importScripts('Common.js');
5+importScripts('Queue.js');
6+importScripts('CommandObj.js');
7+importScripts('ThreadMessage.js');
8+importScripts('CommandMgr.js');
9+
10+
11+self.postToUI = new postToUI();
12+self.postToUI.setMessageHandler( receiveUIMessage );
13+
14+
15+var data = new Object();
16+// Worker threadのGrobal object上にpropertyを追加
17+// (window objectではないため、UI threadには見えない)
18+var cmdMgr = new CCommandMgr();
19+
20+/*
21+onmessage = function (evt) {
22+*/
23+function receiveUIMessage (evt) {
24+ "use strict";
25+ console.log("[Worker thread] Message received.");
26+ console.log(evt.data);
27+
28+
29+ // cmdQueに1件追加
30+ cmdMgr.requestCommand(evt.data);
31+
32+ // Command処理
33+ cmdMgr.processCommands();
34+
35+}
36+
37+
38+/*
39+ while ( true ) {
40+ // Command処理
41+ cmdMgr.processCommand();
42+
43+ // 終了条件を作成したい
44+ // postMessageで終了要求受信時
45+ // cmdQue消化完了してから
46+ // Loopを抜ける
47+ }
48+*/