aboutsummaryrefslogtreecommitdiff
path: root/files/ja/web/svg/namespaces_crash_course/example/index.html
blob: 1a99e4cafa70aedc148ef671ecbfefaece3e9470 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
---
title: 例
slug: Web/SVG/Namespaces_Crash_Course/Example
tags:
  - SVG
  - XML
translation_of: Web/SVG/Namespaces_Crash_Course/Example
---
<p>この例で、私達は <a href="/ja/docs/XHTML">XHTML</a><a href="/ja/docs/Web/SVG">SVG</a><a href="/ja/docs/Web/JavaScript">JavaScript</a><a href="/ja/docs/DOM">DOM</a> 2 を「ほこり」の群れを動かすのにつかっています。これらのほこりは 2 つの簡単な法則によって制御されています。1 つめは、それぞれのほこりがマウスカーソルの方向に向かって移動しようとします。2 つ目はそれぞれのほこりはほこりの位置の平均から遠ざかろうとします。組み合わせることで、このとても自然に見える動きができます。</p>
<p>これは完全に Flash やその他のベンダ特有の拡張を用いずに、 W3C 標準- XHTML と SVG と JavaScript で実現されています。これは Firefox 1.5 以上で動作します。</p>
<p><a class="internal button liveSample" href="http://developer.mozilla.org/samples/svg/swarm-of-motes.xhtml">実行例を表示</a></p>
<pre class="brush:xml">&lt;?xml version='1.0'?&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:svg="http://www.w3.org/2000/svg"&gt;
	&lt;head&gt;
	&lt;title&gt;ほこりの群&lt;/title&gt;
	&lt;style type='text/css'&gt;
	&lt;![CDATA[
		label, input
		{
			width: 150px;
			display: block;
			float: left;
			margin-bottom: 10px;
		}
		label
		{
			text-align: right;
			width: 75px;
			padding-right: 20px;
		}
		br
		{
			clear: left;
		}
	]]&gt;
	&lt;/style&gt;
	&lt;/head&gt;
	&lt;body onload='update()'&gt;
		&lt;svg:svg id='display' width='400' height='300'&gt;
			&lt;svg:circle id='cursor' cx='200'
