【Javascript】線の点・太さ(lineWidth)から、輪郭の座標を算出する

こんにちはー。更新が遅れてしまいすみません。

あけましておめでとうございます。今年もよろしくお願いします。

今回は、線の点・太さから、輪郭の座標をとる方法を紹介します。
HTML5 Canvas の stroke() メソッドを、SVG などを使わず、自分で実装する感じです。

なお、自分で考えて手探りでやってみた方法なので、もっと効率のいい方法があるかもしれません。

なぜやりたいのか

matter.js というライブラリがあり、
それを使って、マウスで書いた線を Body に変換したかったのですが、
線を Body に直接することができなかったので、作ろうと思いました。

Constant とか使えばできそうですが、面白そうなのでやってみます。

やってみる

始点・終点

始点は1つ後の点から現在の点、終点は現在の点から1つ前の点を引いて、
逆三角関数でラジアンにし、それに垂直な方向になるように輪郭線を打ちます。

var lineWidth = 5;
var points = [
  { x: 30, y: 50 },
  { x: 120, y: 150 }
];
var outline1 = [];
var outline2 = [];

points.forEach((point, index) => {
  if (index === 0) {
    // 始点
    // Math.PI / 2 は degree で 90°
    var rad = Math.atan2(points[index + 1].y - point.y, points[index + 1].x - point.x) - Math.PI / 2;
    var sin = Math.sin(rad) * lineWidth;
    var cos = Math.cos(rad) * lineWidth;
    outline1.push({ x: point.x + cos, y: point.y + sin });
    outline2.push({ x: point.x - cos, y: point.y - sin });
  } else if (index === points.length - 1) {
    // 終点
    var rad = Math.atan2(point.y - points[index - 1].y, point.x - points[index - 1].x) - Math.PI / 2;
    var sin = Math.sin(rad) * lineWidth;
    var cos = Math.cos(rad) * lineWidth;
    outline1.push({ x: point.x + cos, y: point.y + sin });
    outline2.push({ x: point.x - cos, y: point.y - sin });
  }
});

See the Pen Drawing outlines of a line by shundroid (@shundroid) on CodePen.0

途中の点

いやー、これが難しかったです・・。
方法としては、輪郭線は角の二等分線上で交わるので、
そこで、sinθ = lineWidth となるときの cos をとってくる感じです。

求めた後、回転移動させるのですが、まずは移動させなくてもいいパターンでやってみます。

※省略部分は↑のコードと変わらない部分です。

var lineWidth = 5;
var points = [
  { x: 200, y: 100 },
  { x: 100, y: 100 },
  { x: 150, y: 50 }
];

// 省略

points.forEach((point, index) => {
  if (index === 0) {
    // 省略
  } else if (index === points.lenght - 1) {
    // 省略
  } else {
    var rad1 = Math.atan2(points[index - 1].y - point.y, points[index - 1].x - point.x);
    var rad2 = Math.atan2(points[index + 1].y - point.y, points[index + 1].x - point.x);
    var rad = (rad2 - rad1) / 2;
    var x = Math.cos(rad) * lineWidth / Math.sin(rad);
    var y = lineWidth;
    outline1.push({ x: point.x + x, y: point.y + y });
    outline2.push({ x: point.x - x, y: point.y - y });
  }
});

See the Pen Drawing outlines of a line 2 by shundroid (@shundroid) on CodePen.0

回転移動させる

これでできたっぽいですが、これは入ってくる線の角度が 0° だったときのみ動きます。
それ以外で動かすようにするには、いったん入ってくる線を基準にして求め、それを回転移動させる必要があります。

回転移動については下のサイトが詳しいです。参考にしてみてください。
http://www.geisya.or.jp/~mwm48961/kou2/linear_image3.html

rad1 を基準にしたので、 rad1 の分だけ回転させればいいのです。

