Skin:
[NORMAL]
[BLUE] [DOS] [LIGHT]  / コピーするための表示 / 実行
比較対象からの変更点をマーキング
このファイル: canvas - 20180805.html
比較対象: canvas - 20180803.html

1 <!DOCTYPE html>
2 <head>
3 <meta content="text/html; charset=UTF-8" http-equiv="content-type">
4 <title>UntitledHomepage6047Canvas</title>
5 <script>
6 /*
7 このスクリプトの目的:
8
9 ●1 一連のアニメを合理的にAnmにまとめている。 大きな目的。
10
11 ●2 一連のアニメの終了でcallbackが実行できている。 大きな目的。
12
13 ●3 関数での移動ができている。
14
15 */
16 console.clear();
17 console.log( "=============== script ==============" );
18 function con() { console.log( Array.prototype.join.call( arguments, " " ) ); }
19 function $( id ) { return document.getElementById( id ); }
20 var HereDocument = /\/\*\s*([^]*?)\s*\*\//;
21 // usage: var txt = ( function() { /*multiTXT*/ } ).toString().match( HereDocument )[ 1 ];
22
23
24 function onloadx() {
25
26 canvasEL = $( "canvasELID" );
27 canvas = canvasEL.getContext( '2d' );
28 screenW = canvas.canvas.width;
29 screenH = canvas.canvas.height;
30
31
32
33
34 //画面要素の作成
35 elements = new Object();
36 elements.A = new Element( 50, 300, null, null, "red" );
37 elements.B = new Element( 500, 300, null, null, "green" );
38 elements.C = new Element( 250, 300, null, null, "blue" );
39 elements.T = new TextElement( 50, 400, "" );
40
41
42 //アニメエンジン始動
43 anms = new Array();
44 timerMS = 100; //※この値が小さいほどなめらか
45 timerID = setInterval( run, timerMS );
46
47
48 //イベントプログラム 実行★
49 //これが1行1行自前のエンジンで実行されるプログラムの例
50 // //suspend はその行を実行後、エンジンは停止する。エンジンを再開するためにはどこかでresume()を実行する。
51 // //anm130 はその行を130ms遅らせて実行する。(正しくは実行後、130ms待ってから再開する…)
52 var src = function() {
53
54 testPose(); //suspend
55 mes_slime(); //stepin
56
57 }.toString().match( /\{([\s\S]*)\}/ )[ 1 ];
58
59 program = new Instruction( null, null, null, src, null );
60 program.exec();
61
62 }
63 function mes_slime() {
64 mes = "スライムがあらわれた!";
65 for( var i = 0; i < mes.length; i++ ) {
66 elements.T.text = mes.substr( 0, i + 1 ); //anm130
67 draw( canvas );
68 }
69 }
70 function testPose() {
71
72 //アニメの作成 ※アニメが終了したら、callbackとして、エンジンの再開のresume()を実行する。
73 anm = new Anm( timerMS, 2000, function() { program.resume(); } ); //★
74
75 //●3 関数での移動ができている。
76
77 //どのように移動するかを定義する関数
78
79 //放物線 関数
80 f1 = function() {
81 var cnt = this.parent.cnt;
82 var cntmax = this.parent.cntmax;
83
84 var x = cnt / cntmax; //0~1
85 x -= .5;
86
87 var y = x * x * 1000;
88
89 return y;
90 }
91
92 //正弦波 関数
93 f2 = function() {
94 var cnt = this.parent.cnt;
95 var cntmax = this.parent.cntmax;
96
97 var y = Math.sin( cnt ) * 20;
98
99 return y;
100 }
101
102 //各動き
103 anm.add( elements.A, "x", elements.A.x, elements.C.x );
104 anm.add( elements.A, "y", elements.A.y, elements.C.y, f1 );
105 anm.add( elements.B, "x", elements.B.x, elements.C.x );
106 anm.add( elements.B, "y", elements.B.y, elements.C.y, f2 );
107 anms.push( anm );
108
109 }
110 function run() {
111 var drawFLG = false;
112
113 //アニメ実行
114 for( var i = 0; i < anms.length; i++ ) {
115 var anm = anms[ i ];
116
117 if( anm.step() == false ) {
118 //アニメの終了
119
120 //●2 一連のアニメの終了でcallbackが実行できている。 大きな目的。
121
122 anms.splice( i--, 1 ); //アニメ削除
123 anm.callback(); //アニメ後処理
124 continue;
125 }
126
127 drawFLG = true;
128
129 }//for i
130
131 if( drawFLG ) draw( canvas );
132 }
133 function draw( cc ) {
134 cc.clearRect( 0, 0, screenW, screenH );
135 //画面要素を描く(赤、青、緑の四角)
136 for( var name in elements ) {
137 var element = elements[ name ];
138 element.draw( cc );
139 }
140 }
141
142
143 //---クラス アニメオブジェクト
144
145 function Anm( timerMS, ms, callback ) {
146 //●1 一連のアニメを合理的にAnmにまとめている。 大きな目的。
147
148 //ひとつのアニメオブジェクトに cnt, cntmax が1組あり、
149 this.cnt = 0;
150 this.cntmax = Math.floor( ms / timerMS );
151
152 //ひとつのアニメオブジェクトに複数の動き motions があるところが、合理的。
153 this.motions = new Array();
154 this.callback = callback ? callback : function() {};
155
156 /*
157 つまり、このようにすれば、
158 複数の動きを同じ時間に開始し、終了し、終了したら callback を1回実行する
159 ということがやりやすくなる。
160
161 これをSVC(Side View Character)に例えると、あるポーズから別のポーズへ3秒で変更する場合、
162 全ての関節を3秒で回転させ、回転完了して別のポーズになったら callback を1回実行する。
163 ということがやりやすくなる。
164
165 この callback を1回実行するというのは、自作のJavaScriptエンジンからSVCのポーズアニメを実行したとき、
166 アニメの完了でcallbackを使ってエンジンへ戻る、という用途を想定している。
167 */
168
169 this.repeat = false;
170 this.reverse = false;
171 this.direction = 1;
172 }
173 Anm.prototype.add = function( element, member, sx, ex, f ) {
174
175 var motion = {
176 element : element, //アニメ対象オブジェクト
177 member : member, //アニメ対象オブジェクトの対象変数名
178 sx : sx, //アニメ開始位置
179 ex : ex, //アニメ終了位置
180 length : ex - sx, //アニメ範囲
181 parent : this, //Anm
182 f : f, //次の値計算関数
183 firstF : 0, //次の値計算関数の結果の初期値
184 isNum : element[ member ].match ? false : true, //次の値計算関数の結果は数値か、文字列か
185 };
186
187 if( f ) motion.firstF = motion.f(); //次の値計算関数の結果の初期値を定義
188
189 this.motions.push( motion );
190 };
191 Anm.prototype.step = function() {
192
193 //check. アニメの終了検知
194 if( this.reverse ) { //reverseモード時に
195
196 if( this.cnt < 0 || this.cnt > this.cntmax ) { //範囲外なら
197 this.cnt = this.direction < 0 ? 1 : this.cntmax - 1; //範囲内に戻し
198 this.direction *= -1; //方向を逆にする。
199 }
200
201 } else if( this.cnt > this.cntmax ) { //範囲外なら
202
203 return false;
204
205 }
206
207 //各動きmotionについて
208 for( var i = 0; i < this.motions.length; i++ ) {
209 var motion = this.motions[ i ];
210 with( motion ) {
211 if( isNum ) {//変更する値が数値である場合
212
213 if( f ) //関数定義がされている場合
214
215 element[ member ] = sx + f() - firstF; //←関数はここで実行
216
217 else //単純な移動 始点から目的地までの距離*進捗
218
219 element[ member ] = sx + length * ( this.cnt / this.cntmax );
220
221 } else //変更する値が文字列である場合( たとえば、"RGB(255,255,255)" など )
222
223 element[ member ] = f();
224 }//with
225 }//for i
226
227 this.cnt += this.direction;
228
229 return true;
230 };
231
232 //---クラス 画面要素オブジェクト
233
234 function Element( x, y, w, h, color ) {
235 this.x = x ? x : 0;
236 this.y = y ? y : 0;
237 this.w = w ? w : 24;
238 this.h = h ? h : 24;
239 this.color = color ? color : "black";
240 }
241 Element.prototype.draw = function( cc ) {
242 cc.fillStyle = this.color;
243 cc.fillRect( this.x, this.y, this.w, this.h );
244 cc.strokeStyle = "black";
245 cc.strokeRect( this.x, this.y, this.w, this.h );
246 };
247
248 function TextElement( x, y, text ) {
249 this.x = x ? x : 0;
250 this.y = y ? y : 0;
251 this.text = text ? text : "";
252 }
253 TextElement.prototype.draw = function( cc ) {
254 cc.fillStyle = this.color;
255 cc.strokeStyle = "black";
256 cc.font = "italic 32px 'MS Pゴシック'";
257 cc.fillText( this.text, this.x, this.y );
258 // cc.strokeRect( this.x, this.y, this.w, this.h );
259 };
260
261
262 </script>
263 <style>
264 </style>
265 </head>
266
267 <body onload="onloadx();" style="
268 background-color : lightgray;
269 ">
270 <canvas id="canvasELID" width="512" height="448" style="
271 display : block;
272 margin : auto;
273 background-color : white;
274 border : solid 1px black;
275 ">There is no canvas.</canvas>
276 </body>
277 <script src="batch - 20180805.js"></script>
278 </html>