cy='150' r='7' fill='#0000ff' fill-opacity='0.5'/&gt;
		&lt;/svg:svg&gt;

		&lt;p&gt;ほこりの群れは 2 つの簡単な法則によって制御されています。1 つめは、それぞれのほこりがカーソルの方向に向かって移動しようとします。2 つ目はそれぞれのほこりはほこりの位置の平均から遠ざかろうとします。組みあわせることで、このとても自然に見える動きができます。&lt;/p&gt;

		&lt;p&gt;
		これは完全に Flash やその他のベンダ特有の拡張を用いずに、 W3C 標準 – XHTML / SVG / JavaScript - によって実現されています。現在のところ、これは Mozilla Firefox 1.5 以上で動作するでしょう。&lt;/p&gt;

		&lt;div&gt;
		(C) 2006 &lt;a id='emailme' href='#'&gt;Nick Johnson&lt;/a&gt;

		&lt;script type='text/javascript'&gt;
		&lt;![CDATA[
			// spam ボット撃退
			var email = '@riovia.net';
			email ='nick' + email;
			document.getElementById('emailme').href = 'mailto:'+email;
		]]&gt;
		&lt;/script&gt;
		This software is free for you to use in any way whatsoever,
		and comes with no warranty at all.&lt;/div&gt;

		&lt;form action="" onsubmit="return false;"&gt;
			&lt;p&gt;
			&lt;label&gt;ほこりの数:&lt;/label&gt;
				&lt;input id='num_motes' value='5'/&gt;
				&lt;br/&gt;

			&lt;label&gt;最大速度:&lt;/label&gt;
				&lt;input id='max_velocity' value='15'/&gt;
				&lt;br/&gt;

			&lt;label&gt;カーソルへの引力:&lt;/label&gt;
				&lt;input id='attract_cursor' value='6'/&gt;
				&lt;br/&gt;

			&lt;label&gt;仲間との反発力:&lt;/label&gt;
				&lt;input id='repel_peer' value='5'/&gt;
				&lt;br/&gt;
			&lt;/p&gt;
		&lt;/form&gt;

	&lt;script type='text/javascript'&gt;
	&lt;![CDATA[

		// ほこりの配列
		var motes;

		// 表示用の要素の取得。
		function Display()
		{
			return document.getElementById('display');
		}

		// 表示用の要素の大きさを定義。
		// これを配列の 2 組タプル(x,y)として返す
		function Dimensions()
		{
			// 描画用の要素
			var display = Display();
			var width = parseInt( display.getAttributeNS(null,'width') );
			var height = parseInt( display.getAttributeNS(null,'height') );

			return [width,height];
		}

		// これはマウスの移動イベントで呼び出される
		var mouse_x = 200, mouse_y = 150;
		function OnMouseMove(evt)
		{
			mouse_x = evt.clientX;
			mouse_y = evt.clientY;

			var widget = document.getElementById('cursor');
			widget.setAttributeNS(null,'cx',mouse_x);
			widget.setAttributeNS(null,'cy',mouse_y);
		}
		document.onmousemove = OnMouseMove;

		// カーソルの (x,y) を定義
		function Cursor()
		{
			return [mouse_x, mouse_y];
		}

		// ほこりの平均 (x,y) を定義
		function AverageMotePosition()
		{
			if( !motes )
				return [0,0];

			if( motes.length == 0 )
				return [0,0];

			var i;
			var sum_x=0, sum_y=0;
			for(i=0; i&lt;motes.length; i++)
			{
				sum_x += motes[i].x;
				sum_y += motes[i].y;
			}

			return [sum_x/motes.length, sum_y/motes.length];
		}

		// よりよい、整数の乱数
		function Rand(modulo)
		{
			return Math.round( Math.random() * (modulo-1));
		}

		// Mote クラス
		function Mote()
		{
			// 描画領域の大きさ
			var dims = Dimensions();
			var width = dims[0], height = dims[1];

			// 始めるときのランダムな座標を選ぶ。
			this.x = Rand( width );
			this.y = Rand( height );

			// 速度の初期値はゼロ。
			this.vx = this.vy = 0;

			// 視覚的要素---初期状態ではなし
			this.elt = null;
		}

		// これをクラスに。
		new Mote();

		// Mote::applyForce() -- 与えられた方向に
		// 速度を調整。
		// 警告: 疑似的な物理 -- なんらかの/実際の/物理法則によって
		// 制御されているわけでありません
		Mote.prototype.applyForce = function(pos, mag)
		{
			if( pos[0] &gt; this.x )
				this.vx += mag;
			else if( pos[0] &lt; this.x )
				this.vx -= mag;

			if( pos[1] &gt; this.y )
				this.vy += mag;
			else if( pos[1] &lt; this.y )
				this.vy -= mag;
		}

		// Mote::capVelocity() -- ほこりの速度の
		// 上限を設定。
		Mote.prototype.capVelocity = function()
		{
			var max = parseInt( document.getElementById('max_velocity').value );

			if( max &lt; this.vx )
				this.vx = max;
			else if( -max &gt; this.vx )
				this.vx = -max;

			if( max &lt; this.vy )
				this.vy = max;
			else if( -max &gt; this.vy )
				this.vy = -max;
		}

		// Mote::capPosition() -- ほこりの位置の
		// 上限下限を設定。
		Mote.prototype.capPosition = function()
		{
			var dims = Dimensions();
			if( this.x &lt; 0 )
				this.x = 0;
			else if( this.x &gt;= dims[0] )
				this.x = dims[0]-1;

			if( this.y &lt; 0 )
				this.y = 0;
			else if( this.y &gt;= dims[1] )
				this.y = dims[1]-1;
		}

		// Mote::move() -- ほこりの移動、スクリーンの更新。
		Mote.prototype.move = function()
		{
			// カーソルの引力を適応。
			var attract = parseInt( document.getElementById('attract_cursor').value );
			var cursor = Cursor();
			this.applyForce(cursor, attract);

			// ほこりの位置の平均からの反発を適用
			var repel = parseInt( document.getElementById('repel_peer').value );
			var average = AverageMotePosition();
			this.applyForce(average, -repel);

			// 速度にでたらめさを追加。
			this.vx += Rand(3)-1;
			this.vy += Rand(3)-1;

			// 速度の上限を適応
			this.capVelocity();

			// 速度を適応。
			var old_x = this.x, old_y = this.y;
			this.x += this.vx;
			this.y += this.vy;
			this.capPosition();

			// 描画。

			if( this.elt === null )
			{
				var svg = 'http://www.w3.org/2000/svg';
				this.elt = document.createElementNS(svg,'line');
				this.elt.setAttributeNS(null,'stroke','green');
				this.elt.setAttributeNS(null,'stroke-width','3');
				this.elt.setAttributeNS(null,'stroke-opacity','0.5');
				Display().appendChild( this.elt );
			}

			this.elt.setAttributeNS(null,'x1',old_x);
			this.elt.setAttributeNS(null,'y1',old_y);

			this.elt.setAttributeNS(null,'x2',this.x);
			this.elt.setAttributeNS(null,'y2',this.y);
		}


		function update()
		{
			// 最初の呼び出し?
			if( !motes )
				motes = [];

			// 幾つのほこりがあるべき ?
			var num = parseInt( document.getElementById('num_motes').value );
			if( num &lt; 0 )
				num = 0;

			// 量を厳密に確認。
			// 少なすぎ ?
			while( motes.length &lt; num )
				motes.push( new Mote() );
			// あるいは多すぎ ?
			if( num == 0 )
				motes = [];
			else if( motes.length &gt; num )
				motes = motes.slice(0,num-1);

			// ほこりをランダムに移動
			if( motes.length &gt; 0 )
				motes[ Rand( motes.length ) ].move();

			// これを 100 分の 1 秒ごとに再実行。
			setTimeout('update()', 10);
		}
	]]&gt;
	&lt;/script&gt;
	&lt;/body&gt;
&lt;/html&gt;
</pre>