以下前回からのコピペ説明
ブックマークレットの意味がよくわからず、
このツールを堪能できていない人も多いようですね。。。
このツールは「いいねどんだけ〜」のリンク部分を右クリックしてブックマークに保存したり、
ブックマークバーにリンクをドラックしてブックマークしたりしておいて、
いいね数を調べたいサイトをブラウザで開いた状態で、
保存しておいたブックマークを押す(開く)とアラートでお知らせするというものです。
ではどうぞ。
もはや解説はいるまい。
Popular Posts:Similar Posts:]]>新春!TOHHHHH!みくじ
http://tohhh.jp/
SHIFTBRAIN Inc.
http://www.shiftbrain.co.jp/
SHIFTBRAIN Backyard
http://shiftbrain.tumblr.com/
devjamメモなので、
技術的な事に少し触れると、
「新春!TOHHHHH!みくじ」はNode.jsのSocket.ioで、スマホのセンサーのデータを飛ばしている。
「SHIFTBRAIN Inc.」はpjax(簡易版)してみた。
「SHIFTBRAIN Backyard」はtumblrをカスタマイズしまくった。
Node.jsのSocket.ioは案件でも使ったので、特に新しい事はしていないけど、
pjaxとtumblrカスタマイズは初めての試みだった。
色々と落とし穴もあって、バッドノウハウが蓄積されたw
モック/プロトタイプを提案時に制作するという話から、
デザイナーってなんだ?という話になりました。
WEBに関わる業界内では、WEBデザイナー、グラフィックデザイナー、
モーションデザイナー、インタラクティブデザイナーと
いろいろな肩書きがありますが、
バックエンドだって、変数名ひとつにしても、
担当する人間は気を配って決めています。
つまりデザインしているんです。
一方で、リッチなインタラクティブコンテンツの完成図を伝えるにあたって
photoshopで作られた静止画ベースではカバーしきれなくなってきていると感じます。
漠然とそんな風に思っていましたが、今日の勉強会に参加された方々も
そういう認識で、やっぱりそういう流れなのかなと改めて考えさせられました。
組織によってはすでにそうなってるかもしれないが、
インタラクティブコンテンツに関しては、表現や仕組みがリッチであればあるほど、
デザインしなければならない要素は、psdだけではなく、もっと多岐に渡り、
今後のデザイナーはそれらを俯瞰的、総合的に把握できる能力が
求められるのかもしれない。お話を伺いながらそんな風に思いました。
とはいえ、そんな人材はそうそういないので、
どこもグラフィック、インタラクティブ、システムと
それぞれ担当が分かれがちだと思いますが、、
その結果、たとえばモーションだけが突出したような、
いびつなアウトプットになってしまいがちな気がします。
個人的には、モック/プロトタイプを作る立場が統括的にデザインするのが、
インタラクティブコンテンツに関しては自然かなと。
そんな風に思った勉強会アフターでした。
主催の糸数さんをはじめ、参加者のみなさんお疲れさまでした。
また情報共有等々してきましょう!
配列から指定した値を取り除く!というものです。
spliceの変形です。
Array.prototype.remove = function() { var i, j, l, m; l = arguments.length; i = 0; while (i < l) { m = this.length; j = 0; while (j < m) { if (arguments[i] === this[j]) { this.splice(j, 1); m--; } else { j++; } } i++; } return this.length; };
これだと、prototypeを書き換えてしまうので、それもどうかと思いつつ、
この機能がもともと実装されてたらいいのになーと思ったり。
使う時はこんな感じで。
Popular Posts:Similar Posts:]]>var ary = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; ary.remove(5); ary.remove(8, 9, 0); console.log(ary); //[1, 2, 3, 4, 6, 7]
いくつかの案件で、カードを敷き詰めたような、
いわゆるMasonry Layoutを実装したのですが、
それが有名なライブラリではうまくいかず、自作してみました。
参考にしたのはこの3つ
jQuery Masonry
http://masonry.desandro.com/
Isotope
http://isotope.metafizzy.co/
jquery.vgrid.js
http://blog.xlune.com/2009/09/jqueryvgrid.html
どれもソートが可能な反面、隙間がところどころに発生してしまい、
そこを詰めたいな、ということになり、そこそこ詰めるように
作り直してみました。
言葉では美味く説明できませんが、
サンプルを見て頂くと分かりやすいと思います。
http://devjam.github.com/jquery.cram.js/
なるべく隙間を埋めてしまう仕様上ソートはできません。
順番が変わっても隙間を無くしたいという方はどうぞ。
「ゲームのアップデートは有ります。もっといい企画を立ってまたブログします。」
:: GAME INFO ::
TITLE : SHIFTBIRD
PROGRAM SUPPORT : kaminary
CHARACTER DESIGN : Mucho
:: HOW TO GAME ::
90秒以内にアイテムを使って鳥を撃って落とすゲームです。
:: 操作 ::
ITEM
ITEM1 = KEY [1] 連発銃
ITEM2 = KEY [2] ショットガン
ITEM3 = KEY [3] 砂時計
MOVE
上 = KEY [W]
下 = KEY [S]
左 = KEY [A]
右 = KEY [D]
ATTACK
SHOT = MOUSE [LEFT BUTTON]
//全体的な流れです。 init() THREE.JS基本設定 Camera setting Render setting //ターゲット表示 CrossHair setting contentLoad() //回りの風景 skybox img load bullet modeling json&teture load setup() controller setup skybox setup //キャラクター生成 chr setup [BoxMan class (MD2CharacterComplex.js) ] chr camera setup addEvent() mouse Event keyboard Event gamestart() game time setup game option setup game item setup //鳥作り ShiftBird.jsからclass import bird make [shifrBird class (ShiftBird.js) ] animation() gameStatus check camera position check controller update //character 移動とアニメーションアップデート chr update //たまと鳥のヒットテスト bullets & birds hit check
SHIFTBIRD
どうも。kaminalyです。
以前、「URLに対するフェイスブックのいいね数を調べるツール。」
をメモったんですが、
それを改良したので、またメモっていますよ。
ブックマークレットの意味がよくわからず、
このツールを堪能できていない人も多いようですね。。。
このツールは「いいねどんだけ〜」のリンク部分を右クリックしてブックマークに保存したり、
ブックマークバーにリンクをドラックしてブックマークしたりしておいて、
いいね数を調べたいサイトをブラウザで開いた状態で、
保存しておいたブックマークを押す(開く)とアラートでお知らせするというものです。
ではどうぞ。
こちらは、@hidekiyさんのプロキシと
海外のシェアカウントサービスのsharedcount.comと
@dankogaiさんのxhrの実装をマッシュアップして作りました。
せっかくjQurey.ajaxからxhrにしたのに、IEでの挙動があやしいので、
ChromeやFirefoxなどで使うのをお勧めします。
アラートにerrorと出ることがありますが、
ページの取得に失敗したときに出るものです。
何度試してもerrorになる場合は・・・あきらめてください(汗
興味ある人は続きの開発メモもご覧下さい。
以前のやつは、いいねのトータルの数値で、
本当はshereとlikeとコメントに分けられるみたいなので、
詳細な情報に分けるというのと、ツイッターとググタスとはてブを追加しようと思って、
作業に取りかかりました。
実装はさらっと終わりました。
こんな感じ。
//bookmarklet javascript:( function(){ var s=document.createElement('script'); s.type='text/javascript'; s.onload=b; s.src='https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js'; document.body.appendChild(s); function b(){ var $=jQuery.noConflict(true),u=encodeURIComponent(location.href); //facebook $.get('https://api.facebook.com/method/fql.query?query=select%20like_count,%20share_count,%20total_count%20from%20link_stat%20where%20url%3D%22'+u+'%22', function(d){ var fl = $(d).find('like_count').text(), fs = $(d).find('share_count').text(), ft = $(d).find('total_count').text(), fc = ft - fl - fs; //twitter $.get('http://cdn.api.twitter.com/1/urls/count.json?url='+u, function(d){ var tt = d.count; //google+ $.get('https://plusone.google.com/u/0/_/+1/fastbutton?count=true&url='+u, function(d){ var gp = $(d).find('#aggregateCount').text(); //はてブ $.get('http://api.b.st-hatena.com/entry.count?url='+u, function(d){ var hb = d == '' ? 0 : d; alert('Facebook\n-Like: ' + fl + '\n-Share: ' + fs + '\n-Comment: ' + fc + '\n-Total: ' + ft + '\nTwitter\n-Tweet: ' + tt + '\nGoogle+\n-+1: ' + gp + '\nHatena\n-bookmark: ' + hb); }); }); }); }); } } )();
で、テストしてみると・・・
エラー。
ほにゃ?
よくよく考えてみたら、クロスドメインじゃね?
なんで、Facebookだけの時は上手く動いたんだろ?
で、調べるとすぐに、
ヘッダ情報のAccess-Control-Allow-Originの存在を知ることになりました。
この情報の値を、許可するホスト名か、*にしてあげると、
XMLHttpRequest Level 2からクロスドメインでajaxできるそうです。
その際、IEでは独自実装のXDomainRequestを使えば
IE8以降で同じくクロスドメインでajaxできるそうです。
なるほど。
ヘッダ情報を追加するためのプロキシはphpなりなんなりですぐに用意できます。
例えば、
<?php //cross domain ajax proxy header("Access-Control-Allow-Origin: *"); //今回はPOST, OPTIONSは必要ないけどテンプレート的に付けている。OPTIONSはfirefox対策 header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); //IE8 fix header("Access-Control-Allow-Headers: *"); //適宜 header("Content-Type: text/plain; charset=UTF-8"); //どこかしらのurlからデータをゲットしてそのまま出力 if($_GET["url"]){ $url = rawurlencode($_GET["url"]); $facebook = file_get_contents("https://api.facebook.com/method/fql.query?query=select%20like_count,%20share_count,%20total_count%20from%20link_stat%20where%20url%3D%22".$url."%22"); $twitter = file_get_contents("http://cdn.api.twitter.com/1/urls/count.json?url=".$url); $google = file_get_contents("https://plusone.google.com/u/0/_/+1/fastbutton?count=true&url=".$url); $hatena = file_get_contents("http://api.b.st-hatena.com/entry.count?url=".$url); } print <<<__HD__ <data> {$facebook} <twitter>{$twitter}</twitter> {$google} <hatena>{$hatena}</hatena> </data> __HD__;
上記のプロキシを使うなら、こんなjsを用意すれば動く。
「プロキシのURL」は設置した場所に書き換える。
IE対策のためにjQuery.ajaxからxhrに実装をかえてあります。
//bookmarklet javascript:( function(){ var s=document.createElement('script'); s.type='text/javascript'; s.onload=b; s.src='https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js'; document.body.appendChild(s); function b(){ var $=jQuery.noConflict(true), u='プロキシのURL.php?url='+encodeURIComponent(location.href), c=function(d){ var jq = $(d), fl = jq.find('like_count').text(), fs = jq.find('share_count').text(), ft = jq.find('total_count').text(), fc = ft - fl - fs, tt = eval('(' + jq.find('twitter').text() + '.count)'), gp = jq.find('#aggregateCount').text(), hb = jq.find('hatena').text(); hb = hb == '' ? 0 : hb; alert('Facebook\n Like: ' + fl + '\n Share: ' + fs + '\n Comment: ' + fc + '\n Total: ' + ft + '\n\nTwitter\n Tweet: ' + tt + '\n\nGoogle+\n +1: ' + gp + '\n\nHatena\n bookmark: ' + hb); }, x; if (window.XDomainRequest){ u.replace('https', 'http'); x = new XDomainRequest(); x.onload = function(){ c(x.responseText); }; x.open('GET', u); }else{ x = new XMLHttpRequest(); x.onreadystatechange = function(){ if (x.readyState === 4) c(x.responseText); }; x.open('GET', u, true); } x.send(); } } )();
とここまで進んだところで、
設置するSSLないな。。。(本当はあるんだけど、サーバ共有でなんかハズい)
httpsに置いておかないと、https付きのサイトで使えない。
むむむ。
ボロボロの精神状態でウェブを彷徨っていると、
allow-any-origin.appspot.comにたどり着いた。
これは!上記のヘッダ情報を付けてくれるプロキシ!しかもSSLに対応!
神、神が現れたのか?
書き換えたのがこちら。
IEのXDomainRequestがhttpsだと上手く動かない。
しらべると、httpでないとダメっぽい。
httpのサイトだったらhttp、httpsのサイトだったらhttpsに合わせるというような
記事も見かけてやってみたけどダメだった。
この時点で、IEではIE8以降でなおかつhttpのサイトでしか動きません。になる。
//bookmarklet javascript:( function(){ var s=document.createElement('script'); s.type='text/javascript'; s.onload=b; s.src='https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js'; document.body.appendChild(s); function b(){ var $=jQuery.noConflict(true), u=encodeURIComponent(location.href), p='http'+(window.XDomainRequest && u.substr(0,5) != 'https' ? '' : 's' )+'://allow-any-origin.appspot.com/'; //facebook xhr(p+'https://api.facebook.com/method/fql.query?query=select%20like_count,%20share_count,%20total_count%20from%20link_stat%20where%20url%3D%22'+u+'%22', function(d){ var jq = $(d); fl = jq.find('like_count').text(), fs = jq.find('share_count').text(), ft = jq.find('total_count').text(), fc = ft - fl - fs; //twitter xhr(p+'http://cdn.api.twitter.com/1/urls/count.json?url='+u, function(d){ var tt = eval('(' + d + '.count)'); //google+ xhr(p+'https://plusone.google.com/u/0/_/+1/fastbutton?count=true&url='+u, function(d){ var gp = $(d).find('#aggregateCount').text(); //はてブ xhr(p+'http://api.b.st-hatena.com/entry.count?url='+u, function(d){ var hb = d == '' ? 0 : d; alert('Facebook\n Like: ' + fl + '\n Share: ' + fs + '\n Comment: ' + fc + '\n Total: ' + ft + '\n\nTwitter\n Tweet: ' + tt + '\n\nGoogle+\n +1: ' + gp + '\n\nHatena\n bookmark: ' + hb); }); }); }); }); function xhr(u,c){ var x; if (window.XDomainRequest){ x = new XDomainRequest(); x.onload = function(){ c(x.responseText); }; x.open('GET', u); }else{ x = new XMLHttpRequest(); x.onreadystatechange = function(){ if (x.readyState === 4) c(x.responseText); }; x.open('GET', u, true); } x.send(); } } } )();
Ver1はIE全く動かなかった(チェックすらしてなかった汗)から、
今回はIEも対応しようと思っていたのに残念な空気がながれだす。
1回調べるのにプロキシに4回もリクエストするのもなんか申し訳なくなってきた。
で、いいねの情報を分割できる事を知ったサービスでもある、
sharedcount.comからデータをパクってとマッシュアップしよう。
そうしよう。
最終的なソースはこちら。
sharedcount.comからのデータを整形したのと、
はてブがなかったので足したのと、
ロードが長くなってしまったので、「Now Loading...」の表示を足した。
あと、403エラーが出る事があったので、errorアラートを出すようにした。
//bookmarklet javascript:( function(){ var s=document.createElement('script'); s.type='text/javascript'; s.onload=b; s.src='https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js'; document.body.appendChild(s); function b(){ var $=jQuery.noConflict(true), u=encodeURIComponent(location.href), p='http'+(window.XDomainRequest && u.substr(0,5) != 'https' ? '' : 's' )+'://allow-any-origin.appspot.com/', l=$(' Now Loading... ').css({position:'absolute',zIndex:10000,textAlign:'center',fontSize:'20px',backgroundColor:'#990',color:'#fff',margin:'0',padding:'30px 0',width:'100%',top:$('body').scrollTop()+'px'}).prependTo('body'); //sharedcount.com xhr(p+'http://sharedcount.com/?url='+u, function(d){ var s = $(d).find('#stats').html().replace(/\n/g,'').replace(/<!--([^>]|[^-][^-]>)*-->/g,'').replace(/<\/?h3>/g,'\n').replace(/<br[^>]*>/g,'\n'); //はてブ xhr(p+'http://api.b.st-hatena.com/entry.count?url='+u, function(d){ var h = d == '' ? 0 : d; l.remove(); alert(s + '\nHatena\nbookmarks: ' + h); }); }); function xhr(u,c){ var x; if (window.XDomainRequest){ x = new XDomainRequest(); x.onload = function(){ c(x.responseText); }; x.onerror = function(){ l.remove(); alert('error'); }; x.open('GET', u); }else{ x = new XMLHttpRequest(); x.onreadystatechange = function(){ if (x.readyState === 4){ if(x.status == 200){ c(x.responseText); }else{ l.remove(); alert('error'); } } }; x.open('GET', u, true); } x.send(); } } } )();
かなり遠回りをして、
最終的に完全に他力本願ツールになってしまった。
IE8以降でhttpは対応のはずだったんだけど、IE8でなぜか動かなかった。
もしかしたら、IE8fixのヘッダが入ってないのかも。
まぁ、IEは非対応と言い切ってしまったほうが安全なのである。
現在FPS_base.html と FPS_Control.htmlがあります。
FPS_baseは名前とおりThree.jsのrendering構成Baseで
FPS_Controlはmouseやkeyboardに反応できるeventを追加してcameraを一人称視点で変えてみました。
FPS_base
FPS_Control
sourceはこんな感じです。FPS_BASEの構成の基本にして書きました。
(function() { var sw,sh, scene, camera,fov,aspect,near,far, renderer, light, stats; var chScene, chCamera; function init() { /* WINDOW SIZE */ sw = WindowSize.width(); sh = WindowSize.height(); /* SCENE SETTING*/ scene = new THREE.Scene(); /* RENDERER SETTING */ renderer = new THREE.WebGLRenderer({antialias : true}); renderer.setSize(sw,sh); document.body.appendChild(renderer.domElement); /* CAMERA SETTING */ fov = 45; aspect = sw/sh; near = 0.1; far = 10000; camera = new THREE.PerspectiveCamera(fov,aspect,near,far); camera.position.set(0,500,1000); scene.add(camera); /* LIGHT SETTING */ light = new THREE.DirectionalLight( 0xffffff, 1.5 ); light.position.set( 200, 450, 500 ); light.shadowMapWidth = 1024; light.shadowMapHeight = 1024; light.shadowMapDarkness = 0.95; scene.add(light); /* STATS */ stats = new Stats(); stats.domElement.style.position = 'absolute'; stats.domElement.style.top = '0px'; stats.domElement.style.zIndex = 100; document.body.appendChild( stats.domElement ); /* CROSSHAIR SECEN */ renderer.autoClear = false; chScene = new THREE.Scene(); chCamera = new THREE.PerspectiveCamera(fov,aspect,near,far); chCamera.position.set(0,0,0); chScene.add(chCamera); /* SETUP & RENDERING LOOP */ setup(); addEvent(); requestAnimationFrame(rendering); } // ------------------------------------------------------------------ // RENDERING // ------------------------------------------------------------------ function rendering() { delta = clock.getDelta(); animation(); renderer.setDepthTest(true); renderer.clear(); renderer.render(scene, camera); renderer.setDepthTest(false); renderer.render(chScene, chCamera); stats.update(); requestAnimationFrame(rendering); } var lookTarget = new THREE.Vector3(0,0,0); function animation() { camera.position = chr.camera.position; camera.rotation = chr.camera.rotation; //camera.lookAt(lookTarget); controler.update(delta); chr.update(); } // ------------------------------------------------------------------ // SETUP & ADD EVENT // ------------------------------------------------------------------ var clock,delta, ground,chr,tower, controler, crossHair; function setup() { clock = new THREE.Clock(); // object ground = new Ground("asset/img/grasslight-big.jpg") chr = new Cube(new THREE.Vector3(0,50,200),100,100,100,0xff0000); tower = new Cube(new THREE.Vector3(0,500,0),100,1000,100,0x0000ff); chr.cameraOn(); // controler controler = new FPC_Controler(chr.camera, renderer.domElement); controler.movementSpeed = 400; controler.lookSpeed = .2; controler.lookVertical = true; controler.constrainVertical = true; controler.verticalMin = (30 * Math.PI) / 180; controler.verticalMax = (100 * Math.PI) / 180; // CrossHair crossHair = new CrossHair(); scene.add(ground.root); scene.add(chr.root); scene.add(tower.root); } function addEvent() { document.addEventListener("keydown", onKeyDown, false); renderer.domElement.addEventListener("mousedown", onMouseDown, false); } // ------------------------------------------------------------------ // EVENT HANDLER // ------------------------------------------------------------------ function onKeyDown(e){ switch(e.keyCode){ case 32: /*space*/ break; case 49: /*1*/ crossHair.change(0); break; case 50: /*2*/ crossHair.change(1); break; case 51: /*3*/ break; case 52: /*4*/ break; case 53: /*5*/ break; }; } function onMouseDown(e){ switch ( e.button ) { case 0: console.log("attack"); break; } } // ------------------------------------------------------------------ // OBJECT CLASS // ------------------------------------------------------------------ //GROUND CLASS function Ground(imgURL) { this.root = new THREE.Object3D(); this.gt = THREE.ImageUtils.loadTexture( imgURL ); this.gg = new THREE.PlaneGeometry( 3000, 3000 ); this.gm = new THREE.MeshPhongMaterial( { color: 0xffffff, map: this.gt, perPixel: true } ); this.mesh = new THREE.Mesh( this.gg, this.gm ); this.mesh.material.map.wrapS = this.mesh.material.map.wrapT = THREE.RepeatWrapping; this.mesh.rotationAutoUpdate = true; this.mesh.castShadow = false; this.mesh.material.map.repeat.set( 100, 100 ); this.root.add(this.mesh); } Ground.prototype.constructor = Ground; //CUBE CLASS function Cube(position,width,height,depth,color,imgURL) { this.geo = new THREE.CubeGeometry(width,height,depth); this.mat = new THREE.MeshLambertMaterial({color:color});//new THREE.MeshBasicMaterial();// this.mesh = new THREE.Mesh(this.geo, this.mat); this.mesh.position.set(0,0,0); this.root = new THREE.Object3D(); this.root.add(this.mesh); this.root.position.set(position.x, position.y, position.z); } Cube.prototype.update = function(){ if(this.camera){ if(this.camera.position.y < 50 || this.camera.position.y > 50) this.camera.position.y = 50; this.root.position = this.camera.position; this.root.rotation = this.camera.rotation; } } Cube.prototype.cameraOn = function(){ if(!this.camera){ this.camera = new THREE.PerspectiveCamera(45,sw/sh,.1,10000); this.camera.position = this.root.position; this.root.add(this.camera); console.log(this.camera) } } Cube.prototype.cameraOff = function(){ if(this.camera){ this.root.remove(this.camera); this.camera = null; } } Cube.prototype.constructor = Cube; //CROSSHAIR CLASS function CrossHair() { this.CrossHairID = 0; this.CrossHairMaps = ["asset/img/crosshair1.png","asset/img/crosshair2.png"]; this.CrossHairMap = THREE.ImageUtils.loadTexture( this.CrossHairMaps[this.CrossHairID]); this.CrossHair = new THREE.Sprite({ useScreenCoordinates: false}); this.CrossHair.alignment = THREE.SpriteAlignment.center; this.CrossHair.useScreenCoordinates = false; this.CrossHair.position.z = -1000; // console.log(chScene); this.CrossHair.map = this.CrossHairMap; chScene.add(this.CrossHair); } CrossHair.prototype.change = function(id){ if(this.CrossHairID == id || this.CrossHairID > this.CrossHairMaps.length - 1) return; this.CrossHairID = id; this.CrossHairMap = THREE.ImageUtils.loadTexture( this.CrossHairMaps[this.CrossHairID]); this.CrossHair.map = this.CrossHairMap; } CrossHair.prototype.constructor = CrossHair; window.addEventListener("load",init) }).call(this);
ここで問題点がいくつかありましたけどその中で
下のsourceを見ると FPC_Controler(...)のClassは元々Three.jsのFirstPersonControlsというclassでした。
FirstPersonControlsClassはkeyboardやmouseのeventが定義されて上書きができなかったところで別のClassにして修正をしました。
controler = new FPC_Controler(chr.camera, renderer.domElement);
次の公開は来週になる予定です。
次は鳥が飛んでいて鳥を落とすまでと思います。
よろしくお願いします。
Popular Posts:Similar Posts:]]>先日Unibaさんと合同でWebGL(Three.js)/GLSLな勉強会をしました。
会社以外で前にでて話すってのは、なかなか機会がないので良い刺激になった。
あと、勉強会に参加してくれた方々の反応が良かったので、
ほっこりした感じで終わる事が出来た。
バンドマンだった時の寒いMCを思い出す。
もし、みんなが無反応だったら、やけ酒だったろうね。酒飲めないけど。
と、話がそれましたが、
その勉強会の時、Unibaの今野さん(@nulltask)が
Three.jsのDomRendererというニッチなネタでせめていて、
その時ふと、Three.jsを使ってサイトをぶっ壊すネタを思いつきました。
くだらないです。ええ、くだらないし、役にも立たないです。
↓をブックマークして使うとブックマークレットとして使えます。
explosion
ただ押すと、このサイトが吹っ飛びます。
まだ実装途中ですが、爆発音を付けたいと思ってます。
爆発音鳴るようにしました。
ソースはgithubに置いてあります。てけとーに遊んでみてください。
https://github.com/kaminaly/explosion.js
Processing.jsを試してみたんですが、IE8でエラーが出て動かなかったため、
簡易Processing風なテンプレートを自作することにした次第です。
そんな背景があるので、記述の仕方はProcessingになるべくあわせています。
基本となるCanvasクラスを拡張して書くことを前提にしています。
coffee scriptだとこんな感じ
class Canvas1 extends Canvas #--------------------------------------------------- setup: -> @fillColor = "#202020" @strokeColor = 'rgba(0, 0, 0, 0.1)' @backgroundColor = 'rgb(240, 240, 240)' @pi = Math.PI * 2 @pointMin = 5 @pointMax = 60 @Num = 0 @play() update: -> pointNum = (@mouseX / @width * @pointMax + @pointMin) @Num += (pointNum - @Num) * 0.1 draw: -> @background() points = @getPoints() l = points.length i = 0 while i < l j = i + 1 while j < l @line points[i][0], points[i][1], points[j][0], points[j][1] j++ i++
吐き出されたJSはこんな感じ
(function() { var Canvas1, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; Canvas1 = (function(_super) { __extends(Canvas1, _super); function Canvas1() { return Canvas1.__super__.constructor.apply(this, arguments); } Canvas1.prototype.setup = function() { this.fillColor = "#202020"; this.strokeColor = 'rgba(0, 0, 0, 0.1)'; this.backgroundColor = 'rgb(240, 240, 240)'; this.pi = Math.PI * 2; this.pointMin = 5; this.pointMax = 60; this.Num = 0; return this.play(); }; Canvas1.prototype.update = function() { var pointNum; pointNum = this.mouseX / this.width * this.pointMax + this.pointMin; return this.Num += (pointNum - this.Num) * 0.1; }; Canvas1.prototype.draw = function() { var i, j, l, points, _results; this.background(); points = this.getPoints(); l = points.length; i = 0; _results = []; while (i < l) { j = i + 1; while (j < l) { this.line(points[i][0], points[i][1], points[j][0], points[j][1]); j++; } _results.push(i++); } return _results; }; this.Canvas1 = Canvas1; }).call(this);
ソースをGithubにアップしてみました。まだ慣れてないのでgitドキドキ
https://github.com/devjam/canvas.js