SVGs are fun. Scalable Vector Graphics are really just fancy XML files. And this means we can use JavaScript to manipulate them. Which opens up a lot of possibilities.
SVGs are fun. Scalable Vector Graphics are really just fancy XML files. And this means we can use JavaScript to manipulate them. Which opens up a lot of possibilities.
Before we get too far into this, take a moment to play with the demo:
I was looking for a way to create a rating system that allowed learners to rate slides on a scale of 1-5. I am sure there are ways to build this within Captivate but I have this weird problem that makes me seek out alternative methods. And these usually involve JavaScript.
What I wanted was a solution that would allow learners to click on a set of stars to indicate their opinion. That would then be aggregated with all the other learners’ selection. But I also wanted a smooth animation during the selection and when the average was updated.
My solution ended up using an SVG file (with a mask), Captivate variables, and some JavaScript.
To begin a created an SVG file that contains two boxes, black and gold. It also has a ‘mask’ that consists of five star shaped paths.
Then I dropped my SVG into Captivate and created a couple of variables to track and display the learner’s rating and the average rating.
Now it’s time for some JavaScript! I tend to solve these types of puzzles in stages. First I wanted to make sure that I could find the SVG within Captivate and resize the black box (under the mask).
var obj = $("#stars_democ_object")[0];
var svgdoc = obj.getSVGDocument();
var box = svgdoc.getElementById("box");
var rating = window.cpAPIInterface.getVariableValue("Text_Entry_Box_1");
$(box).animate({ width: rating * 20 + "%" });
Let’s break that down:
- Find the HTML element that holds our SVG.
- Get the SVG document
- Get the black box inside our SVG
- Get the rating the learner entered.
- Animate the width of the black box to the percentage indicated by the learner.
That works pretty well! Now let’s add some mouse over animations.
var user_stars_obj = $("#stars_user_ratingc_object")[0];
var user_stars_svgdoc = user_stars_obj.getSVGDocument();
var user_stars_box = user_stars_svgdoc.getElementById("box");
var ratio = 0;
$("#stars_user_rating").mousemove(function(event) {
ratio = Math.round((event.offsetX / $("#stars_user_rating").width()) * 100);
window.cpAPIInterface.setVariableValue("var_user_rating", ratio);
user_stars_box.setAttribute("width", ratio + "%");
});
$("#stars_user_rating").mousedown(function() {
$("#stars_user_rating").off("mousemove");
$("#stars_user_rating").off("mousedown");
});
This starts the same as the previous code. We get all our data and elements.
Then we add two listeners to the DIV element (that contains the SVG). One to listen for the mouse moving over it. The other listens for mouse clicks on it.
When the mouse moves over the SVG we get it’s position and set our black box’s width to match it. Note I did not bother to animate this since it follows the mouse movement. We also push the value back into our Captivate variable so we can display it.
I will spare you the finished code. But you can grab it here.
Watch the video to learn more about the final solution.