You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Roku频道开发:如何旋转Poster节点或实现全屏旋转?

Roku频道幻灯片图片旋转解决方案

一、核心问题分析

你遇到的旋转失效或效果异常,主要原因在于:

  • 未设置rotationCenter,默认绕左上角旋转导致图片偏移出屏幕
  • 旋转后未调整图片缩放和位置,无法适配屏幕尺寸
  • 全屏旋转需要操作顶层容器而非单个Poster节点

二、实现步骤与代码修改

1. 调整XML结构(添加旋转容器)

将Poster放入全屏Group容器,方便控制单节点旋转或全屏旋转:

<component name="PlaylistRendererScreen" extends="Scene">
    <script type="text/brightscript" uri="PlaylistRendererScreen.bs" />
    <children>
        <!-- 全屏旋转容器 -->
        <Group id="rotationContainer" width="1920" height="1080" translation="[0,0]">
            <Poster id="testPoster"
                    width="1920"
                    height="1080"
                    loadWidth="1920"
                    loadHeight="1080"
                    translation="[0,0]"
                    visible="true" />
        </Group>
    </children>
</component>

2. 修改BrightScript逻辑

核心功能:

  • 监听图片加载完成事件,获取原始宽高判断横竖版
  • 设置旋转中心与角度,调整缩放让图片适配屏幕
  • 支持单独旋转Poster或全屏旋转容器
sub init()
    m.poster = m.top.findNode("testPoster")
    m.rotationContainer = m.top.findNode("rotationContainer")
    
    m.mediaList = [
        { type: "image", url: "横版图片URL" },
        { type: "image", url: "竖版图片URL" },
        { type: "image", url: "横版图片URL" },
        { type: "image", url: "竖版图片URL" },
    ]

    m.currentIndex = 0
    m.interval = 5000   ' 切换间隔(5秒)

    ' 监听图片加载状态,获取原始尺寸
    m.poster.observeField("loadStatus", "onPosterLoadStatusChanged")
    
    startSlideShowTimer()
    showMedia()
end sub

sub startSlideShowTimer()
    if (m.timer = invalid)
        m.timer = createObject("roSGNode", "Timer")
        m.timer.duration = m.interval / 1000
        m.timer.repeat = true
        m.timer.observeField("fire", "onTimerFired")
        m.top.appendChild(m.timer)
    end if
    m.timer.control = "start"
end sub

sub onTimerFired()
    m.currentIndex = (m.currentIndex + 1) mod m.mediaList.count()
    showMedia()
end sub

sub showMedia()
    mediaItem = m.mediaList[m.currentIndex]
    mediaType = mediaItem.type
    mediaUrl = mediaItem.url

    if (mediaType = "image")
        ' 切换图片前重置所有旋转、缩放参数
        resetRotationAndScale()
        m.poster.uri = mediaUrl
        m.poster.visible = true
    else if (mediaType = "video")
        ' 视频展示逻辑可在此补充
    end if
end sub

sub onPosterLoadStatusChanged(event as Object)
    if event.getData() = "ready"
        ' 获取图片原始宽高
        imgWidth = m.poster.texture.width
        imgHeight = m.poster.texture.height
        ' 判断是否为竖版图片
        isVertical = imgHeight > imgWidth

        if isVertical
            ' ========== 方案1:仅旋转Poster节点 ==========
            m.poster.rotationCenter = [0.5, 0.5] ' 设置绕自身中心旋转
            m.poster.rotation = 90
            
            ' 计算缩放比例,让旋转后的图片填满屏幕
            scaleX = 1080.0 / imgWidth
            scaleY = 1920.0 / imgHeight
            finalScale = max(scaleX, scaleY)
            
            m.poster.scale = [finalScale, finalScale]
            ' 调整位置让图片居中
            translatedX = (1920 - imgHeight * finalScale) / 2
            translatedY = (1080 - imgWidth * finalScale) / 2
            m.poster.translation = [translatedX, translatedY]

            ' ========== 方案2:全屏旋转(整个屏幕跟着转) ==========
            ' m.rotationContainer.rotationCenter = [0.5, 0.5]
            ' m.rotationContainer.rotation = 90
            ' ' 旋转后容器宽高互换,调整尺寸适配屏幕
            ' m.rotationContainer.width = 1080
            ' m.rotationContainer.height = 1920
            ' m.rotationContainer.translation = [(1920 - 1080)/2, (1080 - 1920)/2]
            ' ' 调整Poster适配旋转后的容器
            ' m.poster.width = 1920
            ' m.poster.height = 1080
            ' scaleX = 1080.0 / imgWidth
            ' scaleY = 1920.0 / imgHeight
            ' finalScale = max(scaleX, scaleY)
            ' m.poster.scale = [finalScale, finalScale]
            ' translatedX = (1080 - imgHeight * finalScale) / 2
            ' translatedY = (1920 - imgWidth * finalScale) / 2
            ' m.poster.translation = [translatedX, translatedY]
        else
            ' 横版图片适配屏幕
            scaleX = 1920.0 / imgWidth
            scaleY = 1080.0 / imgHeight
            finalScale = max(scaleX, scaleY)
            
            m.poster.scale = [finalScale, finalScale]
            translatedX = (1920 - imgWidth * finalScale) / 2
            translatedY = (1080 - imgHeight * finalScale) / 2
            m.poster.translation = [translatedX, translatedY]
        end if
    end if
end sub

' 重置所有旋转、缩放、位置参数,避免影响下一张图片
sub resetRotationAndScale()
    m.rotationContainer.rotation = 0
    m.rotationContainer.width = 1920
    m.rotationContainer.height = 1080
    m.rotationContainer.translation = [0, 0]
    m.rotationContainer.rotationCenter = [0, 0]
    
    m.poster.rotation = 0
    m.poster.scale = [1, 1]
    m.poster.translation = [0, 0]
    m.poster.rotationCenter = [0, 0]
end sub

3. 关键说明

  • 旋转中心设置:必须将rotationCenter设为[0.5,0.5],让节点绕自身中心旋转,否则会偏移出屏幕
  • 缩放适配:旋转后图片的宽高维度互换,需重新计算缩放比例,确保图片填满屏幕且居中
  • 全屏旋转切换:注释方案1代码,取消方案2代码的注释即可实现全屏旋转效果,此时整个容器内的所有元素都会跟着旋转

内容的提问来源于stack exchange,提问作者Suleyman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 17:45:53