「プログラミング」カテゴリーアーカイブ

Programing

永遠の旅人、芭蕉の足跡

芭蕉足跡の一つ

時空と季節を超越して江戸時代の俳人、松尾芭蕉の足跡のひとつを訪ねてみます。BGMはヨーロッパの著名な民謡《ドナウ川のさざなみ》を用意しました。最上川とは趣きは異なりますが著作権がらみで世界の民謡を取り上げました。画像は小高い山から眺めた庄内平野です。

音声再生ボタンを押下してなにもかもスタートです。

プログラムコードについて

俳句はInkscapeでPathデータを作りました。Inkscapeは漢字の振り仮名はサポートしてくれません。振りがなは漢字と同様にしてPathデータを作り、本文との位置はTry and Goで決めます。この作業は時間に比例して確実に進みます。

このアプリが生成したプログラムコードに手を加えて画像とテキストの共存を図っています。両立のポイントはopacityを巧妙に操ることです。ソースコードの公開は故あって先延ばしになります。

 

特別なクリスマスプレゼント

プログラミング教育必修化

来年の4月から小学校においてプログラミング教育が必修化になります。プログラミングを構えすぎると難解と言えますが、自然に使っていくと入りやすいでしょう。赤ちゃんは覚えたものだけを大胆に使います。

覚えたものを一つずつ使っていけばやがて高みに到達するでしょう。まずは臆せずに使いましょう。

動きのある書類

電子書類にちょっとした動きを付けるにはHTML, CSS, JavaScriptを使いこなすと多彩な表現が可能です。恐縮ですが以下のサンプルは難解の部に入ります。以下のような動くドキュメントを表現できる一つの例を挙げます。末尾にHTMLコードを示します。

あかりちゃん クリスマスおめでとう 音符記号をクリックして開始 ♫音楽:甘茶の音楽工房より 『ヴァルス』♫ ©2019 TacM, Ver0.01

 

 

 

個別に改造する方法

以前に、七五三お祝いのメッセージにおいて「玲依ちゃん」の七五三を祝いました。当事者の氏名を変更することは初心者には難儀であることを述べました。名前を一筆書きのように表示するには、独自のフォントを作成するに等しくLazy-Line-Painterなどの専門知識を必要とします。

ここでは「あかりちゃん」の仮名を使っていますが遅延表示をしていないので容易に関係者の名前に変更できます。また、BGMはフリー素材の音源を使っていますが家族で楽しむぶんには最新の人気曲に差し替えることも可能でしょう。

上の図は「あかりちゃん」を表示するコードの一部分です。赤字のところを置き換えれば個別に対応できます。BGMを独自のものに差し替えるにはaudio要素のsrcに音声オブジェクトの格納アドレスを指定します。

出来合いの作品だけでなくオリジナル作品をどしどし発表して存在感を発揮してください。

HTMLコード

<!DOCTYPE html>
<html>
<head>
<style>
  body{
    width: 100%;
    height: 100%;
    margin: 0;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  #kisho6 {
    width: 50vw;
    height: 50vh;
    overflow: visible;
  }
</style>
<script type="text/javascript" charset="utf-8">
const day=["12/92kisho-0.png", "04/jitensha.png", "04/dokusho.png", 59, 63, 63, "04/f1-kaban.png",
           "12/hirune.png",    "12/sanpo.png",    "12/otohsan.png", 50, 56, 68, "04/f2-hoikuen.png"];
var i=0;

