目次
サンプル・プログラムの実行例

サンプル・プログラムのダウンロード
textProgressBar.html | サンプル・プログラム本体 |
バージョン | 更新日 | 内容 |
---|---|---|
1.0.0 | 2024/12/01 | 初版 |
解説:初期値
pasteImage.html
25: // 初期値(START) ==========================================================
26: const TITLE = 'クリップボードにある画像を取得'; // プログラム・タイトル
27: const REFERENCE = 'https://www.pahoo.org/e-soul/webtech/js01/js01-17-01.shtm';
28: const WIDTH = 600; // 横幅(ピクセル)
29: const MAX_IMAGES = 4; // 最大画像数
30: // imgのリスト;MAX_IMAGESの数だけ用意すること
31: const IMAGE_LIST = ['image1', 'image2', 'image3', 'image4'];
32:
33: document.addEventListener('DOMContentLoaded', () => {
34: //タイトル等を表示する.
35: document.title = TITLE;
36: document.getElementById('title').innerHTML = TITLE + ' <span style="font-size:small;">' + getLastModified() + '版</span>';
37: document.getElementById('reference').innerHTML =`
38: ※参考サイト <a href="${REFERENCE}">${REFERENCE}</a>
39: `;
40:
41: //スタイルシートをセットする.
42: document.getElementById('help').style.width = WIDTH + 'px';
43: document.getElementById('help1').innerHTML = `画像は ${MAX_IMAGES}個までペーストできます.`;
44: let width = Math.floor(WIDTH / MAX_IMAGES);
45: IMAGE_LIST.forEach((value, index) => {
46: document.getElementById(value).style.width = width + 'px';
47: document.getElementById(value).style.height = 'auto';
48: });
49: });
50: // 初期値(END) ==========================================================
Bluesky では、2024年(令和6年)12月時点の1メッセージあたり最大文字数は300文字(英数字も日本語も1文字とカウントする)であり、これを定数 MAX_LENGTH にあらかじめ代入した。また、メッセージ中のURLは1つにつき23文字とカウントされるため、これも URL_LENGTH に代入した。
解説:指定コンテナにプログレスバーの原型を追加する
textProgressBar.html
74: /**
75: * 指定コンテナにプログレスバーの原型を追加する
76: * @param Object containar コンテナ
77: * @return なし
78: */
79: function addProgressBar(containar) {
80: containar.innerHTML = `
81: <span id="${CHARCOUNTER}"></span>
82: <svg id="${PROGRESS}" viewBox="0 0 36 36">
83: <path
84: d = "M18 2a16 16 0 1 1 0 32 16 16 0 0 1 0-32"
85: fill = "none"
86: stroke = "lightsteelblue"
87: stroke-width = "4.0"
88: />
89: <path
90: id = "${PROGRESSBAR}"
91: d = "M18 2a16 16 0 1 1 0 32 16 16 0 0 1 0-32"
92: fill = "none"
93: stroke = "royalblue"
94: stroke-width = "4.0"
95: stroke-dasharray ="100, 100"
96: />
97: </svg>
98: `;
99: document.getElementById(PROGRESS).style.width = '24px';
100: document.getElementById(PROGRESS).style.height = '24px';
101: document.getElementById(PROGRESS).style.marginRight = '5px';
102: }
解説:文字数カウンタとプログレスバーを更新する
textProgressBar.html
104: /**
105: * 文字数カウンタとプログレスバーを更新する
106: * @param なし
107: * @return なし
108: */
109: function updateCounter() {
110: const textarea = document.getElementById(TEXTAREA);
111: const charCount = document.getElementById(CHARCOUNTER);
112: const progressBar = document.getElementById('progressBar');
113: const urlRegex = /https?:\/\/[^\s]+/g; // URLパターン
114: const text = textarea.value;
115: let textLength = text.length;
116:
117: // URLを23文字としてカウント
118: const urls = text.match(urlRegex);
119: if (urls) {
120: const actualUrlLength = urls.join('').length;
121: textLength = textLength - actualUrlLength + (urls.length * URL_LENGTH);
122: }
123:
124: // 残り文字数とプログレスバーを更新する
125: const remainingChars = MAX_LENGTH - textLength;
126: charCount.textContent = remainingChars;
127:
128: const percentage = Math.max((remainingChars / MAX_LENGTH) * 100, 0);
129: progressBar.setAttribute('stroke-dasharray', `${percentage}, 100`);
130:
131: // 制限文字数を下回ったら red
132: if (remainingChars < 0) {
133: progressBar.setAttribute('stroke', 'red');
134: charCount.style.color = 'red';
135: // 残り20文字未満なら orange
136: } else if (remainingChars < 20) {
137: progressBar.setAttribute('stroke', 'orange');
138: charCount.style.color = 'orange';
139: // それ以外は royablue
140: } else {
141: progressBar.setAttribute('stroke', 'royalblue');
142: charCount.style.color = 'royalblue';
143: }
144: }

まず、テキスト中にあるURLを正規表現でキャッチアップし、冒頭で定義した URL_LENGTH としてカウントする。
残り文字数を remainingChars に代入したら、カウンタの値を更新する。
残り文字数の全体に対する割合(パーセント)を計算したら、これをプログレスバーの属性 stroke-dasharray に代入する。stroke-dasharray は、SVG図形に適用する属性で、ダッシュ(線の部分)とギャップ(空白の部分)の長さを、カンマやスペースで区切った数値リストとして指定する。ここでは、残り文字数の割合がダッシュで、全体は空白の扱いになる。
さらに、制限文字数を下回ったり、残り20文字未満になったらカウンタやプログレスバーの色を変更するようにした。
解説:HTML本文
textProgressBar.html
150: <body>
151: <h2 id="title" name="title"></h2>
152: テキストボックス<br>
153: <textarea id="msg" name="msg"></textarea>
154: <div id="counter" name="counter"></div>
155:
156:
157: <!-- 使い方 -->
158: <div id="help" name="help" style="border-style:solid; border-width:1px; margin:20px 0px 0px 0px; padding:5px; font-size:small; overflow-wrap:break-word; word-break:break-all;">
159:
160: <h3>使い方</h3>
161: <ol>
162: <li>テキストボックスに文字を入力してください.</li>
163: <li>入力文字数に応じ,右下のプログレスバーが変化します.</li>
164: </ol>
165: <div id="reference" name="reference"></div>
166:
167: <script>
168: // プログレスバー更新イベント登録
169: document.getElementById(TEXTAREA).addEventListener('input', updateCounter);
170: </script>
171:
172: </body>
入力テキストボックス <textarea> とカウンタやプログレスバーを配置するコンテナ <div id="counter"> を静的に配置している。これらはJavaScriptで動的に生成しても構わない。

最後に、先ほど定義したユーザー関数 updateCounter を、テキストボックスの inputイベントとして追加登録する。オブジェクトがないと登録できないので、この位置にスクリプトを書いている。
参考サイト
- PHPでBlueskyに投稿する:ぱふぅ家のホームページ
- PHPでSVGを使って年表を表示:ぱふぅ家のホームページ