substr($target, 33, 10)
が正しいです。引数の3番目は、取得したい文字列の長さですね。文字列終了位置を指定していました。。どうも、JavaScriptのslice関数とごっちゃになっていたようで。
とりあえず、今回はこれだけです。添付しておきます。あ、ついでに、セーフモード版もダウンロードできるようにしています。
2009/3/31
substr($target, 33, 10)
が正しいです。引数の3番目は、取得したい文字列の長さですね。文字列終了位置を指定していました。。どうも、JavaScriptのslice関数とごっちゃになっていたようで。
とりあえず、今回はこれだけです。添付しておきます。あ、ついでに、セーフモード版もダウンロードできるようにしています。
— posted by martin at 02:30 am
Comment [0]
TrackBack [0]
2009/3/29
カテゴリー » 開発日誌 » JavaScript
おはようございます。時間があるときに、以下のようなサイトを作成しているのですが、この2枚のスクリーンショットは、違うところがあります。どこが違うのかというと、2枚目のやつは、ボックスのコーナーが丸っこくなっていて、いわゆる角丸コーナーと言われるものになっています。


ちょっとお洒落っぽいサイトデザインにしようと思っているのですが、そのためには、角張ったデザインよりも、角が取れたデザインの方が良いかなと考えました。で、角丸コーナーは、FirefoxやWebKit系のSafariやChromeは、以下のような感じでCSSでの指定が可能です。
-moz-border-radius: 10px; // Firefox -webkit-border-radius: 10px; // Webkit系
問題は、これらのCSSに対応していないOperaやIEです。Operaは、近い将来にサポートするでしょうけど、IEは、今後数年は期待できないかもです。なので、これら2つのブラウザに対しては、JavaScriptを通じてのアプローチを取ることになります。
IEでは、VMLを利用するのがよさげです。しかも角丸コーナーのためにあるようなroundrectというのが予め実装されているので、これを使うのが簡単そうですが、例えば最初に挙げたサイトショットにあるように、ナビ―ゲーションタブの上側だけ丸っこくしたいとかいう場合の制御が難しいです。なので、VMLを使うにしても、もうちょっと、凝ってみることにします。そもそも角丸コーナーを実現するには、以下のようなアプローチを取るのが自然でしょう。

要は、4つの各コーナーに小さい円を描いて、それをクリッピングすれば良いわけです。これなら、ボーダー半径は、FirefoxやWebkit系で指定する値と同様に振る舞うことが期待出来ます。で、それを実際に書き下したのが以下。
<div style="background:#fffacd; position:absolute; right:-20px; bottom:-20px; width:50px; height:50px; clip:rect(25px 50px 50px 25px);"> <v:group style="width:50px; height:50px; position:absolute;" coordsize="50,50"> <v:oval fillcolor="#fff" strokeweight="20px" strokecolor="#ffd700" style="left:9px; top:9px; width:30px; height:30px;" /> </v:group> </div>
これをIEで見ると、以下のように見えます。なかなか良い感じですね。