function startPlay(){								//
var music = new Audio("http://aidesign.lolipop.jp/wp-content/uploads/2019/04/valse.mp3");
	music.addEventListener("ended", closeProc, false);
	music.play();
}
function closeProc(){								//BGMの終了イベント
  renewal();
}
function renewal(){									//congratulateAdmission, closeProc
	var j = (i++ % 2) * 7;							//j : 0 or 7
	f0.setAttribute("xlink:href", "http://aidesign.lolipop.jp/wp-content/uploads/2019/" + day[j]);
	f1.setAttribute("xlink:href", "http://aidesign.lolipop.jp/wp-content/uploads/2019/" + day[j+1]);
	f2.setAttribute("xlink:href", "http://aidesign.lolipop.jp/wp-content/uploads/2019/" + day[j+2]);
	f0.setAttribute("height", day[j+3]);
	f1.setAttribute("height", day[j+4]);
	f2.setAttribute("height", day[j+5]);
	setTimeout(function(){
	  console.log("finish", j, day[j+6]);
	  f3.setAttribute("xlink:href", "http://aidesign.lolipop.jp/wp-content/uploads/2019/" + day[j+6]);
	  if(i%2 == 0){
		headmsg1.setAttribute("visibility", "visible");
	  }
	},1500);										//8000 &#x27a1; 1500
}
function congratulateAdmission(){					//音符記号ボタンのクリックで起動
  renewal();
  headmsg1.setAttribute("visibility", "hidden");
  document.getElementById('text814').style.fillOpacity = "1.0";
  document.getElementById('text824').style.fillOpacity = "1.0";
  startPlay();										//starting
}
</script>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" width="297mm" height="210mm" viewBox="0 0 297 210" id="kisho6">
  <g transform="translate(0,0)">
     <g><image id="f0" x="10" y="70" width="78" height="59" xlink:href="http://aidesign.lolipop.jp/wp-content/uploads/2019/12/92kisho-0.png"></g>
     <g><image id="f1" x="110" y="70" width="78" height="63" xlink:href="http://aidesign.lolipop.jp/wp-content/uploads/2019/04/jitensha.png"></g>
     <g><image id="f2" x="200" y="70" width="78" height="63" xlink:href="http://aidesign.lolipop.jp/wp-content/uploads/2019/04/dokusho.png"></g>
     <g><image id="f3" x="10" y="145" width="265" height="66" xlink:href="http://aidesign.lolipop.jp/wp-content/uploads/2019/04/f1-kaban.png"></g>
     <text id="text814" x="15" y="25" font-size="14" fill="deeppink" fill-opacity="0.1">あかりちゃん</text>
     <text id="text824" x="15" y="50" font-size="24" fill="cyan" fill-opacity="0.1">クリスマスおめでとう</text>
  </g>
<g id="frame">
<path id="around" fill="none" stroke="pink" stroke-width="0.1rem" d="M5,5 L275,5 L275,220 L5,220 L5,5 Z"/>
<image id="f4" x="0" y="0" width="23" height="18" xlink:href="http://aidesign.lolipop.jp/wp-content/uploads/2019/04/elephant.png">
<animateMotion dur="20s" calcMode="linear" repeatCount="indefinite"><mpath xlink:href="#around" /></animateMotion>
</g>
<text id="headmsg1" x="140" y="20" font-size="10" fill="darkgreen">&#x97F3;&#x7B26;&#x8A18;&#x53F7;&#x3092;&#x30AF;&#x30EA;&#x30C3;&#x30AF;&#x3057;&#x3066;&#x958B;&#x59CB;</text>
<a onclick="congratulateAdmission();" style="text-decoration:underline;">
<text x="10" y="250" font-size="8">&#x266B;&#x97F3;&#x697D;&#x3A;&#x7518;&#x8336;&#x306E;&#x97F3;&#x697D;&#x5DE5;&#x623F;&#x3088;&#x308A;&#x20;&#x300E;&#x30F4;&#x30A1;&#x30EB;&#x30B9;&#x300F;&#x266B;&emsp;&copy;2019 TacM, Ver0.01</text>
</a>
</svg>
</body>
</html>

 

重ね書きの一例

透かし文字

文書に至急極秘複製を禁ずなどの文字を文書に重ね書きして注意を喚起する方法があります。

古いWORDではあらかじめ用意した文字を重ね書きしていましたが今では自由に文字列を指定できるようになっているようです。

HTMLはテキストのほか画像や図形の重ね書きが可能です。そのうえ、透過率のopacityにより多彩な表現ができます。

ここでは書類の絵文字(📄)をPDFの説明文に重ね書きしています。

HTMLはフリーで使えるほか、より良い品質を目指してグローバルな協議会にて管理されています。

RESULT

📄

