JavaScriptを色々あれこれしようとするがひたすら失敗を繰り返している
| Revision | 1 (tree) |
|---|---|
| Time | 2016-11-12 07:36:43 |
| Author | |
File Drop, Browser上での要素の操作まで
Edgeでの確認のみ
| @@ -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 |
| @@ -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 |
| @@ -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 | +} |
| @@ -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 | + |
| @@ -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 |
| @@ -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 |
| @@ -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 | +} |
| @@ -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 |
| @@ -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 |
| @@ -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 | +})(); |
| @@ -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> |
| @@ -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 | +*/ |