Creating an analog Fitbit Ionic Clockface (Part 3)

Due to a request, I’m adding another part to the tutorial: How to add the date.

Since the original tutorials were written, Fitbit have made updates and so the ‘innerText’ we were using before will soon be deprecated we need to change it to ‘text’.

First up, let’s add the update to index.gui  This will be added after the ‘WatchFace’ line so it is below to show you where:

<image id="WatchFace" class="WatchFace" href="background.png" />
<text id="date1" class="date1" />
<text id="date2" class="date2" />

These need to be just after the class WatchFace because they will show on top of the background, but under the hands.

Next, update the styles.css file. Add this to the bottom underneath ‘elevationValue’:

#date1 {
  font-size: 32;
  font-family: Seville-Condensed;
  text-length: 32;
  text-anchor: middle;
  x: 174;
  y: 170;
  fill: blue;
}

#date2 {
  font-size: 32;
  font-family: Seville-Condensed;
  text-length: 32;
  text-anchor: middle;
  x: 174;
  y: 195;
  fill: blue;
}

Next, we update index.js  Add this under ‘let elvValue’. I have included it here to show where to add it:

let elvValue = document.getElementById("elevationValue");
let dateText1 = document.getElementById("date1");
let dateText2 = document.getElementById("date2");

// Define days
let days = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];
let months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]

Next, we need to ask the Fitbit Ionic what the date info is. To do that, we create a variable object for now. We’ll add it into the updateText function:

function updateText() {
  // Create variable object to current time
  let now = new Date();

Finally, under ‘hrm.start’ we update the date text fields:

hrm.start();  
// Update Day and Month
dateText1.text = now.getDate() + " " + months[now.getMonth()];
// Update Day of week
dateText2.text = days[now.getDay()];

And you’re done! This is what it will now look like:

The full index.js:

import clock from "clock";

// Import useful data
import { HeartRateSensor } from "heart-rate";
import { today } from "user-activity";
import document from "document";

// Update the clock every minute
clock.granularity = "seconds";

// Set up variables - get references to document elements
let hrtValue = document.getElementById("heartrateValue");
let stpValue = document.getElementById("stepsValue");
let calValue = document.getElementById("caloriesValue");
let elvValue = document.getElementById("elevationValue");
let dateText1 = document.getElementById("date1");
let dateText2 = document.getElementById("date2");

// Define days
let days = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];
let months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]

// Create new HR Sensor handle
let hrm = new HeartRateSensor();
// When the value changes, update text
hrm.onreading = function() {
  // Peek the current sensor values
  hrtValue.text = hrm.heartRate || 0;

  // Stop monitoring the sensor
  hrm.stop();
}

// Update calories, altitude, steps and heartrate
function updateText() {
  // Create variable object to current time
  let now = new Date();
  // Update Steps taken
  stpValue.text = today.adjusted.steps || 0;
  // Update Calories burned
  calValue.text = today.adjusted.calories || 0;
  // Update Altitude walked
  elvValue.text = today.adjusted["elevationGain"] || 0;
  // Update Heart Rate
  hrm.start();  
  // Update Day and Month
  dateText1.text = now.getDate() + " " + months[now.getMonth()];
  // Update Day of week
  dateText2.text = days[now.getDay()];
}

// Update text every second
setInterval(updateText, 1000);

The full index.gui:

<svg class="background">
  <defs>
    <section>
      <symbol id="sec-hand">
        <line x1="0" y1="0" x2="0" y2="120" stroke-width="2"/>
      </symbol>
      <symbol id="min-hand">

      </symbol>
      <symbol id="hour-hand">

      </symbol>
      <symbol id="center-dot">
        <circle r="4" fill="#F5F5F5"/>
        <circle r="2" fill="fb-dark-gray"/>
      </symbol>
    </section>
    <symbol id="clock-widget" class='clock-widget' type='clock-widget'
        focusable='false' pointer-events='visible' system-events='all' width='348' height='250' data-size='16'/>
  </defs>
  
  <image id="WatchFace" class="WatchFace" href="background.png" />
  <text id="date1" class="date1" />
  <text id="date2" class="date2" />
  
  <use id="analog-watch-hands" href='#clock-widget' x='0' y='0' >
    <g transform="translate(50%,50%)">
      <g id="second-hand">
        <use href="#sec-hand" class="sec-hand" />
      </g>
      <g id="minute-hand">
        <use href="#min-hand" class="min-hand" />
         <image href="minuteHand.png" width="9" height="125" class="min-hand" /> 
      </g>
      <g id="hour-hand">
        <use href="#hour-hand" class="hour-hand" />
         <image href="hourHand.png" width="13" height="80" class="hour-hand" /> 
      </g>
      <g id="dot">
        <use href="#center-dot" class="center-dot" />
      </g>
    </g>
  </use>
<text id="heartrateText" class="heartrateText">BPM</text>
  <text id="stepsText" class="stepsText">STP</text>
  <text id="caloriesText" class="caloriesText">CAL</text>
  <text id="elevationText" class="elevationText">ELV</text>
  <text id="heartrateValue" class="heartrateValue">???</text>
  <text id="stepsValue" class="stepsValue">???,???</text>
  <text id="caloriesValue" class="caloriesValue">??,???</text>
  <text id="elevationValue" class="elevationValue">??</text> 
</svg>

The full styles.css:

.background {
  viewport-fill: fb-black;
}

.sec-hand {
  y: -105;
  fill: fb-light-gray;
}

.min-hand {
  x: -4;
  y: -108;
}

.hour-hand {
  x: -6;
  y: -67;
}

#WatchFace {
  x: 0;
  y: 0;
  width: 348;
  height: 250;
}

#heartrateText {
  font-size: 32;
  font-family: Seville-Condensed;
  text-length: 32;
  text-anchor: end;
  x: 348;
  y: 55;  
  fill: yellow;
}

#stepsText {
  font-size: 32;
  font-family: Seville-Condensed;
  text-length: 32;
  text-anchor: start;
  x: 0;
  y: 55;
  fill: yellow;
}

#caloriesText {
  font-size: 32;
  font-family: Seville-Condensed;
  text-length: 32;
  text-anchor: start;
  x: 0;
  y: 215;
  fill: yellow;
}

#elevationText {
  font-size: 32;
  font-family: Seville-Condensed;
  text-length: 32;
  text-anchor: start;
  x: 308;
  y: 205;
  fill: yellow;
}

#heartrateValue {
  font-size: 32;
  font-family: Seville-Condensed;
  text-length: 32;
  text-anchor: end;
  x: 348;
  y: 25;  
  fill: white;
}

#stepsValue {
  font-size: 32;
  font-family: Seville-Condensed;
  text-length: 32;
  text-anchor: start;
  x: 0;
  y: 25;
  fill: white;
}

#caloriesValue {
  font-size: 32;
  font-family: Seville-Condensed;
  text-length: 32;
  text-anchor: start;
  x: 0;
  y: 245;
  fill: white;
}

#elevationValue {
  font-size: 32;
  font-family: Seville-Condensed;
  text-length: 32;
  text-anchor: end;
  x: 348;
  y: 245;
  fill: white;
}

#date1 {
  font-size: 32;
  font-family: Seville-Condensed;
  text-length: 32;
  text-anchor: middle;
  x: 174;
  y: 170;
  fill: blue;
}

#date2 {
  font-size: 32;
  font-family: Seville-Condensed;
  text-length: 32;
  text-anchor: middle;
  x: 174;
  y: 195;
  fill: blue;
}

 

(Visited 472 times, 7 visits today)