Canvasで座標がうまくとれないときの対処法

Canvasで (相対的な) 座標を取得するときのセオリーは, 以下のようにする

var canvas  = document.querySelector('canvas');
var context = canvas.getContext('2d');

canvas.addEventListener('mousemove', function(event) {
    var x = event.pageX - canvas.offsetLeft;
    var y = event.pageY - canvas.offsetTop;
}, true);

ところが, 複雑なレイアウト (floatしているとか) をしているWebページの場合なんかだとcanvasのoffsetLeftとoffsetTopがおかしな値になって, 座標が意図どおりに取得できないことがある.

その場合の対処法としては, iframeを利用した方があります.

iframeに読み込むページはCanvas要素が配置されるHTMLとなります.

canvas.html

<!DOCTYPE html> 
<html>
<head>
<title>Canvas</title>
<style>
 html, body {overflow:hidden;}
</style>
<script>
(function() {
    document.addEventListener('DOMContentLoaded', function() {
        var canvas  = document.querySelector('canvas');
        var context = canvas.getContext('2d');

        //iframeのサイズいっぱいにCanvasを広げる
        canvas.setAttribute('width',  window.innerWidth);
        canvas.setAttribute('height', window.innerHeight);
}, true);
})();
</script>
</head>

<body>
    <canvas></canvas>
</body>
</html>

html, body {overflow:hidden;} のスタイル指定は, iframeを読み込んだ側でスクロールバーを表示させないためのスタイル設定です.

あとは, 読み込む側のページです.

<!-- .... ->

<iframe src="canvas.html" width="600" height="600"></iframe>

<!-- .... ->

以上です.

別ドメインにどうしても配置しなくてはならず, かつ, iframeのページ間 (読み込む側と読み込まれる側) でスクリプトのやりとりをする場合, クロスオリジン制限の問題が発生しますが, window.postMessageメソッドとwindow.onmessageイベントハンドラを駆使すれば, その制限を解決することが可能です.

Web Audio API 次期仕様

http://webaudio.github.io/web-audio-api/

これをみると, AnalyserNodeにgetFloatTimeDomainDataメソッドが追加されているようです. 時間ドメインでもdB単位で波形描画可能になるみたい…と思ったら既にChromeには実装されていて驚きです.

現状の仕様からの変更で言えば, AudioListenerのsetVelocityメソッドはなくなるようです. また, PannerNodeのpanningModelプロパティに設定可能な音響アルゴリズムが ‘HRTF’ と ‘equalpower’ のみになるようです (つまり, ‘soundfield’ が削除されるようです).

新しく追加されるノードとしては,  AudioWorkerノードがあります. これは, まだどのブラウザにも実装されていないようなので, 実際にどういうものなのかはわかりませんが, オーディオ処理に特化したWebWorkersのようなものなのでしょうか ?

とにかく, これらの変更がブラウザに実装されるのが楽しみです.

GitHub Pull Request の基本

昨日に引き続き, 今日もHTML5 ROCKSのリポジトリにPull Requestしました.

(備忘録的な意味もこめて, ) Pull Requestを送る手順をメモしておきます.

1. Pull Requestを送るリポジトリをFork

これは, gitの機能ではなく, GitHubの機能です. リポジトリをForkすることで, 自分の思うように変更が可能になります. Forkするには, 対象のリポジトリのGitHubのページの右上にある「Fork」ボタンを押すだけです.

 

GitHub Fork
GitHub Fork ボタン

2. Forkしたリポジトリをclone

Forkしたリポジトリをローカルの開発環境であつかうために, cloneしてきます. 注意していただきたいのは, Forkしたリポジトリをcloneしてください

$ git clone [Forkしたリポジトリ]

3. 開発用のブランチを作成

masterブランチはいわゆるトピックブランチ (最新の状態で, 常に正常に動作する. 戻りたいときの目印的な役割) としておいたほうがいいので, 新たにブランチを作成します. ブランチ名は適当に決めてください. とりあえず, ここではmy-workとします.

$ git branch
* master
$ git branch  my-work
$ git branch
* master
   my-work
$ git checkout my-work
   master
* my-work

また, checkoutに-bオプションをつければ, ブランチの作成とチェックアウトを同時にできます.

$ git checkout -b my-work

4. git add / git commit

上記の手順までできていれば, あとはふつうにgitでバージョン管理するようにリポジトリを更新していくだけです. Forkしたリポジトリなのでどんな変更をしようが問題ないですし, トピックブランチ (masterブランチ) があるので, いつでも開始状態に戻ることが可能です.

5. リモートブランチの作成