var lineWidth = 5;
var points = [
  { x: 200, y: 100 },
  { x: 100, y: 100 },
  { x: 150, y: 50 }
];

// 省略

points.forEach((point, index) => {
  if (index === 0) {
    // 省略
  } else if (index === points.lenght - 1) {
    // 省略
  } else {
    var rad1 = Math.atan2(points[index - 1].y - point.y, points[index - 1].x - point.x);
    var rad2 = Math.atan2(points[index + 1].y - point.y, points[index + 1].x - point.x);
    var rad = (rad2 - rad1) / 2;
    var x = Math.cos(rad) * lineWidth / Math.sin(rad);
    var y = lineWidth;

    var rx = x * Math.cos(rad1) - y * Math.sin(rad1);
    var ry = x * Math.sin(rad1) + y * Math.cos(rad1);
    outline1.push({ x: point.x + rx, y: point.y + ry });
    outline2.push({ x: point.x - rx, y: point.y - ry });
  }
});

See the Pen Drawing outlines of a line 3 by shundroid (@shundroid) on CodePen.0

これでできました!間の点はいくつあってもできます。

See the Pen Drawing outlines of a line 4 by shundroid (@shundroid) on CodePen.0

random にやっているので、急カーブになった場合、輪郭がちょうとんがります。
これは↓でもある、miterLimit を早く実装して直したいです。

考えた別の方法

線を直線の式に変えて、連立方程式で交点を出す

中学2年生で習うことでできそうですが、
どの線とどの線が交わるのかを見つけるのが超難しそうだったのでやめました。

今後やりたいこと

lineCap、lineJoin、miterLimit を実装する

Canvas にある、これらのプロパティも実装してみたいです。
miterLimit は今がんばっています。

【Emscripten】 C++ でJSの関数を関数ポインタとして使う

ものすごく久しぶりの投稿となってしまいました。すみません。

今回は、Emscripten で C++ を実行するときに、
JSの関数を関数ポインタとして登録し、それを呼び出せるようにする方法を紹介します。

実行環境

  • Ubuntu 14.04.5 LTS
  • emcc 1.36.0
  • clang version 3.9.0

やりたいこと

  • JS の関数を set_js_listener 関数を使用して登録する
  • call_listener 関数を呼び出した時、登録した JS の関数を実行する

手順1: set_js_listener、call_listener 関数を実装

typedef void(*JS_LISTENER)();
JS_LISTENER js_listener = NULL;

extern "C"
{
  void set_js_listener(JS_LISTENER f)
  {
    js_listener = f;
  }
}

void call_listener()
{
  js_listener();
}

EMSCRIPTEN_BINDINGS()
{
  emscripten::function("call_listener", &call_listener);
}

typedef を利用して、型を簡略化して使用できるようにしています。

また、set_js_listener は、EMSCRIPTEN_BINDINGS は使用せず、
ビルド時に EXPORTED_FUNCTIONS で js から呼び出せるようにします。
そうしないと、次のようなエラーが出ます。
emscripten_failed_js_pointer
(EMSCRIPTEN_BINDINGS、allow_raw_pointers を使用した場合)

手順2: ビルドする

$ emcc main.cpp -std=c++11 -s RESERVED_FUNCTION_POINTERS=1 --bind -s EXPORTED_FUNCTIONS="['_set_js_listener']"

それぞれの引数は、次のような意味があります。
std=c++11 を指定しないと、embind を使用する際にエラーが出ます。
-s RESERVED_FUNCTION_POINTERS=1 : 1つの関数ポインタを使えるようにします。
--bind : embind を使えるようにします。
-s EXPORTED_FUNCTIONS="['_set_js_listener']" : set_js_listener を js から呼び出せるようにします。

手順3: 関数ポインタをJSで作成する

var fnPointer = Runtime.addFunction(function() {
  console.log("called!");
});

// 登録する
Module.ccall("set_js_listener", "void", [], [fnPointer]);

