Skip to content

xnano.core.effects

xnano.core.effects

xnano.core.effects


Turn effect descriptions into native tachyonfx effects.

Functions:

build_native_effect

build_native_effect(effect: AbstractEffect) -> Effect

Lower an effect description to a native effect instance.

Parameters:

  • effect (AbstractEffect) –

    The neutral effect description to lower.

Returns:

  • Effect

    A native Effect ready to run.

Source code in xnano/core/effects.py
def build_native_effect(effect: AbstractEffect) -> native.Effect:
    """Lower an effect description to a native effect instance.

    Args:
        effect: The neutral effect description to lower.

    Returns:
        A native ``Effect`` ready to run.
    """
    if isinstance(effect, FadeEffect):
        return native.fade_to_fg(
            _require_native_color(effect.color, label="color"),
            effect.duration_ms,
            _resolve_native_interpolation(effect.interpolation),
        )
    if isinstance(effect, FadeFromEffect):
        return native.fade_from_fg(
            _require_native_color(effect.color, label="color"),
            effect.duration_ms,
            _resolve_native_interpolation(effect.interpolation),
        )
    if isinstance(effect, FadeToEffect):
        return native.fade_to(
            _require_native_color(effect.color, label="color"),
            _require_native_color(effect.background, label="background"),
            effect.duration_ms,
            _resolve_native_interpolation(effect.interpolation),
        )
    if isinstance(effect, FadeFromBothEffect):
        return native.fade_from(
            _require_native_color(effect.color, label="color"),
            _require_native_color(effect.background, label="background"),
            effect.duration_ms,
            _resolve_native_interpolation(effect.interpolation),
        )
    if isinstance(effect, DissolveEffect):
        return native.dissolve(
            effect.duration_ms,
            _resolve_native_interpolation(effect.interpolation),
        )
    if isinstance(effect, CoalesceEffect):
        return native.coalesce(
            effect.duration_ms,
            _resolve_native_interpolation(effect.interpolation),
        )
    if isinstance(effect, SweepInEffect):
        return native.sweep_in(
            _resolve_native_motion(effect.direction),
            effect.gradient_length,
            effect.randomness,
            _require_native_color(effect.color, label="color"),
            effect.duration_ms,
            _resolve_native_interpolation(effect.interpolation),
        )
    if isinstance(effect, SweepOutEffect):
        return native.sweep_out(
            _resolve_native_motion(effect.direction),
            effect.gradient_length,
            effect.randomness,
            _require_native_color(effect.color, label="color"),
            effect.duration_ms,
            _resolve_native_interpolation(effect.interpolation),
        )
    if isinstance(effect, SlideInEffect):
        return native.slide_in(
            _resolve_native_motion(effect.direction),
            effect.gradient_length,
            effect.randomness,
            _require_native_color(effect.color, label="color"),
            effect.duration_ms,
            _resolve_native_interpolation(effect.interpolation),
        )
    if isinstance(effect, SlideOutEffect):
        return native.slide_out(
            _resolve_native_motion(effect.direction),
            effect.gradient_length,
            effect.randomness,
            _require_native_color(effect.color, label="color"),
            effect.duration_ms,
            _resolve_native_interpolation(effect.interpolation),
        )
    if isinstance(effect, PaintEffect):
        return native.paint(
            _require_native_color(effect.color, label="color"),
            _require_native_color(effect.background, label="background"),
            effect.duration_ms,
            _resolve_native_interpolation(effect.interpolation),
        )
    if isinstance(effect, PaintForegroundEffect):
        return native.paint_fg(
            _require_native_color(effect.color, label="color"),
            effect.duration_ms,
            _resolve_native_interpolation(effect.interpolation),
        )
    if isinstance(effect, PaintBackgroundEffect):
        return native.paint_bg(
            _require_native_color(effect.background, label="background"),
            effect.duration_ms,
            _resolve_native_interpolation(effect.interpolation),
        )
    if isinstance(effect, SleepEffect):
        return native.sleep_effect(effect.duration_ms)
    if isinstance(effect, SequenceEffect):
        if not effect.effects:
            raise ValueError("sequence effects require at least one child")
        return native.sequence_effects(
            [build_native_effect(child) for child in effect.effects]
        )
    if isinstance(effect, ParallelEffect):
        if not effect.effects:
            raise ValueError("parallel effects require at least one child")
        return native.parallel_effects(
            [build_native_effect(child) for child in effect.effects]
        )
    if isinstance(effect, RepeatEffect):
        if effect.child is None:
            raise ValueError("repeat effects require a child effect")
        child = build_native_effect(effect.child)
        if effect.times is not None:
            return native.repeat_effect(child, times=effect.times)
        if effect.duration_ms != 300:
            return native.repeat_effect(child, duration_ms=effect.duration_ms)
        return native.repeat_effect(child)
    if isinstance(effect, DelayEffect):
        if effect.child is None:
            raise ValueError("delay effects require a child effect")
        return native.delay_effect(
            effect.duration_ms,
            build_native_effect(effect.child),
        )

    raise ValueError(f"unsupported effect type: {type(effect)!r}")

