LoginSignup
2
2

More than 3 years have passed since last update.

数学用ソフトウェアキーボードをJavaScriptで作ってみた

Posted at

分数の入力ができない

 算数のWeb教材を作成したとき、整数と小数はキーボードから入力できるが、「分数は入力できない」という問題にぶつかりました。このような場合には、「選択肢を用意する」という方法で対処を行うのが普通です。でも、小学生のプリント問題で、分数でしか回答できない場合に「選択肢から選ぶ」というのは、あまりに不自然な感じがします。そこで「分数を入力する」ために、数学用ソフトウェアキーボードをJavaScriptで作ってみました。
 分数に加えて、「ルート √ 累乗 23 パイ π」も入力できるようにして、中学校数学のWeb教材に対応するソフトウェアキーボードの作成を目標としました。

サンプルサイト

 今回のサンプルサイトはこちらです。
http://iwate-manabi-net.sakura.ne.jp/math_software_keyboard/

 ソフトウェアキーボードを利用した教材サンプルはこちらです。
http://www1.iwate-ed.jp/tantou/joho/material/g-tablet-m/index.html

MathJax を使って数式を表示

 数式の表示にはMathJaxをJavaScriptライブラリとして利用しました。
https://www.mathjax.org/
 最新版のMathJax3が公開になっていますが、今回は古いバージョンを使用します。WARNINGが表示されますが、気にせず使っていきましょう。
 使い方についてはこちらのページを参照願います。
http://www.eng.niigata-u.ac.jp/~nomoto/download/mathjax.pdf

HTMLソース

index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({ tex2jax: { inlineMath: [['$','$'], ["\\(","\\)"]] } });
</script>
<script type="text/javascript"
   src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML">
</script>
<script src="js/jquery.min.js"></script>
<script src="js/jquery-ui.min.js"></script>
<script src="js/jquery.ui.touch-punch.js"></script>
<script src="math_software_keyboard.js"></script>
<link rel="stylesheet" href="math_software_keyboard.css">
<title>数学用ソフトウェアキーボード</title>
</head>
<body>
<h1>数学用ソフトウェアキーボード</h1><br>
<div id="setumei">
1 次の計算をしなさい。<br>
    ※ 例: <span class='siki'>\(2\sqrt{3}\)</span> の入力→ 「2」「ルート」「3」
</div><br>
<div style='float:left'>
(1)  <span class='siki'>\(3\sqrt{5}+6\sqrt{5}\)</span><br>
   <span id='buttonShow1' class='buttonShowClass'>クリックして答えを入力</span>
答  <span id='kotae1' class='siki'><font size='3'></font></span>
  <span id='maru1' class='maru'></span>
</div>
    <div id='kaisetu1' class='kaisetu'></div>
<div style='clear: both'></div>
<div id='inputButton1'></div><br><br>
</body>
</html>

CSSソース

math_software_keyboard.css
/* math_software_keyboard.css */
#setumei{
    font-weight: bold;
    color: #060;
}

.buttonShowClass{
    background-color: #cff;
    padding: 10px 10px 10px 10px;
    border-radius:4px;
    border:1px solid #bbd;
    box-shadow:2px 2px 2px 2px rgba(200, 200, 200, 0.4);
    margin: 0px 5px;
    cursor:pointer;
}

.waku{
    user-select: none; /* CSS3 単語を選択させない */
    -moz-user-select: none; /* Firefox */
    -webkit-user-select: none; /* Safari、Chromeなど */
    -ms-user-select: none; /* IE10かららしい */
    -webkit-tap-highlight-color:#fff;
    background-color: #eef;
    padding: 10px 5px 5px 5px;
    border-radius:4px;
    border:1px solid #888;
    box-shadow:2px 2px 2px 2px rgba(200, 200, 200, 0.4);
    margin: 0px 5px;
    width:800px;
}

.bs{
    user-select: none; /* CSS3 単語を選択させない */
    -moz-user-select: none; /* Firefox */
    -webkit-user-select: none; /* Safari、Chromeなど */
    -ms-user-select: none; /* IE10かららしい */
    -webkit-tap-highlight-color:#fff;
    background-color: #ccf;
    padding: 10px 10px 10px 10px;
    border-radius:4px;
    border:1px solid #999;
    box-shadow:2px 2px 2px 2px rgba(200, 200, 200, 0.6);
    margin: 0px 5px;
    cursor:pointer;
    font-weight:bold;
}

