Google Maps APIとTwitter APIを連携させて遊んでみた。

2010.1.29 金曜日

なんだかやたら忙しくなり、
忙しくなればなるほど余分なことやって遊びたくなるという。

何気なくTwitterのAPI仕様書を読み直してたら、検索用のAPIでgeocodeを指定出来るとのことで、試しにGoogle Maps APIと連携させてみた。

[TwitterMaps]

地図の右側に、表示範囲内で発言された最新15件のツイートを表示。
地図を動かす度にAPIを実行するので、制限(100回/1h)に引っかかりやすそう。

地図上にピンを打って表示できるかな…と期待してたんだけど、
検索のAPIは認証不要で使えるからか(?)戻ってくるデータにgeocodeが入ってこないみたい。

APIから戻ってくるデータは
「geo」には一律nullが入っていて、
「location」に、プロフィールの「現在地」がテキストで入っている物と、緯度経度が入っている物が混じってる感じだった。

Twitter用の人工無能BOTを作ってみた。

2010.1.22 金曜日

まぐ(β) (mag_bot)
http://twitter.com/mag_bot

followingの発言を随時読み取って学習し、1時間に1回くらいの頻度で独り言をつぶやきます。
Rubyで書かれており、形態素解析システムはChaSenを使用しています。

自動フォロー/リムーブについて

フォローをすると自動でフォローを返し、それ以降、貴方の発言からも学習するようになります。
※スパムアカウントのフォロー防止の為、以下の条件に当てはまった場合は自動フォローをしないようになっています。

  • 発言数が極端に少ない。
  • 発言内容が半角英数のみ。
  • ツイートが非公開になっている。

煩わしくなったらフォローを外して置くと、こちら側からも自動でフォローを外します。

※フォローのチェックは30分間隔で行ってます。

学習する言葉について