関数ポインタは、Runtime.addFunction を通して使用します。
set_js_listener は、Module.ccall を使用して呼び出します。

手順4: 登録した関数ポインタを呼び出す

JS から関数ポインタを呼び出します。

Module.call_listener();

emscripten_called_js_pointer

called! とコンソールに出力されたので、登録した関数が呼び出されたことがわかります。

コード

今回実行したコードは次のようになりました。


参考

http://stackoverflow.com/questions/12358877/passing-js-function-to-emscripten-generated-code

【Windows】serialport モジュールなどで node-gyp を使うとき、Visual Studio をインストールせずに使う

こんにちはー。

久しぶりの投稿となります。

というのは、パソコンを落としてしまって、ハードディスクを壊してしまったからです‥。
幸い、壊れているのはハードディスクだけだったので、それを交換したら動きました。

その交換するまでの間、パソコンを貸していただいて、それで開発をしていたのですが、
開発していたリポジトリで、「serialport」モジュールを使っていました。

しかし、このモジュールをビルドするときに、Visual Studio と python が必要だと思っていて、
Visual Studio 入れると一気に8GBとか使うので、
入れないでやる方法があったので紹介します。

Visual C++ Build Tools を使う

http://landinghub.visualstudio.com/visual-cpp-build-tools

これなんです。これが Visual Studio の代わりになります。
↑ で、「Download Visual C++ Build Tools」をクリックして、ダウンロードして実行、
すべてデフォルトのオプションでインストールします。

npm config を変更

$ npm config set msvs_version 2015 --global

これをやらないと、↓のエラーが出てしまいます。

MSBUILD : error MSB3428: Visual C++ コンポーネント "VCBuild.exe" を読み込めませんでした。この問題を解決するには、次のいずれかを行ってください。 1) .NET Framework 2.0 SDK イ
ンストールする。 2) Microsoft Visual Studio 2005 を
インストールする。 3) その他の場所にインストールされている場合、コンポーネントの場所をシステム パスに追加する。 [...\node_modules\serialport\
build\binding.sln]

これで Visual C++ Build Tools でビルドできます。

あと Python 2.7 もいれましょう

これも忘れずに!

ちなみに

serialport モジュールのページでは、Visual Studio をインストールする方法しか書いてありませんが、
node-gyp の Github では、Visual C++ Build Tools を使う方法が紹介されています。

https://github.com/nodejs/node-gyp

Webpack で Ace(Brace)を使うとエラーが出る

こんにちはー。

Ace、便利ですよねー!
js で作られたテキストエディタで、
Webアプリで「ちょっとコード打つとこ作りたい」とかいうときに使えます。

さて、今回はこれを、Webpack から使って、まとめられるようにしたいと思います。

brace を使う

thlorenz/brace
brace - browserify compatible version of the ace editor.

普通の ace を、Browserify で使えるようにしたそうです。

インストール

$ npm install --save brace

bower からインストールしたくて、探しましたがなかったです。

webpack.config.js

node_modulesをbundleできるようにします。

module.exports = {
// ...
  resolve: {
    modulesDirectories: ["node_modules"]
  },
  plugins: [new webpack.ResolverPlugin(
    new webpack.ResolverPlugin
      .DirectoryDescriptionFilePlugin("package.json", ["main"])
  )]
};

しかしエラー

これで、Browserify ならうまくいくらしいのですが、
Webpack だと、エラーが出てしまい、
テキストエディタ上でのエラー表示機能などが使えませんでした。

webpack-brace-error

Could not load worker TypeError: Argument 1 is not valid for any of the 2-argument overloads of URL.createObjectURL.
スタックトレース:
WorkerClient@file:///.../bundle.js:16481:21
this.createWorker@file:///.../bundle.js:21703:23
this.$startWorker@file:///.../bundle.js:8833:29
this.$onChangeMode@file:///.../bundle.js:8789:14
this.setMode/<@file:///.../bundle.js:8770:18
exports.loadModule@file:///.../bundle.js:3766:27
this.setMode@file:///.../bundle.js:8759:10
@file:///.../bundle.js:53:2
__webpack_require__@file:///.../bundle.js:20:12
@file:///.../bundle.js:40:18
@file:///.../bundle.js:1:11

