Cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Coding noob, variably background on simple clock interface

I have no coding experience, learning what I can from forums like this.

I made a simple watch face that shows the time. date and heart rate for the fitbit since. Works perfectly.

 

Wanted to make it just a tad more unique by having the back ground change based on the heart rate. After digging and trial and error, this is what I came up with and yes....it doesn't work.

 

In my Index.js file I have the following, the addition is the "background = function(evt) "

if (HeartRateSensor) {
const hrm = new HeartRateSensor({ frequency: 1 });
hrm.addEventListener("reading", () => {
hrmData.text = `HR: ${hrm.heartRate}`;
});
sensors.push(hrm);
hrm.start();
} else {
hrmLabel.style.display = "none";
hrmData.style.display = "none";
}

background = function(evt) {
if (hrm.heartRate < 84){
show = "BG1";
} else if (hrm.heartRate > 84){
show = "BG2";
}
}

 

Then in the Index.view file I have:

<svg class="background">
<svg id="BG1" display="inline">
<image href="img1.png" />
<text id="myclock"></text>
<text id="myDate" />
<text id="hrm-data" class="sensor-data"></text>
</svg>

<svg id="BG2" display="inline">
<image href="img2.png" />
<text id="myclock"></text>
<text id="myDate" />
<text id="hrm-data" class="sensor-data"></text>
</svg>
</svg>

I was figuring based on the if statement in index.js it would switch which SVG portion to view. but to no avail. 

 

If there is an easier way what is the base code and in which files do I put what?

Best Answer
0 Votes
10 REPLIES 10

Try something like this:

 

if (HeartRateSensor) {
const hrm = new HeartRateSensor({ frequency: 1 });
hrm.addEventListener("reading", () => {
hrmData.text = `HR: ${hrm.heartRate}`;

if (hrm.heartRate < 84){

    BG2.style.display = 'none';

    BG1.style.display = 'inline';


} else if (hrm.heartRate > 84){
    BG2.style.display = 'inline';

    BG1.style.display = 'none';
}


});
sensors.push(hrm);
hrm.start();
} else {
hrmLabel.style.display = "none";
hrmData.style.display = "none";
}



 

 

Use BG.style.display = 'inline' or 'none'.

 