残りの角についても同様にすればOKです。ただし、IEのVMLバグなのかどうか分かりませんが、作成したVML画像の位置が1ピクセルぐらい微妙にずれる場合があるようです。理論的には、OKのはずなんですが。。
さて、Operaの場合はどうでしょうか。OperaはVMLはサポートしませんが、代わりにSVGをサポートします。なので、これを用いて、上で述べたようなアプローチを取ればOKですね。大体以下のようなスクリプトでOKでしょう。
function svg_corner(id, location, r, obg){
var d = document, e = d.getElementById(id);
if(e.currentStyle.position == 'static'){
e.style.setProperty('position', 'relative', null);
}
r = r || 10;
var svg = d.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.style.setProperty('position', 'absolute', null);
var ibg = e.currentStyle.backgroundColor;
ibg = ibg == 'transparent' ? '#fff' : ibg;
if(!obg){
var p = e.parentNode;
while(p && p.currentStyle.backgroundColor){
obg = p.currentStyle.backgroundColor;
if(p.nodeName == "HTML") break;
if(obg && obg != "transparent") break;
p = p.parentNode;
}
}
obg = (!obg || obg == "transparent") ? "#fff" : obg;
var bc = e.currentStyle.borderColor;
bc = (!bc || bc == "transparent") ? "#fff" : bc;
var bw = parseInt(e.currentStyle.borderWidth);
var rect = d.createElementNS('http://www.w3.org/2000/svg', 'rect');
var oval = d.createElementNS('http://www.w3.org/2000/svg', 'circle');
var attr = [];
switch (location){
case 'tl' : attr = [r + bw/2, r + bw/2, 'top', -bw, 'left', -bw]; break;
case 'tr' : attr = [0, r + bw/2, 'top', -bw, 'right', -bw]; break;
case 'bl' : attr = [r + bw/2, 0, 'bottom', -bw, 'left', -bw]; break;
case 'br' : attr = [0, 0, 'bottom', -bw, 'right', -bw]; break;
}
oval.setAttribute('fill', ibg);
oval.setAttribute('cx', attr[0]); oval.setAttribute('cy', attr[1]);
oval.setAttribute('r', r);
oval.setAttribute('stroke', bc); oval.setAttribute('stroke-width', bw + 'px');
rect.setAttribute('fill', obg);
rect.setAttribute('width', r * 2 + bw + 'px'); rect.setAttribute('height', r * 2 + bw + 'px');
svg.appendChild(rect);
svg.appendChild(oval);
svg.style.setProperty(attr[2], attr[3] + 'px', null); svg.style.setProperty(attr[4], attr[5] + 'px', null);
svg.style.setProperty('width', r + bw/2 + 'px', null); svg.style.setProperty('height', r + bw/2 + 'px', null);
e.insertBefore(svg, e.firstChild);
}
これらをまとめると、以下のようなデモンストレーションが出来ます。このデモでは、ID指定した要素に対して角丸を発動していますが、特定のクラス名を持ったものに対して、ということも簡単に出来るでしょう。
上のサンプルでは、ついでにFirefoxやWebkit系でも、スクリプトでボーダー属性を指定するようにしています。このふたつ、指定の仕方が微妙に違うんですよねぇ。ちょっとはまりました。以下の感じ。document.getElementById(id).style.WebkitBorderTopLeftRadius = radius + "px"; // Webkit系 document.getElementById(id).style.MozBorderRadiusTopleft = radius + "px"; // Firefox。leftのLも小文字。
なお、OperaでのSVGの使い方は、「Operaで丸角を実現するCSSを試してみた (解決)
」や「角丸にするためにライブラリを作ってみる
」が参考になりました。
— posted by martin at 01:15 pm
Comment [0]
TrackBack [0]
2009/3/24
早速ですが、ppBlog1.8.0RCでのoParts.jsのAjaxライブラリをいじったせいか、Firefoxで、角丸スクリプトを使用していると、サーバーからcornerplay.jsを呼び込もうとして、そこで反応が止まりますね。他のブラウザでは問題ないようですが。なので、この部分は以前のやつに戻しました。oParts.jsの最新版(oParts.version = '20090324.123224')を添付しておきます(1.8.0RC向けです)。
ついでに、oParts.js、lib.js、phooeffect.jsは、圧縮してファイルサイズを丸めたやつをindex.phpの方で指定できるので、これも添付しておきますね。指定の仕方は、index.phpの最後にあるechoHTMLの引数で指定します。
echoHTML(array('photoeffect.min.js','oParts.min.js','lib.min.js')); // これで HTMLを出力
— posted by martin at 09:05 pm
Comment [0]
TrackBack [0]
こんばんは、martinです。ppBlogのバージョンアップを行いました。前回バージョンは1.7.7とかでしたが、結構、修正が多岐に渡っているのでバージョンを1.8.0としてます。ただし、まだ細かいところまで検証出来ていない気もするので取り敢えず試用版という扱いです。試用版と言っても、このサイトで使っているものと同じですけど。
前バージョンで特に大きなバグとかはなかったと思うので、基本的には使い勝手の向上を目指したり、機能を改善したものです。新機能というほどのこともないですが、今、このサイトで使っているヘッドラインモードに関して、基本的には、設定した文字数でエントリーの文章をカットしますが、<!--]]-->という文字列を挿入することで、そこまでの文章や画像をそのまま表示させることが可能です。今まで、この機能がなかったのが不思議なくらいですが。。この指定タグは、エディタのボタンに付いてます。
エディタで言えば、「文の整形」の項目で、従来の整形ブロック(PREタグ)の下に「整形ブロック[class="thru"]」というのが追加されています。このタグを使うことで、PRE要素に対してソースハイライト表示用のsyntax.jsが適応されるのを回避することができます。
見栄えの点で言えば、開発日誌にも書いてきましたが、ソーシャルブックマークの挙動を修正して、複数記事表示モードの際は、各種ブックマークへのエントリーを促すボタンが表示されます。このボタンをクリックすると、その場で登録したブックマークを呼び出す仕組みです。単独記事モードの際は、このエントリーボタンではなくて、各種アイコンが表示されます。
後は、モブログに関して、フォーラムの方で出ていた要望をそのまま採り入れたものになっています。すなわち、
です。カテゴリーの指定は、メールのタイトルに続く、連続した2つの空白の後のカテゴリーインデックス(数字)(半角全角ともに可)で可能です。カテゴリーインデックスとは、カテゴリー設定ファイル(category.ini.php)を編集エディタで開くと配列リストになっていますが、それを上から順に1,2,3と数えた数字になります。これは、普通に表示されるサイドバーのカテゴリーのメニュー順と一致します。サブカテゴリーも通し番号になっているので、この指定方法で問題ないです。具体例を挙げると、以下のような感じ。
春の息吹 3
みたいな感じです。これで、カテゴリーリストで上から3番目のカテゴリー名が、投稿先のカテゴリーになります。2番目の添付画像の位置指定ですが、これは、文章中でどこに表示させるかという位置指定と、画像に関する位置指定(左寄り、中央、右寄り)の両方の指定が可能です。方法は、表示させたい位置で、%pict1_l、%pict1_c、%pict1_rとか%pict3_cなどの指定をすることで可能です。順に、1枚目の画像を左寄り(leftのエル)、センタリングのc、右寄り(rightのアール)という指定になります。最後の例のように複数枚でも、その番号を指定すれば良いです。
念のため言っておくと、モブログにおけるこれらの指定は、あくまでオプションなので、従来通りの投稿で問題ないです。
こんなとこですかねぇ。試用版で恐縮ですが、不具合やら要望とかありましたらお願いします。
— posted by martin at 01:38 pm
Comment [4]
TrackBack [0]
こんばんは。どうも昨日辺りから自宅のネット接続がとろいです。ppBlogは、ファイル数は390個(決して多くはないと思いますけど)近くあるのですが、それが昨日は全部アップロード出来ずじまい。愛用しているFFFTPGの転送画面が何度も途中でフリーズしたようになってました。昔、28.8kbps?ぐらいのモデムでピーガラガラとかやってたのを思い出しはしませんでしたが。
というわけで、ブログシステムというものは、多機能になればなるほど、当然のようにそのサイズが肥大化していきます。なので、サーバー上に、圧縮されたZIPファイルをさくっとアップロードして、そこで展開するのが楽だよなぁ、と思ったので、PHPの充実したオンラインマニュアルを片手に、そういうスクリプトを書いてみました。最初に書いたのが以下です。ローカルのテスト環境でわけなく作動したので、こりゃいけるとサーバー上で試したら、zip_open関数がないと怒られました
function my_unzip($zipFile=''){
$zip_dir = getcwd().'/'; // カレントディレクトリの取得
if(is_dir(str_replace('.zip', '', $zipFile))){ // 既に展開されたディレクトリがあるならば
exit("Already exists!");
}
$i = 0; // どれくらいファイルがあるのか知りたい
if($zip = zip_open($zip_dir.$zipFile)){
while($zip_entry = zip_read($zip)){
$file = zip_entry_name($zip_entry);
$zdir = $zip_dir.dirname($file);
if(!is_dir($zdir)){
@mkdir($zdir, 0777); // ディレクトリないなら作成
echo "Directory: ".dirname($file)."/ created.<br />¥n"; // メッセージ表示
}
if(zip_entry_open($zip, $zip_entry, 'rb')){ // ファイルの書き出し
if($fp = @fopen($file, 'wb+')){
fputs($fp, zip_entry_read($zip_entry, zip_entry_filesize($zip_entry)));
fclose($fp);
echo " File ".++$i.": $file created.<br />¥n";
}
}
zip_entry_close($zip_entry);
} #while
}
zip_close($zip);
return TRUE; // 無事に終わったらTRUEを返す
}
これを以下のようにしてローカルで走らせました。
if(my_unzip('ppBlog180b.zip')){
echo "Successfully extracted!¥n";
} else echo "Failure!¥n";
したら、ファイル数が390個近くあることが判明。で、実際にオンラインのサーバー上でもやってみたら駄目だったわけです。なので、シェルコマンドでトライしてみました。
$zip_file = getcwd().'/ppBlog180b.zip'; // 展開するファイルを指定
function unzip($zip_file){
return shell_exec("unzip $zip_file"); // UNIX系には、まず付いてるであろうunzipを使う
}
if($zip = unzip($zip_file)){
echo "<pre>$zip</pre>¥n"; // これでずらっと展開されたファイルが表示される
echo "$zip_file: Successfully extracted!
";
echo '<a href="./ppBlog180b/install.php">installation</a>'; // 続けてppBlogのインストール画面へ誘導
} else{
echo("Failed to extract: $zip_file¥n");
}
そしたら、今度は上手く行きました。すべてのファイルがそっくりサーバー上で展開されていました。これは楽チンですねぇ。上のスクリプトは、単にZIP圧縮されたフォルダを展開するだけなので、サーバー上に作成されたディレクトリは、圧縮前のフォルダの名前と同じになります。多分、copyコマンドとかchdirで、展開先やら名前を指定できるでしょうね。
一応、この簡単なスクリプトを添付しておきます。お使いのサーバーで動くかどうかは保証しませんが。。と、その前にppBlog180b.zipがないことには・・・。
— posted by martin at 03:58 am
Comment [0]
TrackBack [0]
Comments