デバイスの互換性について Rocky.js は Pebble OS v4.x を必要とするため、Pebble Classic および Pebble Steel には対応しません。
Note: Pebble の新しい JavaScript ランタイムを開発中です!以前の Rocky.js 実装はModdableに置き換えられます。Moddable は、Pebble 開発に強化された機能をもたらす最新のオープンソース JavaScript エンジンです。Moddable を使用すると、開発者はより充実したランタイムと SDK で C と JavaScript を組み合わせたアプリを作成できます。詳細についてはこのブログ投稿をご覧ください。このチュートリアルは参考用にアーカイブされていますが、将来の SDK バージョンでは動作しない可能性があります。
まずは基本から始めて、シンプルなデジタル文字盤を作成し、最後に次のような見た目のアナログ時計を作成します:

まだの場合は、SDK Pageにアクセスして、最新バージョンの Pebble Tool と最新の SDK をダウンロードしてインストールする方法を学んでください。
Pebble Tool と SDK 4.0 をインストールしたら、次のコマンドで新しい Rocky.js プロジェクトを作成できます:
$ pebble new-project --rocky helloworld
これにより、helloworldという新しいフォルダが作成され、基本的な Rocky.js アプリケーションに必要な基本構造が配置されます。
文字盤は、定期的な間隔(通常は 1 分ごと、または特定のイベントが発生したとき)でディスプレイを更新する、本質的に長時間実行されるアプリケーションです。画面の更新頻度を最小限に抑えることで、時計のバッテリー寿命を節約できます。
文字盤のメインエントリーポイントは/src/rocky/index.jsなので、このファイルの編集から始めます。
最初に行う必要があるのは、Rocky.js ライブラリをインクルードすることです。これにより、Pebble 文字盤を作成するために必要な API にアクセスできます。
var rocky = require("rocky");
次に、rocky.on('minutechange', ...)の呼び出しでminutechangeイベントにコールバックメソッドを登録します。これは、内部時計の分が変わるたびに(そしてハンドラが登録されたときにも)発火されます。文字盤は、画面を再描画するためにminutechangeイベントの一部としてrequestDrawメソッドを呼び出す必要があります。
rocky.on("minutechange", function (event) {
rocky.requestDraw();
});
NOTE: より頻繁に、またはそれほど頻繁に更新する必要がない場合は、
secondchange、hourchange、daychangeイベントも登録できます。
次に、drawイベントにコールバックメソッドを登録します。これはrocky.requestDraw()の各呼び出しの後に発火されます。コールバック関数に渡されるeventパラメータにはCanvasRenderingContext2Dオブジェクトが含まれており、これはディスプレイの特性を判断し、ディスプレイにテキストや図形を描画するために使用されます。
rocky.on("draw", function (event) {
// Get the CanvasRenderingContext2D object
var ctx = event.context;
});
RockyDrawCallbackは、CanvasRenderingContext2Dオブジェクトを通じて提供されるメソッドを使用して、スマートウォッチのディスプレイをレンダリングする場所です。
NOTE:
drawイベントは、ハンドラが最初に登録されたときなど、他のタイミングでも発火される可能性があります。
シンプルなデジタル文字盤を作成するには、次のことを行う必要があります:
minutechangeイベントをサブスクライブするdrawイベントをサブスクライブして、ディスプレイを更新できるようにする現在の時刻を表示する最小限の文字盤を作成するには、/src/rocky/index.jsの内容を次のコードに置き換えましょう:
var rocky = require("rocky");
rocky.on("draw", function (event) {
// Get the CanvasRenderingContext2D object
var ctx = event.context;
// Clear the screen
ctx.clearRect(0, 0, ctx.canvas.clientWidth, ctx.canvas.clientHeight);
// Determine the width and height of the display
var w = ctx.canvas.unobstructedWidth;
var h = ctx.canvas.unobstructedHeight;
// Current date/time
var d = new Date();
// Set the text color
ctx.fillStyle = "white";
// Center align the text
ctx.textAlign = "center";
// Display the time, in the middle of the screen
ctx.fillText(d.toLocaleTimeString(), w / 2, h / 2, w);
});
rocky.on("minutechange", function (event) {
// Display a message in the system logs
console.log("Another minute with your Pebble!");
// Request the screen to be redrawn on next pass
rocky.requestDraw();
});
文字盤をコンパイルするには、プロジェクトファイルを保存したことを確認してから、プロジェクトのルートディレクトリから次のコマンドを実行します:
$ pebble build
コンパイルが成功すると、'build' finished successfullyというメッセージが表示されます。
コードに問題がある場合、コンパイラはどの行にエラーが含まれているかを通知するので、修正できます。詳細については、トラブルシューティングとデバッグを参照してください。
次のコマンドを実行して、エミュレータに文字盤アプリをインストールし、ログを表示します:
$ pebble install --logs --emulator basalt
文字盤が読み込まれるときに読み込みバーが表示され、その後すぐにエミュレータで文字盤が実行されているのが見えるはずです。

