HEXA BLOG
ヘキサブログ
プログラム
たまには失敗のjavaScript
お久しぶりです。
前回のブログ1月以上の間が空きまして、
この間色々な事がありました。
間もなく引越し予定のgood sunこと山口です。
今回もJavaScriptネタをやろうとしたのですが、
最初にお断りさせて頂きますが、一部失敗しました。
そんな時もあります。
まずは何がしたかったのか説明させて頂きます。
以前JavaScriptでマルチタッチが取れるというお話を書かせて頂きました。
今回はいつもより少し時間があったので
このタッチについてサンプルを作ってみようとしました。
そこまでは良かったのです。
問題は音を鳴らしてみようと思った所です。
GoogleChromeでは
var audio = new Audio(音データ); audio.play();
で音が鳴ります。
ここまでは確認しました。
まだ問題ありません。
これをAndroidで確認すると…
鳴りません。
おかしいと思い検索エンジンで調査を開始しました。
なんと現行のAndroidやiOS端末のブラウザはJavaScript単体で音を鳴らすことが出来ないようです。
完全に調査不足でした。
しかし失敗はこれだけに留まりません。
どのように失敗なのかは今回のサンプルを実行していただくのが早いと思います。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name=”viewport” content=”width=480, user-scalable=no, maximum-scale=0.6667″ /> <title>javascriptサンプル</title> </head> <body> <dir style="vertical-align: middle; margin-left:auto; margin-right:auto;"> <canvas id="canvas"></canvas> </dir> </body> <script type="text/javascript" charset="UTF-8"> //! ノード管理クラス function NodeManager(){ this.nodes = new Array(); } NodeManager.prototype.create = function(x, y){ this.nodes.push(new Node(x, y)); } NodeManager.prototype.update = function(){ for(var i = this.nodes.length - 1; i >= 0; i--){ if(!this.nodes[i].update()){ if(i == 0){ if(this.nodes.length > 1){ this.nodes = this.nodes.slice(1, this.nodes.length); }else{ this.nodes = new Array(); } }else{ if(i + 1 == this.nodes.length){ this.nodes = this.nodes.slice(0, i); }else{ var tmparray = this.nodes.slice(0, i); this.nodes = tmparray.concat(this.nodes.slice(i + 1, this.nodes.length)); } } } } } NodeManager.prototype.draw = function(context2d){ for(var i = 0; i < this.nodes.length; i++){ this.nodes[i].draw(context2d); } } var nodeManager = new NodeManager(); //! ノードクラス function Node(x, y){ // パラメータはランダムで決定 this.posx = x; this.posy = y; this.color = "#"+((Math.floor(Math.random()*255) << 16) | (Math.floor(Math.random()*255) << 8) | Math.floor(Math.random()*255)).toString(16); this.isFill = Math.random() > 0.5 ? true : false; this.width = Math.floor(Math.random()*10) + 3; this.rad = 5; this.life = Math.floor(Math.random()*10) + 30; } //! 更新関数 Node.prototype.update = function(){ this.rad += 10; this.life--; if(this.life <= 0){ return false; } return true; } //! 描画関数 Node.prototype.draw = function(context2d){ context2d.beginPath(); context2d.arc(this.posx, this.posy, this.rad, 0, 360, false); if(this.isFill == true){ context2d.fillStyle = this.color; context2d.fill(); }else{ context2d.strokeStyle = this.color; context2d.lineWidth = this.width; context2d.stroke(); } context2d.closePath(); } //! フレーム管理クラス function Frame(){ var _this = this; // クリアカラーとキャンバスサイズ this.clearColor = "#202030"; // コンテキストの準備 this.canvas = window.document.getElementById("canvas"); this.context2d = this.canvas.getContext('2d'); this.canvas.width = document.body.scrollWidth; this.canvas.height = document.body.scrollHeight; // クリアカラーでクリアする this.context2d.fillStyle = this.clearColor; this.context2d.fillRect(0, 0, this.canvas.width, this.canvas.height); // タッチイベントの追加 document.getElementsByTagName("body").item(0).ontouchstart = function(event){ _this.onTouchStart(event); }; document.getElementsByTagName("body").item(0).ontouchmove = function(event) { _this.onTouchMove(event); }; document.getElementsByTagName("body").item(0).ontouchend = function(event) { _this.onTouchEnd(event); }; // もしくはクリック this.canvas.onclick = function(event){ _this.onMouseClick(event); } } Frame.prototype.onMouseClick = function(event){ nodeManager.create(event.clientX, event.clientY); } Frame.prototype.onTouchStart = function(event){ event.preventDefault(); event.touches.length; for(var i = event.touches.length - 1; i >= 0; i--){ nodeManager.create(event.touches[i].pageX, event.touches[i].pageY); } } Frame.prototype.onTouchMove = function(event){ event.preventDefault(); } Frame.prototype.onTouchEnd = function(event){ event.preventDefault(); } //! 実行 Frame.prototype.run = function(lastTime){ // クリア this.context2d.fillStyle = this.clearColor; this.context2d.fillRect(0, 0, this.canvas.width, this.canvas.width); nodeManager.update(); nodeManager.draw(this.context2d); //! 更新を行う var nowTime = new Date(); // 20FPS var nextTime = 50 - (nowTime.getTime() - lastTime.getTime()); if(nextTime <= 0){ nextTime = 1; } var _this = this; setTimeout(function(){_this.run(nowTime);}, nextTime); } var frame = new Frame(); frame.run(new Date()); </script> </html>
動くのはこちらから
(動作確認が出来ているのは、Android+OperaMobile、iOS+Safariです。
残念ながらAndroid+標準ブラウザではマルチタッチ認識しないようです。
iOS+OperaMiniはそもそもタッチ認識しませんでした。)
…画面サイズがおかしいです。
フルスクリーンをやりたいなと思ってみたのですが御覧の結果です。
何事も慌ててやってはいけないという事ですね。
反省です。
次回までの課題ですね。
今回の目玉マルチタッチの取得に関しては
document.getElementsByTagName("body").item(0).ontouchstart = function(event){ _this.onTouchStart(event); };
この辺が該当の箇所になります。
ちゃんとクロージャな呼び出しも健在です。
次は今回カットした音に関連してデータに関して何かやれたらなと思っています。
ではまた。
CATEGORY
- about ヘキサ (166)
- 部活動 (6)
- CG (18)
- プロジェクトマネジメント (1)
- 研修 (5)
- 美学 (1)
- いいモノづくり道 (230)
- 採用 -お役立ち情報も- (149)
- プログラム (188)
- デザイン (99)
- ゲーム (274)
- 日記 (1,104)
- 書籍紹介 (113)
- その他 (875)
- 就活アドバイス (20)
- ラーメン (3)
- ライフハック (25)
- イベント紹介 (10)
- 料理 (23)
- TIPS (7)
- 怖い話 (3)
- サウンド (5)
- 子育て (1)
- 筋トレ (1)
- 商品紹介 (21)
- アプリ紹介 (31)
- ソフトウェア紹介 (33)
- ガジェット紹介 (12)
- サイト紹介 (10)
- 研究・開発 (34)
- 回路図 (4)
- アナログゲーム (40)
- 交流会 (21)
- 報告会 (3)
- インフラ (25)
- グリとブラン (6)
- カメラ (9)
- クラフト (27)
- 部活 (14)
- 画伯 (15)
- カレー (6)
- 音楽(洋楽) (6)
- 映画・舞台鑑賞 (43)
- 飼育 (5)
- いぬ (8)
- ねこ (19)
ARCHIVE
- 2024年
- 2023年
- 2022年
- 2021年
- 2020年
- 2019年
- 2018年
- 2017年
- 2016年
- 2015年
- 2014年
- 2013年
- 2012年
- 2011年
- 2010年
- 2009年
- 2008年
- 2007年