Also I got rid of background = function(evt) {, and I moved the if statement into the function where the heart rate is being read. 

 

Hope it helps!

Best Answer

I added it, but it wants me to define the bg1 and bg2. also what do I do in the image.view file? I downloaded it and made it sharable via google drive if you want to take a look. 

https://drive.google.com/file/d/1SimQS2EHIu04msgEmcYM0zXUBekF69hH/view?usp=sharing

Best Answer
0 Votes

I will take a look at this tomorrow. 

Best Answer

Ok, so in the index.view file, you can leave it as it is. Everything looked fine there. But it is wanting you to define them because you haven't declared them as variables yet. So at the top of your code, not in any functions, put these two lines.

 

let BG1 = document.getElementById('BG1');

let BG2 = document.getElementById('BG2');

 

the word "let' is just making a variable, and then we name the variable with BG1 or BG2. Then the document.getElementById is a javascript function that can take something that you have made in the index.view file and let you modify it in javascript. So we need to tell it what ID the object that we want has. That is what is in parenthesis. <svg id="BG2" display="inline"> So in this line of code, the id of this object is BG2, so we name the variable that, and also you put that in the parenthesis. 

 

I hope that helps you understand. I know that it took me a few months for it to make sense.

Best Answer
0 Votes

Awesome that worked. but now when the HRM is greater than 84, the BG2 pops up, but the Clock/Date/HRM disappears. like it's putting the BG2 as an overlay instead of a BG. Im thinking is due to my image.view file. Screenshots below, and my image.view file in the code box below.

*Side note, I know the BG2 image is blurry, I will be adding a better one soon, just using for testing.

Before 84HRM
https://drive.google.com/file/d/1aCo1uSrWEKwO6Tm3GU-jZBn-DrIBQ4IW/view?usp=sharing

After 84HRM
https://drive.google.com/file/d/1zVqJ9VC-C-J18kOPwmfO5Rx4hDu_JA1u/view?usp=sharing

 

<svg class="background">
  
    <svg id="BG1">
        <image href="BG1.png" />
        <text id="myclock"></text>
        <text id="myDate" />
        <text id="hrm-data" class="sensor-data"></text>
    </svg>

    <svg id="BG2">
        <image href="BG2.png" />
        <text id="myclock"></text>
        <text id="myDate" />
        <text id="hrm-data" class="sensor-data"></text>
    </svg>
  
</svg>

 

Best Answer
import clock from "clock";
import document from "document";
import { preferences } from "user-settings";
import * as util from "../common/utils";
import { display } from "display";
import { HeartRateSensor } from "heart-rate";

const myclock = document.getElementById("myclock");
const hrmData = document.getElementById("hrm-data");
const myDate = document.getElementById("myDate");
const sensors = [];

clock.granularity = "minutes";
clock.ontick = (evt) => {
  let today = evt.date;
  let hours = today.getHours();
  let monthnum = today.getMonth();
  let day = today.getDate();
  if (preferences.clockDisplay === "12h") {
    // 12h format
    hours = hours % 12 || 12;
  } else {
    // 24h format
    hours = util.zeroPad(hours);
  }
  let mins = util.zeroPad(today.getMinutes());
  myclock.text = `${hours}:${mins}`;
  
  var month = new Array();
  month[0] = "01";
  month[1] = "02";
  month[2] = "03";
  month[3] = "04";
  month[4] = "05";
  month[5] = "06";  
  month[6] = "07";
  month[7] = "08";
  month[8] = "09";
  month[9] = "10";
  month[10] = "11";
  month[11] = "12";
  
  let monthname = month[monthnum];
  
  myDate.text = `${monthname}-${day}`;

}

let BG1 = document.getElementById('BG1');
let BG2 = document.getElementById('BG2');

if (HeartRateSensor) {
const hrm = new HeartRateSensor({ frequency: 1 });
hrm.addEventListener("reading", () => {
hrmData.text = `HR: ${hrm.heartRate}`;

if (hrm.heartRate < 84){
    BG2.style.display = 'none';
    BG1.style.display = 'inline';

} else if (hrm.heartRate > 84){
    BG2.style.display = 'inline';
    BG1.style.display = 'none';
}


});
sensors.push(hrm);
hrm.start();
} else {
hrmLabel.style.display = "none";
hrmData.style.display = "none";
}

display.addEventListener("change", () => {
  // Automatically stop all sensors when the screen is off to conserve battery
  display.on ? sensors.map(sensor => sensor.start()) : sensors.map(sensor => sensor.stop());
});
Best Answer
0 Votes

Also for the date. is there an easier way to do the leading zero in the month and day? 

Best Answer

Ok, I think I will need to restructure your index.view file. 

<svg class="background">
<image id = 'BG1' href="BG1.png" />

<image id = 'BG2' href="BG2.png" />
<text id="myclock"></text>
<text id="myDate" />
<text id="hrm-data" class="sensor-data"></text>
</svg>

 

 

 

The reason it wasn't working (I hope 😉) is because you were giving the clock, data, and heartrate labels the same id twice. So I cut the svg in half, but redid it so it should work this time. 

 

About getting the month easier: You seem to be doing it the same way that I do. It is fine.

Best Answer
0 Votes

Awesome, got it all to work.

Updated the background images. and it works great until I ran into a bug.

It seems when I go to an app on the watch, or Alexa, the background image will just disappear completely, and unless I swipe around a lot or reset it the background image will not come back.

 

Here is the full build:

https://drive.google.com/file/d/16hQlXlSkDSXw4OiCXYnWdjC6VRBzZU32/view?usp=sharing

Index.js

import clock from "clock";
import document from "document";
import { preferences } from "user-settings";
import * as util from "../common/utils";
import { display } from "display";
import { HeartRateSensor } from "heart-rate";

const myClock = document.getElementById("myClock");
const hrmData = document.getElementById("hrm-data");
const myDate = document.getElementById("myDate");
const sensors = [];

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

clock.granularity = "minutes";
clock.ontick = (evt) => {
  let today = evt.date;
  let dayName = days[today.getDay()];
  let hours = today.getHours();
  let month = util.zeroPad(today.getMonth() + 1);
  let monthName = months[today.getMonth()];
  let dayNumber = util.zeroPad(today.getDate());
  if (preferences.clockDisplay === "12h") {
    // 12h format
    hours = hours % 12 || 12;
  } else {
    // 24h format
    hours = util.zeroPad(hours);
  }
  let mins = util.zeroPad(today.getMinutes());
  myClock.text = `${hours}:${mins}`;
  myDate.text = `${dayName}, ${monthName}-${dayNumber}`;
}

let BG1 = document.getElementById('BG1');
let BG2 = document.getElementById('BG2');

if (HeartRateSensor) {
const hrm = new HeartRateSensor({ frequency: 1 });
hrm.addEventListener("reading", () => {
hrmData.text = `${hrm.heartRate}`;
  
if (hrm.heartRate <= 100){
    BG2.style.display = 'none';
    BG1.style.display = 'inline';

} else if (hrm.heartRate > 100){
    BG2.style.display = 'inline';
    BG1.style.display = 'none';
}

});
sensors.push(hrm);
hrm.start();
} else {
hrmLabel.style.display = "none";
hrmData.style.display = "none";
}

display.addEventListener("change", () => {
  // Automatically stop all sensors when the screen is off to conserve battery
  display.on ? sensors.map(sensor => sensor.start()) : sensors.map(sensor => sensor.stop());
});

 

Common > Utils.js

// Add zero in front of numbers < 10
export function zeroPad(i) {
  if (i < 10) {
    i = "0" + i;
  }
  return i;
}


Resources > Index.view

<svg class="background">
  
  <svg>
    <image id = 'BG1' href="AllioredBanners.png" />
    <image id = 'BG2' href="WarMode.png" />
    <text id="myClock"></text>
    <text id="myDate"></text>
    <text id="hrm-data" class="sensor-data"></text>
   </svg>

</svg>


 Resources > Style.css

#myDate {
  font-size: 35;
  font-family: System-Bold;
  text-length: 32;
  text-anchor: middle;
  x: 130;
  y: 210;
  fill: white;
}

