時針、分針、秒針を三角形のマークにしたアナログ時計。
目盛りは、時間を表すものを2ドット幅・長めにして描画。時間と時間の間は5等分にし、1ドット幅・短めに描画。
時分秒を表すのに、針形状ではなく3角形のマークのマークにし、頂点方向を外周に向けるように描画している。
一応、考えられるだけの手動最適化をしているが、全部の処理に約100msかかっている。ただこれでも初期バージョンの半分ぐらいの処理時間にはなったのだが。
using Toybox.WatchUi;
using Toybox.Graphics;
using Toybox.System;
using Toybox.Lang;
using Toybox.Math;
class sample1View extends WatchUi.WatchFace {
var center;
var pi2; // Math.PI * 2.0
function initialize() {
WatchFace.initialize();
pi2 = Math.PI * 2.0;
}
// Load your resources here
function onLayout(dc) {
center = [dc.getWidth()/2, dc.getHeight()/2];
}
// 角度の絶対値を使用し座標を生成しハッシュマークを表示する
function drawHashMarks(dc) {
var vLong = center[0] - 10;
var vShort = center[0] - 5;
var aDel = Math.PI / 30.0;
for (var i = 0; i < 60; ++i) {
var vAngle = aDel * i;
var vSin = Math.sin(vAngle);
var vCos = Math.cos(vAngle);
if (i % 5 == 0) {
dc.setPenWidth(2);
dc.drawLine(center[0] + center[0] * vSin, center[1] + center[0] * vCos,
center[0] + vLong * vSin, center[1] + vLong * vCos);
}
else {
dc.setPenWidth(1);
dc.drawLine(center[0] + center[0] * vSin, center[1] + center[0] * vCos,
center[0] + vShort * vSin, center[1] + vShort * vCos);
}
}
}
// 3角マークを、角度の絶対値で作成して表示
function drawMark(dc, radius, angle, size) {
var vSin = Math.sin(angle);
var vCos = Math.cos(angle);
var cPos = [center[0] + radius * vSin, center[1] - radius * vCos];
var angle1 = angle + pi2 / 3.0;
var angle2 = angle + Math.PI * 4.0 / 3.0;
var vPoints = [
[cPos[0] + size * vSin, cPos[1] - size * vCos],
[cPos[0] + size * Math.sin(angle1), cPos[1] - size * Math.cos(angle1)],
[cPos[0] + size * Math.sin(angle2), cPos[1] - size * Math.cos(angle2)]
];
dc.fillPolygon(vPoints);
}
// 時分の針を表示
function drawHMHand(dc) {
var wAngle = pi2 / 60.0;
var clockTime = System.getClockTime();
dc.setColor(Graphics.COLOR_RED, Graphics.COLOR_BLACK);
drawMark(dc, center[0] * 0.83, ((clockTime.hour % 12) * 60 + clockTime.min) / 12.0 * wAngle, 12);
dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_BLACK);
drawMark(dc, center[0] * 0.85, clockTime.min * wAngle, 6);
drawMark(dc, center[0] * 0.80, clockTime.sec * wAngle, 6);
}
// Update the view
function onUpdate(dc) {
dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_BLACK);
dc.clear();
drawHashMarks(dc);
drawHMHand(dc);
}
}
ちなみに、目盛りを描画する処理にHashMarksとつけたのだが、これはConnect IQのサンプルの目盛りを描画する関数にそう付けられていたから。時計の目盛りのことを英語名ではhash marksというのだろうか。
追記(1/14)
sin/cosの使用位置がx,yで逆だった。恥ずかしい。
ソースコードは面倒なので、修正しない予定。
コメント