JavaScriptを色々あれこれしようとするがひたすら失敗を繰り返している
| Revision | 30 (tree) |
|---|---|
| Time | 2016-11-26 00:19:48 |
| Author | |
保存ファイル読み込み処理
| @@ -51,6 +51,12 @@ | ||
| 51 | 51 | } |
| 52 | 52 | |
| 53 | 53 | |
| 54 | + .DispObj { | |
| 55 | + display: inline-block; | |
| 56 | + position:absolute; | |
| 57 | + marginj:0; padding:0; | |
| 58 | + } | |
| 59 | + | |
| 54 | 60 | /* パレットグループ要素の定義 */ |
| 55 | 61 | .palgroup { |
| 56 | 62 | display: inline-block; |
| @@ -14,12 +14,12 @@ | ||
| 14 | 14 | <div id="DispField" data-objid="DisplayField" data-focus="true"> |
| 15 | 15 | </div> |
| 16 | 16 | <!-- 固定ボタン (選択要素の削除, 保存, …) --> |
| 17 | - <button type=button class="pal" data-objid="pal" data-palid="0" data-value="0xff000001">削除</button> | |
| 18 | - <button type=button class="pal" data-objid="pal" data-palid="1" data-value="0x00ff0001">設定保存</button> | |
| 19 | - <button type=button class="pal" data-objid="pal" data-palid="2" data-value="0x0000ff01">設定Drop</button> | |
| 20 | - <button type=button class="pal" data-objid="pal" data-palid="3" data-value="0xffffff01">アニメ停止</button> | |
| 21 | - <button type=button class="pal" data-objid="pal" data-palid="4" data-value="0x00000000">button5</button> | |
| 22 | - <a href="#" id="save" download="savefilename.txt">画像保存</a><br /> | |
| 17 | + <button type=button class="pal" data-objid="pal" data-palid="0" title="フォーカス中の要素を削除します">削除</button> | |
| 18 | + <button type=button class="pal" data-objid="pal" data-palid="1" title="現在のパレット設定を保存します">設定保存</button> | |
| 19 | + <button type=button class="pal" data-objid="pal" data-palid="2" title="設定画面を表示します">設定Drop</button> | |
| 20 | + <button type=button class="pal" data-objid="pal" data-palid="3" title="アニメーションを停止します">アニメ停止</button> | |
| 21 | + <button type=button class="pal" data-objid="pal" data-palid="4" >button5</button> | |
| 22 | + <a href="#" id="save" download="DragDraw.dd" title="DragDraw.ddという名前でダウンロードフォルダに保存します">画像保存</a><br /> | |
| 23 | 23 | |
| 24 | 24 | <!-- Palette --> |
| 25 | 25 | <style id="stylepalbg"> |
| @@ -158,7 +158,7 @@ | ||
| 158 | 158 | } |
| 159 | 159 | </style> |
| 160 | 160 | |
| 161 | - <fieldset class="palgroup palgrouphorizon" data-objid="palgroup0"> | |
| 161 | + <fieldset class="palgroup palgrouphorizon" data-objid="palgroup0" title="背景の色や画像を設定するパレットです"> | |
| 162 | 162 | <legend class="pallegend"> Background Palette </legend> |
| 163 | 163 | <div class="palbg palbg0" data-objid="palbg0" data-palid="0"></div> |
| 164 | 164 | <div class="palbg palbg1" data-objid="palbg1" data-palid="1"></div> |
| @@ -168,7 +168,7 @@ | ||
| 168 | 168 | </fieldset> |
| 169 | 169 | <br /> |
| 170 | 170 | |
| 171 | - <fieldset class="palgroup palgrouphorizon" data-objid="palgroup1"> | |
| 171 | + <fieldset class="palgroup palgrouphorizon" data-objid="palgroup1" title="テキストの色を設定するパレットです"> | |
| 172 | 172 | <legend class="pallegend"> Text Color Palette </legend> |
| 173 | 173 | <div class="paltxtcol paltxtcol0" data-objid="paltxtcol0" data-palid="0">あ</div> |
| 174 | 174 | <div class="paltxtcol paltxtcol1" data-objid="paltxtcol1" data-palid="1">あ</div> |
| @@ -179,7 +179,7 @@ | ||
| 179 | 179 | |
| 180 | 180 | <br /> |
| 181 | 181 | |
| 182 | - <fieldset class="palgroup palgrouphorizon" data-objid="palgroup2"> | |
| 182 | + <fieldset class="palgroup palgrouphorizon" data-objid="palgroup2" title="動きを設定するパレットです"> | |
| 183 | 183 | <legend class="pallegend"> Action Palette </legend> |
| 184 | 184 | <div class="palact palact0" data-objid="palact0" data-palid="0"></div> |
| 185 | 185 | <div class="palact palact1" data-objid="palact1" data-palid="1"></div> |
| @@ -10,9 +10,12 @@ | ||
| 10 | 10 | function logQuiet(str) { |
| 11 | 11 | // 処理なし |
| 12 | 12 | }; |
| 13 | +function isStoreApp() { | |
| 14 | + // ★識別方法を知りたい…… | |
| 15 | + return true; | |
| 16 | +}; | |
| 13 | 17 | |
| 14 | 18 | |
| 15 | - | |
| 16 | 19 | function rectData( left, top, right, bottom ) { |
| 17 | 20 | this.setData( left, top, right, bottom ); |
| 18 | 21 | }; |
| @@ -42,6 +45,7 @@ | ||
| 42 | 45 | |
| 43 | 46 | // Image fileを読み込み、その内容を対象CSSに設定 |
| 44 | 47 | // CSSには "'cssstr1' + fileBlob + 'cssstr2'" が設定される |
| 48 | +// image/text共に読み込んだ内容をそのままCSS定義にする | |
| 45 | 49 | function setImageFileToCSS( |
| 46 | 50 | ele, // CSS書き換え対象Element |
| 47 | 51 | num, // 書き換える CSS要素番号 (ele.sheet.cssRules[n] ← このnの値) |
| @@ -61,7 +65,7 @@ | ||
| 61 | 65 | num, // 書き換える CSS要素番号 (ele.sheet.cssRules[n] ← このnの値) |
| 62 | 66 | cssstr1, // CSS書き換え前半文字 |
| 63 | 67 | cssstr2, // CSS書き換え後半文字 |
| 64 | - file // Textファイルを指している file object | |
| 68 | + file // CSS定義が1つだけ入った Textファイルを指している file object | |
| 65 | 69 | ) { |
| 66 | 70 | // drop fileの読み込み |
| 67 | 71 | let reader = new FileReader(); |
| @@ -77,8 +81,122 @@ | ||
| 77 | 81 | ele.sheet.insertRule(csstext, num); |
| 78 | 82 | }; |
| 79 | 83 | |
| 84 | +// CSSに定義をセット | |
| 85 | +function setStrToCSS( | |
| 86 | + ele, // CSS設定先 style object | |
| 87 | + num, // 設定対象添え字 (ele.sheet.cssRule[n] の nの値) | |
| 88 | + str, // 設定する文字列 | |
| 89 | + reg // [option] 抜き出し用 正規表現, または null | |
| 90 | +) { | |
| 91 | + if (null == ele | |
| 92 | + || null == str | |
| 93 | + || ele.sheet.cssRules.length <= num | |
| 94 | + || num < 0) { | |
| 95 | + console.error('CSS定義追加に失敗 setStrToCSS() パラメータエラー'); | |
| 96 | + console.error('setStrToCSS params ele=' + ele + ', num=' + num + ', ele.cssRules num=' + ((null != ele) ? ele.sheet.cssRules.length : 'null') + ', str=' + str); | |
| 97 | + return false; | |
| 98 | + } | |
| 80 | 99 | |
| 100 | + let addText = str; | |
| 101 | + if (null != reg) { | |
| 102 | + let matchstr = str.match(reg); | |
| 103 | + if (null == matchstr) { | |
| 104 | + console.error('CSS定義追加に失敗 setStrToCSS() 追加文字列エラー'); | |
| 105 | + console.error('setStrToCSS match result=' + matchstr + ', reg=' + reg + ', str=' + str); | |
| 106 | + return false ; | |
| 107 | + } | |
| 81 | 108 | |
| 109 | + addText = matchstr[0]; | |
| 110 | + } | |
| 111 | + ele.sheet.deleteRule(num); | |
| 112 | + ele.sheet.insertRule(addText, num); | |
| 113 | + | |
| 114 | + return true; | |
| 115 | +} | |
| 116 | + | |
| 117 | + | |
| 118 | +// 引数elementに設定されたstylesheetから 全 | |
| 119 | +// "animation定義を含むcss", "対応したkeyframe" を取得する | |
| 120 | +// (@keyframe定義がcssTextから取得できないために作成。 | |
| 121 | +// keyframeはcssのtextではないらしい。css仕様を作っている奴らは馬鹿か!) | |
| 122 | +function getAnimationCssFromElement(ele) { | |
| 123 | + let animationrule = null; | |
| 124 | + let keyframename = null; | |
| 125 | + let keyframerule = null; | |
| 126 | + let outstr = ""; | |
| 127 | + | |
| 128 | + debuglog('アクションパレット情報(CSS) 取得開始 getAnimationCssFromElement() ***************'); | |
| 129 | + for (let i = 0; i < ele.sheet.cssRules.length; i++) { | |
| 130 | + animationrule = ele.sheet.cssRules[i]; | |
| 131 | + if (window.CSSRule.STYLE_RULE == animationrule.type) { | |
| 132 | + // animation定義文字列から keyframe nameを探して取得 | |
| 133 | + keyframename = getNameOfKeyframe(animationrule.style.cssText); | |
| 134 | + if (null != keyframename) { | |
| 135 | + // document内の全style sheetから引数のkeyframe定義を取得 | |
| 136 | + keyframerule = getKeyframeRule(keyframename); | |
| 137 | + } | |
| 138 | + // 指定keyframe定義がない or そもそもanimation定義でない or animation定義syntaxerr の場合は | |
| 139 | + // keyframe領域確保のためダミー定義を返す | |
| 140 | + if (null == keyframerule) { | |
| 141 | + console.error('animation ' + animationrule.style.cssText + 'に対応するkeyframe ' + keyframename + ' が見つからないため、ダミーを設定'); | |
| 142 | + keyframerule = '@keyframes dummy { to { color: black;} }'; | |
| 143 | + } | |
| 144 | + | |
| 145 | + // animation定義を復元 | |
| 146 | + let animationcss = animationrule.selectorText + ' {\r\n' + animationrule.style.cssText + '\r\n}'; | |
| 147 | + debuglog('パレット情報1件追加 ele.sheet.cssRules[' + i + ']\n' + animationcss + '\n' + keyframerule.cssText); | |
| 148 | + outstr += (animationcss + '\r\n' + keyframerule.cssText + '\r\n'); | |
| 149 | + } | |
| 150 | + } | |
| 151 | + debuglog('****************************************************'); | |
| 152 | + | |
| 153 | + return outstr; | |
| 154 | +}; | |
| 155 | +// 引数cssstrから animation-name(@keyframeで付けられる) を取得 | |
| 156 | +function getNameOfKeyframe( | |
| 157 | + cssstr // animation または animation-nameが定義された css文字列 | |
| 158 | +) { | |
| 159 | + // animation-nameでも shorthandでも keyframe nameはparamの先頭固定 | |
| 160 | + let name = null; | |
| 161 | + name = cssstr.match(/animation-name *: *(.+?) /); | |
| 162 | + if (null == name) { | |
| 163 | + name = cssstr.match(/animation *: *(.+?) /); | |
| 164 | + if (null == name) { | |
| 165 | + console.error('文字列から @keyframe名の検索に失敗 getNameOfKeyframe() str=' + cssstr); | |
| 166 | + return null; | |
| 167 | + } | |
| 168 | + } | |
| 169 | + return name[1]; | |
| 170 | +}; | |
| 171 | + | |
| 172 | +// 現在のdocumentに設定されている 全Style Sheetから | |
| 173 | +// ruleNameの名前がついた @keyframe検索 | |
| 174 | +// (Stack Overflowからのもらいもの) | |
| 175 | +function getKeyframeRule(ruleName) { | |
| 176 | + var ss = document.styleSheets, | |
| 177 | + rule, i, x; | |
| 178 | + | |
| 179 | + for (i = 0; i < ss.length; ++i) { | |
| 180 | + if (ss[i].cssRules) { | |
| 181 | + // loop through all the rules | |
| 182 | + | |
| 183 | + for (x = ss[i].cssRules.length - 1; x >= 0; x--) { | |
| 184 | + rule = ss[i].cssRules[x]; | |
| 185 | + if ((rule.type === window.CSSRule.KEYFRAMES_RULE || rule.type === window.CSSRule.WEBKIT_KEYFRAMES_RULE) && rule.name === ruleName) { | |
| 186 | + return rule; | |
| 187 | + } | |
| 188 | + } | |
| 189 | + } | |
| 190 | + } | |
| 191 | + return null; | |
| 192 | +} | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 82 | 200 | // Drop fileから file objectを取得 (同期処理) |
| 83 | 201 | // 複数file 非対応。text or image がヒットした時点でcallbackを呼び出す |
| 84 | 202 | // callback書式(text,image): function(blob) |
| @@ -80,7 +80,6 @@ | ||
| 80 | 80 | // requestAnimationFrameのcallbackから呼び出される |
| 81 | 81 | render() { |
| 82 | 82 | while (0 < this.renderFunc.size()) { |
| 83 | - this.debuglog("render() renderFunc size=" + this.renderFunc.size()); | |
| 84 | 83 | let renderFunction = this.renderFunc.dequeue(); |
| 85 | 84 | renderFunction(); |
| 86 | 85 | } |
| @@ -116,6 +115,7 @@ | ||
| 116 | 115 | // 画面に影響しない範囲で作成できるところまで Dom objectを作成する |
| 117 | 116 | let elType = (null != type.match(/imagebox/)) ? 'img' : 'div'; |
| 118 | 117 | this.DOMobject = document.createElement(elType); |
| 118 | + this.DOMobject.classList.add('DispObj'); | |
| 119 | 119 | this.DOMobject.dataset.objid = this.ObjID; |
| 120 | 120 | this.DOMobject.dataset.orgwidth = this.originalWidth; // transform: scaleの基準サイズ |
| 121 | 121 | this.DOMobject.dataset.orgheight = this.originalHeight; |
| @@ -185,13 +185,12 @@ | ||
| 185 | 185 | return new rectData(0, 0, destW, destH); |
| 186 | 186 | } |
| 187 | 187 | renderCreate() { |
| 188 | - this.DOMobject.style.position = "absolute"; // 決め打ち | |
| 188 | +// this.DOMobject.style.position = "absolute"; // DispObj CSS classで指定 | |
| 189 | 189 | this.DOMobject.style.left = this.x.toString() + "px"; |
| 190 | 190 | this.DOMobject.style.top = this.y.toString() + "px"; |
| 191 | 191 | this.DOMobject.style.width = this.width.toString() + "px"; |
| 192 | 192 | this.DOMobject.style.height = this.height.toString() + "px"; |
| 193 | 193 | this.DOMobject.style.border = "1px solid black"; // 指定するI/Fが必要 |
| 194 | -// this.DOMobject.style.backgroundColor = "#cdcdcd"; | |
| 195 | 194 | if (null != this.text) this.DOMobject.innerHTML = this.text; |
| 196 | 195 | |
| 197 | 196 | document.getElementById('DispField').appendChild(this.DOMobject); |
| @@ -203,6 +202,28 @@ | ||
| 203 | 202 | + ", border=" + this.DOMobject.style.border); |
| 204 | 203 | } |
| 205 | 204 | |
| 205 | + createFromElement(ele) { | |
| 206 | + this.debuglog('createFromElement() ele=' + ele); | |
| 207 | + | |
| 208 | + this.DOMobject = ele; | |
| 209 | + this.type = (null != ele.nodeName.match(/IMG/)) ? 'imagebox' : 'textbox'; | |
| 210 | + this.x = parseInt(ele.style.left); | |
| 211 | + this.y = parseInt(ele.style.top); | |
| 212 | + this.width = parseInt(ele.style.width); | |
| 213 | + this.height = parseInt(ele.style.height); | |
| 214 | + this.originalWidth = ele.dataset.orgwidth; | |
| 215 | + this.originalHeight = ele.dataset.orgheight; | |
| 216 | + this.ObjID = ele.dataset.objid; | |
| 217 | + this.degree = ele.dataset.degree; | |
| 218 | + this.DOMobject.addEventListener('mousedown', this.onMouseDown.bind(this), false); | |
| 219 | + | |
| 220 | + // 画像・テキストは既にelementに読み込み済み | |
| 221 | + // treeにも入っており、更新する必要もないのでこれで完了 | |
| 222 | + } | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 206 | 227 | // DIV box 移動 (移動先確定後の移動) |
| 207 | 228 | // ※ Drag中の表示は別で行っている |
| 208 | 229 | movebox(x, y) { |
| @@ -268,6 +289,8 @@ | ||
| 268 | 289 | } |
| 269 | 290 | // Mouse eventをappAreaからScalerに渡してもらうように設定 |
| 270 | 291 | window.appArea.setMouseEventObj(this.mouseMove.bind(this), this.mouseUp.bind(this)); |
| 292 | + evt.stopPropagation(); // event伝播を自分のところで止める(上位に行かなくなる) | |
| 293 | + evt.preventDefault(); // 要素既定のdefault動作を止める | |
| 271 | 294 | |
| 272 | 295 | |
| 273 | 296 | // Focus設定 |
| @@ -281,6 +304,9 @@ | ||
| 281 | 304 | |
| 282 | 305 | } |
| 283 | 306 | mouseMove(evt) { |
| 307 | + evt.stopPropagation(); // event伝播を自分のところで止める(上位に行かなくなる) | |
| 308 | + evt.preventDefault(); // 要素既定のdefault動作を止める | |
| 309 | + | |
| 284 | 310 | // 画像の仮移動 |
| 285 | 311 | this.endDragX = evt.pageX; |
| 286 | 312 | this.endDragY = evt.pageY; |
| @@ -302,6 +328,8 @@ | ||
| 302 | 328 | this.debuglog("mouseUp"); |
| 303 | 329 | // Mouse event処理対象をクリア |
| 304 | 330 | window.appArea.setMouseEventObj(null, null); |
| 331 | + evt.stopPropagation(); // event伝播を自分のところで止める(上位に行かなくなる) | |
| 332 | + evt.preventDefault(); // 要素既定のdefault動作を止める | |
| 305 | 333 | |
| 306 | 334 | |
| 307 | 335 | // 移動元として座標を保持 |
| @@ -39,7 +39,8 @@ | ||
| 39 | 39 | let styleaction = document.getElementById('stylepalact'); |
| 40 | 40 | let cssbg = stylebg.sheet.cssText; |
| 41 | 41 | let csstextcol = styletextcol.sheet.cssText; |
| 42 | - let cssaction = styleaction.sheet.cssText; | |
| 42 | + let cssaction = getAnimationCssFromElement(styleaction); | |
| 43 | + | |
| 43 | 44 | // 最終出力 |
| 44 | 45 | let savestr = '<style id="stylepalbg">' + cssbg + '</style><style id="stylepaltxtcol">' + csstextcol + '</style><style id="stylepalact">' + cssaction + '</style>' + displayInfo; |
| 45 | 46 |
| @@ -49,10 +50,11 @@ | ||
| 49 | 50 | this.DOMobject.innerHTML = text; |
| 50 | 51 | } |
| 51 | 52 | |
| 53 | + | |
| 54 | + | |
| 52 | 55 | // ブラウザ上への描画 ------------------------- |
| 53 | 56 | render() { |
| 54 | 57 | while (0 < this.renderFunc.size()) { |
| 55 | - // this.debuglog("render() renderFunc size=" + this.renderFunc.size()); | |
| 56 | 58 | let renderFunction = this.renderFunc.dequeue(); |
| 57 | 59 | renderFunction(); |
| 58 | 60 | } |
| @@ -82,6 +82,29 @@ | ||
| 82 | 82 | } |
| 83 | 83 | |
| 84 | 84 | |
| 85 | + // 復元されたDOMに合わせて DispObjを作成する | |
| 86 | + // File Load 処理用 | |
| 87 | + adjustEnvToDOM() { | |
| 88 | + this.clear(); | |
| 89 | + | |
| 90 | + // 復元されたDispObj elementを取得 | |
| 91 | + let listEle = document.getElementsByClassName('DispObj'); | |
| 92 | + | |
| 93 | + this.debuglog('読み込み処理 DOM element設定から内部instanceを作成\nElement=' + listEle.length); | |
| 94 | + | |
| 95 | + let ele = null; | |
| 96 | + for (let i = 0; i < listEle.length; i++) { | |
| 97 | + ele = listEle[i]; | |
| 98 | + this.debuglog('読み込み処理 Element=' + (i+1) + '/' + listEle.length + '\ntype=' + ele.nodeName + ', objid=' + ele.dataset.objid); | |
| 99 | + let dispObj = new CDispObj(); | |
| 100 | + dispObj.createFromElement(ele); | |
| 101 | + | |
| 102 | + this.ObjIDLen = parseInt(ele.dataset.objid) + 1; | |
| 103 | + this.ObjIDarray[this.ObjIDLen - 1] = dispObj; | |
| 104 | + } | |
| 105 | + } | |
| 106 | + | |
| 107 | + | |
| 85 | 108 | // Command処理 ---------------------- |
| 86 | 109 | createDispObj(type, rect, opt) { |
| 87 | 110 | this.debuglog("createDispObj"); |
| @@ -33,7 +33,6 @@ | ||
| 33 | 33 | // requestAnimationFrameからの呼び出しを想定 |
| 34 | 34 | render() { |
| 35 | 35 | while (0 < this.renderFunc.size()) { |
| 36 | - // this.debuglog("render() renderFunc size=" + this.renderFunc.size()); | |
| 37 | 36 | let renderFunction = this.renderFunc.dequeue(); |
| 38 | 37 | renderFunction(); |
| 39 | 38 | } |
| @@ -28,7 +28,7 @@ | ||
| 28 | 28 | |
| 29 | 29 | // Mouse eventを処理するObj |
| 30 | 30 | setMouseEventObj(mouseMove, mouseUp) { |
| 31 | - this.debuglog('setMouseEventObj'); | |
| 31 | + this.debuglog('setMouseEventObj callbackMove=' + ((null != mouseMove)? mouseMove.name: 'null') + ', callbackUp=' + ((null != mouseUp)? mouseUp.name: 'null')); | |
| 32 | 32 | |
| 33 | 33 | this.mouseMoveFunc = mouseMove; |
| 34 | 34 | this.mouseUpFunc = mouseUp; |
| @@ -65,7 +65,7 @@ | ||
| 65 | 65 | file // 画像を指しているfile object |
| 66 | 66 | ) { |
| 67 | 67 | let cssstr1 = '.palbg' + id + ' { background-image: url('; |
| 68 | - let cssstr2 = '); }'; | |
| 68 | + let cssstr2 = '); background-size: cover; }'; | |
| 69 | 69 | setImageFileToCSS(this.stylebg, id, cssstr1, cssstr2, file); |
| 70 | 70 | } |
| 71 | 71 |
| @@ -177,8 +177,11 @@ | ||
| 177 | 177 | // Mouse event |
| 178 | 178 | // 自elementをDragし、Drop時にTarget elementに自分のCSS classを適用する |
| 179 | 179 | onMouseDown(evt) { |
| 180 | + evt.stopPropagation(); // event伝播を自分のところで止める(上位に行かなくなる) | |
| 181 | + evt.preventDefault(); // 要素既定のdefault動作を止める | |
| 182 | + | |
| 180 | 183 | // Mouse eventをappAreaからCSSPalに渡してもらうように設定 |
| 181 | - window.appArea.setMouseEventObj(this.mouseMove.bind(this), null); | |
| 184 | + window.appArea.setMouseEventObj(this.mouseMove.bind(this), this.mouseUp.bind(this)); | |
| 182 | 185 | |
| 183 | 186 | // Drag対象を保持 |
| 184 | 187 | this.draggingDOM = evt.target; |
| @@ -191,6 +194,8 @@ | ||
| 191 | 194 | } |
| 192 | 195 | mouseMove(evt) { |
| 193 | 196 | if (null == this.draggingDOM) return; |
| 197 | + evt.stopPropagation(); // event伝播を自分のところで止める(上位に行かなくなる) | |
| 198 | + evt.preventDefault(); // 要素既定のdefault動作を止める | |
| 194 | 199 | |
| 195 | 200 | // 画像の仮移動 |
| 196 | 201 | this.endDragX = evt.pageX; |
| @@ -206,6 +211,8 @@ | ||
| 206 | 211 | //this.renderMoveDragging(moveX, moveY); |
| 207 | 212 | } |
| 208 | 213 | renderMoveDragging(x, y) { |
| 214 | + if (null == this.draggingDOM) return; | |
| 215 | + | |
| 209 | 216 | this.draggingDOM.style.left = x + "px"; |
| 210 | 217 | this.draggingDOM.style.top = y + "px"; |
| 211 | 218 | if( 1.0 == this.draggingDOM.style.opacity ) |
| @@ -212,6 +219,10 @@ | ||
| 212 | 219 | this.draggingDOM.style.opacity = 0.4; |
| 213 | 220 | } |
| 214 | 221 | mouseUp(evt) { |
| 222 | + if (null == this.draggingDOM) return; | |
| 223 | + evt.stopPropagation(); // event伝播を自分のところで止める(上位に行かなくなる) | |
| 224 | + evt.preventDefault(); // 要素既定のdefault動作を止める | |
| 225 | + | |
| 215 | 226 | let palobjid = this.draggingDOM.dataset.objid; |
| 216 | 227 | let palid = this.draggingDOM.dataset.palid; |
| 217 | 228 |
| @@ -56,6 +56,8 @@ | ||
| 56 | 56 | onMouseDown(evt) { |
| 57 | 57 | // Mouse eventをappAreaからCSSPalに渡してもらうように設定 |
| 58 | 58 | window.appArea.setMouseEventObj(this.mouseMove.bind(this), null); |
| 59 | + evt.stopPropagation(); // event伝播を自分のところで止める(上位に行かなくなる) | |
| 60 | + evt.preventDefault(); // 要素既定のdefault動作を止める | |
| 59 | 61 | |
| 60 | 62 | // Drag対象を保持 |
| 61 | 63 | this.draggingDOM = evt.target; |
| @@ -68,6 +70,8 @@ | ||
| 68 | 70 | } |
| 69 | 71 | mouseMove(evt) { |
| 70 | 72 | if (null == this.draggingDOM) return; |
| 73 | + evt.stopPropagation(); // event伝播を自分のところで止める(上位に行かなくなる) | |
| 74 | + evt.preventDefault(); // 要素既定のdefault動作を止める | |
| 71 | 75 | |
| 72 | 76 | // 画像の仮移動 |
| 73 | 77 | this.endDragX = evt.pageX; |
| @@ -90,6 +94,10 @@ | ||
| 90 | 94 | this.draggingDOM.style.top = y + "px"; |
| 91 | 95 | } |
| 92 | 96 | mouseUp(evt) { |
| 97 | + if (null == this.draggingDOM) return; | |
| 98 | + evt.stopPropagation(); // event伝播を自分のところで止める(上位に行かなくなる) | |
| 99 | + evt.preventDefault(); // 要素既定のdefault動作を止める | |
| 100 | + | |
| 93 | 101 | // Drag中 element情報をクリア |
| 94 | 102 | this.draggingDOM = null; |
| 95 | 103 | // Mouse event callback設定をクリア |
| @@ -51,6 +51,12 @@ | ||
| 51 | 51 | } |
| 52 | 52 | |
| 53 | 53 | |
| 54 | + .DispObj { | |
| 55 | + display: inline-block; | |
| 56 | + position:absolute; | |
| 57 | + marginj:0; padding:0; | |
| 58 | + } | |
| 59 | + | |
| 54 | 60 | /* パレットグループ要素の定義 */ |
| 55 | 61 | .palgroup { |
| 56 | 62 | display: inline-block; |
| @@ -14,12 +14,12 @@ | ||
| 14 | 14 | <div id="DispField" data-objid="DisplayField" data-focus="true"> |
| 15 | 15 | </div> |
| 16 | 16 | <!-- 固定ボタン (選択要素の削除, 保存, …) --> |
| 17 | - <button type=button class="pal" data-objid="pal" data-palid="0" data-value="0xff000001">削除</button> | |
| 18 | - <button type=button class="pal" data-objid="pal" data-palid="1" data-value="0x00ff0001">設定保存</button> | |
| 19 | - <button type=button class="pal" data-objid="pal" data-palid="2" data-value="0x0000ff01">設定Drop</button> | |
| 20 | - <button type=button class="pal" data-objid="pal" data-palid="3" data-value="0xffffff01">アニメ停止</button> | |
| 21 | - <button type=button class="pal" data-objid="pal" data-palid="4" data-value="0x00000000">button5</button> | |
| 22 | - <a href="#" id="save" download="savefilename.txt">画像保存</a><br /> | |
| 17 | + <button type=button class="pal" data-objid="pal" data-palid="0" title="フォーカス中の要素を削除します">削除</button> | |
| 18 | + <button type=button class="pal" data-objid="pal" data-palid="1" title="現在のパレット設定を保存します">設定保存</button> | |
| 19 | + <button type=button class="pal" data-objid="pal" data-palid="2" title="設定画面を表示します">設定Drop</button> | |
| 20 | + <button type=button class="pal" data-objid="pal" data-palid="3" title="アニメーションを停止します">アニメ停止</button> | |
| 21 | + <button type=button class="pal" data-objid="pal" data-palid="4" >button5</button> | |
| 22 | + <a href="#" id="save" download="DragDraw.dd" title="DragDraw.ddという名前でダウンロードフォルダに保存します">画像保存</a><br /> | |
| 23 | 23 | |
| 24 | 24 | <!-- Palette --> |
| 25 | 25 | <style id="stylepalbg"> |
| @@ -158,7 +158,7 @@ | ||
| 158 | 158 | } |
| 159 | 159 | </style> |
| 160 | 160 | |
| 161 | - <fieldset class="palgroup palgrouphorizon" data-objid="palgroup0"> | |
| 161 | + <fieldset class="palgroup palgrouphorizon" data-objid="palgroup0" title="背景の色や画像を設定するパレットです"> | |
| 162 | 162 | <legend class="pallegend"> Background Palette </legend> |
| 163 | 163 | <div class="palbg palbg0" data-objid="palbg0" data-palid="0"></div> |
| 164 | 164 | <div class="palbg palbg1" data-objid="palbg1" data-palid="1"></div> |
| @@ -168,7 +168,7 @@ | ||
| 168 | 168 | </fieldset> |
| 169 | 169 | <br /> |
| 170 | 170 | |
| 171 | - <fieldset class="palgroup palgrouphorizon" data-objid="palgroup1"> | |
| 171 | + <fieldset class="palgroup palgrouphorizon" data-objid="palgroup1" title="テキストの色を設定するパレットです"> | |
| 172 | 172 | <legend class="pallegend"> Text Color Palette </legend> |
| 173 | 173 | <div class="paltxtcol paltxtcol0" data-objid="paltxtcol0" data-palid="0">あ</div> |
| 174 | 174 | <div class="paltxtcol paltxtcol1" data-objid="paltxtcol1" data-palid="1">あ</div> |
| @@ -179,7 +179,7 @@ | ||
| 179 | 179 | |
| 180 | 180 | <br /> |
| 181 | 181 | |
| 182 | - <fieldset class="palgroup palgrouphorizon" data-objid="palgroup2"> | |
| 182 | + <fieldset class="palgroup palgrouphorizon" data-objid="palgroup2" title="動きを設定するパレットです"> | |
| 183 | 183 | <legend class="pallegend"> Action Palette </legend> |
| 184 | 184 | <div class="palact palact0" data-objid="palact0" data-palid="0"></div> |
| 185 | 185 | <div class="palact palact1" data-objid="palact1" data-palid="1"></div> |
| @@ -10,9 +10,12 @@ | ||
| 10 | 10 | function logQuiet(str) { |
| 11 | 11 | // 処理なし |
| 12 | 12 | }; |
| 13 | +function isStoreApp() { | |
| 14 | + // ★識別方法を知りたい…… | |
| 15 | + return true; | |
| 16 | +}; | |
| 13 | 17 | |
| 14 | 18 | |
| 15 | - | |
| 16 | 19 | function rectData( left, top, right, bottom ) { |
| 17 | 20 | this.setData( left, top, right, bottom ); |
| 18 | 21 | }; |
| @@ -42,6 +45,7 @@ | ||
| 42 | 45 | |
| 43 | 46 | // Image fileを読み込み、その内容を対象CSSに設定 |
| 44 | 47 | // CSSには "'cssstr1' + fileBlob + 'cssstr2'" が設定される |
| 48 | +// image/text共に読み込んだ内容をそのままCSS定義にする | |
| 45 | 49 | function setImageFileToCSS( |
| 46 | 50 | ele, // CSS書き換え対象Element |
| 47 | 51 | num, // 書き換える CSS要素番号 (ele.sheet.cssRules[n] ← このnの値) |
| @@ -61,7 +65,7 @@ | ||
| 61 | 65 | num, // 書き換える CSS要素番号 (ele.sheet.cssRules[n] ← このnの値) |
| 62 | 66 | cssstr1, // CSS書き換え前半文字 |
| 63 | 67 | cssstr2, // CSS書き換え後半文字 |
| 64 | - file // Textファイルを指している file object | |
| 68 | + file // CSS定義が1つだけ入った Textファイルを指している file object | |
| 65 | 69 | ) { |
| 66 | 70 | // drop fileの読み込み |
| 67 | 71 | let reader = new FileReader(); |
| @@ -77,8 +81,122 @@ | ||
| 77 | 81 | ele.sheet.insertRule(csstext, num); |
| 78 | 82 | }; |
| 79 | 83 | |
| 84 | +// CSSに定義をセット | |
| 85 | +function setStrToCSS( | |
| 86 | + ele, // CSS設定先 style object | |
| 87 | + num, // 設定対象添え字 (ele.sheet.cssRule[n] の nの値) | |
| 88 | + str, // 設定する文字列 | |
| 89 | + reg // [option] 抜き出し用 正規表現, または null | |
| 90 | +) { | |
| 91 | + if (null == ele | |
| 92 | + || null == str | |
| 93 | + || ele.sheet.cssRules.length <= num | |
| 94 | + || num < 0) { | |
| 95 | + console.error('CSS定義追加に失敗 setStrToCSS() パラメータエラー'); | |
| 96 | + console.error('setStrToCSS params ele=' + ele + ', num=' + num + ', ele.cssRules num=' + ((null != ele) ? ele.sheet.cssRules.length : 'null') + ', str=' + str); | |
| 97 | + return false; | |
| 98 | + } | |
| 80 | 99 | |
| 100 | + let addText = str; | |
| 101 | + if (null != reg) { | |
| 102 | + let matchstr = str.match(reg); | |
| 103 | + if (null == matchstr) { | |
| 104 | + console.error('CSS定義追加に失敗 setStrToCSS() 追加文字列エラー'); | |
| 105 | + console.error('setStrToCSS match result=' + matchstr + ', reg=' + reg + ', str=' + str); | |
| 106 | + return false ; | |
| 107 | + } | |
| 81 | 108 | |
| 109 | + addText = matchstr[0]; | |
| 110 | + } | |
| 111 | + ele.sheet.deleteRule(num); | |
| 112 | + ele.sheet.insertRule(addText, num); | |
| 113 | + | |
| 114 | + return true; | |
| 115 | +} | |
| 116 | + | |
| 117 | + | |
| 118 | +// 引数elementに設定されたstylesheetから 全 | |
| 119 | +// "animation定義を含むcss", "対応したkeyframe" を取得する | |
| 120 | +// (@keyframe定義がcssTextから取得できないために作成。 | |
| 121 | +// keyframeはcssのtextではないらしい。css仕様を作っている奴らは馬鹿か!) | |
| 122 | +function getAnimationCssFromElement(ele) { | |
| 123 | + let animationrule = null; | |
| 124 | + let keyframename = null; | |
| 125 | + let keyframerule = null; | |
| 126 | + let outstr = ""; | |
| 127 | + | |
| 128 | + debuglog('アクションパレット情報(CSS) 取得開始 getAnimationCssFromElement() ***************'); | |
| 129 | + for (let i = 0; i < ele.sheet.cssRules.length; i++) { | |
| 130 | + animationrule = ele.sheet.cssRules[i]; | |
| 131 | + if (window.CSSRule.STYLE_RULE == animationrule.type) { | |
| 132 | + // animation定義文字列から keyframe nameを探して取得 | |
| 133 | + keyframename = getNameOfKeyframe(animationrule.style.cssText); | |
| 134 | + if (null != keyframename) { | |
| 135 | + // document内の全style sheetから引数のkeyframe定義を取得 | |
| 136 | + keyframerule = getKeyframeRule(keyframename); | |
| 137 | + } | |
| 138 | + // 指定keyframe定義がない or そもそもanimation定義でない or animation定義syntaxerr の場合は | |
| 139 | + // keyframe領域確保のためダミー定義を返す | |
| 140 | + if (null == keyframerule) { | |
| 141 | + console.error('animation ' + animationrule.style.cssText + 'に対応するkeyframe ' + keyframename + ' が見つからないため、ダミーを設定'); | |
| 142 | + keyframerule = '@keyframes dummy { to { color: black;} }'; | |
| 143 | + } | |
| 144 | + | |
| 145 | + // animation定義を復元 | |
| 146 | + let animationcss = animationrule.selectorText + ' {\r\n' + animationrule.style.cssText + '\r\n}'; | |
| 147 | + debuglog('パレット情報1件追加 ele.sheet.cssRules[' + i + ']\n' + animationcss + '\n' + keyframerule.cssText); | |
| 148 | + outstr += (animationcss + '\r\n' + keyframerule.cssText + '\r\n'); | |
| 149 | + } | |
| 150 | + } | |
| 151 | + debuglog('****************************************************'); | |
| 152 | + | |
| 153 | + return outstr; | |
| 154 | +}; | |
| 155 | +// 引数cssstrから animation-name(@keyframeで付けられる) を取得 | |
| 156 | +function getNameOfKeyframe( | |
| 157 | + cssstr // animation または animation-nameが定義された css文字列 | |
| 158 | +) { | |
| 159 | + // animation-nameでも shorthandでも keyframe nameはparamの先頭固定 | |
| 160 | + let name = null; | |
| 161 | + name = cssstr.match(/animation-name *: *(.+?) /); | |
| 162 | + if (null == name) { | |
| 163 | + name = cssstr.match(/animation *: *(.+?) /); | |
| 164 | + if (null == name) { | |
| 165 | + console.error('文字列から @keyframe名の検索に失敗 getNameOfKeyframe() str=' + cssstr); | |
| 166 | + return null; | |
| 167 | + } | |
| 168 | + } | |
| 169 | + return name[1]; | |
| 170 | +}; | |
| 171 | + | |
| 172 | +// 現在のdocumentに設定されている 全Style Sheetから | |
| 173 | +// ruleNameの名前がついた @keyframe検索 | |
| 174 | +// (Stack Overflowからのもらいもの) | |
| 175 | +function getKeyframeRule(ruleName) { | |
| 176 | + var ss = document.styleSheets, | |
| 177 | + rule, i, x; | |
| 178 | + | |
| 179 | + for (i = 0; i < ss.length; ++i) { | |
| 180 | + if (ss[i].cssRules) { | |
| 181 | + // loop through all the rules | |
| 182 | + | |
| 183 | + for (x = ss[i].cssRules.length - 1; x >= 0; x--) { | |
| 184 | + rule = ss[i].cssRules[x]; | |
| 185 | + if ((rule.type === window.CSSRule.KEYFRAMES_RULE || rule.type === window.CSSRule.WEBKIT_KEYFRAMES_RULE) && rule.name === ruleName) { | |
| 186 | + return rule; | |
| 187 | + } | |
| 188 | + } | |
| 189 | + } | |
| 190 | + } | |
| 191 | + return null; | |
| 192 | +} | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 82 | 200 | // Drop fileから file objectを取得 (同期処理) |
| 83 | 201 | // 複数file 非対応。text or image がヒットした時点でcallbackを呼び出す |
| 84 | 202 | // callback書式(text,image): function(blob) |
| @@ -80,7 +80,6 @@ | ||
| 80 | 80 | // requestAnimationFrameのcallbackから呼び出される |
| 81 | 81 | render() { |
| 82 | 82 | while (0 < this.renderFunc.size()) { |
| 83 | - this.debuglog("render() renderFunc size=" + this.renderFunc.size()); | |
| 84 | 83 | let renderFunction = this.renderFunc.dequeue(); |
| 85 | 84 | renderFunction(); |
| 86 | 85 | } |
| @@ -116,6 +115,7 @@ | ||
| 116 | 115 | // 画面に影響しない範囲で作成できるところまで Dom objectを作成する |
| 117 | 116 | let elType = (null != type.match(/imagebox/)) ? 'img' : 'div'; |
| 118 | 117 | this.DOMobject = document.createElement(elType); |
| 118 | + this.DOMobject.classList.add('DispObj'); | |
| 119 | 119 | this.DOMobject.dataset.objid = this.ObjID; |
| 120 | 120 | this.DOMobject.dataset.orgwidth = this.originalWidth; // transform: scaleの基準サイズ |
| 121 | 121 | this.DOMobject.dataset.orgheight = this.originalHeight; |
| @@ -185,13 +185,12 @@ | ||
| 185 | 185 | return new rectData(0, 0, destW, destH); |
| 186 | 186 | } |
| 187 | 187 | renderCreate() { |
| 188 | - this.DOMobject.style.position = "absolute"; // 決め打ち | |
| 188 | +// this.DOMobject.style.position = "absolute"; // DispObj CSS classで指定 | |
| 189 | 189 | this.DOMobject.style.left = this.x.toString() + "px"; |
| 190 | 190 | this.DOMobject.style.top = this.y.toString() + "px"; |
| 191 | 191 | this.DOMobject.style.width = this.width.toString() + "px"; |
| 192 | 192 | this.DOMobject.style.height = this.height.toString() + "px"; |
| 193 | 193 | this.DOMobject.style.border = "1px solid black"; // 指定するI/Fが必要 |
| 194 | -// this.DOMobject.style.backgroundColor = "#cdcdcd"; | |
| 195 | 194 | if (null != this.text) this.DOMobject.innerHTML = this.text; |
| 196 | 195 | |
| 197 | 196 | document.getElementById('DispField').appendChild(this.DOMobject); |
| @@ -203,6 +202,28 @@ | ||
| 203 | 202 | + ", border=" + this.DOMobject.style.border); |
| 204 | 203 | } |
| 205 | 204 | |
| 205 | + createFromElement(ele) { | |
| 206 | + this.debuglog('createFromElement() ele=' + ele); | |
| 207 | + | |
| 208 | + this.DOMobject = ele; | |
| 209 | + this.type = (null != ele.nodeName.match(/IMG/)) ? 'imagebox' : 'textbox'; | |
| 210 | + this.x = parseInt(ele.style.left); | |
| 211 | + this.y = parseInt(ele.style.top); | |
| 212 | + this.width = parseInt(ele.style.width); | |
| 213 | + this.height = parseInt(ele.style.height); | |
| 214 | + this.originalWidth = ele.dataset.orgwidth; | |
| 215 | + this.originalHeight = ele.dataset.orgheight; | |
| 216 | + this.ObjID = ele.dataset.objid; | |
| 217 | + this.degree = ele.dataset.degree; | |
| 218 | + this.DOMobject.addEventListener('mousedown', this.onMouseDown.bind(this), false); | |
| 219 | + | |
| 220 | + // 画像・テキストは既にelementに読み込み済み | |
| 221 | + // treeにも入っており、更新する必要もないのでこれで完了 | |
| 222 | + } | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 206 | 227 | // DIV box 移動 (移動先確定後の移動) |
| 207 | 228 | // ※ Drag中の表示は別で行っている |
| 208 | 229 | movebox(x, y) { |
| @@ -268,6 +289,8 @@ | ||
| 268 | 289 | } |
| 269 | 290 | // Mouse eventをappAreaからScalerに渡してもらうように設定 |
| 270 | 291 | window.appArea.setMouseEventObj(this.mouseMove.bind(this), this.mouseUp.bind(this)); |
| 292 | + evt.stopPropagation(); // event伝播を自分のところで止める(上位に行かなくなる) | |
| 293 | + evt.preventDefault(); // 要素既定のdefault動作を止める | |
| 271 | 294 | |
| 272 | 295 | |
| 273 | 296 | // Focus設定 |
| @@ -281,6 +304,9 @@ | ||
| 281 | 304 | |
| 282 | 305 | } |
| 283 | 306 | mouseMove(evt) { |
| 307 | + evt.stopPropagation(); // event伝播を自分のところで止める(上位に行かなくなる) | |
| 308 | + evt.preventDefault(); // 要素既定のdefault動作を止める | |
| 309 | + | |
| 284 | 310 | // 画像の仮移動 |
| 285 | 311 | this.endDragX = evt.pageX; |
| 286 | 312 | this.endDragY = evt.pageY; |
| @@ -302,6 +328,8 @@ | ||
| 302 | 328 | this.debuglog("mouseUp"); |
| 303 | 329 | // Mouse event処理対象をクリア |
| 304 | 330 | window.appArea.setMouseEventObj(null, null); |
| 331 | + evt.stopPropagation(); // event伝播を自分のところで止める(上位に行かなくなる) | |
| 332 | + evt.preventDefault(); // 要素既定のdefault動作を止める | |
| 305 | 333 | |
| 306 | 334 | |
| 307 | 335 | // 移動元として座標を保持 |
| @@ -39,7 +39,8 @@ | ||
| 39 | 39 | let styleaction = document.getElementById('stylepalact'); |
| 40 | 40 | let cssbg = stylebg.sheet.cssText; |
| 41 | 41 | let csstextcol = styletextcol.sheet.cssText; |
| 42 | - let cssaction = styleaction.sheet.cssText; | |
| 42 | + let cssaction = getAnimationCssFromElement(styleaction); | |
| 43 | + | |
| 43 | 44 | // 最終出力 |
| 44 | 45 | let savestr = '<style id="stylepalbg">' + cssbg + '</style><style id="stylepaltxtcol">' + csstextcol + '</style><style id="stylepalact">' + cssaction + '</style>' + displayInfo; |
| 45 | 46 |
| @@ -49,10 +50,11 @@ | ||
| 49 | 50 | this.DOMobject.innerHTML = text; |
| 50 | 51 | } |
| 51 | 52 | |
| 53 | + | |
| 54 | + | |
| 52 | 55 | // ブラウザ上への描画 ------------------------- |
| 53 | 56 | render() { |
| 54 | 57 | while (0 < this.renderFunc.size()) { |
| 55 | - // this.debuglog("render() renderFunc size=" + this.renderFunc.size()); | |
| 56 | 58 | let renderFunction = this.renderFunc.dequeue(); |
| 57 | 59 | renderFunction(); |
| 58 | 60 | } |
| @@ -82,6 +82,29 @@ | ||
| 82 | 82 | } |
| 83 | 83 | |
| 84 | 84 | |
| 85 | + // 復元されたDOMに合わせて DispObjを作成する | |
| 86 | + // File Load 処理用 | |
| 87 | + adjustEnvToDOM() { | |
| 88 | + this.clear(); | |
| 89 | + | |
| 90 | + // 復元されたDispObj elementを取得 | |
| 91 | + let listEle = document.getElementsByClassName('DispObj'); | |
| 92 | + | |
| 93 | + this.debuglog('読み込み処理 DOM element設定から内部instanceを作成\nElement=' + listEle.length); | |
| 94 | + | |
| 95 | + let ele = null; | |
| 96 | + for (let i = 0; i < listEle.length; i++) { | |
| 97 | + ele = listEle[i]; | |
| 98 | + this.debuglog('読み込み処理 Element=' + (i+1) + '/' + listEle.length + '\ntype=' + ele.nodeName + ', objid=' + ele.dataset.objid); | |
| 99 | + let dispObj = new CDispObj(); | |
| 100 | + dispObj.createFromElement(ele); | |
| 101 | + | |
| 102 | + this.ObjIDLen = parseInt(ele.dataset.objid) + 1; | |
| 103 | + this.ObjIDarray[this.ObjIDLen - 1] = dispObj; | |
| 104 | + } | |
| 105 | + } | |
| 106 | + | |
| 107 | + | |
| 85 | 108 | // Command処理 ---------------------- |
| 86 | 109 | createDispObj(type, rect, opt) { |
| 87 | 110 | this.debuglog("createDispObj"); |
| @@ -33,7 +33,6 @@ | ||
| 33 | 33 | // requestAnimationFrameからの呼び出しを想定 |
| 34 | 34 | render() { |
| 35 | 35 | while (0 < this.renderFunc.size()) { |
| 36 | - // this.debuglog("render() renderFunc size=" + this.renderFunc.size()); | |
| 37 | 36 | let renderFunction = this.renderFunc.dequeue(); |
| 38 | 37 | renderFunction(); |
| 39 | 38 | } |
| @@ -28,7 +28,7 @@ | ||
| 28 | 28 | |
| 29 | 29 | // Mouse eventを処理するObj |
| 30 | 30 | setMouseEventObj(mouseMove, mouseUp) { |
| 31 | - this.debuglog('setMouseEventObj'); | |
| 31 | + this.debuglog('setMouseEventObj callbackMove=' + ((null != mouseMove)? mouseMove.name: 'null') + ', callbackUp=' + ((null != mouseUp)? mouseUp.name: 'null')); | |
| 32 | 32 | |
| 33 | 33 | this.mouseMoveFunc = mouseMove; |
| 34 | 34 | this.mouseUpFunc = mouseUp; |
| @@ -23,7 +23,7 @@ | ||
| 23 | 23 | window.postToWorker.setMessageHandler( receiveWorkerMessage ); |
| 24 | 24 | |
| 25 | 25 | |
| 26 | - // UI thread初期化 | |
| 26 | + // UI thread初期化 ---------------------- | |
| 27 | 27 | |
| 28 | 28 | // Mgr obj生成 |
| 29 | 29 | // Create Mgr--- |
| @@ -225,55 +225,47 @@ | ||
| 225 | 225 | |
| 226 | 226 | // 読み込み処理としては |
| 227 | 227 | // 1. 読み込みデータを style部分, html部分に分割 |
| 228 | - // 2. 取得したstyle部分からstyle要素を作成 | |
| 229 | - // 3. 既存のstyle要素と差し替え | |
| 230 | - // 4. html部分を DisplayFieldに読み込み | |
| 231 | - // 5. DOM treeに合わせて DispObj instanceを作成 | |
| 228 | + // 2. 既存のstyle要素と差し替え | |
| 229 | + // 3. html部分を DisplayFieldに読み込み | |
| 230 | + // 4. DOM treeに合わせて DispObj instanceを作成 | |
| 232 | 231 | |
| 233 | 232 | // 1. 読み込みデータを style部分, html部分に分割 |
| 234 | - let cssbg = str.match(/^<style id=\"stylepalbg\">([\s\S]*)<\/style>/)[1]; | |
| 235 | - let csstextcol = str.match(/<style id=\"stylepaltxtcol\">([\s\S]*)<\/style>/)[1]; | |
| 236 | - let cssaction = str.match(/<style id=\"stylepalact\">([\s\S]*)<\/style>/)[1]; | |
| 237 | - // 2. 取得したstyle部分からstyle要素を作成 | |
| 238 | - let newelebg = document.createElement('style'); | |
| 239 | - let neweletextcol = document.createElement('style'); | |
| 240 | - let neweleaction = document.createElement('style'); | |
| 241 | - newelebg.style.cssText = cssbg; | |
| 242 | - neweletextcol.style.cssText = csstextcol; | |
| 243 | - neweleaction.style.cssText = cssaction; | |
| 244 | - newelebg.setAttribute('id', 'stylepalbg'); | |
| 245 | - neweletextcol.setAttribute('id', 'stylepaltxtcol'); | |
| 246 | - neweleaction.setAttribute('id', 'stylepalact'); | |
| 233 | + // style部分取得 (palette group別) | |
| 234 | + let cssbg = str.match(/^<style id=\"stylepalbg\">([\s\S]*?)<\/style>/)[1]; | |
| 235 | + let csstextcol = str.match(/<style id=\"stylepaltxtcol\">([\s\S]*?)<\/style>/)[1]; | |
| 236 | + let cssaction = str.match(/<style id=\"stylepalact\">([\s\S]*?)<\/style>/)[1]; | |
| 237 | + // palette group別情報を さらにpalette要素別に分解 | |
| 238 | + let itemsbg = cssbg.match(/.palbg([\s\S]*?)\}/g); | |
| 239 | + let itemstextcol = csstextcol.match(/.paltxtcol([\s\S]*?)\}/g); | |
| 240 | + let itemsaction = cssaction.match(/.palact([\s\S]*?)\}/g); | |
| 241 | + let itemskeyframe = cssaction.match(/@keyframe([\s\S]*?)\}\s*\}/g); // @keyframeは中括弧が連続する '}}' 部分を終了判定にしている | |
| 247 | 242 | |
| 248 | - // 3. 既存のstyle要素と差し替え | |
| 249 | - // 現在設定されているstyle要素をDOM treeから外す | |
| 250 | - let oldelebg = document.getElementById('stylepalbg'); | |
| 251 | - let oldeletextcol = document.getElementById('stylepaltxtcol'); | |
| 252 | - let oldeleaction = document.getElementById('stylepalact'); | |
| 243 | + // 2. 既存のstyle要素と差し替え | |
| 244 | + let elebg = document.getElementById('stylepalbg'); | |
| 245 | + let eletextcol = document.getElementById('stylepaltxtcol'); | |
| 246 | + let eleaction = document.getElementById('stylepalact'); | |
| 253 | 247 | let eleapp = document.getElementById('apparea'); |
| 254 | -/* | |
| 255 | - eleapp.removeChild(oldelebg); | |
| 256 | - eleapp.removeChild(oldeletextcol); | |
| 257 | - eleapp.removeChild(oldeleaction); | |
| 248 | + for (let i = 0; i < 5; i++) { | |
| 249 | + setStrToCSS(elebg, i, itemsbg[i], null); | |
| 250 | + setStrToCSS(eletextcol, i, itemstextcol[i], null); | |
| 251 | + setStrToCSS(eleaction, i*2, itemsaction[i], null); | |
| 252 | + setStrToCSS(eleaction, i*2+1, itemskeyframe[i], null); | |
| 253 | + } | |
| 258 | 254 | |
| 259 | - // 読み込んだCSSで作成したstyle要素を追加 | |
| 260 | - let eleref = document.getElementsByClassName('palgroup')[0]; | |
| 261 | - eleapp.insertBefore(neweleaction, eleref); | |
| 262 | - eleapp.insertBefore(neweletextcol, neweleaction); | |
| 263 | - eleapp.insertBefore(newelebg, neweletextcol); | |
| 264 | -*/ | |
| 265 | - // 3. 既存のstyle要素と差し替え | |
| 266 | - eleapp.replaceChild(newelebg, oldelebg); | |
| 267 | - eleapp.replaceChild(neweletextcol, oldeletextcol); | |
| 268 | - eleapp.replaceChild(neweleaction, oldeleaction); | |
| 269 | - | |
| 270 | - // 4. html部分を DisplayFieldに読み込み | |
| 255 | + // 3. html部分を DisplayFieldに読み込み | |
| 271 | 256 | window.partsFocus.setClingingPartner(null); // Focus消去 |
| 272 | 257 | window.ObjIDMgr.clear(); // 表示中の要素を削除 (ObjIDMgr.deletebox()は隠すだけなので注意) |
| 273 | - let data = str.match(/<div style=[\s\S]*<\/div>/)[0]; | |
| 274 | - window.displayField.setFieldData(data); | |
| 258 | + // canvas上の要素は div or imgのみ。どちらが先頭かは不確定 | |
| 259 | + let data = str.match(/<(div|img) +class=[\s\S]*/); | |
| 260 | + if (null == data) { | |
| 261 | + console.error('File読み込み失敗 parseDdText() html要素がマッチしない\nindexDiv=' + indexDiv + ', indexImg=' + indexImg + ', str=' +str); | |
| 262 | + return; | |
| 263 | + } | |
| 264 | + // 表示データをそのまま DisplayFieldにセットする (見た目上は再現される) | |
| 265 | + window.displayField.setFieldData(data[0]); | |
| 275 | 266 | |
| 276 | - | |
| 267 | + // 4. DOM treeに合わせて DispObj instanceを作成 | |
| 268 | + window.ObjIDMgr.adjustEnvToDOM(); | |
| 277 | 269 | } |
| 278 | 270 | |
| 279 | 271 |
| @@ -280,6 +272,9 @@ | ||
| 280 | 272 | |
| 281 | 273 | |
| 282 | 274 | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 283 | 278 | // 固定ボタン押下 event handler ---------------- |
| 284 | 279 | |
| 285 | 280 | function onClickPalButton(evt) { |
| @@ -65,7 +65,7 @@ | ||
| 65 | 65 | file // 画像を指しているfile object |
| 66 | 66 | ) { |
| 67 | 67 | let cssstr1 = '.palbg' + id + ' { background-image: url('; |
| 68 | - let cssstr2 = '); }'; | |
| 68 | + let cssstr2 = '); background-size: cover; }'; | |
| 69 | 69 | setImageFileToCSS(this.stylebg, id, cssstr1, cssstr2, file); |
| 70 | 70 | } |
| 71 | 71 |
| @@ -177,8 +177,11 @@ | ||
| 177 | 177 | // Mouse event |
| 178 | 178 | // 自elementをDragし、Drop時にTarget elementに自分のCSS classを適用する |
| 179 | 179 | onMouseDown(evt) { |
| 180 | + evt.stopPropagation(); // event伝播を自分のところで止める(上位に行かなくなる) | |
| 181 | + evt.preventDefault(); // 要素既定のdefault動作を止める | |
| 182 | + | |
| 180 | 183 | // Mouse eventをappAreaからCSSPalに渡してもらうように設定 |
| 181 | - window.appArea.setMouseEventObj(this.mouseMove.bind(this), null); | |
| 184 | + window.appArea.setMouseEventObj(this.mouseMove.bind(this), this.mouseUp.bind(this)); | |
| 182 | 185 | |
| 183 | 186 | // Drag対象を保持 |
| 184 | 187 | this.draggingDOM = evt.target; |
| @@ -191,6 +194,8 @@ | ||
| 191 | 194 | } |
| 192 | 195 | mouseMove(evt) { |
| 193 | 196 | if (null == this.draggingDOM) return; |
| 197 | + evt.stopPropagation(); // event伝播を自分のところで止める(上位に行かなくなる) | |
| 198 | + evt.preventDefault(); // 要素既定のdefault動作を止める | |
| 194 | 199 | |
| 195 | 200 | // 画像の仮移動 |
| 196 | 201 | this.endDragX = evt.pageX; |
| @@ -206,6 +211,8 @@ | ||
| 206 | 211 | //this.renderMoveDragging(moveX, moveY); |
| 207 | 212 | } |
| 208 | 213 | renderMoveDragging(x, y) { |
| 214 | + if (null == this.draggingDOM) return; | |
| 215 | + | |
| 209 | 216 | this.draggingDOM.style.left = x + "px"; |
| 210 | 217 | this.draggingDOM.style.top = y + "px"; |
| 211 | 218 | if( 1.0 == this.draggingDOM.style.opacity ) |
| @@ -212,6 +219,10 @@ | ||
| 212 | 219 | this.draggingDOM.style.opacity = 0.4; |
| 213 | 220 | } |
| 214 | 221 | mouseUp(evt) { |
| 222 | + if (null == this.draggingDOM) return; | |
| 223 | + evt.stopPropagation(); // event伝播を自分のところで止める(上位に行かなくなる) | |
| 224 | + evt.preventDefault(); // 要素既定のdefault動作を止める | |
| 225 | + | |
| 215 | 226 | let palobjid = this.draggingDOM.dataset.objid; |
| 216 | 227 | let palid = this.draggingDOM.dataset.palid; |
| 217 | 228 |
| @@ -56,6 +56,8 @@ | ||
| 56 | 56 | onMouseDown(evt) { |
| 57 | 57 | // Mouse eventをappAreaからCSSPalに渡してもらうように設定 |
| 58 | 58 | window.appArea.setMouseEventObj(this.mouseMove.bind(this), null); |
| 59 | + evt.stopPropagation(); // event伝播を自分のところで止める(上位に行かなくなる) | |
| 60 | + evt.preventDefault(); // 要素既定のdefault動作を止める | |
| 59 | 61 | |
| 60 | 62 | // Drag対象を保持 |
| 61 | 63 | this.draggingDOM = evt.target; |
| @@ -68,6 +70,8 @@ | ||
| 68 | 70 | } |
| 69 | 71 | mouseMove(evt) { |
| 70 | 72 | if (null == this.draggingDOM) return; |
| 73 | + evt.stopPropagation(); // event伝播を自分のところで止める(上位に行かなくなる) | |
| 74 | + evt.preventDefault(); // 要素既定のdefault動作を止める | |
| 71 | 75 | |
| 72 | 76 | // 画像の仮移動 |
| 73 | 77 | this.endDragX = evt.pageX; |
| @@ -90,6 +94,10 @@ | ||
| 90 | 94 | this.draggingDOM.style.top = y + "px"; |
| 91 | 95 | } |
| 92 | 96 | mouseUp(evt) { |
| 97 | + if (null == this.draggingDOM) return; | |
| 98 | + evt.stopPropagation(); // event伝播を自分のところで止める(上位に行かなくなる) | |
| 99 | + evt.preventDefault(); // 要素既定のdefault動作を止める | |
| 100 | + | |
| 93 | 101 | // Drag中 element情報をクリア |
| 94 | 102 | this.draggingDOM = null; |
| 95 | 103 | // Mouse event callback設定をクリア |
| @@ -1,59 +0,0 @@ | ||
| 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 | - </head> | |
| 9 | -<body> | |
| 10 | - | |
| 11 | - <style id="stylepalbg">.palbg0 { | |
| 12 | - background-image: url("data:image/jpeg;base64,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"); | |
| 13 | -} | |
| 14 | -.palbg1 { | |
| 15 | - background-image: url("dummy.png"); | |
| 16 | -} | |
| 17 | -.palbg2 { | |
| 18 | - background-image: url("data:image/jpeg;base64,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"); | |
| 19 | -} | |
| 20 | -.palbg3 { | |
| 21 | - background-image: url("dummy.png"); | |
| 22 | -} | |
| 23 | -.palbg4 { | |
| 24 | - background-image: url("dummy.png"); | |
| 25 | -} | |
| 26 | -</style><style id="stylepaltxtcol">.paltxtcol0 { | |
| 27 | - color: black; | |
| 28 | -} | |
| 29 | -.paltxtcol1 { | |
| 30 | - color: red; | |
| 31 | -} | |
| 32 | -.paltxtcol2 { | |
| 33 | - color: blue; | |
| 34 | -} | |
| 35 | -.paltxtcol3 { | |
| 36 | - color: green; | |
| 37 | -} | |
| 38 | -.paltxtcol4 { | |
| 39 | - color: brown; | |
| 40 | -} | |
| 41 | -</style><style id="stylepalact">.palact0 { | |
| 42 | - animation:animeY1 0.5s ease-in 0.3s; | |
| 43 | -} | |
| 44 | -.palact1 { | |
| 45 | - animation:animeact1 2s ease-in 0.3s; | |
| 46 | -} | |
| 47 | -.palact2 { | |
| 48 | - animation:animeact2 2s ease-in 0.3s; | |
| 49 | -} | |
| 50 | -.palact3 { | |
| 51 | - animation:animeact3 2s ease-in 0.3s; | |
| 52 | -} | |
| 53 | -.palact4 { | |
| 54 | - animation:animeact4 2s ease-in 0.3s; | |
| 55 | -} | |
| 56 | -</style> | |
| 57 | - <div style="border: 1px solid black; border-image: none; left: 150px; top: 150px; width: 50px; height: 50px; position: absolute; opacity: 1;" data-objid="0" data-orgwidth="50" data-orgheight="50" data-degree="0"></div><div class="palbg0" style="border: 1px solid black; border-image: none; left: 42px; top: 65px; width: 83px; height: 111px; font-size: 222%; position: absolute; opacity: 1; transform: rotateZ(9.37209deg);" data-objid="1" data-focus="true" data-orgwidth="50" data-orgheight="50" data-degree="9.372092708579089"></div><div class="palbg2" style="border: 1px solid black; border-image: none; left: 196px; top: 104px; width: 130px; height: 117px; font-size: 234%; position: absolute; opacity: 1; transform: rotateZ(-15.3661deg);" data-objid="2" data-focus="true" data-orgwidth="50" data-orgheight="50" data-degree="-15.366085212823378">テキスト | |
| 58 | -Text</div> | |
| 59 | -</body> | |
| \ No newline at end of file |