月別アーカイブ: 2024年8月

囲みアニメーションの実際

インパクトある囲み表示

テレビニュ-ス報道においてタイトルを四角枠で囲み、一筆書きのようになぞって一周する表示方法があります。NHKやテレビ朝日で見かけました。

次の図、右下のボタンを押してください。

 

以前、 ラジオ文化 で取り上げましたが、div要素のborderを利用していました。svgでpathデータを利用すれば、一筆書きの動くキャッチコピーに応用できそうです。進化版をお届けします。

複数の短歌、俳句、川柳を表示するとき、切れ目に挿入し表現を強調させるために囲みアニメーションを導入しました。

HTMLによる囲みアニメーション表現3例

HTMLのcssやJavaScriptを使ってダイナマイトの導火線が燃え移るように描写するにはAnimationを使うと便利です。ネット上を検索するとAnimationの使い方には、次の3つの方法があります。

①div要素を90度ずつ回転させた4つ要素のborderを時間遅れで表示させ四角の枠を表示する

②同じ要素を4つ用意し、それぞれのborder(border-top, border-right, border-bottom, border-left)を順に時間遅れで表示して囲みアニメーションを実現する

③一つのdiv要素に重ねてsvg要素を定義しpathデータで形成する4角形にanimationを使って囲みアニメーションを実現する

寸評

3つとも同じ機能を実現できます。プログラミングコードサイズは①から順に少なくなります。本格採用は本人の好みで③になりました。①と②と異なり③はLazyLinePainterライブラリを用いてJavaScriptである程度、面倒見てあげなくてはいけませんが、pathデータをcssに用意するだけ済むものもあるようです。

JavaScriptを使うと囲みアニメーションの開始時、終了時にイベント処理を紐づけることが可能で、奥深いアニメーションを実現することができます。

ページの最後に実演とプログラミングコードの閲覧方法を載せました。深みのあるページの表現方法としてお考えいただけたらありがたいです。



実演

ブラウザのロードボタンを押下すれば再実行されます。

ニュース速報
Big News
緊急ニュース


囲みアニメーション関数コードの一例

ページのソースコードを表示させるには 右クリック-検証-ページのソースを表示 などをご利用ください。囲みアニメーションを3例挙げていますが、囲みアニメーションを記事に応用するには気に入った方法を1つ組み込むだけで十分です。

囲碁川柳とくじびき

20首の囲碁川柳を最後まで閲覧いただくとくじびきが始まり25%の当選確率でファンファーレが鳴ります。景品はありませんが囲碁愛好者は挑戦してみてください。
風刺のきいた囲碁川柳
🌏
 ©2024,TacM Rev1.002

余禄

当選率:25%(4回に1回)と言っても、4回挑戦して1回は必ず当選するというものではありません。10000回挑戦して当選する確率は2500回の近辺に納まるという程度でしょう。

一様乱数を検証する

当選率を設定するには

今回、くじを4回引いたら1回は当たるように設定するにはどうすればよいかを検証しました。籤(くじ)をコンピュータで引くとき、一様乱数を使うことは多く知られています。乱数にもいろいろありそのなかの一様乱数とは、『ある区間において([0,1]など)数値が同じ確率で出現する、 確率分布に従う乱数』をいいます。

15人からなるグループで、掃除当番や鍵当番を乱数で決めるとき、一様乱数「Math.random()」を使います。この時、発生した乱数値に15を掛け小数点以下を切り捨て整数化し、0から始まる整理番号(最大値14)に対応させる方法があります。

コンピュータで当選者を決める場合、決定方法を公開し作為がないことを明示しなければなりません。そこで言語処理系が用意した一様乱数が信頼に値するかどうかを検証する簡単な方法を以下に公開します。

検証の一例

以下のJavaScriptプログラミングコードは、0から1未満の一様乱数を発生するMath.random()を利用しています。乱数を1000回発生し0.25未満の乱数値が現れた回数をカウントして表示しています。

乱数関数が一様に分布する値を返してくれたら、カウント累計値は250近辺であることが期待されます。サイコロの目の出現で経験できますが、1から6の目は1/6ずつを想定できますが検査回数を多くしないと平均化は困難です。検査回数を1000, 10000, 100000, 1000000, 10000000の5種類を採用しました。

