Effect

Effect applies GPU shader-based rendering to a Rectangle or Poster

import { Effect } from "@roku-sdk/components";
Effect(props: IEffectProps): JSX.Element

Available since Roku OS 16.0

Description

Effect applies GPU shader-based rendering to a Rectangle or Poster.

Hoist it into a const and pass that as the effect prop on a Rectangle or Poster to enable rounded corners, borders, and gradient fills. Set shaderCompatible on a Poster that takes one.

Prefer the <effect> intrinsic for most uses. The Effect wrapper is a pure passthrough (<effect {...props} />) and exists for consistency with the component library.

Platform availability

Effects require Roku OS 16.0 or later and the OpenGL graphics backend. Elsewhere the effect prop is ignored without an error and the content renders unstyled. To branch on it, read getDeviceInfo() from @roku-sdk/rsg-ts/runtime once: Number(info.osVersion.major) >= 16 && info.graphicsPlatform === "opengl". The node's own supported field is set when the node is created and cannot be read from TypeScript, and effects disabled by device configuration are invisible to that check.

Parameters

NameTypeDescription
propsIEffectProps

Example

// Hoist the effect node to a const — one node, shared by multiple consumers.
// See: rsg-sdk/external/documentation/core-concepts/effects.md § "Hoist the effect into a const"
const framed = <effect borderRadius={24} borderWidth={6} borderColor="0xF39C12FF" borderPadding={2} />;

// The same framed node can be passed to both a rectangle and a poster.

return (
    <layoutGroup layoutDirection="vert" itemSpacings={[12]}>
        <label text="2. Shared" font={SystemFont.Small} width={AREA} />
        <label
            text="One Effect node assigned to both a Rectangle and a Poster. Change it once, both update."
            font={SystemFont.Tiny}
            width={AREA}
            wrap
        />
        <rectangle width={AREA} height={TILE_HEIGHT} color="0x1A1A2EFF" effect={framed} />
        {/* `shaderCompatible` asks for the bitmap to be decoded into a
            shader-usable format. A Poster without it may still show its
            effect depending on the source image, so set it deliberately on
            any Poster that takes one rather than relying on the default. */}
        <poster
            width={AREA}
            height={TILE_HEIGHT}
            loadDisplayMode="scaleToZoom"
            shaderCompatible={true}
            effect={framed}
            uri={photoUri}
        />
    </layoutGroup>
);

Types

IEffectProps

Properties for the Effect node.

Effect applies GPU shader-based rendering to a Rectangle or Poster, enabling rounded corners, borders, and gradient fills. Attach an Effect node to a Rectangle or Poster via the effect prop.

Platform availability: Effects require Roku OS 16.0 or later and the OpenGL graphics backend. Elsewhere the effect prop is ignored without an error and the content renders unstyled. To branch on it, read getDeviceInfo() from @roku-sdk/rsg-ts/runtime once: Number(info.osVersion.major) >= 16 && info.graphicsPlatform === "opengl". The node's own supported field is set when the node is created and cannot be read from TypeScript, and effects disabled by device configuration are invisible to that check.

Hoist the effect into a const. A signal read by the effect={...} expression itself builds a new effect node on every change; signals read by the effect's own fields update it in place.

Example

// Hoist the effect node to a const — one node, shared by multiple consumers.
// See: rsg-sdk/external/documentation/core-concepts/effects.md § "Hoist the effect into a const"
const framed = <effect borderRadius={24} borderWidth={6} borderColor="0xF39C12FF" borderPadding={2} />;

// The same framed node can be passed to both a rectangle and a poster.

return (
    <layoutGroup layoutDirection="vert" itemSpacings={[12]}>
        <label text="2. Shared" font={SystemFont.Small} width={AREA} />
        <label
            text="One Effect node assigned to both a Rectangle and a Poster. Change it once, both update."
            font={SystemFont.Tiny}
            width={AREA}
            wrap
        />
        <rectangle width={AREA} height={TILE_HEIGHT} color="0x1A1A2EFF" effect={framed} />
        {/* `shaderCompatible` asks for the bitmap to be decoded into a
            shader-usable format. A Poster without it may still show its
            effect depending on the source image, so set it deliberately on
            any Poster that takes one rather than relying on the default. */}
        <poster
            width={AREA}
            height={TILE_HEIGHT}
            loadDisplayMode="scaleToZoom"
            shaderCompatible={true}
            effect={framed}
            uri={photoUri}
        />
    </layoutGroup>
);
NameTypeDescription
borderColor?stringBorder stroke color as an RGBA hex string (e.g. "0xFF0000FF").
borderPadding?numberPadding in pixels between the border and the content rect. It changes nothing while borderWidth is 0, so it is not content padding.
borderRadius?number | [number, number, number, number]See below.
borderWidth?numberBorder stroke width in pixels. The border is drawn outside the content rect.
gradientAngle?numberRotation angle of a linear gradient in degrees. The gradient fills the available space from opposite corners.
gradientCentre?Vector2DCenter point of a radial gradient in normalized coordinates. [0, 0] = top-left, [1, 1] = bottom-right.
gradientColors?string[]Ordered list of RGBA color stops for the gradient (e.g. ["0xFF0000FF", "0x0000FFFF"]). At least two colors are required for the gradient to render. Maximum of 8 colors. Outside that range the gradient does not render; in __DEV__ builds the SDK warns once when gradientStyle is not "none".
gradientFillBorder?booleanWhether the gradient fills the border area.
gradientFillContent?booleanWhether the gradient fills the content area (inside the border).
gradientRadius?Vector2DRadii of the radial gradient ellipse in normalized coordinates. 1.0 equals the rectangle's width or height respectively.
gradientStops?number[]Normalized stop positions [0, 1] corresponding to each entry in gradientColors. If omitted, colors are distributed evenly across the gradient. In __DEV__ builds the SDK warns once on a length mismatch or an entry outside [0, 1] when gradientStyle is not "none".
gradientStyle?GradientStyleGradient fill style applied over the content area. No gradient renders while this is "none".

Extends INodeProps.

IEffectProps.borderRadius

Per-corner border radius in pixels.

  • A single number applies a uniform radius to all corners.
  • A four-element tuple sets each corner independently: [topLeft, topRight, bottomRight, bottomLeft].
    The tuple is one Vector4 field, so a FloatFieldInterpolator cannot animate it.

GradientStyle

type GradientStyle = "none" | "linear" | "radial";

Did this page help you?