02-21-2018 09:39 - edited 02-21-2018 09:49
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

02-21-2018 09:39 - edited 02-21-2018 09:49
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
I am wondering if it is possible to change the duration of an animation depending on heart rate. I have tried changing it using heartImage.animate.dur, but I get this error "Cannot set property 'dur' of undefined"
let heartImage = document.getElementById("heartImage"); myHeartRate.text = hrm.heartRate; var beats = String(60/hrm.hearRate); heartImage.animate.dur = beats;
<image id="heartImage" href="Heart.png" x="0" y="-1" width="100%" height="100%" class="foreground"> <animate attributeName="opacity" begin="load;activate" from="1" to="0" dur="1" final="restore" repeatCount="indefinite"/></image>

02-21-2018 11:09
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


02-21-2018 11:09
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
- Who Voted for this post?
I don't think it's possible in the current firmware, but it might be possible in a future update.
You could try:
<image id="heartImage" href="Heart.png" x="0" y="-1" width="100%" height="100%" class="foreground"> <animate id="anim" attributeName="opacity" begin="load;activate" from="1" to="0" dur="1" final="restore" repeatCount="indefinite"/></image>
let heartImage = document.getElementById("heartImage"); let anim = heartImage.getElementById("anim"); anim.dur = beats;
Or just animate yourself using Javascript.
heartImage.style.fillOpacity = 0.5;
04-17-2018 05:03 - edited 04-17-2018 05:05
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

04-17-2018 05:03 - edited 04-17-2018 05:05
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hello there,
I wanted to achieve the same thing, but since the duration cannot (yet) be set in Code, I decided to go for a solution whereby I control the timing of the animation's starting point.
<image id="heartImage" href="Heart.png" x="0" y="-1" width="100%" height="100%" class="foreground"> <animate id="anim" attributeName="opacity" begin="enable" from="1" to="0.5" dur="1" final="restore" repeatCount="1"/>
</image>
The Animation lasts 1 second and goes from opacity "1" to "0.5". But rather than continuously animate, I calculate the time when the animation starts (continuously). The animation starts at "enable". In Code, I make a function that executes the animation manually.
What it does do: pulse according to the heart-rate, since I restart the animation according to a timeout that is calculated using the heart-rate (1000ms * (60 / heart-rate)).
What it doesn't do: I cannot Control the Duration, wich is set to 1 second. So if the heart-rate is twice as fast (120), the animation will not actually get down to 0.5 opacity, but rather to 0.75.
Declarations/Imports:
import document from "document";
import { HeartRateSensor } from "heart-rate";
import { display } from "display";
let previousHeartRate = -1; // Remember the previous heart rate
let heartImage = document.getElementById("heartImage"); // Gets the Image element
let cancelAnimation = false; // To stop animating on Display off
Configure and start the HeartRateSensor:
// Start the heart rate monitor
let hrm = new HeartRateSensor();
hrm.onreading = function() {
let heartRate = hrm.heartRate;
updateHeartRate(heartRate);
}
hrm.start();
Cancel the animation when the display switches off, and start it again when it switches on:
// Add display listener that cancels the continuous animation
display.onchange = function() {
if (display.on) {
cancelAnimation = false;
animate();
}
else {
// Stop the current animation
cancelAnimation = true;
}
}
When the heart-rate is updated, this function is executed:
function updateHeartRate(heartRate) {
if (heartRate != previousHeartRate) {
cancelAnimation = true; // Stop the current Animation cycle
if (heartRate > 0) {
previousHeartRate = heartRate;
}
else {
previousHeartRate = -1;
}
if (display.on) {
cancelAnimation = false;
animate(); // Start animating
}
}
}
Here's the function that does the animation:
function animate() { if (display.on) { heartImage.animate("enable"); // Execute the animation
// Calculate the timeout (1000 is 1 second) let timeout = 1000 * (60 / previousHeartRate); if ( timeout < 0 ) { // In case the previousHeartRate is invalid timeout = 1000; }
// Only continue the animation if it has not been cancelled if (!cancelAnimation) {
// Animate after <timeout> in milliseconds (e.g. 120 = 1000 * (60 /120) = 500) setTimeout(function() {
// Execute the animation animate(); }, timeout); } }
}
so, the "cancelAnimation" variable allows me to Switch off the current Animation, since it animates continuously other wise. I only animate when the Display is on and I calculate the next execution time of the Animation using the heart rate.
I hope this helps, I've tried to make it easy to understand, but also build in some "safeguards" that Keep the animation from going on indefinately.
Regards,
JDT

07-03-2020 00:41
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

07-03-2020 00:41
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
While you still cannot change the "dur" attribute for the animation, you can change the "to" attribute. Interestingly, if you use negative numbers for the "to" attribute, then the animation will speed up. Setting the "to" attribute to -1 sped the animation up by two. So I mapped the BPM to a negative number with the base BPM as 60.
animate.to = map_number(bpm,60,120,0,-1);
function map_number(x,in_min,in_max, out_min, out_max){
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
Note: I am changing the animate.to within the setInterval function call because that is how I am getting the function repeatedly call.
}

07-13-2020 13:12
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

07-13-2020 13:12
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
I'm looking for a way to do similar myself.
Easiest way I could get an animation going the way I want was to make a small PNG of a ECG in the lower right of my screen and then cover it with a rectangle. I have a black background and the rectangle is black. I move the rectangle to the right (off the screen) and it looks like an active ECG. I would love to make it move faster depending on the heartbeat.
If this still isn't possible, I'm still happy with my animation effect.

07-14-2020 20:03
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

07-14-2020 20:03
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
@saaasaab wrote:While you still cannot change the "dur" attribute for the animation,...
I'm not sure which firmware update fixed the dur visibility, but you can absolutely set the dur value now.
Like other GUI attributes, although it is initialized in the gui as a string, it is set in JavaScript as a number.

07-15-2020 14:44 - edited 07-15-2020 15:15
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

07-15-2020 14:44 - edited 07-15-2020 15:15
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Actually your reply made me look closer at JonFitbit's answer.
This does work if you implement it correctly. But basically setting the id in the animation then calculating and setting the duration as anim.dur works great. anim.dur = (90.00/hrm.heartRate); works for my animation.
If anyone else needs something similar:
index.js
let anim = document.getElementById("heartrateAnim");
// When the value changes, update text
hrm.onreading = function() {
// Peek the current sensor values
hrtValue.text = hrm.heartRate || 0;
// Set animation duration
anim.dur = (90.00/hrm.heartRate);
// Stop monitoring the sensor
hrm.stop();
}
index.gui
<image href="heart.png" x="242" y="6" width="20" height="20" />
<image href="heart.png" x="240" y="4" width="24" height="24" >
<animate id="heartrateAnim" attributeName="opacity" from="0" to="1" dur="1" final="restore" repeatCount="indefinite" />
</image>

12-04-2020 00:35
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

12-04-2020 00:35
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
What SDK are you using? I'm trying this on SDK 4.2 since I have a Versa 2 but is not working.