.bc{
    user-select: none; /* CSS3 単語を選択させない */
    -moz-user-select: none; /* Firefox */
    -webkit-user-select: none; /* Safari、Chromeなど */
    -ms-user-select: none; /* IE10かららしい */
    -webkit-tap-highlight-color:#fff;
    background-color: #ffa;
    padding: 10px 5px 10px 5px;
    border-radius:4px;
    border:1px solid #aaa;
    box-shadow:2px 2px 2px 2px rgba(200, 200, 200, 0.6);
    margin: 0px 5px;
    cursor:pointer;
}
.maru{
    user-select: none; /* CSS3 単語を選択させない */
    -moz-user-select: none; /* Firefox */
    -webkit-user-select: none; /* Safari、Chromeなど */
    -ms-user-select: none; /* IE10かららしい */
    -webkit-tap-highlight-color:#fff;
    vertical-align: middle;
    color: red;
    opacity:0;
    font-size: 500%;
}
.siki{
    font-size: 130%;
}

.kaisetu{
    user-select: none; /* CSS3 単語を選択させない */
    -moz-user-select: none; /* Firefox */
    -webkit-user-select: none; /* Safari、Chromeなど */
    -ms-user-select: none; /* IE10かららしい */
    -webkit-tap-highlight-color:#fff;
    color: blue;
    font-size: 120%;
}

JavaScriptソース

math_software_keyboard.js
var mondaiMax= 1;  // 問題数
var kaitouNumber=0;
var kaitouText = new Array();
var buttonText = new Array();
for(var i=0; i<= mondaiMax ; i++){           //問題数
    buttonText[i] = [];
    for(var j=0; j<20; j++){
        buttonText[i][j] = '';
    }
}
var buttonCheckText ="";
var buttonMax  = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; // 初期値 0
var kaisetuText = "";

//    入力用のボタン表示
var bData ="";
    bData = bData + "<div id='inputNow' class='waku'><br>";
    //bData = bData + "<br>";
    bData = bData + "<span id='bbb' class='bs'>分母入力</span><span id='bbe' class='bs'>分数おわり</span>";
    bData = bData + "<span id='brs' class='bs'>ルート</span><span id='bre' class='bs'>ルートおわり</span>";
    bData = bData + "<span id='bpi' class='bs'>π</span><span id='bpw' class='bs'>累乗</span>";
    bData = bData + "<span id='bpm' class='bs'>±</span>";
    bData = bData + " <span id='bal' class='bc'>すべて消す</span><br><br><br>";
    bData = bData + "<span id='bt' class='bs'>+</span><span id='bh' class='bs'>-</span><span id='bk' class='bs'>×</span>";
    bData = bData + "<span id='bw' class='bs'>÷</span><span id='bi' class='bs'>=</span>";
    bData = bData + "<span id='bks' class='bs'>(</span><span id='bke' class='bs'>)</span>";
    bData = bData + "<span id='ma' class='bs'>a</span><span id='mb' class='bs'>b</span><span id='mc' class='bs'>c</span>";
    // bData = bData + "<span id='md' class='bs'>d</span>";
    bData = bData + "<span id='mx' class='bs'>χ</span><span id='my' class='bs'>y</span><span id='mz' class='bs'>z</span>";
    bData = bData + "<span id='bba' class='bc'>←1つもどる</span><br><br><br>";
    bData = bData + "<span id='b1' class='bs'>1</span><span id='b2' class='bs'>2</span><span id='b3' class='bs'>3</span>";
    bData = bData + "<span id='b4' class='bs'>4</span><span id='b5' class='bs'>5</span><span id='b6' class='bs'>6</span>";
    bData = bData + "<span id='b7' class='bs'>7</span><span id='b8' class='bs'>8</span><span id='b9' class='bs'>9</span>";
    bData = bData + "<span id='b0' class='bs'>0</span><span id='bd' class='bs'>.</span>";
    bData = bData + "<span id='bhide' class='bc'>閉じる</span> <span id='bcheck' class='bc'>解答する</span><br><br><br>";
    bData = bData + "</div>";

