カラーキーワードをHEXやRGBに変換したい

category-icon

 こんばんは。久しぶりにDean EdwardsLink のブログを覗いたら、MSIEでカラーキーワード(redとかtomatoとか)やらをHEX方式(#f01234とか)に変換するやり方が載ってました。

function toHex(color) {
  var body  = createPopup().document.body,
  range = body.createTextRange();
  body.style.color = color;
  var value = range.queryCommandValue("ForeColor");
  value = ((value & 0x0000ff) << 16) | (value & 0x00ff00) | ((value & 0xff0000) >>> 16);
  value = value.toString(16);
  return "#000000".slice(0, 7 - value.length) + value;
};
へぇ。これにも元ネタがあって、それはerik's weblogのコメントLink です。

 ppBlogには、cornerplay.jsというJavaScriptがあって、指定ボックスの角を丸くしたり凸凹にしたりできる動作を担当しています。具体的には以下のような感じです。

 こんな感じで、コーナーをちょいと変えると、見た目のアクセントになります。

 で、このボックスの背景色に、tomatoとかindigoとかlavenderなどのいわゆるカラーキーワードLink でも指定できるように、これらカラーキーワードをHEX方式に直した対応表も含めているんですよね(147色ぐらいある)。今、考えるとほかにもやりようがある気もしますが、当時は仕方ないなぁとその対応表をJSON配列にして含めてました。

 このDean Edwardsのやり方なら、対応表なんていりませんね。記述が短くなってファイルサイズも小さくなるだろうし言うことないです。ただ、これはIE限定なので、Firefoxやその他のブラウザでも動くように改良してみましょう。Deanは、「ほかのブラウザは、getComputedStyle()が使えるからバッチリだぜ。」って述べています。

 調べたところ、各ブラウザ(Firefox、Opera、Chrome・SafariなどのWebKit系)で結構動作が違っていて興味深かったです。ただ色の変換をしたいだけなのに、わざわざ既存のDOM構造に影響を与えるようなやり方(色を取得したいがために、document.createElementで新たに要素を作成して、それをdocument.body.appendChildしてDOM構造を改変した後で、getComputedStyle()にて色を取得)は、reflowの問題Link もあり出来れば避けたいところ。

 大体以下のような感じでいけそうです。

function ColorToHEX(color){
 var d = document, ecolor, element = d.createElement("button");
 element.style.color = color;
 ecolor = element.style.color; // ポイント!
 if(ecolor.indexOf("#") !== -1) return ecolor; // Operaの可能性が高い
 if(d.uniqueID){ // IE向け
  color = element.createTextRange().queryCommandValue("ForeColor");
  color = ((color & 0x0000ff) << 16) | (color & 0x00ff00) | ((color & 0xff0000) >>> 16);
  return "#" + ("000000" + color.toString(16)).slice(-6);
 } else { // IE以外のブラウザ
  if(/webkit/i.test(navigator.userAgent)){ // Google Chrome, Safariで基本カラーなら
   var basicColors = {
    "aqua" : "#00ffff", "black" : "#000000", "blue" : "#0000ff", "fuchsia" : "#ff00ff", "gray" : "#808080", "green" : "#008000",
    "grey" : "#808080", "lime" : "#00ff00", "maroon" : "#800000", "navy" : "#000080", "olive" : "#808000", "orange" : "#ffa500",
    "purple" : "#800080", "red" : "#ff0000", "silver" : "#c0c0c0", "teal" : "#008080", "white" : "#ffffff", "yellow" : "#ffff00"
   }
   for (var col in basicColors){
    if(color.toLowerCase() === col) return basicColors[col];
   }
  }
  if(ecolor.indexOf("rgb") !== -1){ // RGB形式で色を返した!
   color = ecolor;
  } else color = getComputedStyle(element, null).getPropertyValue("color");
  return "#" + color.replace(/rgb¥((¥d+?),¥s*(¥d+?),¥s*(¥d+?)¥)/g, function(a, r, g, b){
   return ("000000" + ((+r) * 65536 + (+g) * 256 + (+b)).toString(16)).slice(-6);
  });
 }
};
 流れとしてはこうです。
  1. IEでcreateTextRange()を使うのでBUTTON要素を作成。
  2. それに色を指定する。element.style.color = color
  3. 指定した色の取得。この時点で、OperaがHEX形式の値を返してくれる。Opera一抜け。
  4. 同様に、この時点で、IEはqueryCommandValue経由でBGR値を取得できるので、それをHEXに変換。
  5. IE以外でFirefoxは、ecolorは指定したままの値。getComputedStyleを使うとRGB値を返してくれる。
  6. WebKit系は振る舞いがややこしい。Webの基本17色、例えばredの場合、 ecolor = element.style.color にはredがそのまま入り、tomatoなどの拡張色ならRGB形式を返す。じゃ、getComputedStyleはどうかというと、まだDOMに組み入れていないので空の値を返す。
  7. なので、WebKit系で基本17色であれば、それはJSON対応させてHEX値を返すようにします。そうでなければ、RGB値を返してくれるのでHEX値に変換。
  8. 以上。document.body.appendChildなどでのDOM改変は必要ない点がポイントです。

 WebKit系の振る舞いが独特で、特別な処理が必要になりますが、いずれにせよ、DOMの改変を伴わなくて良いかなぁと(まぁcreateElementはしますが)。ちなみに、OperaでもgetComputedStyleは使えますが、FirefoxやWebKitがRGB値を返すのに対して、OperaはHEX値を返します。RGB値からのHEX値への変換は、いくつか方法があるでしょう。上では正規表現を用いています。逆にHEXからRGBへの変換も色々あると思います。

function HEXToRGB(hex){
 return hex.replace(/#?(¥w{2})(¥w{2})(¥w{2})/, function(a, r, g, b){ 
  return "rgb(" + parseInt(r, 16) + ", " + parseInt(g, 16) + ", " + parseInt(b, 16) + ")"}
 );
}