PDFは、「Portable Document Format」の略で、データを実際に紙に印刷したときの状態を、そのまま保存することができるファイル形式です。パソコンやスマホなどのデバイス、Windows、iOS、Linux、Unix、AndroidなどのOSの垣根を超えて見ることができる「電子的な紙」です。

 

サンプルコード

<style type="text/css">
.radius_test {
    margin-top: -360px;         /* 重ね書きの位置 */
    width: 360px;               /* 幅指定 */
    height: 360px;              /* 高さ指定 */
    border: solid 2px green;	/* 枠線指定 */
    background-color: #fdede4;	/* 背景色指定 */
    border-radius: 10px;        /* 角丸指定 */
    font-size:24px;
    color:navy;
}
</style>
<div style="width:360px; height:360px; font-size:192px; color:yellow; border:0px red solid;"><p style="padding-left:70px; padding-top:50px; opacity:0.6;">&#x1F4C4;</p></div>
<div class="radius_test">
<span style="color:deeppink; font-weight:bold;">PDF</span>は、「Portable Document Format」の略で、データを実際に紙に印刷したときの状態を、そのまま保存することができるファイル形式です。パソコンやスマホなどのデバイス、Windows、iOS、Linux、Unix、AndroidなどのOSの垣根を超えて見ることができる「電子的な紙」です。
</div>

 

めくりフリップその後

おあずけ

テレビ番組やプレゼンにおいてフリップに付箋紙をかぶせて最初は見えないようにし気を持たせるおあずけ手法があります。めくりフリップについては当ブログでは数度、取り上げています。

①動的な表現のいろいろ

②めくりフリップ

③世界の若者二態

先の例では一度めくると元の戻すことができませんでした。再度クリックすれば目隠しが元に戻るようにした例を以下に掲げます。参考になれば幸いです。

お隠れ/御出座ここをクリック

サンプルコード

<html>
<div onClick="document.all.item('okng').style.visibility=(document.getElementById('okng').style.visibility.length==6)?'visible':'hidden';">
<span style="font-size:36px; color:orange;">お隠れ/御出座</span><span style="font-size:18px; color:blue;">ここをクリック</span>
</div>
<div id="okng" style="visibility:hidden; width:360px; height:160px; border:1px solid blue">
<img src="http://aidesign.lolipop.jp/wp-content/uploads/2015/09/hamanasu.png" alt="イラストB" width=350 height=152>
</div>
</html>

おまけ

御出座(ごしゅつざ)とはおでましを言います。テレビ時代劇の北町奉行、遠山左衛門尉様、御出座ぁ~!(きたまちぶぎょう、とうやまさえもんのじょうさま、ごしゅつざぁ~)のきめ台詞が浮かびます。

 

横長画像からの切り抜き

トリミングの新しい試み

横長画像をトリミングあるいは切り抜きをするとき、幅が大きくなると扱いが面倒になります。今回、object-fit:coverとobject-positionを使って部分画像に光を当ててみました。

複数の写真をかなりの枚数ごとにまとめて管理することがあります。一般に画像はサイズが大きくそれをまとめるとさらに大きくなりますが、管理のしやすさを優先する場合があります。

今回採用したobject-fitプロパティは、<img> などで指定された画像をどのようにはめ込むかを設定します。さらにオブジェクトの詳細配置を決めるには、 object-positionプロパティを用います。

object-positionは切り取る位置を全体サイズとの比率で指定します。今回、pxなどの単位で絶対指定する方式は思ったような動作は得られていません。動作確認された%による配置を以下に示します。

ブラウザの再読み込みボタンで何度でも動作出来ます。

動作例

©TacM,2019 Ver0.01

HTMLサンプルコード