ログには、console.log()で記録するように指示したメッセージも表示されているはずです。
Another minute with your Pebble!
Note: ログステートメントを使用していない場合は、コードをコメントアウトして実行を防ぐ必要があります。例:
//console.log();
アナログ文字盤を描画するには、次のことを行う必要があります:
minutechangeイベントをサブスクライブするdrawイベントをサブスクライブして、ディスプレイを更新できるようにする時針を表す線と、分針を表す線の 2 本の線を描画する必要があります。
時間と分の描画コードの重複を避けるために、針を描画する関数を実装する必要があります。望ましい効果を達成するために、一連のCanvasRenderingContext2Dメソッドを使用します。
まず、ディスプレイの中心点を見つける必要があります:
// Determine the available width and height of the display
var w = ctx.canvas.unobstructedWidth;
var h = ctx.canvas.unobstructedHeight;
// Determine the center point of the display
var cx = w / 2;
var cy = h / 2;
これで針の開始点(cx、cy)がわかりましたが、終点を決定する必要があります。これは少しの数学で行うことができます:
var x2 = cx + Math.sin(angle) * length;
var y2 = cy - Math.cos(angle) * length;
次に、ctxパラメータを使用して、針の線幅と色を設定します。
// Configure how we want to draw the hand
ctx.lineWidth = 8;
ctx.strokeStyle = color;
最後に、画面の中心から始めて外側に向かって直線を描画し、針を描画します。
// Begin drawing
ctx.beginPath();
// Move to the center point, then draw the line
ctx.moveTo(cx, cy);
ctx.lineTo(x2, y2);
// Stroke the line (output to display)
ctx.stroke();
var rocky = require("rocky");
function fractionToRadian(fraction) {
return fraction * 2 * Math.PI;
}
function drawHand(ctx, cx, cy, angle, length, color) {
// Find the end points
var x2 = cx + Math.sin(angle) * length;
var y2 = cy - Math.cos(angle) * length;
// Configure how we want to draw the hand
ctx.lineWidth = 8;
ctx.strokeStyle = color;
// Begin drawing
ctx.beginPath();
// Move to the center point, then draw the line
ctx.moveTo(cx, cy);
ctx.lineTo(x2, y2);
// Stroke the line (output to display)
ctx.stroke();
}
rocky.on("draw", function (event) {
var ctx = event.context;
var d = new Date();
// Clear the screen
ctx.clearRect(0, 0, ctx.canvas.clientWidth, ctx.canvas.clientHeight);
// Determine the width and height of the display
var w = ctx.canvas.unobstructedWidth;
var h = ctx.canvas.unobstructedHeight;
// Determine the center point of the display
// and the max size of watch hands
var cx = w / 2;
var cy = h / 2;
// -20 so we're inset 10px on each side
var maxLength = (Math.min(w, h) - 20) / 2;
// Calculate the minute hand angle
var minuteFraction = d.getMinutes() / 60;
var minuteAngle = fractionToRadian(minuteFraction);
// Draw the minute hand
drawHand(ctx, cx, cy, minuteAngle, maxLength, "white");
// Calculate the hour hand angle
var hourFraction = ((d.getHours() % 12) + minuteFraction) / 12;
var hourAngle = fractionToRadian(hourFraction);
// Draw the hour hand
drawHand(ctx, cx, cy, hourAngle, maxLength * 0.6, "lightblue");
});
rocky.on("minutechange", function (event) {
// Request the screen to be redrawn on next pass
rocky.requestDraw();
});
エミュレータでプロジェクトをコンパイルして実行し、結果を確認してください!
ビルドが機能しなかった場合、Build Failedというエラーメッセージが表示されます。一般的なエラーのタイプをいくつか見てみましょう:
ビルドプロセスの一部として、Rocky index.jsファイルは'linting'と呼ばれるプロセスを使用して自動的にエラーがチェックされます。
最初に確認するのは、ビルド出力の'Lint Results'セクションです。
========== Lint Results: index.js ==========
src/rocky/index.js(7,39): error TS1005: ',' expected.
src/rocky/index.js(9,8): error TS1005: ':' expected.
src/rocky/index.js(9,37): error TS1005: ',' expected.
src/rocky/index.js(7,1): warning TS2346: Supplied parameters do not match any signature of call target.
src/rocky/index.js(7,24): warning TS2304: Cannot find name 'funtion'.
Errors: 3, Warnings: 2
Please fix the issues marked with 'error' above.
上記のエラーメッセージでは、エラーが含まれているファイル名、続いてエラーが発生する行番号と列番号が表示されています。例:
Filename: src/rocky/index.js
Line number: 7
Character: 24
Description: Cannot find name 'funtion'.
rocky.on('minutechange', funtion(event) {
// ...
});
ご覧のとおり、このエラーはタイプミスに関連しており、'funtion'は'function'であるべきです。このエラーを修正して再度pebble buildを実行すると、次のように表示されるはずです:
========== Lint Results: index.js ==========
Everything looks AWESOME!
ビルドは成功したが、コードが期待どおりに機能していない場合はどうすればよいでしょうか?ログを使用します!
アプリケーションコードを通じてパンくずトレイルを散りばめて、アプリケーションの実行中に追跡できるようにします。これにより、問題の場所を絞り込むことができます。
rocky.on("minutechange", function (event) {
console.log("minutechange fired!");
// ...
});
ログステートメントを追加したら、アプリケーションを再ビルドしてログを表示します:
$ pebble build && pebble install --emulator basalt --logs
ログステートメントの 1 つがログ出力に表示されていない場合、おそらく前のコードに問題があることを意味します。
上記の手順を試してもまだ問題がある場合は、ヘルプを得られる場所がたくさんあります。Pebble Forumsに質問とコードを投稿するか、Discord Serverに参加してサポートを求めることができます。
これで、JavaScript を使用して新しい Pebble 文字盤を作成するために必要な基本的なプロセスを理解できました!これを行うには:
'rocky'ライブラリをインクルードしましたminutechangeイベントをサブスクライブしましたdrawイベントをサブスクライブしましたコードに問題がある場合は、下のボタンを使用して提供されているサンプルソースコードと照合してください。
アプリケーションのビルドと実行に成功した場合、組み込みの TicToc によく似た非常に基本的な文字盤が表示されているはずです。次のチュートリアルでは、postMessageを使用してモバイルデバイスに情報を渡し、Web から天気データをリクエストします。