・URLやメールアドレスは覚えません。
・スクリーンネーム(@****)やハッシュタグ(#****)も覚えません。

リプライについて

@mag_botに対してリプライを送信すると、@mag_botからのリプライが返ってきます。
フォロー外の人のリプライにも答えます。
但し、同じ相手に対して連続でリプライを返さないようになっています。
一定時間が経過するor他の人へのリプライが挟まるとまた受け付ける状態に戻ります。

—————

先日、TwitterのBOTの話題を耳にしたときに、
何年か前にMargarine(marg)っていう人工無脳プログラムを使って、IRCのBOTを作ってみたら妙にいい感じだった事を思い出して、じゃあそれを使って俺も作ってみようかな、と。

そう思って、ブックマークしてたサイトを訪ねてみたら…既にサイトがなかった…と。

色々探してたら、SourceForgeが残っているのを発見。

Ruby + ChaSen + MySQLという環境が必要。
ChaSenもmargも文字コードEUCなので、それぞれUTF-8対応な状態にに改変した。

あとは、Ruby Twitter GemをインストールしてTwitter関係の動作を整えた感じ。

テキストボックスに透かし文字を入れるJS

2009.11.27 金曜日

最近多い気がする。
テキストボックスが空の時に初期値で警告文とか入っていて、フォーカスすると消えるアレ。
textbox

ここんとこ出番が多かったのでjQueryのプラグインにしてみた。
未入力のままフォームがsubmitされると初期値が送信されちゃうので、親のformオブジェクトを探してsubmitの際に空にするようにしてみた。

サンプル

サンプル

使い方

<br />
$("#text01").setDefaultValue("値を入力してください");<br
/>
$
("#text02").setDefaultValue("値を入力してください", "gray");<br />

第一引数に初期値になるメッセージ
第二引数にクラス名を入れると、初期値を表示している際に適用される。
グレー文字で出したいとか、背景を赤にしたいとかありそうだったので。

ソース

Download: textbox.js
  1. <br />
  2. (function($) {<br />
  3.     $.extend({<br />
  4.         textarea : new function(){<br />
  5.             var TA = this;<br />
  6.             TA.set = function(o, m, c){<br />
  7.                 if (Object.prototype.toString.call(m) != "[object String]")return false;<br />
  8.                 var parent;<br />
  9.                 var p = o.parents();<br />
  10.                 for(var i=0;i</p>
  11. <p.length;i++){<br />
  12.                     if (typeof p[i].elements != "undefined"){<br />
  13.                         $(p[i]).submit(function(){<br />
  14.                             if (o.val() == m){<br />
  15.                                 o.val('');<br />
  16.                             }<br />
  17.                         });<br />
  18.                         break;<br />
  19.                     }<br />
  20.                 }<br />
  21.                 if (o.val() == "" || o.val() == m){<br />
  22.                     o.val(m);<br />
  23.                     if (c) o.addClass(c);<br />
  24.                 }<br />
  25.                 o.focus(function(){<br />
  26.                     if (o.val() == m){<br />
  27.                         o.val('');<br />
  28.                         if (c) o.removeClass(c);<br />
  29.                     }<br />
  30.                 });<br />
  31.                 o.blur(function(){<br />
  32.                     if (o.val() == ""){<br />
  33.                         o.val(m);<br />
  34.                         if (c) o.addClass(c);<br />
  35.                     }<br />
  36.                 });<br />
  37.             }<br />
  38.         }<br />
  39.     });<br />
  40.     $.fn.extend({<br />
  41.         setDefaultValue: function(m, c){<br />
  42.             $.textarea.set($(this), m, c);<br />
  43.         }<br />
  44.     });<br />
  45. })(jQuery);<br />

jQueryと再起関数でツリーメニュー

2009.11.17 火曜日

任意の数の多段に対応したツリーメニュー。
リクエストに、階層単位での処理(開く際に同階層の他のメニューを閉じる)があったんで再起関数を使ったんだけど、jQueryのセレクタでちょっと戸惑った。

再起で1階層づつ処理したかったんで、上手いことやる方法ないかと探してたんだけど、

parent > child 
(親子関係を指定して要素を選択する。)

これって、parentを省略して

$(">child", elem)

って書き方でいけるのね。メモメモ。

サンプル

サンプル

ソース

HTML

  1. <script language="javascript" type="text/javascript" src="jquery.js"></script>
  2. <script language="javascript" type="text/javascript" src="treeMenu.js"></script>
  3.  
  4. <ul id="sample01" class="sample_ul treeMenu">
  5.   <li><span>Menu1</span>
  6.     <ul>
  7.       <li><a href="#">Menu1.1</a></li>
  8.       <li><a href="#">Menu1.2</a></li>
  9.       <li><a href="#">Menu1.3</a></li>
  10.     </ul>
  11.   </li>
  12. </ul>

 
JS

Download: treeMenu.js
  1. $(document).ready(function(){
  2.     $(".treeMenu ul").hide();
  3.     $(".treeMenu").each(function(){
  4.         TM_init($(this));
  5.     });
  6.     function TM_init(elem, sp, so){
  7.         if (!sp) sp = 400;
  8.         if (!so) so = false;
  9.         $(">li:has(ul)", elem).each(function() {
  10.             var myTree = this;
  11.             $(">:first-child", myTree).click(function(e){
  12.                 var target = this;
  13.                 $(">li:has(ul)", elem).each(function(){
  14.                     if ($(">:first-child", this).get()[0] == target){
  15.                         $(">ul:first", this).slideToggle(sp);
  16.                     }else if (so == true){
  17.                         $(">ul:first", this).slideUp(sp);
  18.                     }
  19.                 });
  20.             });
  21.             TM_init($(">ul:first", myTree), sp, so);
  22.         });
  23.     }
  24. });

とりあえずデフォルト状態で、class=”treeMenu”と入っているエレメントに対して自動で設定されるようになってるけど、
速度と挙動(メニューを開いた際に同階層の他のメニューを閉じるか残すか)が変更出来るようにしてあるので、
3~5行目を編集して

//-- 速度と挙動を任意で指定
$
(".treeMenu").each(function(){
    
TM_init($(this), 300, true);
});

 

//-- IDを指定して個別設定
TM_init($("#sample01"));
TM_init($("#sample02"), 500, true);

といった感じでも。

時間もないのでとにかくシンプルにって感じで書いたんだけど、
メニューを開くトリガーに画像を使いたいって事だったので、開閉に応じた画像のスワップとかのリクエストもありそう。
コールバック関数とか渡せるようにしといたら便利になるかなぁ。

スムーススクロールのソースをメモっておこう。

2009.9.1 火曜日

よくあるヤツだけど、微妙な間隔でリクエストされて、なんか毎回書き起こしてる気がするのでメモ的に。
(ちゃんとソースを管理しておけと)

サンプル

jQueryと、jQuery.easingを使用。

jquery.js
jquery.easing.1.3.js
の2つと下記のスクリプトをロードして、
スクロールにしたいアンカーリンクにclass=”sScroll”の属性を付けておくだけ。

#で始まるリンクを自動で拾う、という形の物が多いけど、
アンカーリンクを全部スクロールにしたくない、とか、
他のスクリプトで使う為にダミーのアンカーリンクを多用してるとか(自分がよくやる)
そんなケースの事を考えて、”sScroll”というクラス名のついた<a>タグだけを対象にした。

IEだと、jQueryのoffset()の値がスクロール位置によって狂うので、IEの時はoffset()の値にスクロール位置を加算して補正。
(offset()って絶対位置を取るんじゃなかったっけ…?)
何故か、divタグに直接borderのスタイルを設定した場合のみ狂う模様?(IEのみ)
レアケースだと思うので上記補正は除去

Operaの場合、”html,body”をanimateすると表示がおかしくなるので、Operaの場合のみ”html”を指定。

jquery.easingでイージングを付けたりした時、ページのスクロール量が足りないと動きがおかしくなるので、
アンカー先のスクロール位置がページのスクロール量を超える場合は調整。

やっつけ感漂う気がするけどこんな感じですかねぇ。

Download: smoothScroll.js
  1. /*
  2. * jQuery SmoothScroll
  3. * Copyright (C) 2009 Hidemaro Mukai(http://www.maro-z.com).
  4. */
  5.  
  6. var span = 1000;
  7. var effect = 'easeOutExpo';
  8.  
  9. $(function() {
  10.     var ua = $.browser;
  11.     $("a.sScroll").click(function() {
  12.         if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
  13.             $(this).blur();
  14.             var t = navigator.appName.match(/Opera/) ? "html" : "html,body";
  15.             $(t).queue([]).stop();
  16.             var $targetElement = $(this.hash);
  17.             var scrollTo = $targetElement.offset().top;
  18.             if (window.scrollMaxY) {
  19.                 var maxScroll = window.scrollMaxY;
  20.             } else {
  21.                 var maxScroll = document.documentElement.scrollHeight - document.documentElement.clientHeight;
  22.             }
  23.             if (scrollTo > maxScroll){
  24.                 scrollTo = maxScroll;
  25.             }
  26.             $(t).animate({ scrollTop: scrollTo }, span, effect);
  27.             return false;
  28.         }
  29.     });
  30. });