プログラミングコード

<html>
<head>
    <meta charset="utf-8" />
</head>
<script type="text/javascript">
var NUM=1000;
for(j=0; j<5; ++j){
  var count=0;
  for(var i=0; i<NUM; ++i){
  	var rv=Math.random();
  	if(rv<0.25)	++count;
  }
  console.log(j, NUM, "Count="+count, count/NUM, "Average="+count*100/NUM+"%");
  NUM *= 10;
}
</script>
</html>

実演

考察

実演結果からわかるように検査回数が大きくなるほどAverageは25%に近づきます。Math.randome()から得られる一様乱数値が0.25未満をもって当選とする方式はおおむね大禍ないように思われます。

囲碁川柳を吟ずる

既存システムを利用

文化は積み重ねの歴史です。人間の一生は短いです。そのため、若年期は学ぶことが多く、年齢を重ねて学んだことを実践していくという流れが定着しています。

先人を敬い先人の功績を継承し先人の業績に劣らぬ遺産を残したいものです。

三角関数sin(Θ)を求めることはそう難しくはありませんが、汎用性の高い関数はシステムとか処理系などと呼ばれる中枢が用意しています。

同様にWebドキュメント作成においては、振り仮名を振るには漢字の真上に中央揃いで割り振ると見やすいものです。これらを一括してサポートしてもらえたら大助かりです。

HTMLプログラミング言語には rubyというタグがこれらをサポートしてくれます。振り仮名をサポートするruby要素の使い方の本題に入る前に、便利さを次の例によって体感してください。

東海林しょうじ
東海林とうかいりん
和泉いずみ
にのまえ
御手洗みたらい
一番ケ瀬いちばんがせ
山田 
加茂かも山田 山田 
左沢あてらざわ

均等割りのルール

上のような例において、横書きでは漢字の上に均等割りでカナを振ります。東海林という姓に「しょうじ」と振り仮名を振る場合、漢字3文字の幅に4つのひらがなを均等に割り付ける必要があります。

また、漢字に対して「にのまえ」のような長いフリカナには通常より大きい幅を用意する必要があります。カナを振るrubyという要素は概ね利用者を満足してくれますが課題もあるようです。これらについて触れていきます。

餅は餅屋

他人の優れた点は率直に認め、『自分は我が道を行く』これが現代流です。ruby要素は優れモノであることは上の実証でお分かりです。ここではそれを効果的に利用あるいは応用した具体例を川柳を吟ずるにまとめました。20首の川柳にフリ仮名を振ってそれを朗読します。

囲碁川柳を吟ずる

囲碁川柳の口吟を楽しむには右上のはじめのボタンを押します。主要モダーンブラウザ(chrome, edge, firefix, opera)での動作を確認しています。川柳は江戸川柳や囲碁用語辞典等を参照させていただきました。感謝申し上げます。

🌏
風刺のきいた囲碁川柳
 ©2024,TacM Rev0.003

多様性の尊重と課題

自分の良さを認めてもらうには他人を認めてあげなくてはなりません。他人のものを安易にコピー&ペーストして自分のものとして発表するのはいただけません。世に誇れるものを公開しましょう。

今回、rubyが持っていない機能はJavaScriptプログラミングにて処理を追加しました。次の点です。

①縦方向の余白…振り仮名のある漢字とない漢字を横並びする場合には一工夫を要する

②テキスト-音声変換に利用する…かな振り文章をそのまま、朗読データにはできない

③最初の音声再生にノイズが出る…最初の音声再生には注意喚起の意味が込められている

完璧に対応できていないものもあります。これからの宿題です。鋭意、努力中です。暫時の暇を頂戴いたします。

余禄

若いころ、同じ町内会に東海林(とうかいりん)さんが住んでいました。小中学校までは狭い生活空間でしょうじさんは直立不動で歌う歌手しか思い浮かびませんでした。高校に行くと同じクラスにしょうじ君ととうかいりん君がいてびっくりした経験があります。

地名や人名の読み方は多彩です。そのとき、フリガナが助けてくれます。また、詩の世界ではあえて古風な読み方を推すことがあり、このような場合、ruby要素の一大働き場所と言えるでしょう。

干支(えと)を表示