function HEXToRGB(hex){
 var color = parseInt(hex.replace("#", ""), 16);
 return "rgb(" + ((color >> 16) & 0xff) + ", " + ((color >> 8) & 0xff) + ", " + (color & 0xff) + ")";
}

などですかね。

 ついでなので、カラーキーワードからRGB値に変換する関数も挙げておきます。考え方は基本的に同じです。DOMの改変は必要ないです。

function ColorToRGB(color){
 var d = document, ecolor, element = d.createElement("button");
 element.style.color = color;
 element.style.display = "none";
 ecolor = element.style.color;
 if(ecolor.indexOf("rgb") !== -1) return ecolor; // WebKit系が一抜けする可能性あり。
 if(ecolor.indexOf("#") !== -1){ // OperaはHEX値を返す
  return ecolor.replace(/#?(¥w{2})(¥w{2})(¥w{2})/, function(a, r, g, b){ 
   return "rgb(" + parseInt(r, 16) + ", " + parseInt(g, 16) + ", " + parseInt(b, 16) + ")"}
  );
 }
 if(/webkit/i.test(navigator.userAgent)){ // WebKit系で、基本カラーの場合はRGB値を返さない
  var basicColors = {
   "aqua" : "rgb(0, 255, 255)", "black" : "rgb(0, 0, 0)", "blue" : "rgb(0, 0, 255)", "fuchsia" : "rgb(255, 0, 255)",
   "gray" : "rgb(128, 128, 128)", "green" : "rgb(0, 128, 0)", "grey" : "rgb(128, 128, 128)", "lime" : "rgb(0, 255, 0)",
   "maroon" : "rgb(128, 0, 0)", "navy" : "rgb(0, 0, 128)", "olive" : "rgb(128, 128, 0)", "orange" : "rgb(255, 165, 0)",
   "purple" : "rgb(128, 0, 128)", "red" : "rgb(255, 0, 0)", "silver" : "rgb(192, 192, 192)",
   "teal" : "rgb(0, 128, 128)", "white" : "rgb(255, 255, 255)", "yellow" : "rgb(255, 255, 0)"
  }
  for (var col in basicColors){
   if(color.toLowerCase() === col) return basicColors[col];
  }
 }
 if(d.uniqueID){ // IE用
  color = element.createTextRange().queryCommandValue("ForeColor");
  return "rgb(" + (color & 0xff) + ", " + ((color >> 8) & 0xff) + ", " + ((color >> 16) & 0xff) + ")";
 } else { // FirefoxはこれでRGB値を返す
  return getComputedStyle(element, null).getPropertyValue("color");
 }
}

 こんな感じですかねぇ。ファイルサイズが小さくなるなら、cornerplay.jsを書き換えても良いなぁ。

 ちなみに、圧縮したら920バイトになりました。

