フリップフロップ回路

S,RでQ1の値を変化させます

記憶素子の例です。S,RのあたりをクリックすることでQ1が変化します。

SはsetでQ1を1に倒します。

RはresetでQ1を0に倒します。

0 フリップフロップ回路説明図0-1 フリップフロップ回路説明図0-2 フリップフロップ回路説明図0-3 0
フリップフロップ回路説明図1-1 フリップフロップ回路説明図1-2 フリップフロップ回路説明図1-3
0 フリップフロップ回路説明図2-1 フリップフロップ回路説明図2-2 フリップフロップ回路説明図2-3 0
フリップフロップ回路説明図3-1 フリップフロップ回路説明図3-2 フリップフロップ回路説明図3-3

小画面の時 幅に合わせる 元の大きさで

S,R,Q1,Q2の状態を0,1の表示で示し、さらに、配線にも0ならば青、1ならば赤と色をつけています。

次の2点を押さえてください。

  1. 入力にS,R、出力にQ1,Q2がありますが、出力はQ1のみを考えます。
  2. S,Rは普段は0で、シーソーを倒すために一瞬だけ1にするボタンだと理解してください。
    ずっと1にしておくということはありません。

制作の経緯

この辺のことには詳しくないのですが、教科書に掲載されていたことで扱いました。教科書の解説だけだとわかりにくいので、具体的に動くものがあった方がいいだろうと作成しました。端子だけでなく、配線の heigh/low も見える方が動作を追いやすいだろうというところがポイントです。

配線の色は、配線を透過にして背景色を換えるという手法を思いついたことも制作の動機の一つですが、優れた手法だったかは微妙です。

もう一つの動機は、S,Rが押しているときだけonで離すとoffになるという仕様なので、いつものonclickでなく、onmousedownとonmouseupを試す機会になるということでした。

IE対応

最初の作成が2009年です。授業環境に合わせてLinux-Firefoxで作成しました。そのため、addEventListener()やtextContentを使っていました。