このHTMLプログラミングサンプルは、動的に要素(タグ)を生成し漢字にフリガナを振って、ユニコードに定義された絵文字により干支(えと)を描画しています。  右のボタンを押して開始です。

デジタル抽選機

作為風を装った無作為抽選方法

パリで開催中の2024オリンピックにおいて、柔道競技で同点決勝戦をどのクラスで実行するかを、デジタル抽選機を用いて決定しました。抽選は試合の専攻/後攻をコイントスで決めることを含め、あらゆる場面に現れます。二者択一はコインの裏表で決することができますが、選択肢が多くなると機器を利用することになります。

デジタル抽選 中日スポーツより

抽選結果で特定の人が有利になったり不利になったりすることはまま、あることでしょう。だから、抽選結果には公平性を保つことが必要です。電子機器を使う場合は乱数を用いて作為性のない方法が採用されますが、それを多くの人に認めてもらうことは至難と言えましょう。

抽選の方法

抽選機には多くの種類があります。今回、ルーレットゲームに使う方法を応用しました。ルーレットでは円盤状に10個の窪みを作りその中に1個のボールを転がし、入った窪みの番号を決定値とします。この方法の動く部分と固定部分を逆にして、円状に0~9の数字を印刷した円盤を回転させ、決められた場所に留まった番号を決定値にする仕組みです。

作為らしい抽選

以下の抽選方法には作為はありません。もちろん、一様乱数を作る関数(Math.random)が期待通り動作するとしても話です。作為がないとはなぜか。0~9の数字から1個を選ぶのに乱数を使っているからです。

制御の流れ

①左下隅の開始ボタンを押す
②乱数を使ってアタリ番号0~9から1つを選ぶ
③左上隅にアタリ番号を薄く表示する
④ルーレット円盤を回転する
⑤仮決めした番号と重量別クラス名を表示する
⑥左下隅の停止ボタンを押す
⑦回転速度を少しずつ落とすようにする
⑧回転速度が基準値よりも小さくなったか監視する
⑨条件を満たしたら回転を停止する

抽選方法にひとこと

今回、オリンピックにおいて、デジタル抽選方法で世論が沸騰しています。大昔、富くじが著名寺社で挙行されましたが、そこにヤラセが入って巨悪がはびこり正義感旺盛な主人公が大活躍という小説を読んだことがあります。疑えばキリがありません。

このたびの抽選方法に眼を戻すと、⑥の停止ボタンを押したときに当たりくじが決定するかのように振る舞っていますが、アタリ番号は②で決定済みです。③から⑧までは単なる儀式です。それではこの抽選ソフトは八百長かというとそうではありません。作為風を装った無作為抽選方法です。

左上隅に薄く表示されるアタリ番号を非表示にすれば作為性があるのではとの疑いは解消されるでしょう。

実演

制御の流れを参考にして操作してください。

+108
🌸
🌸
©TacM,2024 Rev0.00

プログラミングコード

