ホームページ | Pirikaで化学 | ブログ | 業務案内 | お問い合わせ |
情報化学+教育トップ | 情報化学 | MAGICIAN | MOOC | プログラミング |
2022.2.26
Pirika.comでプログラミング
山本博志
2-2でデザインした球(▶︎をクリックして開く)
var MyRad=100;
var MyX=175;
var MyY=100;
function MyDraw(){
MyColor="rgb(255,165,0)";
var InitCx=MyX+MyRad*(223-175)/100;
var InitCy=MyY+MyRad*(64-100)/100;
var InitCr=0.1*MyRad;
var EndCx=MyX+0.25*MyRad;
var EndCy=MyY-0.25*MyRad;
var EndCr=0.75*MyRad;
ctx.beginPath();
ctx.arc(MyX, MyY, MyRad, 0, Math.PI*2, true);
var gradient2=ctx.createRadialGradient(InitCx,InitCy,InitCr,EndCx,EndCy,EndCr);
gradient2.addColorStop(0.0,"#EEEEEE");
gradient2.addColorStop(1.0,MyColor);
ctx.fillStyle = gradient2;
ctx.fill();
}
MyRadに100、MyXに175、MyYに100を入れています。
この3つは難しい言い方をすると、グローバル変数と言います。MyDrawという絵を描く関数の外側で定義されていて、他の関数の中でも変数として使えます。(実際にはMyColorもグローバル変数です。)
グローバル変数に対応する変数はローカル変数と言います。これは定義された関数の中だけで使えます。
<script>
var グローバル変数=100;
function MyFA{
var MyFAローカル変数=50;
var 答え = MyFAローカル変数 + グローバル変数
//”答え”は150になる。
}
function MyFB{
var MyFBローカル変数=50;
var 答え = MyFBローカル変数 + MyFAローカル変数
//エラー: MyFAローカル変数は他の関数では参照できない。
}
</script>
円は日本中どこでも使えますが、地域振興券はその地域の中でしか使えないような物です。
X | |
---|---|
Y | |
半径 |
それでは実際に他の関数から、グローバル変数の値を変更して見ましょう。
スライダーを動かすにつれ、描画される位置や半径が変わります。
このスライダーオブジェクトは次のように記述されています。最小値minと最大値mxは自分に合わせて変更します。
何もプログラムを書く必要なく、スライダーを動かしたり、値を表示させたりできるのでとても簡単です。
//スライダーを表示・動作させる。
<input id="slider1" type="range" value="175 " min="10" max="490" oninput="this.nextSibling.value = this.value" onchange="this.nextSibling.value = this.value" /><input id="Xval" type="text" size="3" value="175" />
そうしてスライダーで変更された値を取り出すプログラムを作成します。
まず、html の中にあるスライダー要素を指定して、変化が起きた後に呼び出される関数を指定します。
スライダーの読み値は、S1Slider.valueの中に文字変数として入っているので、それを数値変数に変換して、MyXに代入します。
このようにグローバル変数を変更して、MyDraw関数を呼ぶと、指定した位置にオブジェクトを描画します。
<script>
let S1Slider = document.getElementById('slider1');//slider1のオブジェクトを指定します。
S1Slider.addEventListener('input', inputChange);//変化(イベント)が起きたら、inputChange関数を呼ぶ。
function inputChange(event){//スライダーに変化があったら呼ばれる。
MyX=parseInt(S1Slider.value);//Slider.valueは文字列なので、paraseInt関数で整数に変換する。
MyY=parseInt(S2Slider.value);
MyRad=parseInt(S3Slider.value);
MyDraw();//オブジェクトを描画する。
}
このように、inputChange関数の中で値を変更して描画(MyDraw)すると、変更した変数を使って描画します。
PC/Macでは、このキャンバス内で、マウスがどこにいるかをプログラムは知る事ができます。
しかし、タッチは今どこにいるかはわからないので、タッチしたまま動かさないと次のプログラムは動きません。
このキャンバス内でマウス(タッチ)を動かすと、ボタンを押していなくてもマウスの位置を検出する事ができます。(押していても検出できます)
そこで球はマウスが動いている時には追いかけますが、止まると追いかけません。
canvas2.addEventListener('mousemove', function(e) {//マウス動き
onMove(pos(e));
});
canvas2.addEventListener('touchmove', function(e) {//タッチ動き
e.preventDefault();
if (e.changedTouches.length == 1) {
onMove(pos(e.changedTouches[0]));//指[0]の動き
}
});
function onMove(pos) {//マウス、タッチ共通
x=pos[0];
y=pos[1];
MyX2 += (x-MyX2)*0.05;
MyY2 += (y-MyY2)*0.05;
MyDraw2();
var message = 'Mouse position X:' + x + ', Y:' +y;
PrintPosition(canvas2, message);
}
球の代わりに猫の絵にしたり、マウスのポインターをネズミに変えたりして遊べます。
完成形プログラム(▶︎をクリックして開く)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h1>グローバル変数</h1>
<canvas id="canvas" width="500" height="350" style="border:1px solid #CCC;"></canvas>
<div class="example-box">
<table>
<tr>
<th>X</th>
<td><input id="slider1" type="range" min="10" max="490" oninput="this.nextSibling.value = this.value" onchange="this.nextSibling.value = this.value" /><input id="Xval" type="text" size="3" value="175" /></td>
</tr>
<tr>
<th>Y</th>
<td><input id="slider2" type="range" value="100 " min="10" max="340" oninput="this.nextSibling.value = this.value" onchange="this.nextSibling.value = this.value" /><input id="Yval" type="text" size="3" value="100 "/></td>
</tr>
<tr>
<th>半径</th>
<td><input id="slider3" type="range" value="100 " min="10" max="100" oninput="this.nextSibling.value = this.value" onchange="this.nextSibling.value = this.value" /><input id="Rval" type="text" size="3" value="100 "/></td>
</tr>
</table>
</div>
<canvas id="canvas2" width="500" height="350" style="border:1px solid #CCC;"></canvas>
<script type="text/javascript">
// set up canvas
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const canvas2 = document.getElementById('canvas2');
const ctx2 = canvas2.getContext('2d');
let S1Slider = document.getElementById('slider1');//slider1のオブジェクトを取り出す。
S1Slider.addEventListener('input', inputChange);//変化(イベント)が起きたら、inputChange関数を呼ぶ。
let S2Slider = document.getElementById('slider2');
S2Slider.addEventListener('input', inputChange);
let S3Slider = document.getElementById('slider3');
S3Slider.addEventListener('input', inputChange);
var MyRad=100;
var MyX=170;
var MyY=100;
function inputChange(event){//スライダーに変化があったら呼ばれる。
MyX=parseInt(S1Slider.value);//Slider.valueは文字列なので、paraseInt関数で整数に変換する。
MyY=parseInt(S2Slider.value);
MyRad=parseInt(S3Slider.value);
MyDraw()
}
S1Slider.value=""+MyX;
S2Slider.value=""+MyY;
S3Slider.value=""+MyRad;
//MyDraw();
function MyDraw(){
ctx.clearRect(0, 0, canvas.width, canvas.height);
MyColor="rgb(255,165,0)";
var InitCx=MyX+MyRad*(223-175)/100;
var InitCy=MyY+MyRad*(64-100)/100;
var InitCr=0.1*MyRad;
var EndCx=MyX+0.25*MyRad;
var EndCy=MyY-0.25*MyRad;
var EndCr=0.75*MyRad;
ctx.beginPath();
ctx.arc(MyX, MyY, MyRad, 0, Math.PI*2, true);
var gradient2=ctx.createRadialGradient(InitCx,InitCy,InitCr,EndCx,EndCy,EndCr);
gradient2.addColorStop(0.0,"#EEEEEE");
gradient2.addColorStop(1.0,MyColor);
ctx.fillStyle = gradient2;
ctx.fill();
objX = MyX;
objY = MyY;
objWidth = MyRad;
}
var MyRad2=20;
var MyX2=170;
var MyY2=100;
function MyDraw2(){
ctx2.clearRect(0, 0, canvas2.width, canvas2.height);
MyColor="rgb(255,165,0)";
var InitCx=MyX2+MyRad2*(223-175)/100;
var InitCy=MyY2+MyRad2*(64-100)/100;
var InitCr=0.1*MyRad2;
var EndCx=MyX2+0.25*MyRad2;
var EndCy=MyY2-0.25*MyRad2;
var EndCr=0.75*MyRad2;
ctx2.beginPath();
ctx2.arc(MyX2, MyY2, MyRad2, 0, Math.PI*2, true);
var gradient2=ctx2.createRadialGradient(InitCx,InitCy,InitCr,EndCx,EndCy,EndCr);
gradient2.addColorStop(0.0,"#EEEEEE");
gradient2.addColorStop(1.0,MyColor);
ctx2.fillStyle = gradient2;
ctx2.fill();
}
var objX, objY;
var objWidth, objHeight;
function init() {
// オブジェクトの大きさを定義
objWidth = MyRad;
objHeight = MyRad;
// オブジェクトの座標を定義(キャンバスの中央に表示)
objX = MyX;
objY = MyY;
// オブジェクトを描画
MyDraw();
}
/////////////////////////////////////ボールが追いかける
var x, y, relX, relY;
var dragging = false;
function initLis() {
canvas2.addEventListener('mousedown', function(e) {
onDown(pos(e));
});
canvas2.addEventListener('mouseup', function(e) {
onUp(pos(e));
});
canvas2.addEventListener('mousemove', function(e) {
onMove(pos(e));
});
canvas2.addEventListener('touchstart', function(e) {
if (e.changedTouches.length == 1) {
onDown(pos(e.changedTouches[0]));
}
});
canvas2.addEventListener('touchend', function(e) {
if (e.changedTouches.length == 1) {
onUp(pos(e.changedTouches[0]));
}
});
canvas2.addEventListener('touchmove', function(e) {
e.preventDefault();
if (e.changedTouches.length == 1) {
onMove(pos(e.changedTouches[0]));
}
});
canvas2.addEventListener('touchcancel', function(e) {
mOut();
});
}
//座標調整
function pos(e) {
var x, y;
x = e.clientX - canvas2.getBoundingClientRect().left;
y = e.clientY - canvas2.getBoundingClientRect().top;
return [x, y];
}
function onDown(pos) {
x=pos[0];
y=pos[1];
// オブジェクト上の座標かどうかを判定
if (objX < x && (objX + objWidth) > x && objY < y && (objY + objHeight) > y) {
dragging = true; // ドラッグ開始
relX = objX - x;
relY = objY - y;
}
}
function onMove(pos) {
x=pos[0];
y=pos[1];
MyX2 += (x-MyX2)*0.05;
MyY2 += (y-MyY2)*0.05;
MyDraw2();
var message = 'Mouse position X:' + x + ', Y:' +y;
PrintPosition(canvas2, message);
}
function onUp(pos) {
dragging = false; // ドラッグ終了
}
function mOut(pos) {
dragging = false; // ドラッグ終了
}
init();
initLis();
function PrintPosition(canvas, message) {
var context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, 50);
context.font = '12pt "MSゴシック"';
context.fillStyle = 'black';
context.fillText(message, 32, 15);
}
</script>
</body>
</html>
Copyright pirika.com since 1999-
Mail: yamahiroXpirika.com (Xを@に置き換えてください) メールの件名は[pirika]で始めてください。