<component name = "MaskGroupexample" extends = "Group" >
<script>
<![CDATA[
sub init()
maskgroupanimation = m.top.findNode("MaskGroupAnimation")
maskgroupanimation.control = "start"
end sub
]]>
</script>
<children>
<MaskGroup id="exampleMaskGroup" maskuri="pkg:/images/GradientLinear.png" masksize="[512, 288]" maskOffset="[0, 0]" >
<Poster uri = "pkg:/images/dialogpg.jpg" width = "512" height = "288" />
</MaskGroup>
<Animation id = "MaskGroupAnimation" duration = "3" easeFunction = "linear" repeat = "true" >
<Vector2DFieldInterpolator id = "interpolator" fieldToInterp = "exampleMaskGroup.maskOffset" key = "[ 0.0, 0.50, 1.0 ]"
keyValue = "[ [512,0], [-512,0], [512,0] ]" />
</Animation>
</children>
</component>
... and this is perfectly valid BrightScript - just nested array and dictionary literals! It may look unusual if you don't know B/S implies comma when new line separates items but yeah... can save on commas there. And since this is all evaluated as B/S, attributes don't have to be string constants like "[ [512,0], [-512,0], [512,0] ]" - they are genuine expressions that can be calculated during object construction.
["component", {name: "MaskGroupexample", extends: "Group"
init: function()
maskgroupanimation = m.top.findNode("MaskGroupAnimation")
maskgroupanimation.control = "start"
end function
}
["children"
["MaskGroup", {id: "exampleMaskGroup", maskuri: "pkg:/images/GradientLinear.png",
masksize: [512, 288], maskOffset: [0, 0]}
"Poster", {uri: "pkg:/images/dialogpg.jpg", width: 512, height: 288}
]
["Animation", {id: "MaskGroupAnimation", duration: 3, easeFunction: "linear", repeat: true}
"Vector2DFieldInterpolator", {id: "interpolator", fieldToInterp: "exampleMaskGroup.maskOffset",
key: [0.0, 0.50, 1.0], keyValue: [[512,0], [-512,0], [512,0]] }
]
]
]
mg_ex = createObject("roSgNode", "Group")Much better but still tad tedious, since there is createObject() within createObject() or the use temp variables. But notice how "the need" to sub-class and write an initializer vanished naturally.
mg_ex.createChild("MaskGroup", {id: "exampleMaskGroup",
maskuri: "pkg:/images/GradientLinear.png", masksize: [512, 288], maskOffset: [0, 0]
children: [
createObject("roSgNode", "Poster", {uri: "pkg:/images/dialogpg.jpg", width: 512, height: 288})
]
})
mga = createObject("roSgNode", "Animation", {id: "MaskGroupAnimation",
duration: 3, easeFunction: "linear", repeat: true
children: [
createObject("roSgNode", "Vector2DFieldInterpolator", {id: "interpolator",
fieldToInterp: "exampleMaskGroup.maskOffset",
key: [0.0, 0.50, 1.0], keyValue: [[512,0], [-512,0], [512,0]]
})
]
})
mg_ex.appendChild(mga)
mga.control = "start"
MaskGroupExample = { type: "Group"So that's ust a roAA, what do we do with it? Well, in a perfect world i should be able to create the node by calling
init: function()
maskgroupanimation = m.top.findNode("MaskGroupAnimation")
maskgroupanimation.control = "start"
end function
children: [
{ type: "MaskGroup", id: "exampleMaskGroup",
maskuri: "pkg:/images/GradientLinear.png", masksize: [512, 288], maskOffset: [0, 0]
children: [
{ type: "Poster", uri: "pkg:/images/dialogpg.jpg", width: 512, height: 288}
]
}
{ type: "Animation", id: "MaskGroupAnimation",
duration: 3, easeFunction: "linear", repeat: true
children: [
{ type: "Vector2DFieldInterpolator", id: "interpolator",
fieldToInterp: "exampleMaskGroup.maskOffset",
key: [0.0, 0.50, 1.0], keyValue: [[512,0], [-512,0], [512,0]]
}
]
}
]
}
mg_ex = createObject("roSgNode", MaskGroupExample)i.e. passing roAA as argument (instead of string) would be walked by the sgNode constructor, creating all nested nodes. In the mean time though - till the cows come home - it's trivial for us to write own B/S utility function that does the same by walking the tree and createObject() the nested levels.
sub main():
screen = createObject("roSGScreen")
port = createObject("roMessagePort")
screen.setMessagePort(port)
scene = screen.createScene("_scene")
screen.show()
scene.setFocus(true)
scene.backgroundURI = "pkg:/images/rsgde_bg_hd.jpg"
scene._ingest = {__: [
{ _: "Rectangle", id: "textRectangle"
width: 640, height: 60
color: "0x10101000"
backgroundURI: "pkg:/images/rsgde_bg_hd.jpg"
__: { _: "Label", id: "movingLabel"
width: 280, height: 60
horizAlign: "center", vertAlign: "center"
text: "All The Best Videos!"
}
}
{ _: "Animation", id: "scrollbackAnimation"
duration: 10
repeat: true
easeFunction: "linear"
__: { _: "Vector2DFieldInterpolator"
fieldToInterp: "movingLabel.translation"
key: [0.0, 0.5, 1.0]
keyValue: [[0.0, 0.0], [360.0, 0.0], [0.0, 0.0]]
}
}
{ _: "Timer", id: "textTimer"
duration: 5
repeat: true
}
]}
scene._ingest = {_m: {
defaulttext: "All The Best Videos!"
alternatetext: "All The Time!!!"
}}
scene._ingest = {_exec: [
" _observeField(m.texttimer, ""fire"", function(msg): "
" lbl = m.movingLabel "
" if lbl.text = m.defaultText: "
" lbl.text = m.alternateText "
" else: "
" lbl.text = m.defaultText "
" end if "
" end function) "
]}
rect = scene.textRectangle.boundingRect()
centerx = (1280 - rect.width) / 2
centery = (720 - rect.height) / 2
scene.textRectangle.translation = [centerx, centery]
scene.textTimer.control = "start"
scene.scrollbackAnimation.control = "start"
while true:
msg = wait(0, port)
if type(msg) = "roSGScreenEvent" and msg.isScreenClosed() then exit while
end while
end sub
<MyComp messages="["hi", "hello", "world", "none"]">
<!-- after failing with -->
<MyComp messages="['hi', 'hello', 'world', 'none']"
<?xml version="1.0" encoding="utf-8" ?>
<!--********** Copyright 2016 Roku Corp. All Rights Reserved. **********-->
<component name = "EventObserverExample" extends = "Scene" >
<script type = "text/brightscript" >
<![CDATA[
sub init()
m.top.backgroundURI = "pkg:/images/rsgde_bg_hd.jpg"
example = m.top.findNode("textRectangle")
examplerect = example.boundingRect()
centerx = (1280 - examplerect.width) / 2
centery = (720 - examplerect.height) / 2
example.translation = [ centerx, centery ]
m.movinglabel = m.top.findNode("movingLabel")
m.defaulttext = "All The Best Videos!"
m.alternatetext = "All The Time!!!"
m.textchange = false
scrollback = m.top.findNode("scrollbackAnimation")
scrollback.control = "start"
texttimer = m.top.findNode("textTimer")
texttimer.observeField("fire", "changetext")
texttimer.control = "start"
m.top.setFocus(true)
end sub
sub changetext()
if (m.textchange = false) then
m.movinglabel.text = m.alternatetext
m.textchange = true
else
m.movinglabel.text = m.defaulttext
m.textchange = false
end if
end sub
]]>
</script>
<children>
<Rectangle
id = "textRectangle"
width = "640"
height = "60"
color = "0x10101000" >
<Label
id = "movingLabel"
width = "280"
height = "60"
text = "All The Best Videos!"
horizAlign = "center"
vertAlign = "center" />
</Rectangle>
<Animation
id = "scrollbackAnimation"
duration = "10"
repeat = "true"
easeFunction = "linear" >
<Vector2DFieldInterpolator
key = "[ 0.0, 0.5, 1.0 ]"
keyValue = "[ [0.0, 0.0], [360.0, 0.0], [0.0, 0.0] ]"
fieldToInterp = "movingLabel.translation" />
</Animation>
<Timer
id = "textTimer"
repeat = "true"
duration = "5" />
</children>
</component>
We’re upgrading Roku Community to bring you a faster, more mobile-friendly experience. You may notice limited functionality or read-only access during this time. You will not be able to log in or post new comments or kudos during this time. Read more here.
Planned Downtime:
Community will be unavailable for up to 24–48 hours during the upgrade window during the week of May 12 and you may notice reduced functionality.
In the meantime, for additional assistance, visit our Support Site.
Thanks for your patience — we’re excited to share what’s next!