どうやら、w3c-blob という module でエラーが起きています。
これは、Blob が使えないブラウザ用に、Blob を実装している module です。

Blob
Blob オブジェクトはファイルに似たオブジェクトで、immutable な生データです。データを表す blob は必ずしも JavaScript ネイティブなフォーマットではありません。 F...

しかし、サポート状況を見てみると、IEでも10以上、結構多くのブラウザがサポートしています。

ということで、この w3c-blob という module を、
webpack の alias 機能を利用して、
ブラウザの Blob を使うようにしていきます。

1. webpack.config.js があるフォルダに、「alias」フォルダを作成

webpack.config.js があるフォルダに、「alias」フォルダを作成し、
このフォルダの中に、blob.js というファイルを作成します。

blob.js

module.exports = Blob;

1行です。ブラウザで実装されている Blob を使うようにします。

2. webpack.config.js にaliasを登録

4行目-7行目を変更してください。
webpack.config.js

module.exports = {
// ...
  resolve: {
    modulesDirectories: ["node_modules", "alias"],
    alias: {
      "w3c-blob": "blob.js"
    }
  },
  plugins: [new webpack.ResolverPlugin(
    new webpack.ResolverPlugin
      .DirectoryDescriptionFilePlugin("package.json", ["main"])
  )]
};

4行目では、alias フォルダをaliasで使えるようにします。

6行目では、w3c-blob の aliasとして、blob.js(aliasフォルダ内)を登録し、上書きします。

3. 実行してみる

success-webpack-brace

エラーが出ませんでした。
また、テキストエディタ上で、エラーの表示もできるようになりました。

js で文字列が色かどうかを見分ける方法

こんにちはー。

js から css の backgroundColor や、color など、色を指定することがよくあります。
しかし、その時、色でない文字列が backgroundColor などに指定されると、
正しい結果になりません。

今回は、色である文字列が指定されているかを判別する方法を紹介します。

やりたいこと

次のサンプルを見てください。

See the Pen Jsで文字列が色かどうかを判別する by shundroid (@shundroid) on CodePen.0

textbox に、bluergb(255,0,0)を指定して、「判別」ボタンを押すと、「色です」と結果が返ってきます。
しかし、hoge や、1 を指定すると、「色ではありません」となります。

では、この仕組みを説明します。

isColor 関数を実装する

サンプルでは、次のような関数が定義されています。

function isColor(color) {
  var testElement = document.createElement("span");
  testElement.style.backgroundColor = color;
  return testElement.style.backgroundColor !== "";
}

この関数に引数として文字列を指定すると、その文字列が色に変換できるかを返します。

仕組み

testElement.style.backgroundColor のデフォルトの値は "" です。
これに、色に変換できる文字列を指定すると、backgroundColor の値が変化します。
しかし、不正な値が指定されると、backgroundColor の値は変化しません。
これを利用して、testElement.style.backgroundColor !== "" で、
backgroundColorがデフォルトの値でないかで判別しています。

【Canvas】mousemoveのタイミングで円を描くときに円が離れてしまう問題

こんにちはー。

前回、arc を使って描いた時、円が散らばらないようにする方法を紹介すると書いたので書きます。

【JS】Canvasで丸や四角で「消す」方法
こんにちはー。題名のとおり、Canvas の「消す」機能で、丸などに形を変える方法を紹介します。「消す」機能についてまずはじめに、消す方法としてのルールを書いておき...

まず、下の例を見てください。

うまくいかない例

See the Pen Canvas Mousemove 円で描いてうまくいかない例 by shundroid (@shundroid) on CodePen.dark

