2008年05月18日のニュースとネタをお届けします
KIGで使うために作った関数を公開します。任意の大きさのボックスのなかで常に文字列を中央に持ってくるという、表示整形のためのJavaScript関数です。CSSでいうとvertical-align:middleを“誰もがはじめに期待したとおり”の機能で実装したような感じ。ボックスの高さを取得してちょうど真ん中の高さにくる……基本的にテーブルレイアウトでしか実現できなかった機能がいまあなたのもとに!
とりあえず動かせる実物がないと公開の意味がないッ、ということで↓にテスト表示用ボックスを用意しました。お試しください(このページの文章を適当にコピペするとてっとりばやげです)。Office PowerPointのテキストボックスのように動作すれば思惑通りです。
文字が書き換えられ確定される(正確には文字を打ったあとマウスをフォームの外でクリックしたとき)ごとに表示される内容がリアルタイムに変わる……はずです。IE7~とOpera9~、Firefox2~で動作確認済み。IE6だとたぶんHTMLのDOCTYPE宣言がStrictでないとボックスの高さがとんでもないことになります。
この関数では1行(1文字)~無限行まで対応、文字列がボックスの高さ(CSSで指定した高さ)をはみ出ると文字列の高さをどんどん減らしていくline-height減算モード、スクロールバーを出して全体を表示させるoverflow:scrollモード、みすぼらしいことはせずに隠してしまうoverflow:hiddenモード、そして潔く超えた分の文字はカットしてしまうSubstrモード、と多種多様なモードを搭載。使用する局面にあわせて変更できます。ちなみにこのページではline-height減算モードに設定しています。どんどん文字が重なっていくはず!
またこの関数の一番のウリは1行以内に収まった場合は文字の大きさを大きく、文字間を広く設定するという点。文字間を横幅に合わせるという機能に関してはCSSでいうとtext-justify:inter-cluster? CSS3で本格採用されるプロパティだそうなのでよくわかりませんが、とりあえず字間が広がってジャスティファイ[均等割付]されます(日本語/英語関係なく、ただし文字ごとに)。そしていままでCSSでは実現できなかった文字の大きさのジャスティファイ(?)にも対応……1文字しかない場合は超巨大に、4,5文字でもそれなりに巨大になります。これぞまさしく……必殺技の表示にぴったり(=用途が限定的)!
もともとリアルタイムに表示を替えるという用途があったため慣れないJavaScriptで書きましたが、最初から表示させたい場合はPHP(などのサーバサイドスクリプト)で作るのがスマートでしょうし僕としても楽。むしろ自分のJavaScriptの書き方が正しいのかどうか未だにわからないので公開するのも非常にアレなのですが、まぁオオゴトになるまえに恥はかいておかないと! というわけで人柱仕様版として公開いたします。何かご指摘などあればどんどんお願いいたします。またご利用はご計画的に(改変・公開などはトラブルにならない程度にご自由にどうぞ)!
function JustifyStrings(StringsLayer,TargetLayer,Max_FontSize,Max_LetterSpacing,Is_VerticalMode){
/*
-・仕様・-
■優先順位について
・CSSによる設定値より大きいMax_FontSizeについて、文字サイズをMax_FontSizeで上書きしても1行で収まる場合のみ上書きする
-> もちろんCSSによる設定値よりMax_FontSizeが小さい場合は無視(CSSの値のまま変わらない)
-> つまりCSSでの設定値が最小サイズ(ほかの値も同様)
-> もともと1行で収まらない場合も無視
・Max_LetterSpacingは1行で収まった・かつCSSによる初期設定より数値を多く指定した場合にのみ有効(0~nで指定)
・Is_VerticalがOverflowの場合はCSS指定の高さを超えてしまった場合(=基本的に複数行のときのみ)に有効(スクロールバーを出す)
・Is_VerticalがHiddenの場合も同様
・Is_VerticalがNoBreakの場合は改行を禁止にしてhiddenにする(1行ぶんしか表示されない/ただし文字が見切れることも)
・Is_VerticalがSubstrの場合は文字列を強制的にぶったぎる(NoBreakでうまくいかなかった場合用/1行ぶんしか表示されない)
・Is_VerticalがCenteringの場合はいかなる場合においても有効(センタリングする)
-> もし文字がCSS指定の高さを超えてはみ出てしまうような場合はline-heightを文字の大きさより小さくして重ねて表示させる(無理矢理)
・ちなみに水平方向にセンタリングしたい場合は通常通りCSSでtext-align:center;すればOK
■その他
・TargetLayerのPaddingは上下と左右をそれぞれ同じ値で指定する必要がある(上と下は同じ値として計算している)
・半角文字と全角文字が混ざると文字数の計算が面倒なので考慮していない(どちらも1とカウント)
*/
if(!StringsLayer){
var StringsLayer = document.getElementById('StringsLayer');
if(StringsLayer.value){
Strings = StringsLayer.value;
}else{
Strings = StringsLayer.innerHTML;
}
}
if(!TargetLayer){
var TargetLayer = document.getElementById('TargetLayer');
}
TargetLayer.innerHTML = Strings;
if(typeof(Org_LayPadWidth) == "undefined"){
window.Org_LayWidth = Number(TargetLayer.style.width.replace('px',''));
window.Org_LayHeight = Number(TargetLayer.style.height.replace('px',''));
window.Org_LayPadWidth = Number(TargetLayer.style.paddingLeft.replace('px',''));
window.Org_LayPadHeight = Number(TargetLayer.style.paddingTop.replace('px',''));
window.Org_FontSize = Number(TargetLayer.style.fontSize.replace('px',''));
window.Org_LineHeight = Number(TargetLayer.style.lineHeight.replace('px',''));
}
var LayWidth = window.Org_LayWidth;
var LayHeight = window.Org_LayHeight;
var LayPadWidth = window.Org_LayPadWidth;
var LayPadHeight = window.Org_LayPadHeight;
var FontSize = window.Org_FontSize;
var LineHeight = window.Org_LineHeight;
if(TargetLayer.style.fontWeight == 'bold'){
var Is_Bold = 1;
var FontRealSize = Math.ceil(FontSize * 1.1);
var LineRealHeight = Math.ceil(LineHeight * 1.1);
}else{
var Is_Bold = 0;
var FontRealSize = FontSize;
var LineRealHeight = LineHeight;
}
var LineHeightRatio = (LineRealHeight / FontRealSize);
var LetterSpacing = Number(TargetLayer.style.letterSpacing.replace('px',''));
FontRealSize += LetterSpacing;
var Capa_OneLineChar = Math.floor(LayWidth / FontRealSize);
var CharAmount = Number(TargetLayer.innerHTML.length);
if(CharAmount > Capa_OneLineChar){
// 1行あたりの許容文字数を超えた場合(=改行された & 横幅が余っていない)
TargetLayer.style.fontSize = Org_FontSize + "px";
LineAmount = Math.ceil(CharAmount / Capa_OneLineChar);
ParagraphHeight = LineRealHeight * LineAmount;
TopBlank = (Org_LayHeight - ParagraphHeight);
if(TopBlank > 0){
// 高さが収まった場合、縦位置でもセンタリングする(middle位置)
var New_PaddingTop = Math.ceil(TopBlank / 2);
TargetLayer.style.lineHeight = Org_LineHeight + "px";
TargetLayer.style.paddingTop = LayPadHeight + New_PaddingTop + "px";
TargetLayer.style.height = Org_LayHeight - New_PaddingTop + "px";
}else{
// 高さが収まらなかった場合
if(Is_VerticalMode == 'Centering'){
// 文字の高さを強制的に減らしていき収まるようにする(line-heightがfont-sizeを下回るケースもある)
var New_LineHeight = Math.floor(Org_LayHeight / LineAmount);
var New_ParagraphHeight = New_LineHeight * LineAmount;
var New_PaddingTop = Math.ceil((Org_LayHeight - New_ParagraphHeight) / 2);
TargetLayer.style.lineHeight = New_LineHeight + "px";
TargetLayer.style.paddingTop = window.Org_LayPadHeight + New_PaddingTop + "px";
TargetLayer.style.height = Org_LayHeight - New_PaddingTop + "px";
TargetLayer.style.overflow = 'visible';
}else if(Is_VerticalMode == 'Scroll'){
// あきらめてoverflor
TargetLayer.style.overflow = 'scroll';
}else if(Is_VerticalMode == 'Hidden'){
// 表示させないという手も
TargetLayer.style.overflow = 'hidden';
}else if(Is_VerticalMode == 'NoBreak'){
// 1行モード(その1)
TargetLayer.style.overflow = 'hidden';
TargetLayer.style.whiteSpace = 'pre';
}else if(Is_VerticalMode == 'Substr'){
// 1行モード(その2)
TargetLayer.innerHTML = TargetLayer.innerHTML.substr(0,Capa_OneLineChar);
}else{
TargetLayer.style.overflow = 'hidden';
}
}
}else{
// 1行内に文字が収まった場合(=1行しかない & 横幅が余っている)
var Capa_FontRealSize = Math.floor(LayWidth / CharAmount);
var Capa_FontSize = Capa_FontRealSize - LetterSpacing;
if(Is_Bold > 0){
Capa_FontRealSize = Math.floor(Capa_FontSize / 1.1);
}else{
Capa_FontRealSize = Capa_FontSize;
}
if(Capa_FontRealSize > Max_FontSize){
var New_FontRealSize = Max_FontSize;
}else{
var New_FontRealSize = Capa_FontRealSize;
}
var New_LineHeight = Math.floor(New_FontRealSize * LineHeightRatio);
var New_ParagraphWidth = New_FontRealSize * CharAmount;
var Capa_LetterSpacing = Math.floor(LayWidth / CharAmount) - New_FontRealSize;
TargetLayer.style.fontSize = New_FontRealSize + "px";
TargetLayer.style.lineHeight = New_FontRealSize + "px"; // 必要なのはIEだけかも(メイリオの場合再考の余地アリ)
if(Is_VerticalMode){
// 高さを真ん中に持ってくる場合(引数オプションがカラでない限り有効)
var New_PaddingTop = Math.ceil((Org_LayHeight - New_LineHeight) / 2);
if(0 > New_PaddingTop){New_PaddingTop = 0;}
TargetLayer.style.paddingTop = window.Org_LayPadHeight + New_PaddingTop + "px";
TargetLayer.style.height = Org_LayHeight - New_PaddingTop + "px";
}
if(Max_LetterSpacing > LetterSpacing){
// 引数オプションの"Max_LetterSpacing=文字間"が設定されている / LetterSpacingより大きければ、それにあわせる
if(Capa_LetterSpacing > Max_LetterSpacing){
TargetLayer.style.letterSpacing = Max_LetterSpacing + "px";
}else{
TargetLayer.style.letterSpacing = Capa_LetterSpacing + "px";
}
}
}
}
さて肝心のKIGの公開ですが……あ、あともうしばらくお待ちください……! それでは~。
[ 関連キーワード : (キーワードは登録されていません) ]
2008年05月19日 0時更新
日 | 月 | 火 | 水 | 木 | 金 | 土 |
---|---|---|---|---|---|---|
« 04月 | - | 06月 » | ||||
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |