Cross Browser のための DHTML


・文字列修飾関数群

ロゴマークは通常画像で作成しますが文字列だけなら JavaScript を使用すれば比較的簡単にでき、 操作状況に応じて動作や配色を変えたり結構複雑なことも可能になります。

ってことで、いくつか文字列を加工する関数を紹介しましょう。f(^^;


ドロップシャドウ文字

影つき文字を生成する関数です。下のボタンを操作すると「JavaScript」の文字が表示されます。

JavaScript

以下はドロップシャドウ文字列の生成関数のコードです。


// 共通関数 : 数値を16進2桁の文字列に変換する関数
function num2hex(n){
  var h='0123456789ABCDEF';
  if(n>=255) return 'FF';
  if(n<=0)   return '00';
  return h.charAt(Math.floor(n/16))+h.charAt(n%16);
}

// 共通関数 : ラップされない文字列の HTML を作成する関数
function createNWString(html){
  return '<table border=0 cellspacing=0 cellpadding=0>'
        +'<tr><td nowrap>'+html+'<\/td><\/tr><\/table>';
}

// 共通関数 : テンプレート( '%*%' )を指定文字列に変換する関数
function convertTemplateString(html,tmps){
  if(tmps){
    for(var i=0; i<tmps.length; i+=2)
      html=html.replace(
             new RegExp('%'+tmps[i]+'%','g'),tmps[i+1]);
  }
  return html;
}

// 影つき文字のレイアを作成する関数
function createShadowString(x,y,w,h,dx,dy,
                            html,tmps,tmpSs,bd,pdiv){
  var divs = new Array();
  // ドロップシャドウ
  divs[0] = createLayer(x+dx,y+dy,w,h,pdiv,
              createNWString(
                convertTemplateString(html,tmpSs)));
  // 本体部分
  if(bd) divs[1]=createLayer(x,y,w,h,pdiv,
              createNWString(
                convertTemplateString(html,tmps )));
  return divs;
}

影付き文字を生成する関数は createShadowString で、他の関数は共通関数です。

また、この文字の部分は「ライブラリ集」で 紹介している関数です。 上のスクリプトでは記述されていませんので、使用する際には「ライブラリ集」を 参照して追加して下さい。

各関数の呼び出し形式は以下の通りです。

共通関数
  数値を16進2桁の文字列に変換する関数
    - 与えられた数値を 16進数2桁表記文字に変換します
    str = num2hex(n);
      n   : 0 〜 255 までの数値
      str : 16進表記文字列

  ラップされない文字列の HTML を作成する関数
    - 指定された文字列( HTML )をレイアの幅に影響されない
      ような形式にします
    str = createNWString(html);
      html : 変換したい文字列
      str  : 変換した文字列

  テンプレート( '%*%' )を指定文字列に変換する関数
    - 指定された文字列( HTML )に含まれる "%*%" 形式部分を
      与えられた文字列に置き換える関数
    str = convertTemplateString(html,tmps);
      html : "%*%" 形式の文字を含む文字列( HTML )
      tmps : "%*%" の変換ルール
             このルールは "%*%" の "*" 部分の変換方法を
             定義した配列で、

               被変換文字列, 変換文字列

             の2つの要素を1定義とする1次元配列です

      str  : 変換結果の文字列( HTML )

      例えば、
        html = '<font color="%c1%">str<\/font>';
        tmps = new Array( 'c1', '#ff0000' );

        とすれば結果( str )は

        '<font color="#ff0000">str</font>'

        となります

影付き文字用関数
  影つき文字のレイアを作成する関数
    - 影付き文字を生成します
    divs = createShadowString(x,y,w,h,dx,dy,
                              html,tmps,tmpSs,bd,pdiv);
      x,y    : 生成するレイアの位置  (pixel)
      w,h    : 生成するレイアのサイズ(pixel)
      dx,dy  : ドロップシャドウの位置(pixel)
      html   : レイア内に設定する HTML のテンプレート
      tmps   : html の本体部分の変換ルール
      tmpsSs : html の影部分の変換ルール
      bd     : 本体部分のレイアを生成する場合に true
      pdiv   : 親となるレイアオブジェクト または null
      divs   : 生成したレイアオブジェクトの配列
               divs[0] = 影部分のレイア
               divs[1] = 本体部分のレイア

使い方

createShadowString 関数は同じ文字列を2つのルールで加工した HTML で、 少し位置を変えてレイアを生成する関数です。

例えば

<font color="red">JavaScript</font>

の文字に

<font color="#cccccc">JavaScript</font>

の影を (10,10)だけずらして表示したい場合、 両者の違いは色指定のみの違いになります。

そこで異なる部分を変数 "%c1%" で書き直せば、

<font color="%c1%">JavaScript</font>

となります。 "%c1%" 部分は変換ルールとして
本来の文字の場合 "%c1%" は "red" に
影の部分は "%c1%" は "#cccccc" に変換する指定をします。

従って、スクリプトはこのようにします。

divs = createShadowString(x,y,0,0,10,10,
         '<font color="%c1%">JavaScript</font>',
         new Array('c1', 'red'),
         new Array('c1', '#cccccc'),
         true,null);
setDivVisibilities(divs,true); // 文字列を表示する

上のスクリプトの場合、生成する文字列のサイズは予めわからないので、 幅高さ共に 0 を指定しています。 生成したサイズに関する情報を得る場合には対象のレイアで initDivSize を使用する必要があります。

変換部分をタグの属性値だけではなくタグそのものにしたり、 表示する文字列にしたり色々なバリエーションが考えられます。


立体文字

立体的な文字を生成する関数です。 下のボタンを操作すると「JavaScript」の文字が表示されます。

JavaScript

以下は立体文字の生成関数のコードです。


// 立体文字のレイアを作成する関数
function createSolidString(x,y,w,h,th,
                           html,tmps,tmpBs,tmpSs,bd,pdiv){
  var i,divs=new Array();
  divs[0]=createLayer(x-1,y-1,w,h,pdiv,
            createNWString(convertTemplateString(html,tmpBs)));
  for(i=0; i<th; i++)
    divs[i+1]=createLayer(x+1+i,y+1+i,w,h,pdiv,
            createNWString(convertTemplateString(html,tmpSs)));
  if(bd) divs[i+1]=createLayer(x,y,w,h,pdiv,
            createNWString(convertTemplateString(html,tmps )));
  return divs;
}

この文字の部分は「ライブラリ集」で紹介している関数です。 上のスクリプトでは記述されていませんので、 使用する際には「ライブラリ集」を参照して追加してください。

関数の呼び出し形式は以下の通りです。

  立体文字のレイアを作成する関数
    - 指定された文字のレイアを重ねて生成し立体的にします
    divs = createSolidString(x,y,w,h,th,
                      html,tmps,tmpBs,tmpSs,bd,pdiv);
      x,y   : 生成するレイアの位置  ( pixel )
      w,h   : 生成するレイアのサイズ( pixel )
      th    : 文字の厚み            ( pixel )
      html  : レイア内に設定する HTML のテンプレート
      tmps  : html の本体部分の変換ルール
      tmpBs : html の明るい部分( 左上 )の変換ルール
      tmpSs : html の暗い部分( 右下 )の変換ルール
      bd    : 本体部分のレイアを生成する場合に true
      pdiv  : 親となるレイアオブジェクトまたは null
      divs  : 生成したレイアオブジェクトの配列
              divs[0]             = 明るい部分のレイア
              divs[1] 〜 divs[th] = 暗い部分のレイア
              divs[th+1]          = 本体部分のレイア

使い方

createSolidString 関数は同じ文字列を3つのルールで加工した HTML で、 少しずつ位置を変えてレイアを生成する関数で、 基本的にはドロップシャドウ文字列と同じです。

「JavaScript」の文字を( x,y )の位置に立体的に表示するには以下のようにします。

<style type="text/css"><!--
.sd  { font-weight:bold; font-size:72px; }
#sdM1{ color:#ff6666; }
#sdB1{ color:#ff0000; }
#sdD1{ color:#aa0000; }
--></style>
<script language="JavaScript1.2"><!--
sdHTML = '<span class="sd" id="%c1%">'
       + '<font %c2%>J</font>ava<font %c2%>S</font>cript'
       + '</span>';
sdThickness = 4;
sdTmpM = new Array('c1','sdM1', 'c2','color="#ffcc66"');
sdTmpB = new Array('c1','sdB1', 'c2','color="#ffff99"');
sdTmpD = new Array('c1','sdD1', 'c2','color="#aa9933"');
sdDivs = null;

sdDivs=createSolidString(x,y,0,0,
         sdThickness,sdHTML,sdTmpM,sdTmpB,sdTmpD,true,null);
setDivVisibilities(sdDivs,true);
// --></script>

グラデーション文字

わずかに異なる配色のレイアを重ねて文字のグラデーション表示する関数です。 下のボタンを操作すると「JavaScript」の文字が表示されます。

チェックボックスはそれぞれ、「縦」「横」がグラデーションの方向、 「中央」はグラデーションを対象に表示し、 「Round」はグラデーションの配色を対象にします。

文字の下にある「配色を変える」ボタンを操作すると 表示している文字のグラデーションの配色を変更します。

中央 Round
JavaScript

以下はグラデーション文字の生成関数のコードです。


// グラデーション文字用定義からテンプレートに変換する関数
function getGradationTmps(cs,n,i,rnd){
  var tmps=new Array();
  var ncs=Math.floor(cs.length/3);
  var n1 =n-1;
  for(var j=0; j<ncs; j++){
    tmps[j*2]=cs[j*3];
    var s=cs[j*3+1], e=cs[j*3+2];
    var rs=(s>>16)&0xFF, gs=(s>>8)&0xFF, bs=s&0xFF;
    var re=(e>>16)&0xFF, ge=(e>>8)&0xFF, be=e&0xFF;
    var rd=re-rs,        gd=ge-gs,       bd=be-bs;
    if(rnd){
      var k=(i<(n/2))?(i*2):((n-i)*2);
      tmps[j*2+1]='#'+num2hex(Math.floor(rd*k/n1)+rs)
                     +num2hex(Math.floor(gd*k/n1)+gs)
                     +num2hex(Math.floor(bd*k/n1)+bs);
    } else {
      tmps[j*2+1]='#'+num2hex(Math.floor(rd*i/n1)+rs)
                     +num2hex(Math.floor(gd*i/n1)+gs)
                     +num2hex(Math.floor(bd*i/n1)+bs);
    }
  }
  return tmps;
}
// グラデーション文字用のレイアを作成する関数
function createGradationStringLayer(x,y,w,h,z,n,rnd,
                                    html,tmps,css,pdiv){
  var divs=new Array();
  for(var i=0; i<n; i++){
    var div=createLayer(x,y,w,h,pdiv,
              createNWString(
                convertTemplateString(
                  convertTemplateString(html,tmps),
                  getGradationTmps(css,n,i,rnd))));
    // ZIndex 指定されていれば設定する
    div.zdx=z;
    if(z>0) setDivZIndex(div,z++);

    divs[i]=div;
  }
  return divs;
}
// グラデーション文字用のレイアをクリップする関数
function clipGradationString(divs,w,h,d){
  var n =divs.length;
  var n1=n-1;
  for(var i=0; i<n; i++){
    var div=divs[i], ct=0, cr=w, cb=h, cl=0;
    if(d&GradationString.VERT){
      if(d&GradationString.CENTER){
        ct = Math.floor(h*i/(n1*2)); cb=h-ct;
      } else {
        ct = Math.floor(h*i/n1);
      }
    }
    if(d&GradationString.HORZ){
      if(d&GradationString.CENTER){
        cl = Math.floor(w*i/(n1*2)); cr=w-cl;
      } else {
        cl = Math.floor(w*i/n1);
      }
    }
    setDivClip(div,ct,cr,cb,cl);
    div.ct=ct; div.cr=cr; div.cb=cb; div.cl=cl;
  }
  return divs;
}
// グラデーション文字のレイアを作成する関数
function createGradationString(x,y,w,h,z,d,n,rnd,
                               html,tmps,css,pdiv){
  var divs=new Array();
  for(var i=0; i<n; i++){
    var div=createLayer(x,y,w,h,pdiv,
              createNWString(
                convertTemplateString(
                  convertTemplateString(html,tmps),
                  getGradationTmps(css,n,i,rnd))));
    // レイアをクリップする
    var n1=n-1, ct=0, cr=w, cb=h, cl=0;
    if(d&GradationString.VERT){
      if(d&GradationString.CENTER){
        ct = Math.floor(h*i/(n1*2)); cb=h-ct;
      } else {
        ct = Math.floor(h*i/n1);
      }
    }
    if(d&GradationString.HORZ){
      if(d&GradationString.CENTER){
        cl = Math.floor(w*i/(n1*2)); cr=w-cl;
      } else {
        cl = Math.floor(w*i/n1);
      }
    }
    setDivClip(div,ct,cr,cb,cl);
    div.ct=ct; div.cr=cr; div.cb=cb; div.cl=cl;

    // ZIndex 指定されていれば設定する
    div.zdx=z;
    if(z>0) setDivZIndex(div,z++);

    divs[i]=div;
  }
  return divs;
}
// グラデーション文字の色を再設定する
function changeGradationString(divs,rnd,html,tmps,css){
  var n=divs.length;
  for(var i=0; i<n; i++){
    writeDivHTML(divs[i],true,true,
        createNWString(
            convertTemplateString(
                convertTemplateString(html,tmps),
                getGradationTmps(css,n,i,rnd))));
  }
}

この文字の部分は「ライブラリ集」で紹介している関数です。 上のスクリプトでは記述されていませんので、 使用する際には「ライブラリ集」を参照して追加してください。

各関数の呼び出し形式は以下の通りです。

グラデーション文字用定義からテンプレートに変換する関数
  - グラデーション用変換ルールから文字列の変換ルールを
    生成する関数
  tmps = getGradationTmps(cs,n,i,rnd);

    cs   : グラデーション用変換ルール
    n    : 階調数
    i    : 生成する番号
    rnd  : 配色を対象にする場合 true
    tmps : 文字列の変換ルール

グラデーション文字用のレイアを作成する関数
  -  指定された文字の色違いのレイアを重ねて生成します
  divs = createGradationStringLayer(x,y,w,h,z,n,rnd,
                                    html,tmps,css,pdiv);
    x,y  : 生成するレイアの位置  ( pixel )
    w,h  : 生成するレイアのサイズ( pixel )
    z    : 生成するレイアの Zオーダ( 正の整数 )
    n    : グラデーションの数( レイア数 )
    rnd  : 配色を対象にする場合 true
    html : レイア内に設定する HTML のテンプレート
    tmps : html に適用する変換ルール
    css  : html に tmps を適用した後の
           グラデーションの変換ルール
           このルールは "%*%" の "*" 部分をRGB値に変換する際の
           色の決定方法を定義した配列で、

             被変換文字列, 開始時のRGB値, 終了時のRGB値

           の3つの要素を1定義とする1次元配列です

    pdiv : 親となるレイアオブジェクト または null
    divs : 生成したレイアオブジェクトの配列

    例えば html に tmps を適用した結果が

      '<font color="%c1%">str</font>'

    で、16階調に対して css を

      css = new Array( 'c1', 0x000000, 0xffffff );

    と指定した場合、結果は

      <font color="#000000">str</font>
      <font color="#111111">str</font>
            :
      <font color="#ffffff">str</font>

    となります

グラデーション文字用のレイアをクリップする関数
  - createGradationStringLayer で生成したレイアをクリップ
    する関数
  divs = clipGradationString(divs,w,h,d);
    divs : createGradationStringLayer で生成したレイア
    w,h  : 生成したレイアのサイズ( pixel )
    d    : クリップする方法
             GradationString.VERT   : 縦方向にグラデーション
             GradationString.HORZ   : 横方向にグラデーション
             GradationString.CENTER : レイアを対象に配置

グラデーション文字のレイアを作成する関数
  -  指定された文字の色違いのレイアを重ねてクリップして
     グラデーション文字を生成します
  divs = createGradationString(x,y,w,h,z,d,n,rnd,
                               html,tmps,css,pdiv);
    x,y  : 生成するレイアの位置  ( pixel )
    w,h  : 生成するレイアのサイズ( pixel )
    z    : 生成するレイアの Zオーダ( 正の整数 )
    d    : クリップする方法
    n    : グラデーションの数( レイア数 )
    rnd  : 配色を対象にする場合 true
    html : レイア内に設定する HTML のテンプレート
    tmps : html に適用する変換ルール
    css  : html に tmps を適用した後の
           グラデーションの変換ルール
    pdiv : 親となるレイアオブジェクト または null
    divs : 生成したレイアオブジェクトの配列

グラデーション文字の色を再設定する関数
  - 生成したグラデーション文字のレイアに表示している文字を
    変更します
  changeGradationString(divs,rnd,html,tmps,css);
    divs : 生成したグラデーション文字のレイアオブジェクト配列
    rnd  : 配色を対象にする場合 true
    html : レイア内に設定する HTML のテンプレート
    tmps : html に適用する変換ルール
    css  : html に tmps を適用した後の
           グラデーションの変換ルール

使い方

基本的には他の関数と同じです。

「JavaScript」の文字を(x,y)の位置に白(0xFFFFFF)から黒(0x000000)に グラデーションする場合、サイズが(w,h)とわかっている場合には以下のようにします。

<style type="text/css"><!--
.gr  { font-weight:bold; font-size:72px; }
--></style>
<script language="JavaScript1.2"><!--
grHTML = '<span class="gr"><font color="%c1%">'
       + '<font color="%c2%">J<\/font>ava'
       + '<font color="%c2%">S<\/font>cript'
       + '<\/font><\/span>';
grTmp  = null;
grCtmp1= new Array('c1',0xdd0000,0xff9999,
                   'c2',0xffcc66,0xffee66 );
grNumG = 14;     // 階調数
grDivs = null;

// 生成するレイアのサイズがわかっている場合は
//   createGradationString を使用するとラク
grDivs=createGradationString(x,y,w,h,0,GradationString.VERT,
         grNumG,true,grHTML,grTmp,grCtmp1,null);
setDivVisibilities(grDivs,true);
// --></script>

生成する文字サイズが予めわからない場合は( こちらの方が多いかも f^^; )、 createGradationStringLayer 関数で必要なレイアを生成してから、 一旦ブラウザに制御を戻し( これは IE4 対策で setTimeout します )、 その後、生成したレイアを initDivSize してレイアサイズを取得してから clipGradationString でクリップ、最後に setDivVisibilities で表示します。
#> 時間的都合でスクリプトはカット(笑)。


注意事項


応用サンプル

ここで紹介した文字列修飾関数はアイディアによって色々なバリエーションが作れると思います。

例えば、ドロップシャドウの本体の文字列の色を背景色と同じにして表示し、 一定時間間隔で getGradationTmps 関数で中間色を計算しながら表示すると 下の応用サンプルのような演出ができます。

JavaScript

Copyright(c) 1999 - 2001 ShinSoft. All rights reserved.