よくありがちなコンテンツです。
mousemove のイベントが発生した時に円を描いているわけですが、
めっちゃ速く動かして書くと、円と円の間が空いてしまいます。

今回は意外と初歩的なことかもしれませんが、
この、間が空かないようにする方法を描きます。

moveToとlineToを使う

実際に moveTo と lineTo でやった例は、こちらです。

See the Pen Canvas mousemove lineToとmoveTo by shundroid (@shundroid) on CodePen.dark

この方法は、円で描くのではなく、線で描いています。
そのため、円と円の間が描けるわけです。

では、使っている関数を紹介したいと思います。

moveTo 関数

線の始点を指定します。
ここでは、ひとつ前の mousemove での座標、もしくは mousedown での座標を指定しています。

lineTo 関数

lineTo で指定した始点から、
線を引くときの終点を指定します。
ここでは、現在の座標を指定しています。

色を変えるには

CanvasRenderingContext2D.strokeStyle で取得・変更できます。

var ctx = canvas.getContext("2d");
ctx.strokeStyle = "red"; // 赤
ctx.strokeStyle = "green"; // 緑

参考: https://developer.mozilla.org/ja/docs/Web/API/CanvasRenderingContext2D/strokeStyle

太さを変えるには

CanvasRenderingContext2D.lineWidth で取得・変更できます。
円で描いた時は、arc メソッドの第3引数で指定していたので、それの代わりです。

var ctx = canvas.getContext("2d");
ctx.lineWidth = 100;

詳しいサイト

Canvasで使える関数が紹介されています。
「こんな機能あったんだ~」という新発見もあるので、一度見てみてください!

【JS】Canvasで丸や四角で「消す」方法

こんにちはー。
題名のとおり、Canvas の「消す」機能で、丸などに形を変える方法を紹介します。

「消す」機能について

まずはじめに、消す方法としてのルールを書いておきます。

  • 白く塗る はダメ!(背景が白でない場合があるため)
  • 消した部分は透明になるようにする。

実装のポイント

context の globalCompositeOperation を、destination-out に変更すると、
fill や stroke で指定した領域を 切り取る ことができます。

また、このプロパティは、その他いろいろな値に変更できます。

サンプル:円形で消す

globalCompositeOperationを変更した状態で、arc メソッドを呼ぶことでできます。

var ctx = document.getElementById("xxx").getContext("2d");
function eraseArc() {
  ctx.globalCompositeOperation = "destination-out";
  ctx.beginPath();
  ctx.arc(100, 100, 50, 0, Math.PI*2, false);
  ctx.fill();
}

arc() の引数

arc(中心x, 中心y, 半径, 開始角度(ラジアン), 終了角度(ラジアン), どっち回りか(true→反時計回り))

応用例

See the Pen Canvas Erase By Arc by shundroid (@shundroid) on CodePen.dark

  • チェックボックス ON:描く、OFF:消す(globalCompositeOperation で切り替えています)
  • 背景色を変更で、消した部分が透明になっていることを確認できます

掲載したサンプルコードでは、ctx.arc で描画していますが、
このサンプルは mousemove で動いた時に描いているので、arc で描くと円が散らばってしまい、うまく描けません。
そのため、moveTo と、lineTo を使って描いています。

この方法については、次回ブログで書きたいと思います。

「消す」モードを戻したい

このままでは、常に stroke や fill した部分が切り取られてしまうため、
元の値に戻しておきましょう。
デフォルトの値は、source-over です。

var ctx = document.getElementById("xxx").getContext("2d");
ctx.globalCompositeOperation = "source-over";

js の正規表現で、「完全一致」でマッチする

こんにちはー。

機会があって、
正規表現で「完全一致」のテストの方法が知りたくなりました。
今日はその方法を紹介します。

どういうことがしたいのか

/abcde/.test("abcde"); // true
/abcde/.test("abcdef"); // これも true

