オリジナルな表現
紙文化がネット技術に押されて少し形勢を損ねてきています。パピルスや紙から始まった文化はそうたやすく廃れるとは思っていませんが、即時性や拡散性を特徴とするネット社会にはそれにふさわしい手法があります。ちょっと覗いてみましょう。
ネット上の表現には切っても切れないHTML技術を紐解いて新機軸の表現を身に付けよう❣
紙文化がネット技術に押されて少し形勢を損ねてきています。パピルスや紙から始まった文化はそうたやすく廃れるとは思っていませんが、即時性や拡散性を特徴とするネット社会にはそれにふさわしい手法があります。ちょっと覗いてみましょう。
ネット上の表現には切っても切れないHTML技術を紐解いて新機軸の表現を身に付けよう❣
表題について当ブログでは何度も取り上げましたが、今回はJavaScriptを使わないでcssだけで実現しています。月は自転しながら地球の回りを公転していますが両者の回転の関係で月の裏側を目で見ることができません。先般、ある国で人工衛星で撮影した「月の裏側映像」が公開されたように記憶しています。
今まで発表した公転と自転の動きはJavaScriptによる働きが大きかったですが、cssのanimation機能を使ってシンプルに実現できました。
JavaScriptにanimationiterationの終了イベントを捉えて簡単な操作から複雑な制御まで可能になると踏んだのですが、何度か動作を繰り返すうちに、不思議な動作が発見されて今回の公開は見送りになりました。
今回は、HTMLとcssにより、公転と自転を確認しました。アニメーションの動作プログラミングは豊富な経験とは言い難いですが、複数のanimationを組み合わせても期待した動作になりました。人命に関わるような制御に対してcssによる信頼性はデータ不足です。天体の動作を解説するような利用方法に応用できるでしょう。
ここで示した動作は大円が時計回りに2周しますが5個の小円は、大円の1周目は大円に同期して反時計方向に自転するので公転と自転が相殺されて常に下向きになります。大円の2周目において、5個の小円の自転は停止しているので小円の動きは大円と一体です。
『公転と自転』の文字は次第に傾き始め1.5周では真っ逆さまになり2周終了に近づくにしたがって正常な向きになります。アニメーションはゲームのような動きを単に処理すると考えていましたが精密な動作にも向いています。
再実行にはブラウザのロードボタンを押します。
<html> <head> <meta charset="utf-8"> <style type="text/css"> #all03 { /* 全体(大円) */ animation: kf0 12s linear 1 forwards; /* 大円を事実上2回転させる、小円とはdurationを個別に設定して同期する アニメーションを最後の状態で停止させる(animation-fill-mode) */ } #rota0,#rota1,#rota2,#rota3,#rota4 { /* 小円 */ animation: kf1 6s linear 1 reverse; /* animation, reverseは大円の回転方向と逆にする指定 */ } @keyframes kf0 { /* 公転に用いる */ 0% { transform:rotate(0deg); fill:palegreen; } 100% { transform:rotate(720deg); fill:hotpink; } /* 大円を事実上2回転させるために720 */ } @keyframes kf1 { /* 自転に用いる */ 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } /* 大円の1回転中のみ回転 */ } @keyframes fadein {0%{opacity:0;}100%{opacity:1;}} /* 後でメッセージが飛び出す */ </style> </head> <Div style="position:relative; position:absolute; top:50%; left:50%; margin-right:-50%; transform:translate(-50%, -50%); width:560px; height:560px; border:0px solid blue;"> <svg xmlns="http://www.w3.org/2000/svg" width="560" height="560"> <g id="all03" style="transform-origin:50% 50%; stroke:blue; font-size:48px; font-family:'Arial'"> <circle id="hypo0" cx="280" cy="280" r="279" stroke-width="2" style="stroke:darkcyan; fill:ivory;"/> <line id="xaxis" x1="0" y1="280" x2="560" y2="280" stroke-width="1" stroke="deeppink"/> <line id="yaxis" x1="280" y1="0" x2="280" y2="560" stroke-width="1" stroke="blue"/> <g id="rota0" style="transform-origin: 80px 220px;"> <circle id="circ0" cx="80" cy="220" r="50" stroke-width="1"/> <text id="txt02" x="58" y="242">公</text> <!-- 58=80-24+2 242=220+24-2 --> </g> <g id="rota1" style="transform-origin: 180px 280px;"> <circle id="circ1" cx="180" cy="280" r="50" stroke-width="1"/> <text id="txt02" x="158" y="302">転</text> <!-- 158=180-24+2 302=280+24-2 --> </g> <g id="rota2" style="transform-origin: 280px 340px;"> <circle id="circ2" cx="280" cy="340" r="50" stroke-width="1"/> <text id="txt02" x="258" y="362">と</text> <!-- 258=280-24+2 362=340+24-2 --> </g> <g id="rota3" style="transform-origin: 380px 280px;"> <circle id="circ0" cx="380" cy="280" r="50" stroke-width="1"/> <text id="txt02" x="358" y="302">自</text> <!-- 358=380-24+2 302=280+24-2 --> </g> <g id="rota4" style="transform-origin: 480px 220px;"> <circle id="circ1" cx="480" cy="220" r="50" stroke-width="1"/> <text id="txt02" x="458" y="242">転</text> <!-- 458=480-24+2 242=220+24-2 --> </g> </g> <text id="credit" x="247" y="552" font-size="9" style="animation:fadein 4s cubic-bezier(0.33, 1, 0.68, 1) forwards 8s; opacity:0;">©TacM 2024,V0.10</text> </svg> </Div> </html>
小円内の文字が途中から逆さになってやがて平常状態に向き直る様をご確認ください。時間を設定する単位はミリ秒です。このことから推察すればミリ秒の精度で制御可能なシステム作りが可能と思われます。
HTMLを用いて、平安中期の歌人『清少納言』《枕草子》の朗読作品を作りました。ネット上にはプロの声優さんが参加した作品が数多く登録されています。ここでは朗読にはAIによる音声ツールで朗読しています。哀切、熱情のこもったプロの作品にはとてもかないませんが、文字を起こしてテキストデータを作っての表現は音読への道を開いてくれるでしょう。
無機質に近い音声は芸術には程遠いですが将来の発展性に期待しましょう。
ブログの表現は音声よりテキストです。朗読用データはテキストで与えられます。そして、現代版作品以外は旧仮名が混じっています。これは朗読には不向きで朗読に利用するには少し手を加えなければなりません。例を挙げれば、いふ➡言う、あはれ➡哀れ、ちがひ➡違いなどがあります。また、漢字の読み方も雁はがんよりもかりが似つかわしいことがあり、音はおと, ねと読み分けるとよりふさわしい表現になります。この辺りは稿を改めて発表したいと考えています。
《はじめ》ボタンを押下すれば清少納言似の女性による朗読が始まります。
テレビニュ-ス報道においてタイトルを四角枠で囲み、一筆書きのようになぞって一周する表示方法があります。NHKやテレビ朝日で見かけました。
次の図、右下の◢ボタンを押してください。
以前、 ラジオ文化 で取り上げましたが、div要素のborderを利用していました。svgでpathデータを利用すれば、一筆書きの動くキャッチコピーに応用できそうです。進化版をお届けします。
複数の短歌、俳句、川柳を表示するとき、切れ目に挿入し表現を強調させるために囲みアニメーションを導入しました。
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を使うと囲みアニメーションの開始時、終了時にイベント処理を紐づけることが可能で、奥深いアニメーションを実現することができます。
ページの最後に実演とプログラミングコードの閲覧方法を載せました。深みのあるページの表現方法としてお考えいただけたらありがたいです。
ブラウザのロードボタンを押下すれば再実行されます。
ページのソースコードを表示させるには 右クリック-検証-ページのソースを表示 などをご利用ください。囲みアニメーションを3例挙げていますが、囲みアニメーションを記事に応用するには気に入った方法を1つ組み込むだけで十分です。
今回、くじを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)での動作を確認しています。川柳は江戸川柳や囲碁用語辞典等を参照させていただきました。感謝申し上げます。
自分の良さを認めてもらうには他人を認めてあげなくてはなりません。他人のものを安易にコピー&ペーストして自分のものとして発表するのはいただけません。世に誇れるものを公開しましょう。
今回、rubyが持っていない機能はJavaScriptプログラミングにて処理を追加しました。次の点です。
①縦方向の余白…振り仮名のある漢字とない漢字を横並びする場合には一工夫を要する
②テキスト-音声変換に利用する…かな振り文章をそのまま、朗読データにはできない
③最初の音声再生にノイズが出る…最初の音声再生には注意喚起の意味が込められている
完璧に対応できていないものもあります。これからの宿題です。鋭意、努力中です。暫時の暇を頂戴いたします。
若いころ、同じ町内会に東海林(とうかいりん)さんが住んでいました。小中学校までは狭い生活空間でしょうじさんは直立不動で歌う歌手しか思い浮かびませんでした。高校に行くと同じクラスにしょうじ君ととうかいりん君がいてびっくりした経験があります。
地名や人名の読み方は多彩です。そのとき、フリガナが助けてくれます。また、詩の世界ではあえて古風な読み方を推すことがあり、このような場合、ruby要素の一大働き場所と言えるでしょう。
パリで開催中の2024オリンピックにおいて、柔道競技で同点決勝戦をどのクラスで実行するかを、デジタル抽選機を用いて決定しました。抽選は試合の専攻/後攻をコイントスで決めることを含め、あらゆる場面に現れます。二者択一はコインの裏表で決することができますが、選択肢が多くなると機器を利用することになります。
抽選結果で特定の人が有利になったり不利になったりすることはまま、あることでしょう。だから、抽選結果には公平性を保つことが必要です。電子機器を使う場合は乱数を用いて作為性のない方法が採用されますが、それを多くの人に認めてもらうことは至難と言えましょう。
抽選機には多くの種類があります。今回、ルーレットゲームに使う方法を応用しました。ルーレットでは円盤状に10個の窪みを作りその中に1個のボールを転がし、入った窪みの番号を決定値とします。この方法の動く部分と固定部分を逆にして、円状に0~9の数字を印刷した円盤を回転させ、決められた場所に留まった番号を決定値にする仕組みです。
以下の抽選方法には作為はありません。もちろん、一様乱数を作る関数(Math.random)が期待通り動作するとしても話です。作為がないとはなぜか。0~9の数字から1個を選ぶのに乱数を使っているからです。
①左下隅の開始ボタンを押す
②乱数を使ってアタリ番号0~9から1つを選ぶ
③左上隅にアタリ番号を薄く表示する
④ルーレット円盤を回転する
⑤仮決めした番号と重量別クラス名を表示する
⑥左下隅の停止ボタンを押す
⑦回転速度を少しずつ落とすようにする
⑧回転速度が基準値よりも小さくなったか監視する
⑨条件を満たしたら回転を停止する
今回、オリンピックにおいて、デジタル抽選方法で世論が沸騰しています。大昔、富くじが著名寺社で挙行されましたが、そこにヤラセが入って巨悪がはびこり正義感旺盛な主人公が大活躍という小説を読んだことがあります。疑えばキリがありません。
このたびの抽選方法に眼を戻すと、⑥の停止ボタンを押したときに当たりくじが決定するかのように振る舞っていますが、アタリ番号は②で決定済みです。③から⑧までは単なる儀式です。それではこの抽選ソフトは八百長かというとそうではありません。作為風を装った無作為抽選方法です。
左上隅に薄く表示されるアタリ番号を非表示にすれば作為性があるのではとの疑いは解消されるでしょう。
制御の流れを参考にして操作してください。
<!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;">⬅</div> <a id="playstop" href="javascript:void(0)" onclick="startStop();" style="position:absolute; left:20px; top:370px; font-size:64px; text-decoration:none;">▶</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;">🌸</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;">🌸</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;">©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", "■", "▶"]; 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>