22日目 割烹芸人の縦書
まずは簡単な縦書き変換を作っていきます。
指針では、余裕があればと書いてましたが、機能などよく見てみると簡単に実装できそうだったので先にやってしまいます。
■動作概要
テキストエリアに入力された文字を一定の文字数で切り出し、その範囲に改行があればそこで区切って全角スペースで切り出す文字数まで埋める。
「」など横書き前提の文字があれば縦書き用の文字に変換する。最後にHTML用の装飾コードを付与してテキストエリアと簡易プレビュー用の場所に返す。
■文字取得部
まずはボタンを押すとJavascriptが発動するようにします。
function OnButtonClick() {}
で、そしたらテキストエリアに入力された文字を取得します。
const text=document.form1.textarea1.value; //テキストエリアに入力されたもの
他にこまごまとした設定もついでに読み込んで変数に入れておきます。
■文字分割部
まずは文字を分割していきます。縦書き割烹ではこんな風に細長いテキストボックスを並べて実現しているので、指定された文字数で区切ります。
do{
bufstr = text.substr(k, maxlen);
if(RegExp('\r?\n', 'g').test(bufstr)){
bufstr = bufstr.split('\n')[0];
k = k + bufstr.length+1;
bufstr = bufstr +' '.repeat(maxlen - bufstr.length);
}else{
k = k + maxlen;
}
}while(text.length > k);
改行コードがあったらその時点で文字を切り出してます。' '.repeatで足りない分を全角スペースで埋めて他と合わせてます。なお、スペースで埋めないと縦書きの段落ががたがたになります。
■文字コード変換部
なろうさんでは縦書きのプロパティを指定できないのでこのままでは「」や、。が横のままになってしまいます。
なのでそれを縦書き用の文字に変換します。
function replaceStr(bufstr) {
let tempstr = bufstr;
const replacechar_before = ['「','」','『','』','〈','〉','(',')','【','】','、','。','ー','…'];
const replacechar_after = ['﹁','﹂','﹃','﹄','︿','﹀','︵','︶','︻','︼','︑','︒','︱','︙'];
for(let i in replacechar_after){
tempstr = tempstr.replace(new RegExp(replacechar_before[i],'g'),replacechar_after[i]);
}
return unescapeHTML(tempstr);
}
変換するものと変換後の文字を配列に入れて置換させています。
■ポップアップ
変換ボタンなど押したときに表示されるポップアップを実装します。
最初はアラートで作っていたのですが、いちいちOKボタンを押すのが面倒なので一定時間で消えるboxに変えました。
const popup = document.getElementById(popname);
popup.classList.toggle("show");
popnameにshowを付与して実現。
通常はvisibility: hidden;を指定してshowの場合にvisibility: visible;が有効になる。
でCSSにアニメーションも設定します。
animation: fadeIn 1s;
@keyframes fadeIn {
from {opacity: 0;}
to {opacity:1 ;}
}
なおポップアップにはアニメーションを追加していてフェードインするようになっている。
opacity: 0;は透明→opacity:1 ;不透明へと変化、1秒間で遷移する。なおアニメーションはもう少しカスタマイズできて、
animation: fadeIn 2s ease 0s 1 normal;
// キーフレームアニメーション名
//1回のアニメーションにかかる時間を指定
//アニメーションの変化率 ease、linear、ease-out、ease-in-out
//アニメーションの開始をいくら遅らせるかを指定
//アニメーションを何回繰り返すかを指定
//繰り返し時、往復処理をするかを指定
など指定できる。これを極めると複雑なものが作れる。
CSSアニメーションマスターになると動画クラスの動作が可能。
■タブ切り替え
書いたものがすぐ見れないとなかなか面倒なので、リアルタイムプレビューを表示するタブを実装します。
タブはラジオボタンで実現することが多いとのことなので自分もそれにのっとってやってみる。
<input type="radio" name="cp_tab" id="tab1_1" aria-controls="first_tab01" checked>
<input type="radio" name="cp_tab" id="tab1_2" aria-controls="second_tab01">
まず、切り替えたい分だけのラジオボタンを作る。そのあと切り替え用のタブを作る。
<div class="cp_tabpanels">
<div id="first_tab01" class="cp_tabpanel"></div>
<div id="second_tab01" class="cp_tabpanel"></div>
</div>
.cp_tabpanel {
display: none;
}
タブは基本見えないようにしておく。チェックされたものだけ見えるようにする。
.cp_tab > input:first-child:checked ~ .cp_tabpanels > .cp_tabpanel:first-child,
.cp_tab > input:nth-child(2):checked ~ .cp_tabpanels > .cp_tabpanel:nth-child(2){
display: block;
}
■リアルタイムプレビュー
さっき作った2番目のタブに変換した中身を書き込みます。
document.getElementById("second_tab01").innerHTML = newstr+endstr;
変換ボタンを押したときに2番目のタブに中身を書き込む。
■コピーボタン
いちいち選択してコピペとか面倒なのでコピーボタンを付ける。
document.getElementById("copyTarget").select();
document.execCommand("Copy");
ターゲットとなるテキストエリアを選択してCopyする。
■実装
これらを組み合わせて実装します。
流れとしては、テキストエリアに文章を書き込み→設定の変更、調整→変換ボタン→文字分割、文字置換、再合成→出力エリアに書き込み→コピペボタン
ということで縦書き割烹の完成です。
■残った問題
・リアルタイムプレビューのCSSが不十分
小説家になろうのCSSをすべては反映させていないのであくまでも簡易プレビュー
変更される可能性もあるのでほどほどでいいかなと思う。
・英数字の小文字対応
小説家になろうの割烹に小文字で縦にすると連続して表示されるのでうまくない。
なので強制的に大文字化させている。これは小説家になろうの縛りなので無理。
とりあえず完成としておく。
見た目はもう少しいじるけど縦書き変換機能としてはこれで開発終了。
あとは余裕があればの改善で。