このような場合だと、
1行目のようなテストする文字列がパターンと同じ場合、 true になりますが、
含んでいる場合(2行目)も true になってしまいます。
これを、2行目が false になって、1行目だけ true になるようにしたいんです。

完全一致したいとき

https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Regular_Expressions

次のようにすればできました!

/^パターン$/

^が先頭を表し、$が末尾を表します。
だから、それにパターンを挟む形でやれば「完全一致」でマッチできます。

例:

/^下$/.test("下"); // true
/^下$/.test("下町"); // false
/^下$/.test("上下"); // false

メリットは・・?

なら、「if ("下" === "下") {}」でよくない?
と思うかもしれません。
たしかに上の例ではそうですが、
正規表現で比較すると、様々なメリットを得ることもできます。

「完全一致」の or 検索

例えば、次のように書いたとしましょう。

var reg = /^(下|上)$/;

こうすれば、or でのテストもできますよ~

使用例:

/^(下|上)$/.test("下"); // true
/^(下|上)$/.test("上"); // true
/^(下|上)$/.test("上下"); // false
/^(下|上)$/.test("上野"); // false

その他、いろいろな「特殊文字」が使える

完全一致と言っていいのかわかりませんが、
? や、. などの特殊文字も使えます。

どれか1文字にマッチする

. を使います。

/^A.C$/.test("ABC"); // true
/^A.C$/.test("AC"); // false

※ 改行文字にはマッチしません。
  改行文字にマッチするには、\n や、\s(スペースなども含む)を使用します。

直前の文字の1回以上の繰り返しにマッチする

+ を使います。

/^AA+B$/.test("AAB"); //true
/^AA+B$/.test("AAAAAAAAAAAAAAAAB"); // true
/^AA+B$/.test("AB"); //false

※繰り返さない場合(0回以上の繰り返し)にもマッチするときは、* を使います。

その他の特殊文字の意味と使い方は、MDN の記事をご覧ください。

感想

学んでいて、
正規表現って、実用性が高いんだな☆と気づきました。

【Rx.js】画像を非同期に読み込むサンプルコード

こんにちはー。

非同期の処理をいい感じに使える js のライブラリないかなーと探していたら、
Rx.js というのを見つけたので、それを使ったサンプル?を紹介します。

Rx.js とは?

.NET 向けの Reactive Extensions を js 用に移植したもの。
ぼくは、最初 .NET の方を使っていて、
「それの js 版があったらいいな~」と思っていたらピンポイントであったという感じですー。

コードの概要

では、今回書いてみるコードの概要を紹介します。

  1. 3つの画像が配列になっている
  2. それらを非同期で読むが、1つ読み終わったら次を読むという条件。
  3. 1つ読み終わった後と全部読み終わった後にコールバックする

全部いっぺんに非同期で読めばいいと思うかもしれませんが、
画像がウエーブみたいになって読み込まれていくようにしたかったんです。

【Before】Rx.js を使わない場合のコード

var images = ["1.png", "2.png", "3.png"];
function loadImages(oneByOne, finished) {
  var index = 0;
  var loadImage = (name) => {
    var elem = document.createElement("image");
    elem.src = name;
    elem.onload = function() {
      oneByOne(index);
      if (index >= images.length - 1) {
        finished();
      } else {
        loadImage(images[++index]);
      }
    }
  };
  loadImage(images[index]);
}
function main() {
  loadImages((index) => {
    console.log(index + "個目を読み込みました");
  }, () => {
    console.log("読み込み完了");
  });
}

このコードを、Rx.js を使って、シンプルにしてみます。

【After】Rx.js の降臨

// 読み込むとき、ES6 ( + browserify) だと便利
import Rx from "rx"; // ES6 modules