$(function() {  // jQuery を実行 
    $('#inputButton1').hide();  // キーボードの表示を消しておく

    $('#buttonShow1').on('click', function () {
        funcButtonHide();
        kaitouNumber = 1;                              // 問題番号
        $('#inputButton' +kaitouNumber).html(bData);   // キーボードの表示
        $('#inputButton' +kaitouNumber).show('normal');// アニメーション表示
        buttonReload();                                // ボタンを作動させる
        $('#buttonShow' +kaitouNumber).hide();         //「クリックして答えを入力」ボタンを隠す
    });

    function funcKaitou(){
        switch (kaitouNumber){
            case 1:  //問題番号1 の場合
                // 計算式の表示
                kaisetuText =                   ' \\(3\\sqrt{5}+6\\sqrt{5}\\) ';
                kaisetuText = kaisetuText+      '=\\((3+6)\\sqrt{5}\\) ';
                kaisetuText = kaisetuText+      '=\\(9\\sqrt{5}\\)<br>';
                $('#kaisetu' + kaitouNumber).html(kaisetuText);
                // 答え合わせ
                if((kaitouText[kaitouNumber] == '\\({9}\\sqrt{5}\\)')  //9ルート5
                 ||(kaitouText[kaitouNumber] == '\\({9}\\sqrt{5}\\)\\({}\\)')){ //9ルート5 ルートおわり
                    $('#maru' + kaitouNumber ).css('opacity',1);  //正解の場合
                }else{
                    funcBatu();  //不正解の場合
                }
                break;
        };
        MathJax.Hub.Queue(["Typeset",MathJax.Hub,('kaisetu' + kaitouNumber)]);  //数式を表示
        $('#buttonShow'+ kaitouNumber ).hide();         //キーボード表示ボタンを消します
        $('#inputNow').remove();
        $('#inputNow').html("<div id='inputButton" + kaitouNumber + "'></div>");
        $('#inputButton' + kaitouNumber).hide();
        $(('#buttonShow'+ kaitouNumber)).remove();

    };

    function funcBatu(){       //  不正解の場合、バッテンを表示
        $('#maru' + kaitouNumber).text('×');
        $('#maru' + kaitouNumber).css('opacity',1);
        $('#maru' + kaitouNumber).css('color','blue');
    };

    function funcButtonHide() {         //キーボードを消す
        $('#inputNow').remove();
        $('#inputNow').html("<div id='inputButton" + kaitouNumber + "'></div>");
        $('#inputButton' + kaitouNumber).hide();
        $(('#buttonShow'+ kaitouNumber)).show();
    }

    function buttonReload(){ //     数学用ソフトウェアキーボードが押されたとき
        $('#b1' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="1"; buttonMax[kaitouNumber]++ ; display(); });
        $('#b2' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="2"; buttonMax[kaitouNumber]++ ; display(); });
        $('#b3' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="3"; buttonMax[kaitouNumber]++ ; display(); });
        $('#b4' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="4"; buttonMax[kaitouNumber]++ ; display(); });
        $('#b5' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="5"; buttonMax[kaitouNumber]++ ; display(); });
        $('#b6' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="6"; buttonMax[kaitouNumber]++ ; display(); });
        $('#b7' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="7"; buttonMax[kaitouNumber]++ ; display(); });
        $('#b8' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="8"; buttonMax[kaitouNumber]++ ; display(); });
        $('#b9' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="9"; buttonMax[kaitouNumber]++ ; display(); });
        $('#b0' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="0"; buttonMax[kaitouNumber]++ ; display(); });
        $('#bd' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="."; buttonMax[kaitouNumber]++ ; display(); });
        $('#ma' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="a"; buttonMax[kaitouNumber]++ ; display(); });
        $('#mb' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="b"; buttonMax[kaitouNumber]++ ; display(); });
        $('#mc' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="c"; buttonMax[kaitouNumber]++ ; display(); });
        $('#md' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="d"; buttonMax[kaitouNumber]++ ; display(); });
        $('#mx' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="x"; buttonMax[kaitouNumber]++ ; display(); });
        $('#my' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="y"; buttonMax[kaitouNumber]++ ; display(); });
        $('#mz' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="z"; buttonMax[kaitouNumber]++ ; display(); });
        $('#bt' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]=""; buttonMax[kaitouNumber]++ ; display(); });
        $('#bh' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]=""; buttonMax[kaitouNumber]++ ; display(); });
        $('#bk' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="×"; buttonMax[kaitouNumber]++ ; display(); });
        $('#bw' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="÷"; buttonMax[kaitouNumber]++ ; display(); });
        $('#bi' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]=""; buttonMax[kaitouNumber]++ ; display(); });
        $('#bks').on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]=""; buttonMax[kaitouNumber]++ ; display(); });
        $('#bke').on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]=""; buttonMax[kaitouNumber]++ ; display(); });
        $('#bpi').on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="π"; buttonMax[kaitouNumber]++ ; display(); });
        $('#bpm').on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="±"; buttonMax[kaitouNumber]++ ; display(); });
        $('#bbb').on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="分母入力"; buttonMax[kaitouNumber]++ ; display(); });
        $('#bbe').on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="分数おわり"; buttonMax[kaitouNumber]++ ; display(); });
        $('#brs').on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="ルートはじめ"; buttonMax[kaitouNumber]++ ; display(); });
        $('#bre').on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="ルートおわり"; buttonMax[kaitouNumber]++ ; display(); });
        $('#bpw').on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="累乗"; buttonMax[kaitouNumber]++ ; display(); });
        $('#bba').on('click', function () { buttonMax[kaitouNumber]-- ; if( buttonMax[kaitouNumber] <0 ){ buttonMax[kaitouNumber] =0 }display(); });
        $('#bal').on('click', function () { buttonMax[kaitouNumber] =0; display(); });
        $('#bhide').on('click', function () {funcButtonHide();});
        $('#bcheck').on('click', function () {funcKaitou();});
    };
    buttonReload();    //  ボタンを使えるようにする

    function display() {
        buttonCheckText ="";
        var myText="\\({";           //\を表示するには2回\\
        for ( var k=0; k <buttonMax[kaitouNumber] ;k++){
            switch (buttonText[kaitouNumber][k]){
                case "1": myText = myText + "1" ;break;
                case "2": myText = myText + "2" ;break;
                case "3": myText = myText + "3" ;break;
                case "4": myText = myText + "4" ;break;
                case "5": myText = myText + "5" ;break;
                case "6": myText = myText + "6" ;break;
                case "7": myText = myText + "7" ;break;
                case "8": myText = myText + "8" ;break;
                case "9": myText = myText + "9" ;break;
                case "0": myText = myText + "0" ;break;
                case ".": myText = myText + "." ;break;
                case "a": myText = myText + "a" ;break;
                case "b": myText = myText + "b" ;break;
                case "c": myText = myText + "c" ;break;
                case "d": myText = myText + "d" ;break;
                case "x": myText = myText + "x" ;break;
                case "y": myText = myText + "y" ;break;
                case "z": myText = myText + "z" ;break;
                case "": myText = myText + "+" ;break;
                case "": myText = myText + "-" ;break;
                case "×": myText = myText + "×" ;break;
                case "÷": myText = myText + "÷" ;break;
                case "": myText = myText + "=" ;break;
                case "": myText = myText + "(" ;break;
                case "": myText = myText + ")" ;break;
                case "π": myText = myText + "\\pi" ;break;
                case "±": myText = myText + "\\pm" ;break;
                case "分母入力": myText = myText + "}\\over{" ;break;
                case "分数おわり": myText = myText + "}\\)\\({" ;break;
                case "ルートはじめ": myText = myText + "}\\sqrt{" ;break;
                case "ルートおわり": myText = myText + "}\\)\\({" ;break;
                case "累乗": myText = myText + "\^" ;break;
            };
            buttonCheckText = buttonCheckText +buttonText[kaitouNumber][k];
        };
        if(buttonMax[kaitouNumber] > 0){
            if(buttonText[kaitouNumber][buttonMax[kaitouNumber] -1] == "累乗"){    //累乗入力の時に表示が変になるを防ぐ
                myText = myText + "";
            };
        };
        myText = myText + "}\\)";
        //MathJax表示
        $(("#kotae" + kaitouNumber)).html(myText);
        MathJax.Hub.Queue(["Typeset",MathJax.Hub,("kotae" + kaitouNumber)]);
        kaitouText[kaitouNumber]= myText;
    };
     $('body').bind('updated',function(){display()});
});

非表示にしたいボタン(キー)があるときには、
// 入力用のボタン表示
の下の部分で
// bData = bData + <span id='brs' class='bs'>ルート・・・
 ↑このように//を使ってコメントアウトすると、「ルート」ボタンが非表示になります。

2
2
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2