<html>
<body onload="sceneChange();">
<Div style="width:300px; height:315px; border:0px red solid;">
<img id="bj" src="http://aidesign.lolipop.jp/wp-content/uploads/2019/11/bijin8.png" width="2400" height="300" style="width:300px; height:300px; object-fit:cover; object-position:85.714% 0%;">
<div style="margin-top:0px; font-size:12px; color:navy;">&copy;TacM,2019 Ver0.01</div>
</Div>
<img id="la" src="http://aidesign.lolipop.jp/wp-content/uploads/2019/11/bijin8.png" width="2400" height="300" style="width:600px; height:75px;">
<script type="text/javascript" charset="UTF-8">
var m = -1;													//グローバル変数
function sceneChange(){
	var p = ++m % 8 * 100 / 7;								//ローカル変数   14.286=100/7;
	document.getElementById('bj').style.objectPosition = p + '% 0%';	
	console.log(m, document.getElementById('bj').style.objectPosition);
	if(m < 7)	  setTimeout(sceneChange, 3000);			//3秒ごとに8枚の画像を描画する。
}
</script>
</body> 
</html>

プログラミングの肝はsceneChange関数の呼び出し回数カウンタ(m)がグローバル変数、表示画像を指定する変数pをローカル変数に定義することです。その理由は別の機会に語ります。

雑感

object-fit:coverとobject-positionを使った画像のトリミングを体験しました。切り抜いた画像の配置にはobject-positionを利用しますが0%で左端、100%で右端の画像が選択されます。

切り抜きの設定例をHTMLコードの11行目に示します。8枚の画像を順に切り取る場合は7等分のような設定になります。最初に決めた仕様に後でつじつま合わせをしたような違和感を覚えましたが先に決めたが勝ちでしょうか。

 

イベント盛り上げ装飾品

イベントを盛り上げるツール

結婚式や創業祭などは人生の中でそう何度も体験しないものです。記念のイベントを催すに当たり、特注のビンゴゲームで盛り上げてみませんか。それを制御する中核はスマホに収納されています。

会場の映像設備がユーザーに開放されるかどうかにもよりますが、スマホの画像をオンラインで表示できる時代です。

スマホ、パソコン用に開発したオンラインゲームで人生の節目にインパクトを付けて見ましょう。

今回、オリジナル画像は開始時、終了時には主催者を称える動画が表示されます。ビンゴ番号が更新されるタイミングで参加者をクローズアップして描写する演出が可能です。

主催者のアイデアに寄り添い世界に二つとない企画でイベントを盛り上げよう。

ビンゴ籠をクリックして開始です。ビンゴ籠の回転はChromeブラウザが脈動なしでスムースです。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ビンゴゲーム管理ソフトA

Aバージョン

ビンゴゲーム管理ソフトでAバージョンをリリースします。まだ改良点はたくさんあるようですがを一応の区切りです。アメリカの半導体ビジネスでは製品化済みの商品の改訂版にはA,B,Cと枝番を振る慣わしがありました。

画期的なマイコン8ビットCPU Intel8080が世に出ましたが、使いにくい点を改訂したのがIntel8085でした。更に改良して8085Aが出荷されたと記憶しています。それに因んでAを使ってみました。

改良点

改良点は実際のビンゴマシンの動きに近づけて一度使ったビンゴボールを使わないようにして空(から)くじをなくしたことです。ビンゴボールの番号は1~75の75種ですが、一度出現した番号は二度と現れないような処理を追加しています。抽選回数が増えるごとに動きが軽くなります。

 

これら動作は電子的システムの得意とする分野です。また、参加者ごと、抽選回数ごとの処理の切れ目が分かるように間を置いたり背景色を変えています。背景色変更の効果が記事全体に及ぶのはやり過ぎでしょうか。「あちら立てればこちらが立たず」一筋縄ではいかぬものです。

将来への布石

 

結婚式場などのイベント会場には巨大モニタ画面が備わっているようです。また、パブリックビューイングでスポーツなどが観覧できるようになりましたので、紙による抽選ゲームからエレクトリックゲームへの転換が一段と進むことでしょう。

さらなる改良点

①参加人数の入力
②カード番号と参加者の対応付け
③抽選タイミングの指定
④ゲームの記録を残す

管理機能付きビンゴゲームの動作例

ゲーム画面の左上にあるビンゴ籠をクリックし回転させて開始です。リーチが叫ばれるまで時間がかかりますが一度、リーチやビンゴが起きればにぎやかになります。

複合システムの難解な問題