var images = ["1.png", "2.png", "3.png"];
function loadImages() {
  return Rx.Observable.create(loadImagesObservable);
}
function loadImagesObservable(observer) {
  var index = 0;
  var loadImage = (name) => {
    var elem = document.createElement("image");
    elem.src = name;
    elem.onload = function() {
      observer.onNext(index);
      if (index >= images.length - 1) {
        observer.onCompleted();
      } else {
        loadImage(images[++index]);
      }
    }
  };
  loadImage(images[index]);
  return function() { };
}
function main() {
  var subscription = loadImages().subscribe((index) => {
    console.log(index + "個目を読み込みました");
  }, err => {
    console.log("Observe Error: " + err);
  }, () => {
    console.log("読み込み完了");
  });
}
  • 1つ読み終わった時 -> observer.onNext
  • 全部読み終わった時 -> observer.onCompleted

に当てはめました。

Rx.js を使うメリット

キャンセル時の処理を追加できる

上のコードでは書いていませんが、
subscription.dispose でキャンセルでき、
loadImagesObservable の返り値の関数で、dispose された時の処理を追加できるので、
そこで読み込みの処理を停止するように書けば、簡単にできます!

キャンセル時の処理を書いた例: Gist

filter ができる

loadImages().subscribe(...) を、loadImages().filter(...).subscribe(...) にすれば、
フィルターを通すことも簡単にできます。

フィルターを使った例として、「5回に1回、○個目を読み込みましたと表示」するようにしてみます。

// function main() 内を変更
function main() {
  var subscription = loadImages().filter(index => index % 5 === 0).subscribe((index) => {
    console.log(index + "個目を読み込みました");
  }, err => {
    console.log("Observe Error: " + err);
  }, () => {
    console.log("読み込み完了");
  });
}

フィルターを利用した例の全コード: Gist

参考

「RxJS」初心者入門 - JavaScriptの非同期処理の常識を変えるライブラリ | 株式会社LIG
こんにちは、王です。 みなさん、「RxJS」をご存知でしょうか? すごく大雑把に言うと、RxJSとは非同期処理(マウスクリックなどのイベントベースの処理も含める)をす...

追記

2016-04-07 : Rx.js を使ったメリットを中心とするように記事の内容を全面改訂。

Sphero.js で、指定した時間だけ orb.roll をしたい

しばらく投稿してなくてすみません。

Cities Skylines にハマっていました。
え? 動かないんじゃないのだって?
VAIO の設定で、CPU を静かさ優先 -> パフォーマンス優先にしたら、なんとか動きました。
こんなに違うんだ・・
その代わり、パソコンがあったかい~☆し、めっちゃうなっています。
めっちゃ重いけど、めっちゃ面白いです。

さて、今回は、Sphero を Node.js から動かせるというすぐれもの、
Sphero.js に関する Tips ですー。
内容はタイトルの通り!

コード

var sphero = require("sphero");
var orb = sphero("xxx");

orb.connect(function() {
  function a() {
    orb.color("blue");
    orb.roll(100, 0);
    setTimeout(b, 100);
  }
  function b() {
    orb.color("red");
    orb.roll(0, 0);
    setTimeout(c, 100);
  }
  function c() {
    orb.color("green");
    orb.roll(100, 180);
    setTimeout(d, 100);
  }
  function d() {
    orb.color("yellow");
    orb.roll(0, 180);
    setTimeout(a, 100);
  }
  orb.color("black");
  setTimeout(a, 1000);
});

コードの解説

0.1 秒毎に、orb.roll を動かす or 止めると、
色を変えています。

最初は正常に動くのですが、だんだん遅れて、
最終的には止まってしまいました。

これでは、正確に 0.1 秒動くことができなくなってしまいます。

解決法

orb.roll で Sphero を動かす前に orb.ping をして、
通信ができるかどうか確認するとできました。

止まる前は orb.ping はしません。
してしまうと、0.1 秒後に止まると出来無いからです。

止まるときに通信できてなくて、
遅れてしまったらもうしょうがないですが・・

ぼくが試した感じでは、
そういうトラブルはなかったです。