リポジトリの更新をGitHubのForkしたリポジトリに反映するには, GitHub側にもブランチを作成する必要があります.

$ git push origin my-work
$ git branch -r
 remotes/origin/HEAD -> origin/master
 remotes/origin/my-work
GitHub branch
GitHub branch

ブランチをGitHubにも作成すると, リポジトリのページでbranchの切り替えができるはずです.
そこで, リポジトリを更新したbranchであるmy-workに切り替えると, 更新した内容が反映されているはずです.

6. Pull Request

いよいよ最後の手順です. ここまでの作業は言わば自分だけに影響することだったので, そんなに神経質になる必要もなかったのですが, Pull Requestは更新したリポジトリをFork元のリポジトリの制作者に依頼するわけなので, 少し慎重になりましょう.

Pull Request
Pull Request

Pull Requestをするには, Forkした自分のリポジトリの「Pull Request」ボタンを押します.
すると, Pull Requestを送るためのページに切り替わります.

Create Pull Request
Create Pull Request

テキスト入力の箇所は, Pull Requestをした理由を記載します.

「Commits / File Changed」タブで, Pull Requestに含まれるコミットやファイルの差分を確認できます.

以上を確認して問題がなければ, 「Create pull request」ボタンを押します. これで, Fork元のリポジトリの制作者に通知されます.

あとは,  Fork元のリポジトリの制作者が確認をして問題がなければmergeしてくれて, 自分にもその通知が届きます.

* リポジトリのアップデート

Fork + clone してきたリポジトリのmasterブランチはトピックブランチにしておくとメモしましたが, そのままの状態で最新の状態に保たれるわけではないので, 定期的にアップデートして最新の状態にすることが必要です.

1. アップデート用のリモートリポジトリを作成

アップデート用のリポジトリ名をupstreamとします.

$ git remote add upstream [Fork元のリポジトリ]

ここでのポイントは, Fork元のリポジトリを指定することです. そうでないと, 最新のリポジトリの状態を参照することにならないからです,

2. 更新

更新するために, トピックブランチであるmasterブランチにチェックアウトします.

$ git checkout master

そして, 最新のリポジトリのデータを取得します.

$ git fetch upstream
   remote: Counting objects: 14, done.
   remote: Compressing objects: 100% (12/12), done.
   remote: Total 14 (delta 7), reused 6 (delta 2)
   Unpacking objects: 100% (14/14), done.
   From https://github.com/html5rocks/www.html5rocks.com
   13498ed..2cfc907  master     -> upstream/master
    //... etc

最後に, 取得した最新のリポジトリのデータをトピックブランチ (masterブランチ) にマージします.

$ git merge upstream/master
   Updating 0dd88ed..2cfc907
   Fast-forward
   CALENDAR.md                                        |  2 +-
   content/tutorials/webaudio/intro/en/index.html     |  2 +- 
   content/tutorials/webaudio/intro/ja/index.html     | 35 ++++++++-----
   .../webaudio/intro/static/js/filter-sample.js      |  3 +-
   .../webaudio/positional_audio/ja/index.html        | 58 ++++++++++++----------
    5 files changed, 59 insertions(+), 41 deletions(-)
    // ...etc

ちなみに, 既に最新の状態である場合には, 「Already up-to-date」と表示されます.

$ git merge upstream/master
   Already up-to-date.

以上が, Pull Requestを送る基本となります. 最初は手順が多そうに感じますが, やってみると案外そうでもないです.
Pull Requestは敷居が高そうで実はそうでもなく, でも素晴らしい機能なのでどんどん利用しましょう.

オープンソースとPull Request

HTML5 ROCKSの位置オーディオと WebGL の統合のデモがThree.jsとWeb Audio APIのAPI変更により動作しなくなっていたのを自分で改修していたのですが, 元々の制作者により対応されました.

それにともない, 記事のサンプルコードも修正されたのですが, 日本語版の記事のサンプルコードが古いままだったので,

  1. リポジトリをFork
  2. Forkしたリポジトリをローカル環境にclone
  3. 作業用のブランチを作成 (masterはトピックブランチにしておくため)
  4. 修正したものをcommit / push
  5. Pull Request

何気にGitHubのPull Request機能を使うのは初めてでしたが, こんな些細なことでもオープンソースに貢献できるんだなと思いました.

今まで, オープンソースに貢献するというとすごく敷居が高いイメージがあったのですが, 最初はこういった些細な修正から始めることでいいんだなと思いました. そして, GitHubのPull Request機能がそれを可能にしてくれます.

これを機に, ソーシャルコーディングにもどんどんチャレンジしてオープンソースに貢献していきたいです.

Three.js のデモ