今回、抽選のタイミングで背景色を変更しましたがウィジェット欄を含むすべての背景色に及び期待した動作ではありません。

ローカル環境では問題が起きてないので、調査を進めると当記事のJavaScriptオブジェクトidに”main”という名付けをしていることが原因でした。

この名前はウィジェット欄を表示させるコードで既に使用されているようです。id名をユニークな名前に変更したところ、期待した動作が得られました。

ウィジェット欄のコードはWordPressなどのサポートシステムが管理しているので個別に確認することはできません。ウ~ムなかなか難しい問題と言えるでしょう。

ビンゴゲーム管理ソフト

追加された新機能

ビンゴゲームを作って楽しく遊ぶための研究用記事です。今回、20人のビンゴゲーム参加者のゲーム完成状況を時々刻々、表示する機能を追加しました。

ひとりのビンゴカードにおいて縦、横、斜めの12組がビンゴマシンが発する番号と如何に合致しリーチやビンゴ状態に達したかを一目で把握します。

ビンゴマシンが1~75の数を決定すると参加者はビンゴカードにその番号があるかどうかチェックし、あればその部分に穴をあけます。

12組のどれかに4個の穴がそろったらリーチと、5個の穴がそろったらビンゴと叫びます。確率的には少なくなりますが2組、3組、4組が同時に成立することもあります。

その時は一段と気張ってダブルリーチ、トリプルビンゴなどと声を出してもいいかもしれません。

これら一連の動作をビンゴゲーム管理ソフトが処理します。カードマシンの籠から出たボールは再び籠に戻ることはなく、そのため空(から)くじが起きることはないでしょう。

このチェックはまだ施されてないのでたびたび空くじが起きています。空くじなしにする方法で可能ですが実施は次回以降になります。

空くじなしにする方法

空くじなしというか必ずどれかにヒットする完全な方法は、20人全員の発番に用いたボールのみをビンゴマシンの籠に用意します。加えて使い切ったボールを削除する処理を追加すればいいようです。

処理的には1~75のうち、利用したボールの値を、例えば999などと改変し、ソーティングして小さい順に並び替えその上、発生する乱数を1~74と小さくしていきます。

それをインデックスにして先ほど並び替えたテーブルを参照してマシンが発番する番号にします。これを繰り返せば空くじはなくなるでしょう。

それにしても空くじはしらけます。早めの対応が課されているようです。

管理機能付きビンゴゲームの動作例

ゲーム画面の左上にあるビンゴ籠をクリックし回転させて開始です。リーチが叫ばれるまで辛抱強く待ってみましょう。一度、リーチやビンゴが起きれば声が重なるほどにぎやかになります。

音声ファイルの作り方

音声の作り方

ビンゴゲームを作るに当たり、MP3やWAV形式の音声を作るには、テキストを音声に変換してくれるサイトが便利です。今回、Sound of Textを利用させていただきました。

サイトを参照すると上図の①の画面が現れます。Text欄に変換する文言、Voice欄で言語を選択してSubmitをクリックすれば、②の画面が現れます。変換するテキストを確認してDOWNLOADをクリックすると、所定のフォルダにmp3ファイルがダウンロードされます。

テキストの設定例

「リーチ」、「ビンゴ」などの掛け声や感嘆詞音声はサイト上に多く存在し、ダウンロードフリーのものを用意できますが、ユーザーフレンドリーなメッセージは独自に準備します。『カード番号一番さん、ビンゴ完成です。あめでとうございます。』のようなメッセージ音声ファイルを作りました。

音声ファイルの利用例


《音声で意思疎通!》

けさ、ちょっと言い過ぎました。ごめんなさい!

サンプルコード

<!DOCTYPE html>
<html>
<body>
<DIV id="top" style="width:480px; height:400px; font-size:24px;  color:deeppink; border:1px solid green; display:block;">
<audio id="apology" src="http://aidesign.lolipop.jp/wp-content/uploads/2019/09/pardonme.mp3" controls controlslist="nodownload"></audio><BR>
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTeIePErZuNGrIvnBBjYQoeTFz-DsGHMUV0ady7SMI3UltzSWsChQ" 
width="320" height="307" align="left" border="1">《音声で意思疎通!》<BR><BR>けさ、ちょっと言い過ぎました。ごめんなさい!
</DIV>
</body>
</html>

 