#myClock {
  font-size: 40;
  font-family: System-Bold;
  text-length: 32;
  text-anchor: middle;
  x: 180;
  y: 103;
  fill: white;
}

#hrm-data {
  font-size: 20;
  font-family: System-Bold;
  text-length: 32;
  text-anchor: middle;
  x: 262;
  y: 285;
  fill: white;
}

 

Best Answer
0 Votes

That is strange. I would maybe try setting image 1 to inline and image 2 to none outside of the function as well as in the function. So here is the index.js how I would suggest:

 

import clock from "clock";
import document from "document";
import { preferences } from "user-settings";
import * as util from "../common/utils";
import { display } from "display";
import { HeartRateSensor } from "heart-rate";

const myClock = document.getElementById("myClock");
const hrmData = document.getElementById("hrm-data");
const myDate = document.getElementById("myDate");
const sensors = [];

let days = ["Sun", "Mon", "Tue", "Wen", "Thu", "Fri", "Sat"];
let months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
//THE TWO LINES BELOW THIS ARE WHAT I ADDED

BG2.style.display = 'none';
BG1.style.display = 'inline';


clock.granularity = "minutes";
clock.ontick = (evt) => {
  let today = evt.date;
  let dayName = days[today.getDay()];
  let hours = today.getHours();
  let month = util.zeroPad(today.getMonth() + 1);
  let monthName = months[today.getMonth()];
  let dayNumber = util.zeroPad(today.getDate());
  if (preferences.clockDisplay === "12h") {
    // 12h format
    hours = hours % 12 || 12;
  } else {
    // 24h format
    hours = util.zeroPad(hours);
  }
  let mins = util.zeroPad(today.getMinutes());
  myClock.text = `${hours}:${mins}`;
  myDate.text = `${dayName}, ${monthName}-${dayNumber}`;
}

let BG1 = document.getElementById('BG1');
let BG2 = document.getElementById('BG2');

if (HeartRateSensor) {
const hrm = new HeartRateSensor({ frequency: 1 });
hrm.addEventListener("reading", () => {
hrmData.text = `${hrm.heartRate}`;
  
if (hrm.heartRate <= 100){
    BG2.style.display = 'none';
    BG1.style.display = 'inline';

} else if (hrm.heartRate > 100){
    BG2.style.display = 'inline';
    BG1.style.display = 'none';
}

});
sensors.push(hrm);
hrm.start();
} else {
hrmLabel.style.display = "none";
hrmData.style.display = "none";
}

display.addEventListener("change", () => {
  // Automatically stop all sensors when the screen is off to conserve battery
  display.on ? sensors.map(sensor => sensor.start()) : sensors.map(sensor => sensor.stop());
});

 

Best Answer
0 Votes