A Comprehensive Guide To Prototyping VR in Framer

Sophie Rahier
Framer
Published in
7 min readFeb 22, 2017

Prototyping for VR was a key aspect of mine and Ben’s latest week-long project so here’s a summary of a couple things we picked up while prototyping using Sketch and Framer.

Having little experience with Framer and even less with VR prototyping, this article is aimed at those that might feel like these areas form the basis of a new alien race. Using Framer allowed for quick and easy iterations, and didn’t require any 3D renders. The following method was fairly straightforward and flexible, so we hope it’ll come in handy to anyone starting out with VR and/or Framer.

The example we’ll be referring to can be found here, and aims to create a hover animation within a VR environment:

1. Set up

Because of the distortion that occurs when translating design elements or images into VR, using the right grid is essential. KickPush published a Sketch grid template and the couple steps to preview Sketch designed interfaces using the GoPro VR Player. We suggest testing out more complex UIs this way before going onto prototyping.

If you have an oculus at hand, setting it up using the GoPro VR Player will be just like setting up a new monitor.

2. Planning interactions

Something we find particularly useful to stay on track of what we’re doing is writing down every interaction we want to prototype as plain sentences. Mentally go through your user’s journey, noting down animations taking place and what action causes them. Consider this your to-do list when prototyping.

For example:

- Hover over square, square gets bigger
- Hover off the square, square goes back to original size

This is generally good Framer practice, and Charlie Deets’ article which explains prototyping workflows in more detail should definitely be on your reading list if you’re starting with Framer.

3. VR component

The Framer VR Component is the key to an out-of-this-world VR prototype.

Once downloaded, make sure you place a copy of the component in your modules folder of your Framer file.

You then want to call in the component and map the cube-like environment it creates using:

# Call VRComponent module
{VRComponent, VRLayer} = require "VRComponent"

# Create a new VRComponent, map images as environment
vr = new VRComponent
front: "images/front.png"
left: "images/left.png"
right: "images/right.png"
back: "images/back.png"
top: "images/top.png"
bottom: "images/bottom.png"

You can replace the background images (which default to solid colours) by placing images in the images folder of your Framer project folder. You might notice that the GoPro viewer works with equirectangular images while the component requires cubemaps. We used this converter to create cubemaps from equirectangular images.

As well as setting up the VRComponent, we advise to set up a reticle in order to get a better sense of positioning and movement. Feel free to style as desired, here is a fairly standard one:

#Reticle
reticle = new VRLayer
width: 20
height: 20
borderRadius: 100
backgroundColor: "transparent"
borderWidth: 4
reticle.center()

Once that’s set up, you can almost go about creating layers and interactions the same as you would in other Framer prototypes. However you must create layers as VR layers and for each layer created, you must project it as a VR layer using:

#Create a new VR layer
layerA = new VRLayer
# Project layerA as VR layer
vr.projectLayer(layerA)

Next up, hover effects; these require an understanding of heading and elevation settings.

4. Understanding heading and elevation

The VR Component uses a spherical coordinates system, established in terms of heading and elevation, meaning:

heading having a polar angle from 0° to 360° where north is 0°
elevation having a zenith angle from -90° to 90° where horizon is 0°

Changing heading from 0 to 180 will move objects to the right side of the sphere, while when positioned between 180 and 360, objects will be on the left side. Similarly, when the elevation is positive objects will be moved up, and down when it is negative.

The user’s starting point is placed on 0° heading and 0° elevation. From there you can work on the placement of layers by directly using the heading and elevation properties:

#Setting up layer properties
layerA = new VRLayer
elevation: 5
heading: 0

In this example, that translates to LayerA being centred horizontally and up 5°. The coordinates will always relate to the centre of the layer.

You can use these two lines to print the heading and elevation of a layer:

print layerA.heading
print layerA.elevation

This comes in handy when starting to work on hover effects, as they will be dependent on heading and elevation settings. When prototyping VR, a hover is not about the reticle going over other layers, but about what elevation and heading the viewer, or reticle, is directed at.

For hover animations, we therefore define the zone in which the layer is positioned, and set up an action for when the heading and elevation fall in that zone.

The size of the zone depends on the size of the layer. In our example, we set up a 6° elevation by 6° heading zone, which covers the 100x100 layerA. Because layerA has an elevation of 5°, this means the zone will be set between 2° and 8°, or 3° away from 5° on both top and bottom.

The hover animation zone for layerA, in blue, is the combination of set elevation and heading ranges.

Practically, what that means is that we have to set the animation for layerA when the orientation changes and lands within that zone. Once the orientation is not in that zone, layerA should animate back to normal.

To start, all this should happen in the event of an orientation change which we set up as:

#Set an event for orientation change
vr.on Events.OrientationDidChange, (data) ->
heading = data.heading
elevation = data.elevation
tilt = data.tilt

Under this event, we then start adding the heading and elevation conditions that need to be met in order for the animation to take place:

#Set an event for orientation change
vr.on Events.OrientationDidChange, (data) ->
heading = data.heading
elevation = data.elevation
tilt = data.tilt
#Define zone for layerA hover animation
if 2 < elevation < 8 && 0 < heading < 3 || 2 < elevation < 8 && 357 < heading < 360
layerA.animate
scale: 1.3
options:
time: 0.63
curve: Spring(damping: 0.55)
#layerA animates back to normal when not in defined zone
else
layerA.animate
scale: 1
options:
time: 0.63
curve: Spring(damping: 0.55)

In this case, the heading being set as 0° means that two heading zones need to be defined, one for each half of the layer on each side of the zero. In other cases where the layer doesn’t overlap the zero heading line, only the first half of the if statement would be needed.

Side note for code beginners: in this if/else statement, the && and || mean “logical and” and “logical or”. The “logical and” makes it so that the animation only takes place when both conditions are met. The “logical or” makes it so that the animation will take place when one of the conditions is met.

5. Adding audio

Adding audio to VR prototypes requires a quick download and set up of the audio component. Similarly to the VR Component, place a copy of the audio component in your modules folder. You will also need to create a new audio folder in your framer project folder, in which you can place your audio files.

You can then call in the audio component, just like the VR one earlier:

# Call AudioPlayer module
{AudioPlayer} = require "audio"

Then set up the audio file as an audio layer:

#rename audio file
soundA = new AudioPlayer audio: "audio/soundA.mp3"

This audio file can then be played on events:

#Audio is played when layerA is clicked
layerA.onClick ->
soundA.player.play()

In our example, we added it as part of the hover animation.

To conclude, I’d like to encourage anyone with an interest in designing for VR to give this a go. We’ll also be more than happy to share any resources we came across when starting with both Framer or VR, so let us know if you’re interested.

Thanks for reading, and catch us on twitter!

Sophie & Ben

--

--

Sophie Rahier
Framer
Writer for

Product designer at Planes, otherwise mostly outdoors. I love cycling, prototyping, and wonky pottery.