Swoosh! Adding transitions to Alexa.NET.APL documents

A little while ago the Alexa team updated the Alexa Presentation Layer from v1 to v1.1 and with it brought a large range of updates to their components, commands and capabilities.

Now APL already allowed you to make some pretty stunning visual accompaniments. but the new version goes a step beyond with the new VectorGraphic component, transformations and the AnimateItem Command and the latest version of Alexa.NET.APL provides access to that functionality to .NET developers writing APL enabled skills.

Now I happily admit I have absolutely no idea how to make things look cool and interesting, but I’ve been aimed in the direction of someone who can, when yesterday I received a tweet pointing me to the APL Transitions repo of arjun-g who has created a JSON file full to the brim of transition style animations so you can bounce, slide, and swoop your displays into place.

So this article is going to show you how to add and use one of these transitions – the Jack In The Box. For ease of creation I’m going to just add this transition to a simple text control, but of course this could be your own graphic or an image, whatever gave that compelling visual output.

The skill we’re going to use for this is purely a wrapper around the APL work, so the lambda function I’m using is pretty straight forward – no matter what you do or say, it’s going to give you the APL transition with a small response

public SkillResponse FunctionHandler(APLSkillRequest input, ILambdaContext context)
{
    var response = ResponseBuilder.Tell("Here's your transition");
    response.Response.Directives.Add(new RenderDocumentDirective
    {
        Document = GetDocument()
    });
    return response;
}

The rest of the article is going to be about what’s inside the GetDocument method and how you can build it up to generate something like this

Start off – the basic document.

Display support for v1.1 isn’t guaranteed, so the easiest way to get this going is to start off with an APL document that will just show the text – then add the transition information to it. As there’s not a lot to it, I’m going to write it in C# but if it were more complicated you could always save this as a json file and load in the APLDocument from there.

private APLDocument GetDocument()
{
    return new APLDocument(APLDocumentVersion.V1_1)
    {
        MainTemplate = new Layout(
            new Container
            {
                Height = new AbsoluteDimension(100,"vh"),
                Width = new AbsoluteDimension(100,"vw"),
                AlignItems = "center",
                Direction = "column",
                JustifyContent = "center",
                Items = new List<APLComponent>
                {
                    new Text("APL Transition!")
                    {
                        FontSize = 70,
                        Height = new AbsoluteDimension(15,"vh"),
                        Width = new AbsoluteDimension(47,"vw")
                    }
                }
            }).AsMain()
    };
}

So the main template is a container with a text component inside. I’ve written the dimensions of the objects longhand just to see what types are involved but the dimension classes will handle “100vh” etc. just as well

Add the boing! User-Defined Command

So now we have the text component we’re going to add the transition to, we need to add the magic – the custom command that contains all the various animations. There are lots of commands in APL, and user-defined commands allow us to combine a number of these commands in order, as well as the use of custom parameters that can be filled in when the command is called.

A custom command is added to the “commands” section of the main APL document as a key value pair – the key being the name you want to give this new command.

Quick Note: I had an annoying blip where my skill would just not work after adding this – then remembered APL has to be switched on in the interfaces section of the Alexa designer. Don’t forget this otherwise you get the dreaded “there was a problem with the requested skills response”

As arjun-g states in his repo, you can copy his entire json file to a public location and run it as an import, getting all the commands – this is absolutely the right way to do it if you plan to use a lot of the transitions as the APL document can cache the content. As I’m using a single transition – I’m going to place just the JackInTheBox command into its own json file and add it directly (thus showing the pieces that put together). The command looks like this:

