pebble
  • Tutorials
  • Get the SDK
  • Guides
  • Documentation
  • Examples
  • Community
  • Blog
  • More
Privacy
Cookies
Publish

Tutorials

  • C言語でウォッチフェイスを開発する
    • Part 1 - 時間を表示する
    • Part 2 - ウォッチフェイスをカスタマイズする
    • Part 3 - ウェブコンテンツを追加する
    • Part 4 - バッテリーバーを追加する
    • Part 5 - スマホ切断時にバイブレーションする
  • JavaScriptでウォッチフェイスを開発する
    • Part 1 - 時間を表示する
    • Part 2 - ウェブコンテンツを追加する
  • 上級者向けチュートリアル
    • ベクターアニメーション

Build a Watchface in JavaScript using Rocky.js

デバイスの互換性について Rocky.js は Pebble OS v4.x を必要とするため、Pebble Classic および Pebble Steel には対応しません。

Note: Pebble の新しい JavaScript ランタイムを開発中です!以前の Rocky.js 実装はModdableに置き換えられます。Moddable は、Pebble 開発に強化された機能をもたらす最新のオープンソース JavaScript エンジンです。Moddable を使用すると、開発者はより充実したランタイムと SDK で C と JavaScript を組み合わせたアプリを作成できます。詳細についてはこのブログ投稿をご覧ください。このチュートリアルは参考用にアーカイブされていますが、将来の SDK バージョンでは動作しない可能性があります。

まずは基本から始めて、シンプルなデジタル文字盤を作成し、最後に次のような見た目のアナログ時計を作成します:

rocky

最初のステップ

まだの場合は、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

おめでとうございます!

文字盤が読み込まれるときに読み込みバーが表示され、その後すぐにエミュレータで文字盤が実行されているのが見えるはずです。

rocky

ログには、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.js Linter

ビルドプロセスの一部として、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 文字盤を作成するために必要な基本的なプロセスを理解できました!これを行うには:

  1. 新しい Rocky.js プロジェクトを作成しました
  2. 'rocky'ライブラリをインクルードしました
  3. minutechangeイベントをサブスクライブしました
  4. drawイベントをサブスクライブしました
  5. 描画コマンドを使用してディスプレイにテキストと線を描画しました

コードに問題がある場合は、下のボタンを使用して提供されているサンプルソースコードと照合してください。

View Source Code

次のステップ

アプリケーションのビルドと実行に成功した場合、組み込みの TicToc によく似た非常に基本的な文字盤が表示されているはずです。次のチュートリアルでは、postMessageを使用してモバイルデバイスに情報を渡し、Web から天気データをリクエストします。

Go to Part 2 →

Overview

  • 最初のステップ
  • 文字盤の基礎
  • デジタル文字盤の作成
  • 最初のコンパイルとインストール
  • おめでとうございます!
  • アナログ文字盤の作成
  • 針の描画
  • すべてをまとめる
  • トラブルシューティングとデバッグ
  • Rocky.js Linter
  • ログを使用したエラーの特定
  • まだ問題があります!
  • まとめ
  • 次のステップ