function ColorToHEX(b){var g=document,a,e=g.createElement("button");e.style.color=b;a=e.style.color;if(a.indexOf("#")!==-1){return a}if(g.uniqueID){b=e.createTextRange().queryCommandValue("ForeColor");b=((b&255)<<16)|(b&65280)|((b&16711680)>>>16);return"#"+("000000"+b.toString(16)).slice(-6)}else{if(/webkit/i.test(navigator.userAgent)){var f={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",grey:"#808080",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",orange:"#ffa500",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00"};for(var c in f){if(b.toLowerCase()===c){return f[c]}}}if(a.indexOf("rgb")!==-1){b=a}else{b=getComputedStyle(e,null).getPropertyValue("color")}return"#"+b.replace(/rgb¥((¥d+?),¥s*(¥d+?),¥s*(¥d+?)¥)/g,function(h,j,i,d){return("000000"+((+j)*65536+(+i)*256+(+d)).toString(16)).slice(-6)})}};

— posted by martin at 03:46 am   commentComment [0]  pingTrackBack [0]

アクセス解析でドメイン毎にソート

category-icon

 こんにちは、martinです。もう師走はすぐそこですね。先日レヴィ・ストロースW氏が亡くなりました。何となく今年だろうなぁと思って、日記の方で新年の抱負Link を語っていたんですが、ちっとも進んでいません(--)

 フォーラムでアクセス解析関連のバグの報告がありました。→http://forum.p2b.jp/index.php?mode=box&UID=4592Link

 ホストごとの集計の際に、ピリオドで区切られた長いホスト名を短くする処理を入れていたんですが、ホスト名が取得できずにIPアドレスが登録されているときにも、これを適用してしまいIPアドレスが削られて表示されていました。なので正規表現部分を修正しました。

 これだけだと、1行だけの修正なんで、ついでにドメインごとの集計もする記述を加えました。
sortbydomain
こんな感じです。

 どういうドメインでソートするかは、374行目で指定しています。

 $sort_type = array('.jp', '.com', '.net', 'ne.jp', 'co.jp');
なので、例えば、or.jpad.jpなんかも追加したいということであれば、
 $sort_type = array('.jp', '.com', '.net', 'ne.jp', 'co.jp', 'ad.jp', 'or.jp');
みたいにすればOKです。自動的に認識されるかと思います。

 ファイルを添付しておきます。statディレクトリのものと入れ替えてください。

添付ファイル: view.phpattachedIcon 

— posted by martin at 09:10 pm   commentComment [8]  pingTrackBack [0]

16色のカラーパレット

category-icon

こんばんは。コメントで、ppBlogのエディタのカラーパレットが、色が豊富すぎるのでは?というご指摘があり、確かにそう思っていました。計算上は、1677万色程度の指定が可能ですので。

 ブログの文章で、そこまでの色数が必要かというとそうではないでしょうね。なので、基本となる16色のみに絞ったバージョンも用意してみました。スクリーンショットを挙げておきます。

base16
こんな感じの16色です。

 これを有効にするには、editor.jsの6行目にある変数を有効にします。

var useBasicColor = true; // これで簡易パレットになる

 false(あるいは0)を指定すれば、従来のカラーパレットです。

 ちなみに、簡易パレットの色は、editor.jsの593行目で指定しています。

var cols = '', bcolors = ['red','blue','yellow','black','green','silver','lime','gray','olive','white','maroon','navy','purple','teal','fuchsia','aqua'];

 お好みの順番や色に変えても良いでしょう。

 試されたい方はどうぞ。何か不具合を見つけましたらお知らせください。

添付ファイル: editor.jsattachedIcon 

— posted by martin at 06:26 am   commentComment [6]  pingTrackBack [0]

ppBlog1.8.7リリース

category-icon

 こんばんは。久しぶりのエントリーです。ppBlogがバージョンアップしてv1.8.7になりました。前バージョンは1.8.5で、バージョン1.8.6はありません。それなりにいじったのと、例によって奇数好きなので。

 v1.8.5との差異ですが、既知のバグに対するものと、後、使い勝手の向上の部分がメインです。既知のバグとしては、画像のアップロードに関してですが、いつのバージョンからか、大きさ(縦横のサイズ)が小さい画像をわざわざリサイズして大きい画像にしたりしてたので、その辺りを修正しています。画像アップロードに関してですが、JPEG写真であれば、それの縮小時に品質を指定出来るようにしました。初期値は75ですが、お好みに合わせて、85から90あたりを指定するとリサイズされた写真でも綺麗に仕上がるかと思います(参考エントリーLink )。

 後は、タグの文字種(タグに半角括弧を含んでいたりとか)によっては、タグのエントリーが上手くピックアップ出来ないのにも対処しています。このためにindex.phpのタグ表示部分に少し修正が入っています。

 他には、アクセス解析のデータは、3-4か月分のストックにしました。それ以前の古いアクセスデータは自動的に削除されます。従来は、削除されずにどんどん溜まっていましたが、多すぎるログファイルは、パフォーマンスにも影響しますし。バージョンアップをすると、古いデータ(stat/dataディレクトリの中)はすべて削除されますので、残しておきたい方は、予めFTPソフトなどでダウンロードしておいてください。

 動画貼り付け支援関連でも修正が入っています。動画投稿サイトも、いつの間にやらサービスが終了していたところは削除してます。テクノラティのサービスも終了するLink ようで、ppBlogではこの機能も少し取り入れていたので残念といえば残念ですが仕方ないですね:(

 使い勝手の向上ですが、目に見える部分では、エントリー作成でのエディタ部分ですかね。スクリーンショットを挙げておきます。
EditorShot1
フォント修飾系が増えてます。B,S,Eとか。

 従来は、太字にする「B」ボタンで、<strong>foo</strong>みたく入力されていましたが、これは文字通り<b>foo</b>となるようにしました。このB要素ですが、

<span style="font-weight: blod">foo</span>
という出力にしようかと迷ったのですが、こう書くとひとつは冗長なのと、後、視覚的強調のためにわざわざ用意してあるのだから、あえて使ってみようという思いもあります。一般的には、視覚的強調ならCSSで代用すべきLink という意見が多いように思いますが、B要素を使うことでアクセシビリティの低下を招くとも思いませんし、HTML5でも採用されているので存在意義があるんでしょう。個人的には、日本語文中のアルファベットや数字なんかに使うと視覚的に見やすいのでは思っています。これまでは、特に論理的強調でもないのにstrong要素ばかりを使っていたので、それはちょっと反省しています。

 で、strong要素は、「S」というボタンで入力できます。同様に、EM要素Link を入力する「E」ボタンも付けました。なんだかBSEで狂牛病みたいですが、たまたまです。なお、強調の度合いとしては、EM要素より強い強調にはSTRONG要素という使い分けのようです。

 アルファベット圏では、EM要素内の文字列はイタリック体(斜体)として表示されますが(もっともブラウザ依存です)、少なくとも日本語では、斜体文字という文化はないようで、例えばメイリオフォントには斜体は存在しませんし、スタイルシートでイタリック体を指定しても無視されます。じゃどうやって、「強調」であることを示すかというと、よくあるのは、文字列に読点を打つとか括弧でくくるとかでしょうか。この点では、EM要素は「強勢」と呼ぶほうがふさわしい気もします。

 ppBlogのベーシックテーマでは、このEM要素に対しては、ドットを付けるという風にしています。スタイルシートを用いて、EM要素の背景にドット画像を指定しているのですが、長さの調整とか文字列との位置関係とか難しいです。

これはEM要素で囲まれた文字列です

 ここでは文字列の下にドットが来るようにしていますが、上に置いてもよいでしょう。上だと、なんとなく小学生の頃に音楽の授業で習ったスタッカートWを思い出しますね:) 確か、アマリリスを笛で弾くときに意識するように言われた覚えがあります。ラリラリラリラ~♪でしたっけ?

 エディタ関連でもうひとつ。これは前から実装しないといけないなぁと思っていたんですが、カラーパレットで色を選択した際に、その最後に選択した色を覚えておく機能です。最後に選んだ色は、左側に表示させるようにしました。この部分をクリックすることで、同じ色指定が可能になります。

EditorShot2
こんな感じです。

 こんなところでしょうか。v1.8.5との差分ファイルを添付しておきます。

 

追 記 2009/10/16 13:47:24

 強調のために、文字列に打つ点は、「圏点W」と呼ぶらしいですね。Wikipediaのページにある圏点は参考になるのでは思います。
添付ファイル: DIFF185_187.zipattachedIcon 

— posted by martin at 09:55 am   commentComment [12]  pingTrackBack [1]

IEでCSS3のドロップシャドウを使いたい

category-icon

 こんばんは、martinです。CSS3+JavsScriptネタでも。目標は、IEでもCSS3のドロップシャドウ効果が得られるようになること。以下のような感じで、Firefoxとほぼ同等の効果を得ることが出来ます。左がIE8で右がFirefoxです。

[2010/08/04 01:02:25] プログラムアップデート→http://p2b.jp/2010/08/04/IE-compatible-CSS3-dropShadowLink

comparison
影のぼやけた感じも再現。
 CSS3では、テキストにドロップシャドウの効果を付けるtext-shadow定義されていてLink (まだドラフト段階かな)、既にFirefox3.5やSafari, Chrome, Opera10などは対応しています。典型的には、以下のような感じで指定します。
text-shadow: 1px 2px 3px tomato; // 順にx-offset、y-offset、ぼかし半径、影の色。最初に色指定でもOK。

 また、テキストに対する影だけでなく、DIVなどのボックス要素に対するドロップシャドウとして、box-shadowLink というのもあり、これは、FirefoxとSafari、Chromeで先行実装されています(Opera10はまだかな)。指定の仕方は、text-shadowと同様です。ほんとは、spread-radiusというオプションのパラメータもあるのですが、これはなくても良いんじゃないかと思ってます。

   -moz-box-shadow: 1px 2px 3px chocolate; // 順にx-offset、y-offset、ぼかし半径、影の色。
-webkit-box-shadow: 1px 2px 3px chocolate; // Safari, Chrome用の記述。

 また、box-shadow固有の属性として、insetというのがあります。これは、ドロップシャドウをボックスの内側に見せるものです。

   -moz-box-shadow: inset 0 0 1em red;
-webkit-box-shadow: inset 0 0 1em red;

 今のところ、insetオプションを理解するのは、Firefox3.5だけのようです。

 あれっ、ドロップシャドウって、IEが10年ぐらい前から実装してなかったっけ?と思う方もいるでしょう。そう確かにそんなものがありました。IE独自のフィルター機能を使ってそれっぽいことが出来ます。

 これらが紹介された当初はクールだと思いましたが、使い勝手が今イチだったのと、あとは、玉に瑕というか白璧の微瑕(はくへきのびか)だったと思うのは(ここまでいうと誉めすぎですが)、影の「ぼかし」が指定出来なかったことです。キリッとした輪郭の影では折角の魅力も半減です(個人的に)。おそらく、影のぼかしはそれなりにCPUのパワーを必要とするので、当時はまだ難しかったのかもしれません。なので、これらが広くWebサイトで使われるということはなかったです。AjaxのようにまたしてもIEの早すぎた実装だったわけです。

 昨今、パソコンの性能も上がり、IE以外のモダンなブラウザがCSS3のtext-shadowをサポートするようになったせいか、この頃は色んなサイトでドロップシャドウ効果を見かけるようになりました。

 なので、まだまだシェアの大きいIEでも、CSS3に準拠した、それらしいドロップシャドウを付けたいということで考えてみました。基本的な考え方は、上で述べたマイクロソフト独自のFilter BlurLink を用いて、影のぼかしを演出するということです。このBlurは、要素自体をぶれた表現にするので、それを別のレイヤーとして生成して、それを影を付けたい要素の背後に配置するというものです。別のレイヤー生成というと、大げさな気もしますが、ぼやけた感じを出すには、これ以外の方法はない気がしますし、Firefoxにしても、影は別レイヤーなんじゃないんでしょうか、知りませんが。

 とりあえず、それっぽいモノができたのでデモをお見せします。

 

IEでもCSS3のドロップシャドウを実現するデモLink

 text-shadowbox-shadowもカンマで区切った複数の指定が可能なので、これにも対応してみました。

.multi-text-shadow {
 font: bold 3em Arial, sans-serif; color: white;
 padding: 10px;
 text-shadow: 1px 2px 2px #555, 0 0 1em blue, 0 0 0.2em blue; /* ここでは3つ指定している */
}
 上の指定だと、以下のような感じになります。
multi-text-shadow
IE8でのスクリーンショットです。

 また、現時点では、Firefox3.5のみが対応しているinsetオプションも解するようにしてみました。IE8でのスクリーンショットをば。

inset-demo
なかなか良い感じでは。
 で、実際の設置方法ですが、なるべく簡単に設置できるように、外部スクリプトとしました。CSSでの記述は、特別なものは必要ないです。普通に上に挙げたような感じで、text-shadowやbox-shadowの指定をしておけば良いです。後は、ドロップシャドウを効かせたいページで、外部スクリプトを次のように呼び出せばOKです。
<script type="text/javascript" src="path/to/css3shadow.htc"></script>
 ファイルの名前css3shadow.htcさえ変えなければOKで、それを置いた相対パスを、各自で記述すれば良いです。

 これ以外の指定方法としては、このスクリプト自体は、完全にIE向けなので、Firefoxその他のブラウザには不要なものです。なので、その分のトラフィックを減らしたいということであれば、IE向けの条件コメントを使って、

<!--[if lt IE9]>
<script type="text/javascript" src="path/to/css3shadow.htc"></script>
<![endif]-->

でも良いと思います。これであれば、Firefoxなどではコメントとして解釈されるので、サーバーからcss3shadow.htcが呼び込まれることはないです。

 まだ、書き上げたばかりなんで、細かいチェックは出来ていませんが、外部スクリプトを呼び込むだけなので、気軽に試して頂けるかと思います。css3shadow.htcを添付しておきます。8KB未満の小さいファイルです。

 ちなみに、影の色指定ですが、透明度を設定できるrgba方式にも対応しています。これは、通常のRGB形式に加えて、4つめに透明度を指定出来るものです。ゼロで透明、1で不透明となります。

rgba(123, 100, 125, 0.3); /* 透明度30%の指定 */

 オフトピですが、RGBって、たまにRBGとタイプミスしたり、あれっ?どっちだっけと混乱するときがありますが、キーボードで、上から順にRGBとなっている、と覚えると良いです。

 以下、Mozillaの参考サイトを挙げておきます。

添付ファイル: css3shadow.htcattachedIcon 

— posted by martin at 12:35 pm   commentComment [14]  pingTrackBack [1]

T: Y: ALL: Online:
Created in 0.0051 sec.
prev
2024.3
next
          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