Thress.jsの基本となる物体 (形状と表面材質で構成) とライトで構成されるscene, そして, カメラをレンダリングする基本処理と, 各オブジェクトのパラメータ (ポジションや回転など) を設定しながら, どのように3Dレンダリングされるのかを確認できるデモを作成してみました.

http://curtaincall.weblike.jp/prog/javascript/webgl/cube

Three.jsの基本を体感的に理解するために少しでもお役に立てればと思います.

 

Three.jsを使ってみた

WebGLを始めた頃, ライブラリに頼らずに…と思いましたが, やはり3Dの壁は大きく, JavaScriptのAPIに追加して, 行列などの数学の知識やシェーダー (ES : OpenGL Shading Language) の習得といったことが必要ということが取り組んでいくうちにわかってしまい….

さすがにこれはちょっときつい…ということで, まずはいったんライブラリは利用しないという方向性はとりあえずあきらめました.

そして,WebGLのデファクトスタンダードなライブラリであるThree.jsを利用することから改めて始めようと思いました.

Thress.jsの基本となる処理は, 物体 (Mesh) とライトで構成されるscene,オブジェクト そして, カメラとなるオブジェクトをレンダラーのrenderメソッドに指定するというすごくシンプルなことです.

さらに, 物体 (Mesh) とは

  • 形状
  • 表面材質 (色やテクスチャ)

を表す2つのオブジェクトで構成されます.

また, 物体 (Mesh) やライト, カメラは位置や回転などを指定することが可能です.

GitHub Pages (gh-pages) のブランチをローカルにcloneする

GitHubのSettingsからページを作成して, 既にgh-pagesのブランチが存在する場合…

$ git remote -v
origin	https://github.com/****/****.git (fetch)
origin	https://github.com/****/****.git (push)

$ git fetch origin
remote: Counting objects: 14, done.
remote: Compressing objects: 100% (12/12), done.
remote: Total 14 (delta 1), reused 8 (delta 0)
Unpacking objects: 100% (14/14), done.
From https://github.com/****/****
 * [new branch]      gh-pages   -> origin/gh-pages

$ git branch
* master

$ git checkout -b gh-pages --track origin/gh-pages
Branch gh-pages set up to track remote branch gh-pages from origin.
Switched to a new branch 'gh-pages'

$ git branch
* gh-pages
  master

以上.

contentEditable キャレットの後に文字列を挿入する

contentEditable領域でキャレットの後に文字列を挿入する場合.

IE以外のブラウザであれば, 簡単です

document.execCommand('insertHTML', false, '挿入する文字列');

問題はInternet Explorerなのですが,

IE11とIE11未満では方法が異なります.

var contentEditable = document.querySelector('[contentEditable]');

//これがないと挿入できない
contentEditable.focus();

if (document.selection) {
    //IE11未満
    var selection = document.selection();
    var range       = selection.createRange();

    range.pasteHTML('挿入する文字列');
} else if (navigator.userAgent.toLowerCase().indexOf('trident') !== -1) { //IE11 document.execCommand('paste', false, '挿入する文字列'); }

IE11からは, 他のブラウザに準拠するようになったので, document.selectionが定義されていません.
しかしながら, 中途半端な準拠で ‘insertHTML’がexecCommandで実行できません. その代替手段として, ‘paste’を実行します. ただし, この’paste’ を実行すると初めにクリップボードに貼り付けを許可するかどうかのダイアログが出てしまうのでユーザビリティはあまりよろしくありませんが…しかたないですね.

以上をまとめるとこんな感じになります.

var contentEditable = document.querySelector('[contentEditable]');

//これがないと挿入できない
contentEditable.focus();

if (document.selection) {
    //IE11未満
    var selection = document.selection();
    var range       = selection.createRange();

    range.pasteHTML('挿入する文字列');
} else if (navigator.userAgent.toLowerCase().indexOf('trident') !== -1) { //IE11 document.execCommand('paste', false, '挿入する文字列'); } else { //Chrome, Firefox, Safari, Opera etc document.execCommand('insertHTML', false, '挿入する文字列'); }

 

yum Error: Cannot find a valid baseurl for repo: baseの対処法

yumコマンドで,

Error: Cannot find a valid baseurl for repo: base

というエラーが出てしまった場合, 以下のファイルを編集する

vi /etc/yum.repos.d/CentOS-Base.repo

mirrorlistをコメントアウトして, baseurlのコメントをはずす

[base]
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os
baseurl=http://ftp.riken.jp/Linux/centos/$releasever/os/$basearch/

おそらくこれで解決すると思います.

参考 :http://qiita.com/asukiaaa/items/f92bfa7ba6fba2aeb7ed