Roku Developer Program

Developers and content creators—a complete solution for growing an audience directly.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Level 7

Help me clear my canvas layers!

Hello,

I'm working on a channel that needs custom player controls, so I'm using an imageCanvas and a videoPlayer. I can paint the controls (png files) and they show up correctly; but I simply cannot get them to go away. They persist even after I sideload the channel! Here's the instantiation:

player = createObject("roVideoPlayer")
canvas = createObject("roImageCanvas")
port = createObject("roMessagePort")
canvas.setMessagePort(port)
player.setMessagePort(port)
player.setDestinationRect(canvas.getCanvasRect())

Then later, I go to put the controls on the screen (simplified here):

addButton: function (button_name)
url = invalid
if button_name = "pause"
url = "pkg:/assets/images/btn-pause.png"
else if button_name = "play"
url = "pkg:/assets/images/btn-play.png"
end if
if url = invalid
logger("warning", "unknown UI button " + button_name)
return invalid
end if

x1 = m.displaySize.w / 2 - 40
y1 = m.displaySize.h * 3 / 4 - 38

button = { TargetRect: { x: int(x1), y: int(y1), w: 80, h: 76 }, url: url }
m.canvas.setLayer(0, [button])
m.canvas.show()
end function

But there's no combination of clear(), sleep(), clearLayer() &c. that does anything. And as I said, even if I go into a different channel, and then reload my custom code again, the same canvas persists. What's going on? Do I need to use a different imageCanvas? Is there any way to control the z ordering of my canvases, other than lexically? I guess I could create and close new canvases every time I needed to paint the chrome?

EDIT: It's not simply the setLayer() that persists; I stop() the channel, and then in the debugger do an addButton(1, "foobar") -- and that button persists!

TIA.
0 Kudos
12 Replies
Roku Employee
Roku Employee

Re: Help me clear my canvas layers!

Try using a layer other than layer 0. Layer zero doesn't respond to the clear command as expected. Layer zero's weird behavior can also be used for some cool effects.

On another note, you might want to try using roScreen instead of ImageCanvas if you want a nice responsive User Interface.

- Joel
0 Kudos
Level 7

Re: Help me clear my canvas layers!

"RokuJoel" wrote:
Try using a layer other than layer 0. Layer zero doesn't respond to the clear command as expected. Layer zero's weird behavior can also be used for some cool effects.

On another note, you might want to try using roScreen instead of ImageCanvas if you want a nice responsive User Interface.

- Joel

OK, thanks. Now I'm using layers 2 and 3 (for different UI elements). But I still can't clear them. If 'canvas' is a member of the array:

m.canvas.clearLayer(m.buttonLayer)
m.canvas.setLayer(m.buttonLayer, {Color: "#000000FF"})
m.canvas.show()

... but the layer doesn't clear. Is there something simple I'm missing?
0 Kudos
Roku Employee
Roku Employee

Re: Help me clear my canvas layers!

You could try just using SetLayer:

canvas.SetLayer(3, {Color:"#FF000000", CompositionMode:"Source"})

to clear the layer.

ClearLayer seems to be inconsistent in its behavior.

- Joel
0 Kudos
Roku Employee
Roku Employee

Re: Help me clear my canvas layers!

In your OP you instantiate your roImageCanvas as canvas, then later you refer to it as m.canvas. Is it possible this is a scope issue, or that you have two different objects when you meant to only have one?
0 Kudos
Level 7

Re: Help me clear my canvas layers!

"RokuChris" wrote:
In your OP you instantiate your roImageCanvas as canvas, then later you refer to it as m.canvas. Is it possible this is a scope issue, or that you have two different objects when you meant to only have one?

I'm pretty sure they're the same, but I can only check lexically. Is there any programmatic way to tell which canvas I'm dealing with? An id or a hash value or something?
0 Kudos
Level 9

Re: Help me clear my canvas layers!

I've used the image canvas quite a bit, in a number of my channels, and I've never run into any issues with ClearLayer. I suspect it's definitely a referencing issue, and you're trying to clear the layer on a different canvas instance.
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
Level 7

Re: Help me clear my canvas layers!

"TheEndless" wrote:
I've used the image canvas quite a bit, in a number of my channels, and I've never run into any issues with ClearLayer. I suspect it's definitely a referencing issue, and you're trying to clear the layer on a different canvas instance.

I have no trouble ascribing this to user error. I just wish that I understood the environment a little better.
0 Kudos
Level 9

Re: Help me clear my canvas layers!

"jfb_mdialog" wrote:
"TheEndless" wrote:
I've used the image canvas quite a bit, in a number of my channels, and I've never run into any issues with ClearLayer. I suspect it's definitely a referencing issue, and you're trying to clear the layer on a different canvas instance.

I have no trouble ascribing this to user error. I just wish that I understood the environment a little better.

There's no way to identify which canvas instance you're referencing, so you'd need to track it in your code. Are you ever explicitly setting m.Canvas = canvas? If not, then they're definitely not the same instance.
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
Level 7

Re: Help me clear my canvas layers!

OK, so I've made some progress, although I'm still pretty much spinning my wheels. I'm now able to reliably paint one of my UI elements, and then make it go away. The (simplified) code looks as follows:

function ui_paint_scrubber ()
m.canvas.setLayer(m.scrubber_layer, m.scrubber_definition)
m.scrubber_displayed_p = true
return true
end function

function ui_hide_scrubber ()
m.reset_layer(m.scrubber_layer)
m.scrubber_displayed_p = false
return true
end function


However, I'm also trying to put something on top of the scrubber (using a z-index higher than that of the scrubber_layer), and while I can put that up, I can't make it go away. In addition, I can't get the correct solution to work -- painting the scrubber (a ~50ms operation) once into a background (negative z-index) layer and then swapping it with a visible layer as requested. If I create a negative z-index layer (calling setLayer(negative_index, some_content)), I can't summon that layer forward.

I'm seeing inconsistent or missing documentation on how to manage layers; for instance, nowhere is it defined which if any layer the video is playing on; nowhere is it made explicit that layer 0 is privileged; and nowhere is it explained what layer swapping entails (e.g., is it commutative?). How do I make a layer transparent? Is the color specification RGBA or ARGB? What about gaps (setLayer(3, content), setLayer(5, othercontent) yields ... ?)?

Again, I'm aware that the problem is my lack of information, not the platform itself, but I'm still not able to find any answers to these questions.

Thanks in advance for any light that anybody can shed.
0 Kudos