その後、インターネット上に公開するにあたり、時代遅れのインターネットエクスプローラ(IE)でも対応している手法に書き換えました。addEventListener()はelement.onmousedown=function(){...に、textContentはfirstChild.nodeValueに書き換えるので良かったのですが、一番の問題は透過pngでした。IEのver6は24ビットカラーの透明度に対応していなかったのです。

2009年といえばWindows7が出た年です。Vistaはほとんど普及せずXPが主流でした。XPにインストールされていたIEはver6。IEをバージョンアップしてもver8でこれを使っている人が多かったのです。

対策は256色のpngにして、一色の透過にすることでしたが、斜めの線がある図なので一色だとギザギザが目立ちます。結局斜め線の部分は色を変更した2枚の図を用意して取り替えることになりました。

解説

位置の特定は、idをたくさん置いて、getElementByIdで行っています。

イベントハンドラは、element.onmousedown =function(){son();} などとしています。son()と直接書くとその場で実行してしまうのでこの書き方をします。

son(), soff(), ron(), roff() で、s,r のon,offで起こることを実際にtrue/falseを使ってシミュレートしています。その後setcolor()でその結果に応じで表示を変えていきます。

背景色を換えるには、element.style.backgroundColor = onncolor; など、

画像を入れ替えるのは、element.firstChild.src = "img/flipflop12onn.png"; などです。

改めて考えると、(1)ronのときと(2)その後、(3)sonの時と(4)その後の4つの状態しかないので、4枚の画像を用意して切り替えればいいじゃないかという気もします。画像の1セットは15.6KB、交換画像のある今回のタイプは24.2KB。4枚の画像を用意する場合は8×4=32KBです。各端子の状態を実際に計算しているので、他の回路に応用が可能で結果に確信が持てるというメリットがあります。ただし画像をタイル状に切り分けるのは面倒ですからこの部分は別の方策が望ましいと思います。

モバイル対応

さらに、面倒だったのがモバイル対応です。初期画面は図を縮小させずにスクロールします。

tableの親のdiv.tableタグにcssで、overflow:auto;を指定し、width,heightを正確に書いています(画像のないセルにはwidthを指定しています)。 imgにつけることが多いmax-width:100%;の指定は削除します。これでpre同様にdiv.tableのみ横スクロールになります。

ボタンをつけて画面にフィットさせることを選ぶことができるようにしました。図を構成するタイル状の画像の縦横比が同じでないので縮小すると隙間ができて背景色が漏れます。

縮小にするポイントは、すべてのimgにmax-width:100%;の指定を入れること。モバイルのブラウザはtableを320pxに収めようとします。imgは割り当てられたセル幅の100%になるように縮小されます。tableのwidth,heightをautoにしておくことで、縦横比が保存されたまま縮小されます。丸め誤差で隙間ができるのだと推測しています。

デスクトップ機のディスプレイには影響はありません。タイル状にするデメリットがまた一つ増えたというところです。

もう一つ問題があります。タッチパネルにはonmousedown,onmouseupがありません。タップがクリックになり、mousedownで押さえている状態を作ることができません。ちなみにonmouseoverもありません。タップでonmouseoverイベントも起こります。

プログラム

<script>
var s=false;
var r=false;
var a= ! s;
var d= ! r;
var b,c,q1,q2;
var e00,e01,e02,e04, e11,e12,e13, e20,e21,e22,e23,e24, e31,e32;
var onncolor = "#ff0000";
var offcolor = "#003399";
function setlistner() {
     e00 = document.getElementById("flipflop00");
     e00.onmousedown =function(){son();}
     e00.onmouseup   =function(){soff();}
     e01 = document.getElementById("flipflop01");
     e01.onmousedown =function(){son();}
     e01.onmouseup   =function(){soff();}
     e02 = document.getElementById("flipflop02");
     e04 = document.getElementById("flipflop04");
     e11 = document.getElementById("flipflop11");
     e11.onmousedown =function(){son();}
     e11.onmouseup   =function(){soff();}
     e12 = document.getElementById("flipflop12");
     e13 = document.getElementById("flipflop13");
     e20 = document.getElementById("flipflop20");
     e20.onmousedown =function(){ron();}
     e20.onmouseup   =function(){roff();}
     e21 = document.getElementById("flipflop21");
     e21.onmousedown =function(){ron();}
     e21.onmouseup   =function(){roff();}
     e22 = document.getElementById("flipflop22");
     e23 = document.getElementById("flipflop23");
     e24 = document.getElementById("flipflop24");
     e31 = document.getElementById("flipflop31");
     e31.onmousedown =function(){ron();}
     e31.onmouseup   =function(){roff();}
     e32 = document.getElementById("flipflop32");
     roff();
}
function son(){
  s = true; a = !s; b = q2;
  q1 = !(a && b);
  c = q1;
  q2 = !(c && d);
  b = q2;
  setcolor();
}
function soff(){
  s = false; a = !s; b = q2;
  q1 = !(a && b);
  c = q1;
  q2 = !(c && d);
  b = q2;
  setcolor();
}
function ron(){
  r = true; d = !r; c = q1;
  q2 = !(c && d);
  b = q2;
  q1 = !(a && b);
  c = q1;
  setcolor();
}

function roff(){
  r = false; d = !r; c = q1;
  q2 = !(c && d);
  b = q2;
  q1 = !(a && b);
  c = q1;
  setcolor();
}

function setcolor(){
   if(s) {
     e01.style.backgroundColor=onncolor;
     e00.firstChild.nodeValue="1";
     e00.style.color=onncolor;
   }else {
     e01.style.backgroundColor=offcolor;
     e00.firstChild.nodeValue="0";
     e00.style.color=offcolor;
   }
   if(a) e02.style.backgroundColor=onncolor;
    else e02.style.backgroundColor=offcolor;
   //if(b) e12.style.backgroundColor=onncolor;
   // else e12.style.backgroundColor=offcolor;
   //if(c) e22.style.backgroundColor=onncolor;
   // else e22.style.backgroundColor=offcolor;
   if(b) e12.firstChild.src="ffimgonf/flipflop12onn.png";
    else e12.firstChild.src="ffimgonf/flipflop12off.png";
   if(c) e22.firstChild.src="ffimgonf/flipflop22onn.png";
    else e22.firstChild.src="ffimgonf/flipflop22off.png";

   if(d) e32.style.backgroundColor=onncolor;
    else e32.style.backgroundColor=offcolor;
   if(r) {
      e31.style.backgroundColor=onncolor;
      e20.firstChild.nodeValue="1";
      e20.style.color=onncolor;
   }else {
      e31.style.backgroundColor=offcolor;
      e20.firstChild.nodeValue="0";
      e20.style.color=offcolor;
   }
   if(q1){
      //e13.style.backgroundColor=onncolor;
      e13.firstChild.src="ffimgonf/flipflop13onn.png";
      e04.firstChild.nodeValue="1";
      e04.style.color=onncolor;
   } else{
      //e13.style.backgroundColor=offcolor;
      e13.firstChild.src="ffimgonf/flipflop13off.png";
      e04.firstChild.nodeValue="0";
      e04.style.color=offcolor;
   }
   if(q2){
      //e23.style.backgroundColor=onncolor;
      e23.firstChild.src="ffimgonf/flipflop23onn.png";
      e24.firstChild.nodeValue="1";
      e24.style.color=onncolor;
   }else {
      //e23.style.backgroundColor=offcolor;
      e23.firstChild.src="ffimgonf/flipflop23off.png";
      e24.firstChild.nodeValue="0";
      e24.style.color=offcolor;
   }
     
}
window.onload = function(){
  setlistner();
}
</script>

説明図

行番号、列番号の確認です。

0 1 2 3 4
0 0 フリップフロップ回路説明図0-1 フリップフロップ回路説明図0-2 フリップフロップ回路説明図0-3 0
1 フリップフロップ回路説明図1-1 フリップフロップ回路説明図1-2 フリップフロップ回路説明図1-3
2 0 フリップフロップ回路説明図2-1 フリップフロップ回路説明図2-2 フリップフロップ回路説明図2-3 0
3 フリップフロップ回路説明図3-1 フリップフロップ回路説明図3-2 フリップフロップ回路説明図3-3

途中省略で、

小画面の時 幅に合わせる 元の大きさで

html

<table id="flipflop">
<tbody>
<tr>
<td id="flipflop00" rowspan="2">0</td>
<td id="flipflop01"><img src="ffimgonf/flipflop01.png"></td>
<td id="flipflop02"><img src="ffimgonf/flipflop02.png"></td>
<td id="flipflop03"><img src="ffimgonf/flipflop03.png"></td>
<td id="flipflop04" rowspan="2">0</td>
</tr>

<tr>
<td id="flipflop11"><img src="ffimgonf/flipflop11.png"></td>
<td id="flipflop12"><img src="ffimgonf/flipflop12.png"></td>
<td id="flipflop13"><img src="ffimgonf/flipflop13.png"></td>
</tr>

<tr>
<td id="flipflop20" rowspan="2">0</td>
<td id="flipflop21"><img src="ffimgonf/flipflop21.png"></td>
<td id="flipflop22"><img src="ffimgonf/flipflop22.png"></td>
<td id="flipflop23"><img src="ffimgonf/flipflop23.png"></td>
<td id="flipflop24" rowspan="2">0</td>
</tr>

<tr>
<td id="flipflop31"><img src="ffimgonf/flipflop31.png"></td>
<td id="flipflop32"><img src="ffimgonf/flipflop32.png"></td>
<td id="flipflop33"><img src="ffimgonf/flipflop33.png"></td>
</tr>
</tbody>
</table>

css

.table { overflow: auto; }
table#flipflop{
   width:448px;  /*32+98+113+173+32*/
   height:206px; /*42+60+62+42*/
   border-collapse:collapse;
   border-spacing: 0px;
   border:none;
   margin:1% 2% 2% 2%;
}
table#flipflop td{
   padding:0;
   border:none;
}
table#flipflop img{
   padding:0;
   margin:0;
   border:none;
   vertical-align: bottom;
}
#flipflop #flipflop00{
   vertical-align: top;
   text-align:center;
   width:32px;
   padding:0 ;
   font-size:30px;
}
#flipflop #flipflop20{
   vertical-align: bottom;
   text-align:center;
   width:32px;
   padding:0 ;
   font-size:30px;
}
#flipflop #flipflop04{
   text-align:right;
   width:32px;
   padding:0;
   font-size:36px;
}
#flipflop #flipflop24{
   text-align:right;
   width:32px;
   padding:0;
   font-size:36px;
}