Forum Discussion

Jonathan_Hill's avatar
Jonathan_Hill
Super Hero
10 months ago

FREE: Dial-driven map navigation activity

Hello!

For the upcoming E-Learning Heroes Challenge #453 on Using Dials I have created this dial-driven map navigation activity.


This demo contains three 'picture as dial' controls:

-  To start the course, you need to turn the compass so its edge connects Point A and Point B

- Then, you have to turn the compass housing to the correct orientation to get your bearing

- While you're doing this, the compass needle - which is also a dial locked in a disabled state - will oscillate slightly

You can play the demo here.


Dial as drag and drop

I created the compass in PowerPoint and exported it as a large, hi-res PNG image. I  doubled its height using Pixlr and used Storyline's Convert to Dial feature to create a custom dial.





This dial has four states, which are triggered by changes to the associated Compass_Base variable:



Changes to the same variable also trigger events within the demo, effectively making this a 'drag and drop' activity, but with a fixed axis. Unlike a 'drag and drop' it is accessible via the keyboard.

Dial in both directions

In its default setting, a dial can only make one complete turn, which is limiting when you are trying to mimic a real-life object that can turn in both directions. To overcome this, the second dial in my demo has a 1440° rotation and its starting position is 687° - about halfway, just left of centre - to match the appearance of the compass base.


This dial can turn clockwise or anti-clockwise for two rotations in each direction before coming to a stop. But that does make it quite tricky to use its position to calculate a bearing, as positions 0, 360, 720, 1080 and 1440 all point north.

To compensate for this, I asked ChatGPT to write some custom Javascript for me:

// Function to calculate the heading
function calculateHeading(compass) {
    // Calculate the heading with special handling for multiples of 360
    var heading = 360 - (compass % 360);

    // Adjust heading for cases where it's 360 but should be 0
    if (heading === 360) {
        heading = 0;
    }

    return heading;
}

// Function to adjust heading to 0 whenever it becomes 360
function adjustHeading(heading) {
    if (heading === 360) {
        heading = 0;
    }
    return heading;
}

// Get the value of the Storyline variable Compass and calculate Heading
var Compass = player.GetVar("Compass"); // Assuming "Compass" is the name of your Storyline variable
var Heading = calculateHeading(Compass);

// Adjust Heading to 0 whenever it becomes 360
Heading = adjustHeading(Heading);

// Set the Storyline variable "Heading" to the adjusted value
player.SetVar("Heading", Heading); // Assuming "Heading" is the name of your Storyline variable


And this is the result:

With this code, I can tell if the compass housing is upside down even if it has been turned more than once.  Pointing the compass housing south is a common mistake for novice navigators, but my demo will spot this and provide correction.

Dial as animation

The third dial is purely for decoration. During the second part of the activity, I wanted the compass needle to move gently as you were turning the compass housing - just as it does in real life - and also to act as a 'plausible distractor'. Another common mistake when taking a bearing on a map is to set the compass housing to the position of the compass needle, not the lines on the map.

This dial has a more limited rotation and range:


I used ChatGPT again to create some custom Javascript that makes the compass needle oscillate each time the compass housing is turned:

// Function to randomly adjust Compass_Needle between 8 and 15, returning to 11 within 0.50 seconds
function adjustCompassNeedle() {
    var randomValue = Math.floor(Math.random() * 8) + 8; // Generates a random number between 8 and 15
    player.SetVar("Compass_Needle", randomValue);

    setTimeout(function() {
        player.SetVar("Compass_Needle", 11); // Return Compass_Needle to 11 after 0.50 seconds
    }, 500);
}

// Variable to store the previous value of Compass
var previousCompassValue;

// Function to handle changes in the Compass variable
function handleCompassChange() {
    var currentCompassValue = player.GetVar("Compass"); // Get the current value of the Compass variable

    // Check if the Compass value has changed
    if (currentCompassValue !== previousCompassValue) {
        // Call the function to adjust Compass_Needle
        adjustCompassNeedle();
        // Update the previous value of Compass
        previousCompassValue = currentCompassValue;
    }
}


And here's a close-up of the result:


There's quite a bit more going on in this demo - notably some Jump To Time powered animations and controlling a Zoom Panel with Pause/Play Timeline triggers - but in this write-up I wanted to focus on my use of dials, as that's the topic of this week's Challenge.

So please dial me up if you have any more questions!