ビンゴゲーム作成部品

ビンゴゲームの部品

ビンゴゲームをJavaScriptで作成するに当たり、様々な機能を分担するパーツから成り立ちます。今回、参加者全員のヒット状態を一覧表に表示するパーツを作成しました。

thやtd要素へのアクセスは独特の方法がありますが、ここではそれぞれにidを付加したオーソドックスな方法を採用しています。

背景色を動的に設定するにはdocument.getElemeniById(‘idxx’).style.backgroundColorに背景色を代入します。

例えば、下の図に示すようにカード番号3番の12組のヒット数を表示しています。G列がビンゴ、5行目がリーチであり、背景色をそれぞれマゼンタ、ディープスカイブルーでそれ以外はヒット回数を表しています。

余談ですがスタイルシートにはbackground-colorプロパティがあり、背景色を指定するにはstyle.background-colorとすべきですが、-(ハイフン)はマイナス演算子と誤解されエラーになります。そのため、ハイフンを省き次の文字を大文字にするのが習わしです。これをマスターする時は悩みましたがかなりの月日が経ちました。

背景色動的設定機能を拡張して右の図のようにサインカーブを描いてみました。サイン値は0~2π間で-1~1の値を採りますが、角度を1~12、サイン値を12組に引き当てています。

背景色を動的に設定する機能を応用した描画

BINGO 12345 \/

サンプルコード

<Div id="wrapper" style="width:180px; font-size:20px; background:aliceblue;">
<table id="status" style="text-align:center; border-collapse:collapse; width:20px; font-size:14px;" border=1>
<tr><th>  </th><th bgcolor="pink">B</th><th bgcolor="pink">I</th><th bgcolor="pink">N</th><th bgcolor="pink">G</th><th bgcolor="pink">O</th>
<th bgcolor="lime">1</th><th bgcolor="lime">2</th><th bgcolor="lime">3</th><th bgcolor="lime">4</th><th bgcolor="lime">5</th>
<th bgcolor="yellow"><span style="font-family:Arial;">&#x5c;</span></th><th bgcolor="peachpuff">/</th></tr>
</table>
</Div>
<script type="text/javascript" charset="utf-8">
var v, w, x;
var table = document.getElementById('status');				// table要素を生成
for (var i = 1; i <= 12; i++) {								// tr部分のループ
    var tr = document.createElement('tr');					// tr要素を生成
    for (var j = 0; j < 13; j++) {							// th・td部分のループ
      x='n'+letter2(i)+letter2(j);							// id作成
      if(j==0)	{v='th';w=i;}								// th table-header
      else		{v='td';w=0;}								// td table-data
      var td = document.createElement(v);					// th・td要素を生成
      td.id = x;											// th・td要素にidを付ける
      td.textContent = w;									// th・td要素内にテキストを追加
      tr.appendChild(td);									// th・td要素をtr要素の子要素に追加
    }
    table.appendChild(tr);									// tr要素をtable要素の子要素に追加
}
document.getElementById('wrapper').appendChild(table);		// 生成したtable要素を追加する

    document.getElementById('n0301').innerHTML = 2;
    document.getElementById('n0302').innerHTML = 0;
    document.getElementById('n0303').innerHTML = 1;
    document.getElementById('n0304').innerHTML = 5;
    document.getElementById('n0304').style.backgroundColor = "magenta";
    document.getElementById('n0305').innerHTML = 3;
    document.getElementById('n0306').innerHTML = 2;
    document.getElementById('n0307').innerHTML = 0;
    document.getElementById('n0308').innerHTML = 0;
    document.getElementById('n0309').innerHTML = 1;
    document.getElementById('n0310').innerHTML = 4;
    document.getElementById('n0310').style.backgroundColor = "deepskyblue";
    document.getElementById('n0311').innerHTML = 3;
    document.getElementById('n0312').innerHTML = 2;

function letter2(num) {return ('0' + num ).slice(-2);} <!-- send '01' -->
</script>