このサイトでは、分析、カスタマイズされたコンテンツ、および広告に Cookie を使用します。このサイトを引き続き閲覧すると、Cookie の使用に同意するものと見なされます。
Hi, Developers,
straightapps.com ロゴ
作成 September 11, 2020、最終更新 September 29, 2020
トップページ > Web 開発トップ > 素因数分解トレーニング
line
Web 開発
line

素因数ボタンをクリックして、素因数分解せよ!!

※ 表示が正しくないと思う場合は、JavaScript を有効にしてください。

ここに素因数分解されるべき値が表示されます。
ここに回答途中の式が表示されます。

Let's play prime factorization!!

素因数分解に慣れよう!

表示された数字を、割り切れる素数で割っていこう。 2〜13のボタンをタップして、数字が1になるまで割っていきましょう! 割り切れない数字を選ぶと、先に進みません。 最後までできてもできなくても、「別の問題に挑戦」ボタンで、新しい数字で再開できます。


現時点でのテスト済みブラウザは、

  • Windows 10 PC の Edge, Chrome, FireFox
  • Windows 10 PC の Internet Explorer(スクリプトの実行許可が必要)
  • Android 9 スマホの Chrome, FireFox, Edge
  • です。

    スマホやタブレットで開く場合は、 この QR コード ( URL の QR コード
    https://www.straightapps.com/web/js-soinsuu-bunkai.html
    )
    が、このページの URL になっています。 QR コード読み取りアプリで読み取ると便利です。

    ▲ページ先頭へ

    ここから先は開発情報です

    投稿 September 26, 2020

    ここから先は、上記「素因数分解トレーニング」開発を行った際に調べたりした JavaScript コードについての情報です。

    コードに入る前に、ご参考までに、お知らせです。 私は普段は、Windows デスクトップアプリを C++/MFC で書いています。 HTML は手書き(テキストエディタ)で、JavaScript も基本は手書きです。 Visual Studio 2015 エディタを使って書く部分もありますが、タブとスペースの処理の関係で、あまり好んでいません。 ですので、自然に、Windows っぽくなっている部分が出ています。 また、C++ で Android アプリ作成にもチャレンジしているので、その比較もするかも知れません。

    このプログラムを書き始めたときの JavaScript のレベルとしては、 言語仕様としては C/C++ と似ている部分が多いので、苦労しないレベルです。 関数や書き方については、ネットでコードを参照すれば、いくらか書ける程度です。 JavaScript で書いたコードは、1文字でも間違えていると全体が動作しなくなるようなのですが、 どこがおかしいか、タイプミスや文字不足、カッコの閉じ忘れや変数名の書き間違いなどに気付く能力は、 おそらく十分にあるようです。

    前置きは以上として、まずは、HTML 部です。

    JavaScript ソースは、理想的に2つにわけていますが、今はまだ、2つにする意味はほぼありません。 1つ目、soinsuu-init.js は、 <head> 〜 </head> タグ内でロードしています。 目的は、グローバルに参照する変数や関数の定義です。 あとでコードを書きますが、ちゃんとわけていないため、今は適当な感じになってしまっています。

    <script type="text/javascript" src="js/soinsuu-init.js"></script>
    

    もう1つは、 body タグ内でロードしている、soinsuu.js です。 ここにほとんどの機能が実装されています。 関数を、<head> 〜 </head> タグ内でロードしている soinsuu-init.js に書くべきなのか、 soinsuu-init.js で定義している変数をこちらに置いてもいいのか、置くべきなのか、 速度的なところや、使用メモリ的なところや、マナー的なところは、今は理解していません

    JavaScript でテキスト表示を変更している部分は、 「を、下の素数ボタンを押して、素因数分解せよ!」の行と 「は、何で割り切れるかな?」の行、 および「ここに回答途中の式が表示されます。」の行です。 後述しますが、いずれも id ( タグにつけた、他と重複しない名前です。 ) を付けた div 領域を、innerHTML で置き換える処理です。 つまり、HTML で書いたテキストを表示するのではなく、その都度動的に書き換えて表示を更新する、ということです。

    <div id="left-value">ここに素因数分解されるべき値が表示されます。</div>
    <div id="answering">ここに回答途中の式が表示されます。</div>
    
    <!-- button 要素部を省略(このあとすぐ) -->
    

    「別の問題に挑戦」ボタンの下にある、計算途中のエリアcanvas に描画しています。 canvas とは、自由に絵を描ける領域のことです。

    <!-- button 要素から続きます(このあとすぐ) -->
    
    <p>
    <canvas id="canvas-calc"></canvas>
    </p>
    

    素因数(数字)選択ボタンや「別の問題に挑戦」ボタンは、button 要素 で、 JavaScript 関数を呼び出す形になっています。 これが、上2つのコードの間に挟まっています。

    <p>
    <button onclick="numPressed(2)" title="2で割る"> 2 </button>
    <button onclick="numPressed(3)" title="3で割る"> 3 </button>
    <button onclick="numPressed(5)" title="5で割る"> 5 </button>
    <button onclick="numPressed(7)" title="7で割る"> 7 </button>
    <button onclick="numPressed(11)" title="11で割る"> 11 </button>
    <button onclick="numPressed(13)" title="13で割る"> 13 </button>
    </p>
    
    <p>
    <button onclick="makeNewNumber()">別の問題に挑戦</button>
    </p>
    

    canvas の定義のあとで、soinsuu.js を読み込んでいます。

    以降のセクションで、それぞれ詳細を確認していきます。

    なお、ご参考までに、JavaScript ソースコードそのものを、拡張子 js を拡張子 txt に変えて、次のリンクより開けるようにしてあります。
    soinsuu-init.txt
    soinsuu.txt
    ※ 作成時はタブを4文字としていますので、環境によってはタブが8文字のため、 コメント等がずれて見えるかも知れません。
    ※ 念のため書き添えますが、このソースコードをこのまま転載・公開することはご遠慮ください。

    ▼ セクション一覧

    JavaScript コードのロード位置
    ページ読み込み時の処理
    【基礎】HTML 要素のテキストの書き換え
    【基礎】Object 型の変数の使い方
    【基礎】Math クラスの利用
    【基礎】可変サイズの配列と操作
    問題作成関数 makeNewNumber
    ボタン入力処理
    途中計算式の描画(canvas)
    このあとは・・・

    なお、本サイトのご利用に際しては、必ずプライバシーポリシー(免責事項等)をご参照ください。

    ▲ページ先頭へ

    JavaScript コードのロード位置

    投稿 September 26, 2020

    soinsuu-init.js は、 <head> 〜 </head> タグ内でロードしていますが、 この場所で読み込む場合は、ページ本体のデータ(body 部)が読み込まれる前に、ロードされるようです。

    なので、この中で、例えばあとで定義されている div id="left-value" にアクセスしようとしても、アクセスできません。

    var pow = new Object();		// 正解を保持するオブジェクト
    var numOrg = 1;			// 素因数分解される元の値
    var num = 1;			// 残りの素因数分解される値
    var ans = new Object();		// プレーヤーの回答を保持するオブジェクト
    var inp = [];			// 要素数未定の配列
    

    soinsuu-init.js にあるのは上記のものだけです。 C/C++ と違うのは、変数の型が緩いということです。 (古い)Visual Basic の Variant 型と同じように、整数でも実数でも文字列でも入ります。 今の Visual Basic には Variant 型はないようですので、比較はできませんが。 実際には、ちゃんと 目的別に用意することもできる ( Microsoft の TypeScript というものを使うと管理しやすいようですが、まだ調べていません。 ) ようですが、今は気にしません(便利さに甘えます)。

    ほぼすべての機能が実装されている soinsuu.js は、 body タグ内でロードされています。 これは、HTML の body を先頭から読み込んでいき、 そのコードに到達したときに読み込まれる、というものです。

    <script type="text/javascript" src="js/soinsuu.js"></script>
    

    ここでは、これより前で定義された div id="left-value"canvas id="canvas-calc" にアクセスできます。

    なお、JavaScript のコードは、head や body タグ内に直接記述することも可能です。 機能テストには有効かもしれませんが、ごちゃごちゃになるので、おすすめできる方法ではありません。 また、HTML タグの onClick などに直接コードを書くこともできるようですが、小規模でない限りは、混乱のもとになるかと思います。

    <script type="text/javascript">
    <!--
    	<!-- JavaScript コードを記述 -->
    // -->
    </script>
    <noscript>
    	<!-- JavaScript が無効の場合の注意書きなどを記述 -->
    </noscript>
    
    ▲ページ先頭へ

    ページ読み込み時の処理

    投稿 September 26, 2020

    body が読み進まれていき、script の行まで到達すると、src で指定されたファイルが読み込まれます。

    <script type="text/javascript" src="js/soinsuu.js"></script>
    

    soinsuu.js は、 div id="left-value"canvas id="canvas-calc" にアクセスしますので、 この script の行は、それらよりあとに記述されていなくてはなりません。 一般的には </body> の直前でいいようですが、 このページでは、読みにくくならないように、 必要なすべての HTML 要素の定義が終わった直後、 つまり canvas の定義の直後に置いています。

    なお、ただ単純に、ブラウザがその行を解析するときに読む、というだけのようですから、 script 行が複数あれば、それぞれそのタイミングで読み込まれるようです。

    soinsuu.js の先頭部分は、次のような流れになっています。

    まずは、canvas のサイズを決定しています。

    var canvas = document.getElementById('canvas-calc');
    var w = document.documentElement.clientWidth;
    var h = 48;
    
    if (w > 480){			// 十分広い場合は
    	w = 480;		// 480 ピクセルまでとします
    }
    
    canvas.width = w;		// canvas の幅設定
    canvas.height = h;		// canvas の高さ設定
    

    変数 canvas に、canvas id="canvas-calc" を取得しています。 変数 w にブラウザの表示可能領域の横幅を取得し、変数 h に最小の高さ 48 を設定しています。 48 は、このプログラムで使うテキストを、1行表示できるだけのサイズです。

    横幅が 480 ピクセル以上ある場合は、480 ピクセルまでとしています。 今この解説文を書いている時点では、
    w = Math.min( 480, w );
    と書くと思いますが、このときはまだ知りませんでした。 自由に利用できる Math クラスの min 関数を呼び出して、480 と w の小さいほうを w にセットする、という意味です。

    サイズが決まったら、canvas の width と height プロパティにセットします。 body タグ内で読み込まれた JavaScript ファイルは先頭から順に実行されていきますので、 このコード(および続くコード)は、自動的に実行されることになります。

    続けて、「コンテキストを取得」しています。 これは、canvas の描画設定を行うための「手続き」です。

    var ctx = canvas.getContext('2d');
    

    例えば、テキストを描画するためのフォントの設定は、コンテキスト ctx を使用して、次のように記述します。

    ctx.font = "36px 'ヒラギノ角ゴ Pro', 'Hiragino Kaku Gothic Pro', 'MS ゴシック', 'MS Gothic', sans-serif";
    

    サイズは 36 ピクセルで、フォント名を記述している順に探し、最初に見つかったフォントを使用する、という意味です。

    そのあと正確には canvas の幅の調整を行っていますが、それは重要ではないので飛ばし、 新しい問題を作成するための関数呼び出しに進みます。

    makeNewNumber();
    

    これは、自分で作成した関数 makeNewNumber を、引数なしで呼び出している、という意味です。 どこでこの関数を定義しているかと言えば、このファイルのあとのほうです。 同一ファイル内にあるからいいのか、別のファイルでもいいのかどうかは調べていませんが、 C/C++ なら、定義前の関数を呼び出すことはできません。 融通が利くというのか、甘い言語仕様なのかはわかりません。

    関数本体はあとにまわし、続きの処理を見ていくと、 次にメインループを定義しています。

    function main()
    {
    	<!-- 繰り返し実行する処理を記述 -->
    	requestAnimationFrame( main );
    }
    

    まず、function で定義されている関数は、呼び出されるまで実行されません。 なんだか変な気分ですが、そうなので、そういうことです。 ですので、処理上は、関数の終了まで読み飛ばされます。

    もし main 関数が呼び出され、実行されると、記述した処理を実行できます。 最後に書くべき requestAnimationFrame 関数は、 引数に main を渡しているので、このあとまた main 関数を実行する、という意味だそうです。 極めて厳密にはどのようになっているかわかりませんが、 メインループを構築するときの一般的な手続きのようですから、こうしています。

    また、この素因数分解プログラムでは、ユーザーの入力なく自動的に表示が更新されることがありませんので、 本来ループで描画する必要はないと思われますが、 今後もこの形で進もうとしていましたので、この形で残しています。

    main 関数の定義のあと、いよいよ起動部分が記述されています。

    addEventListener('load', main(), false);
    

    「リスナー」の概念が、個人的にはわかりにくいのですが、 「監視する者」という感じで解釈しています。 この場合は、load、すなわちページの読み込みが完了したのを検知し、 main 関数を実行する、という意味になるようです。 最後の false については、今は気にしていません。

    このあとは関数の定義しかありませんので、上記 addEventListener 関数が実行されたら この soinsuu.js の実行は終わりで、続きの HTML が読み込まれていくことになると思います。 そしてすべて読み込まられた、main 関数を開始し、ループし続ける、という流れです。

    もちろん、main 関数の前に呼び出している makeNewNumber 関数も定義しています。 詳細はあとで触れます。

    ▲ページ先頭へ

    【基礎】HTML 要素のテキストの書き換え

    投稿 September 26, 2020

    HTML 要素を取得し、 innerHTML プロパティを書き換えることにより、 HTML 要素にある内部の文字列を動的に書き換えることができます。

    div id="left-value" 部分の書き換えは、 updateValue 関数で行っています。 この関数の呼び出しは、 新しい問題が作成されたとき makeNewNumber 関数からと、 素因数ボタンが押されたときに呼び出される numPressed 関数 からのみです。

    var elem = document.getElementById('left-value');
    var data = '置き換える文字列';
    elem.innerHTML = data;
    

    div 〜 /div の文字列が、「置き換える文字列」に置き換えられます。 もともとあった文字列は削除されます。

    このプログラムでは、left-value には、updateValue 関数で、 「を、下の素数ボタンを押して、素因数分解せよ!」と、 「は、何で割り切れるかな?」の2行を表示するようにしています。 また、正解が出たときには「おめでとう!」表示に切り替わります。

    コード詳細を確認

    ▲ページ先頭へ

    【基礎】Object 型の変数の使い方

    投稿 September 28, 2020

    C/C++ で言うところの構造体が、 なんと定義することなく自由に作成できてしまいます。 メンバーを完全に自由に定義でき、自由に参照できてしまうため、 タイプミスを犯した場合もエラーとならず、問題点を探すのが大変難しそうです。

    soinsuu-init.js で次のように定義した pow に、 makeNewNumber 関数 で、値を設定している部分です。

    var pow = new Object();		// 正解を保持するオブジェクト
    
    pow.n2 = Math.floor(Math.random() * 6);	// 2の0乗〜5乗までを適当に決める
    pow.n3 = Math.floor(Math.random() * 5);	// 3は4乗まで
    pow.n5 = Math.floor(Math.random() * 4);	// 5は3乗まで
    <!-- 同様の部分は省略 -->
    

    n2 や n3 といった メンバー変数 ( C/C++ の呼び方ですので、JavaScript では違う呼び方があるかも知れません。 ) は、事前に定義することなく、いきなり値を代入できています。 Math クラスの使い方は、このあとすぐ扱います。

    ここでは整数ばかり設定していますが、結局は変数ですので、自由に設定可能です。

    ball.img = new Image();
    ball.img.src = 'img/pin.png';
    

    このように、画像データを設定することも可能です(このプログラムでは画像は利用していません)。

    ▲ページ先頭へ

    【基礎】Math クラスの利用

    投稿 September 28, 2020

    Math クラスがどんな関数を持っているかは、ネットを検索すればすぐわかりますので、ここでは基本的なもののみ触れておきます。

    Math.random() は、0 以上 1 未満 ( 「未満」のときは、その値 1 を含みません。 ) の乱数を返します。

    多くの場合は 0 〜 1 の乱数が欲しいのではなく、「1 〜 10 の間の数」のような値が欲しいと思います。 このため、Math.floor( 値 ) 関数を組み合わせます。 この関数は、「値」以下の最大の整数を返してくれます。 正の値なら小数点以下を切り捨てですが、負の値の場合はそうではありませんので、ご注意ください。

    pow.n2 = Math.floor(Math.random() * 6);	// 2の0乗〜5乗までを適当に決める
    

    この場合は、コメントにある通り、pow.n2 に 0 〜 5 のいずれかの値を設定します。 Math.random() * 6 では、0 以上 6 未満の値が返り、それを Math.floor で小数部をカットしている形です。

    このほか、よく使うと思われるものを挙げておきます。

    Math.abs( 値 ) は、値の絶対値を返します。 つまり、1 なら 1 を、-1 でも 1 を返してくれます。

    Math.max( 値1, 値2 ) は、値1と値2を比較し、 大きいほうの値を返してくれます。

    逆に、Math.min( 値1, 値2 ) は、値1と値2を比較し、 小さいほうの値を返してくれます。

    このプログラムでも使っている、Math.pow( 値1, 値2 ) だと、 値1の「値2」乗を返してくれます。 つまり、Math.pow( 2, 3 ) だと2の3乗なので、8 が返されます。

    まだまだあるようですので、計算が必要になったときに、関数を調べてみると、見つかるかも知れません。

    ▲ページ先頭へ

    【基礎】可変サイズの配列と操作

    投稿 September 28, 2020

    ここでは触れませんが、2次元配列はとても使いにくいと思います。 が、ここで触れる1次元配列は、自由度が高く、とても使いやすいです。

    soinsuu-init.js で次のように定義した inp を、 makeNewNumber 関数 で、初期化しています。

    var inp = [];			// 要素数未定の配列
    
    inp.length = 1;			// 要素数1
    inp[0] = 0;			// 値は0
    

    このようにして、要素数を 1 に設定しています。 C/C++ 等と同じように、添字は 0 から開始されます。 最初の要素(この場合は1つなので唯一です)の値を 0 としています。 もちろん、設定できるのは数値に限られるわけではなく、文字列を設定したりもできます。

    素因数ボタン ( HTML の button 要素で、「2」や「3」などと書かれているボタンのことです。 ) が押されたとき、押された値の順を記録するため、次にように配列を拡張できます。

    inp.length ++;
    inp[ inp.length - 1 ] = value;
    

    inp.length に1を足し、要素数を1つ拡張しています。 そして新しく追加された要素に、値 value をセットしています。 value は押されたボタンの値を引数で渡されたもので、「2」なら 2、「3」なら 3 です。 最後の要素は、例えば要素数 3 なら添字は 0 〜 2 なので、inp.length - 1 になっています。

    ここで、length は関数ではなくプロパティですので、参照にカッコは不要で、 読み出し・設定とも可能です。

    ▲ページ先頭へ

    問題作成関数 makeNewNumber

    投稿 September 28, 2020

    新しい問題を作成する関数 makeNewNumber は、メインループ定義のあと、 addEventListener('load', main(), false); 呼び出しのすぐあとに、 記述されています。 記述位置は、同一ファイル内であれば、どこでもいいのではないかと思います。

    HTML や JavaScript の新しい要素は特にありませんので、ご覧になりたい方は、 折りたたまれている部分「コード詳細を確認」を展開してください。

    概要としては、 C/C++ でいうところの構造体のように使えるオブジェクト pow に、 正解となる値を設定します。 「素因数分解される値」を構成するのが、2の何乗、3の何乗・・・13の何乗かをランダムに決め、 設定しています。 自由に設定しすぎると、とても大きな値になってしまいかねませんので、 2は5乗まで、3は4乗まで・・・11は2乗まで、13は1乗までと制限し、 さらに11と13は同時にあると大きくなるので、どちらかのみに制限しています。

    それをもとに、変数 numOrg に、pow から計算された「素因数分解される値」を設定しています。 プレーヤーの回答は、オブジェクト ans に格納するため、 各値をゼロクリアしています。 最後に、それを表示し、また、オブジェクト inp を初期化し、 このあとユーザーが入力した値を順番に記録できるようにしています。 同時に、canvas のサイズも初期化しています。

    コード詳細を確認

    ▲ページ先頭へ

    ボタン入力処理

    投稿 September 29, 2020

    素因数ボタン ( HTML の button 要素で、「2」や「3」などと書かれているボタンのことです。 ) が押されたとき、numPressed 関数が呼び出されます。

    <button onclick="numPressed(2)" title="2で割る"> 2 </button>
    <button onclick="numPressed(3)" title="3で割る"> 3 </button>
    <!-- 同様の記述は省略 -->
    

    button 要素の onclick イベント、すなわちボタンが押されたとき、 numPressed 関数に、押されたボタンの数字を渡して、呼び出しています。

    numPressed 関数では、その値で割り切れるかどうかを判断し、 割り切れるならその入力を配列 inp に記録して、 途中経過を更新します。 div タグの文字列の更新については「HTML 要素のテキストの書き換え」に、 canvas への途中経過の描画については「途中計算式の描画(canvas)」に書いています。

    HTML や JavaScript の新しい要素は特にありませんので、ご覧になりたい方は、 折りたたまれている部分「コード詳細を確認」を展開してください。

    コード詳細を確認

    「別の問題に挑戦」ボタンは、初期化時に呼び出したものと同じ、 makeNewNumber 関数を呼び出します。

    <button onclick="makeNewNumber()">別の問題に挑戦</button>
    

    新しい問題を作成し、ユーザーの回答や途中経過などを初期化しています。

    ▲ページ先頭へ

    途中計算式の描画(canvas)

    投稿 September 29, 2020

    canvas への 途中計算式の描画は、main 関数で行っています。 先にも書いた通り、ユーザーの入力なく自動的に更新されることはありませんので、 ループ内で描画する必要がないと言えますが、このあとのプログラムに続く部分ですので、 このままにしています。

    まず最初に、canvas 全体をグレーで塗りつぶしています。 Windows デスクトップアプリとしては、 画面 DC ( デバイス コンテキストと呼んでいます。 ) に対してこんなことをしたら、 ウィンドウがチラついてチラついて仕方がありませんが、 Android アプリなどと同じように、いちいち全画面を描画しても大丈夫みたいです。

    ctx.fillStyle = "rgb( 230, 230, 230 )";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    

    位置を決めて、一番最初の数字(問題とした数字) numOrg を記入します。

    var x;
    var y = 40;
    
    ctx.font = "36px 'ヒラギノ角ゴ Pro', 'Hiragino Kaku Gothic Pro', 'MS ゴシック', 'MS Gothic', sans-serif";
    ctx.fillStyle = '#000';				// 黒文字で
    x = x_num - ctx.measureText( numOrg ).width;	// 右端を x_num にあわせる
    ctx.fillText( numOrg, x, y );			// canvas 領域の座標(y座標は'下'を指している)
    y += 40;
    

    ctx.font に、フォント情報を設定しています。 ここではサイズを 36 ピクセルにして、その後に続くフォントを順番に探して、見つかったフォントを使います。 ですので、このままなら、可能性としては、利用環境ごとに正しい表示が得られません。

    ctx.fillStyle では、文字の色を設定しています。 塗りつぶしの時は rgb で指定していますが、CSS での指定と同じように、# のあとに RGB 値を 16 進数で並べても OK です。

    y 座標には、変数定義時に 40 を設定しています。 この値は、Windows とは違い、文字の下の座標を示していますので、注意が必要です。 そいて x 座標には、ctx.measureText( 文字列 ).width で、 選択中のフォントで「文字列」を描画するとき、どれだけの幅が必要かを返す関数を使用しています。 x_num は、事前に10文字表示するための x 座標の右端を設定していますので、 「10桁表示で右詰め」となる x となります。

    ctx.fillText( 文字列, x 座標, y 座標 ) で、テキストを描画しています。 なお、numOrg は数値として扱っていますが、文字列として渡すと文字列として解釈されます。 個人的には便利なので好きですが、バグの温床になることは間違いありません

    var numTmp = numOrg;					// 途中経過の表示用
    for ( var i = 1;  i < inp.length; i++ ){
    

    途中経過表示用に numTmp を定義し、もともとの値 numOrg をコピーしています。 以下ループで、配列 inp の要素数(正確にはそれマイナス1)だけ繰り返されるようにしています。 配列 inp の要素数は、ユーザーの入力回数(正確にはそれマイナス1)です。

    	numTmp /= inp[i];
    	if (numTmp > 1){					// 割ったあと1になるなら表示しません
    
    		ctx.fillStyle = '#F00';				// 赤文字で
    		x = 50 - ctx.measureText( inp[i] ).width;	// 右端を 50 にあわせる
    		ctx.fillText(inp[i], x, y - 40);		// 1行上に表示
    

    途中経過表示用の numTmp を、ユーザー入力の値 inp[ i ] で割ります。 この値が1になるなら、表示しません(そういうルールにしているため)。

    この部分では、割られる数字の左に表示している赤い文字(入力文字)を描画しています。 赤を指定し、文字の右端を 50 ピクセル位置で右詰め表示できる位置を決定しています。 表示位置は、今の y より1行上になるべきなので、1行のピクセル数 40 を引いて描画しています。

    		ctx.fillStyle = '#000';
    		ctx.fillText(')', 55, y - 40);			// 1行上に表示すべき
    		ctx.fillRect(55, y - 40 + 2, x_num - 55 + 10, 2);// ラインを引く
    

    この部分では、ラインの部分を書いています。 描画が面倒なので、閉じかっこを描画したあと、下に横ラインを引いています。 デバイスや環境によっては、少しずれてしまいますが、今は良しとします。

    途中計算部分

    		x = x_num - ctx.measureText( numTmp ).width;	// 右端を x_num にあわせる
    		ctx.fillText( numTmp, x, y);			// クライアント領域の座標(y座標は'下'を指しているよう)
    	}
    	y += 40;
    }
    

    最後に、今 y が指す行に、割られた後の数値を描画しています。

    ▲ページ先頭へ

    このあとは・・・

    投稿 September 26, 2020

    このプログラムの次に作成した DaysUntil では、日付の取得やコンボボックス(ドロップダウンリスト)の操作を扱っています。

    ▲ページ先頭へ
    line
    関連トピックス
    line


    その他のおすすめ

    ウェブ開発に関するトピックは、「ウェブ開発トップ」にまとめられています。



    © 2017-2020 StraightApps.com 無断転載を禁じます。No reproduction without permission.