{
            "parameters": [
                "duration",
                "delay"
            ],
            "commands": [
                {
                    "type": "AnimateItem",
                    "duration": "${duration * 0.5}",
                    "delay": "${delay || 0}",
                    "value": [
                        {
                            "property": "opacity",
                            "from": 0,
                            "to": 0.5
                        },
                        {
                            "property": "transform",
                            "from": [
                                {
                                    "scaleX": 0.1,
                                    "scaleY": 0.1
                                },
                                {
                                    "rotate": 30
                                }
                            ],
                            "to": [
                                {
                                    "scaleX": 0.45,
                                    "scaleY": 0.45
                                },
                                {
                                    "rotate": -10
                                }
                            ]
                        }
                    ]
                },
                {
                    "type": "AnimateItem",
                    "duration": "${duration * 0.2}",
                    "value": [
                        {
                            "property": "opacity",
                            "from": 0.5,
                            "to": 0.7
                        },
                        {
                            "property": "transform",
                            "from": [
                                {
                                    "scaleX": 0.45,
                                    "scaleY": 0.45
                                },
                                {
                                    "rotate": -10
                                }
                            ],
                            "to": [
                                {
                                    "scaleX": 0.63,
                                    "scaleY": 0.63
                                },
                                {
                                    "rotate": 3
                                }
                            ]
                        }
                    ]
                },
                {
                    "type": "AnimateItem",
                    "duration": "${duration * 0.3}",
                    "value": [
                        {
                            "property": "opacity",
                            "from": 0.7,
                            "to": 1
                        },
                        {
                            "property": "transform",
                            "from": [
                                {
                                    "scaleX": 0.63,
                                    "scaleY": 0.63
                                },
                                {
                                    "rotate": 3
                                }
                            ],
                            "to": [
                                {
                                    "scaleX": 1,
                                    "scaleY": 1
                                },
                                {
                                    "rotate": 0
                                }
                            ]
                        }
                    ]
                }
            ]
        }

So I import that json from a file (ensuring content is set to Copy If Newer) as a CommandDefinition object and then add the definition to the APL Document.

var definition = JsonConvert.DeserializeObject<CommandDefinition>(System.IO.File.ReadAllText("JackInTheBox.json"));

return new APLDocument(APLDocumentVersion.V1_1)
{
    Commands = new Dictionary<string, CommandDefinition>
    {
        {"JackInTheBox",definition }
    },
    MainTemplate = …

Put the two together

Okay. So we have the command that’s going to do the animations, and we have a text component. So how does one fit to the other? Well this involves two pieces

The first is the Custom Command – which allows us to call a command with a custom name and add any required parameters.

The second is the OnMount section of APL Components. Rendered as onMount it’s been added as part of APL v1.1 (it’s also on the document) and it’s an array of commands that will run when the document loads the component – regardless of the components state (like, even if its not visible).

So we’re going to add the custom command to the onMount section of the text object, and that will give us the desired transition.

new Text("APL Transition!")
{
    FontSize = 70,
    Height = new AbsoluteDimension(15,"vh"),
    Width = new AbsoluteDimension(47,"vw"),
    OnMount = new List<APLCommand>
    {
        new CustomCommand("JackInTheBox")
        {
            ParameterValues = new Dictionary<string, object>
            {
                {"duration",2000 }
            }
        }
    }
}

And that’s it – the custom command is executed when you invoke the skill, which causes the text to swing its way toward the user. I thought a duration of 2000 allowed even a small video to be able to pick up on what was happening. If your layouts are in json files that’s not a problem – any command name not recognised in the Alexa.NET.APL list appears as a custom command, so they still work if you add them to existing documents.

Rinse, Repeat, More awesome!

Now I’m okay saying that the reason I picked JackInTheBox is because it was small enough that it could be added to the article directly, but still have a very clear result on video – but the work that’s been done on these transitions is fantastic. There’s every slide and zoom you can imagine and although no-one wants an Alexa skill like a powerpoint presentation, these are really powerful transitions that can be added for some great results, and I’m looking at trying to mix transition with the sound library to make some real impact.

It’s only a simple example – but I added the APL Transition project to the Alexa.NET.Samples repo for developers to take a look at. It’s in no way ready to drop straight in – the dimensions I’ve used are absolute as I was running it next to one of my larger devices. This would have to have been tweaked for a Show 5 or Spot (or I should have used one of the new responsive templates!)