<!DOCTYPE html>
<html>
<body>
<Div id="top" style="position:relative; width:580px; height:460px; border:1px solid blue; font-size:64px; color:mediumvioletred; background-color:aliceblue;">
<img id="disc" src="https://aidesign.lolipop.jp/wp-content/uploads/2017/10/turnTable.png" width="360" height="360" style="position:absolute; left:110px; top:30px; width:360px; height:360px; transform:rotate(90deg);">
<div id="basis" style="position:absolute; left:472px; top:184px; font-size:32px; font-weight:bold; color:black;">&#x2b05;</div>
<a id="playstop" href="javascript:void(0)" onclick="startStop();" style="position:absolute; left:20px; top:370px; font-size:64px; text-decoration:none;">&#x25b6;</a>
<div id="weightNo" style="position:absolute; width:130px; height:64px; left:430px; top:6px;   font-size:48px; display:flex; justify-content:right; border:0px solid; color:olive;">+108</div>
<div id="targetNo" style="position:absolute; width:90px;  height:90px; left:30px;  top:2px;   font-size:77px; opacity:0.05; display:flex; justify-content:center; display:flex; align-items:center; border:0px solid blue; color:olive;">&#x1f338;</div>
<div id="luckyNum" style="position:absolute; width:90px;  height:90px; left:460px; top:350px; font-size:77px; opacity:1.0;  display:flex; justify-content:center; display:flex; align-items:center; border:0px solid blue; color:olive;">&#x1f338;</div>
<div id="result77" style="position:absolute; width:220px; height:40px; left:180px; top:400px; font-size:26px; opacity:1.0;  display:flex; justify-content:center; display:flex; align-items:center; border:0px solid blue; color:olive; font-weight:bold;"></div>
<div style="position:absolute; left:230px; top:444px; font-size:12px; color:blueviolet;">&copy;TacM,2024 Rev0.00</div>
</Div>
<script type="text/javascript" charset="utf-8">
var INTERVAL=80;														//回転スピード, 74 ~ 30 25 10
var k=clickCount=degree=-1;												//clickCount:開始/停止, degree:回転角
const weightClass=[" -60", " -66", " -72", " -78", " -84", " -90", " -96", "-102", "-108", "+108", "■", "&#x25b6;"];
const onClk=document.getElementById("playstop");
function startStop(){													//開始あるいは停止を制御する関数
	k = ++clickCount % 2;												//あらかじめ決められたアタリ番号:Pre-determined hit numbers
	onClk.innerHTML = weightClass[k+10];								//停止 回転
	console.log("K=", clickCount, onClk.innerHTML, INTERVAL);
	if(k==0){															//停止中から開始
		document.getElementById("targetNo").innerHTML=randomize();
		document.getElementById("top").style.backgroundColor="lightyellow";
		console.log("ルーレットを回す", document.getElementById("targetNo").innerHTML);
		revolution();													//ルーレットを回す
	}
	else document.getElementById("top").style.background="aliceblue";	//回転中から停止 停止指示の検出を明示
}
function revolution(){													//回転を制御する関数, intervalの間隔で起動
	var d=(++degree)%36*10+90;											//90 0 5 10 15 20 ~ 355,   90 ~ 440
	var e=Math.floor((d-72)/36) % 10;									//0 ~ 9
	document.getElementById("luckyNum").innerHTML = e;					//console.log("Degree=", degree, d,e);
	document.getElementById("weightNo").innerHTML = weightClass[e];
	document.getElementById("disc").style.transform="rotate("+d+"deg)";	//回転を制御
	if(k==0)	setTimeout('revolution()', INTERVAL);					//引き続き回転を制御する
	else{																//停止指令を受けた
		INTERVAL += 6;													//回転速度を落とす
		console.log("停止処理中", INTERVAL, document.getElementById("targetNo").innerHTML, e);
		if(INTERVAL<300 || document.getElementById("targetNo").innerHTML!=e)setTimeout('revolution()', INTERVAL);		//引き続き回転を制御する
		else{document.getElementById("result77").innerHTML="選択クラス:"+weightClass[e];console.log("INTERVALが300を超え、かつ、ターンテーブルが最初の設定位置になった");}//抽選結果を表示
	}
}
function randomize(){return Math.floor(Math.random()*10);}				//乱数発生関数 //0~1 ➔ 0~10
</script>
</body>
</html>

夏休み自由研究2024-1

干支を図示化する

十二支を図示化してみました。以下の12枚からなる個々の図から1枚の集合図を作りました。横方向に4枚、縦に3枚ずつ並べています。それぞれの図はサイズ277x277ピクセルで集合図のサイズは1108×831ピクセルです。集合画像から必要な干支の画像を引き出すには clip:rectという属性を利用しています。

干支(えと)の画像は円状に描画されます。360度を12等分し30度間隔で画像表示されます。三角関数を利用しています。その他には時間制御関数のsetTimeout関数にて時間差表示を処理します。

干支は時計方向に2回転の描画で、1周目はユニコードに定義された絵文字で次行に表示されますがブラウザにより特徴があります。

🐁🐂🐅🐇🐉🐍🐎🐏🐒🐓🐕🐖

子丑寅卯辰巳午未申酉戌亥

2周目は漢字表示です。中央の干支は集合画像から切り取った画像で上には読みの振り仮名が表示されます。

干支は12種あり配列として扱うと繰り返し処理にすることができます。夏休み自由研究としてはかなり高度な部類に属すると言えましょう。

集合画像

実演

再実行するにはロードボタン↻を押下します