apply_native_cell_filter

apply_native_cell_filter(
    effect_description: AbstractEffect,
    native_effect: Effect,
) -> Effect

Apply an effect description's terminal cell filter to an effect.

Source code in xnano/core/effects.py
def apply_native_cell_filter(
    effect_description: AbstractEffect,
    native_effect: native.Effect,
) -> native.Effect:
    """Apply an effect description's terminal cell filter to an effect."""
    if effect_description.cell_filter is None:
        return native_effect
    filters = {
        "all": native.CellFilter.ALL,
        "text": native.CellFilter.TEXT,
        "non_empty": native.CellFilter.NON_EMPTY,
        "background": native.CellFilter.BACKGROUND,
        "background_only": native.CellFilter.BACKGROUND_ONLY,
    }
    return native_effect.with_filter(filters[effect_description.cell_filter])

resolve_native_effect

resolve_native_effect(
    effect: AbstractEffect | KnownEffectKind,
    *,
    duration_ms: int = 300,
    color: ColorLike | None = None,
    background: ColorLike | None = None,
    direction: EffectMotion | None = None,
    gradient_length: int | None = None,
    randomness: int | None = None,
    interpolation: EffectInterpolation | None = None,
    effects: Sequence[AbstractEffect] | None = None,
    child: AbstractEffect | None = None,
    times: int | None = None,
    key: str | None = None
) -> Effect

Resolve and lower an effect description to a native effect.

Terminal-only: lowers through build_native_effect. See the xnano.effects module docstring for why this lowering step lives behind the terminal controller rather than growing a second (web) lowering path there.

Parameters:

  • effect (AbstractEffect | KnownEffectKind) –

    A built effect instance or a known effect kind string.

  • duration_ms (int, default: 300 ) –

    Duration of the effect in milliseconds.

  • color (ColorLike | None, default: None ) –

    Foreground or accent color for color-driven effects.

  • background (ColorLike | None, default: None ) –

    Background color for two-color effects.

  • direction (EffectMotion | None, default: None ) –

    Motion direction for slide and sweep effects.

  • gradient_length (int | None, default: None ) –

    Gradient length for slide and sweep effects.

  • randomness (int | None, default: None ) –

    Randomness for slide and sweep effects.

  • interpolation (EffectInterpolation | None, default: None ) –

    Interpolation curve for the effect.

  • effects (Sequence[AbstractEffect] | None, default: None ) –

    Child effects for sequence and parallel composition.

  • child (AbstractEffect | None, default: None ) –

    Child effect for repeat and delay composition.

  • times (int | None, default: None ) –

    Repeat count for repeat effects.

  • key (str | None, default: None ) –

    Identity used by a controller to de-duplicate this effect per target field.

Returns:

  • Effect

    A native Effect instance.

Source code in xnano/core/effects.py
def resolve_native_effect(
    effect: AbstractEffect | KnownEffectKind,
    *,
    duration_ms: int = 300,
    color: ColorLike | None = None,
    background: ColorLike | None = None,
    direction: EffectMotion | None = None,
    gradient_length: int | None = None,
    randomness: int | None = None,
    interpolation: EffectInterpolation | None = None,
    effects: Sequence[AbstractEffect] | None = None,
    child: AbstractEffect | None = None,
    times: int | None = None,
    key: str | None = None,
) -> native.Effect:
    """Resolve and lower an effect description to a native effect.

    Terminal-only: lowers through ``build_native_effect``. See the
    ``xnano.effects`` module docstring for why this lowering step lives
    behind the terminal controller rather than growing a second (web)
    lowering path there.

    Args:
        effect: A built effect instance or a known effect kind string.
        duration_ms: Duration of the effect in milliseconds.
        color: Foreground or accent color for color-driven effects.
        background: Background color for two-color effects.
        direction: Motion direction for slide and sweep effects.
        gradient_length: Gradient length for slide and sweep effects.
        randomness: Randomness for slide and sweep effects.
        interpolation: Interpolation curve for the effect.
        effects: Child effects for sequence and parallel composition.
        child: Child effect for repeat and delay composition.
        times: Repeat count for repeat effects.
        key: Identity used by a controller to de-duplicate this effect
            per target field.

    Returns:
        A native ``Effect`` instance.
    """
    resolved = resolve_effect(
        effect,
        duration_ms=duration_ms,
        color=color,
        background=background,
        direction=direction,
        gradient_length=gradient_length,
        randomness=randomness,
        interpolation=interpolation,
        effects=effects,
        child=child,
        times=times,
        key=key,
    )
    return apply_native_cell_filter(resolved, build_native_effect(resolved))