The FocusEngine module allows you to simulate the grid focus behavior seen on streaming media players like Apple TV and Roku. Use the keyboard, RemoteLayer, or another mechanism to direct focus around your prototype’s canvas.
Once initialized, any visible layer can be brought into focus, even if it’s off screen. This permits the activation of off-screen menus. Visual appearance of focused elements can be customized.
$ cd /your/framer/project
$ npm i @blackpixel/framer-focusengine
Copy or save the FocusEngine.coffee
file into your project's modules
folder.
In your Framer project add the following:
fe = require "FocusEngine"
fe.focusStyle.scale = <number>
fe.focusStyle.shadowX = <number>
fe.focusStyle.shadowY = <number>
fe.focusStyle.shadowColor = <string> (hex or rgba)
fe.focusStyle.shadowBlur = <number>
fe.focusStyle.shadowSpread = <number>
fe.unfocusStyle.shadowX = <number>
fe.unfocusStyle.shadowY = <number>
fe.unfocusStyle.shadowColor = <string> (hex or rgba)
fe.unfocusStyle.shadowBlur = <number>
fe.unfocusStyle.shadowSpread = <number>
(Unfocused scale is always assumed to be the layer’s original scale. This need not be 1. You may get better visual results by drawing your layer slightly larger than needed and setting its initial scale to something less than 1.)
fe.time = <number>
myFocusableLayers = [layerA, layerB, layerC]
fe.initialize(myFocusableLayers)
fe.addLayer(layerD)
document.addEventListener "keydown", (event) ->
keyCode = event.which
switch keyCode
when 13 then fe.changeFocus("select")
when 37 then fe.changeFocus("left")
when 38 then fe.changeFocus("up")
when 39 then fe.changeFocus("right")
when 40 then fe.changeFocus("down")
else null
fe.placeFocus(layerA)
fe.focusPrevious()
(Note that focus cannot be placed on a layer whose visibility, or whose ancestor’s visibility, is false. You may need to delay calling focusPrevious()
until the FlowComponent’s transition is ended, perhaps by using .onTransitionEnd
.)
layerA.on "focus", ->
layerA.on "unfocus", ->
layerA.on "selected", ->
Integration with RemoteLayer
RemoteLayer = require "RemoteLayer"
myRemote = new RemoteLayer
clickAction: -> fe.changeFocus("select")
swipeUpAction: -> fe.changeFocus("up")
swipeDownAction: -> fe.changeFocus("down")
swipeLeftAction: -> fe.changeFocus("left")
swipeRightAction: -> fe.changeFocus("right")
fe.debug = true
Attempting to perform a placeFocus()
call as FocusEngine is changing its own focus will fail. (The call is discarded.) If you need to override FocusEngine's logic, Use a slight delay to ensure the call is respected.
layerA.on "unfocus", ->
Utils.delay 0.1, ->
fe.placeFocus(layerB)
Website: blackpixel.com · GitHub: @bpxl-labs · Twitter: @blackpixel · Medium: @bpxl-craft