Nubu
  • Features
  • How it works
  • Pricing
  • Integrations
  • FAQ
  • Contact
  • Docs
  • Blog
  • Log in
  • Log inSign up
    Nubu

    Creative automation for teams that ship campaigns, not busywork.

    Try for free
    Product
    FeaturesNubu MotionHow it worksPricingIntegrationsFAQ
    Company
    AboutContactDocsBlogLog in
    Legal
    Privacy policyTerms of serviceData deletion
    © 2026 Bear Studios · Nubu
    Introduction
    Templates overviewInstalling Nubu BuilderAdding template compsAdding propertiesAdding footageSetting defaultsExporting your templateUploading a template
    Flows overviewAvailable nodesAdding a nodeConnecting nodesWorking with dataTemplates and outputsUsing AI nodesBuilding a creative
    CampaignsTemplatesAssetsGlossariesRendersSettings
    Connecting Meta AdsConnecting Google AdsConnecting OpenAIConnecting Gemini AI StudioConnecting Anthropic
    AI Assistant overviewPrompt examplesAssistant settings and controls
    Nubu Motion scripts: the reference
    OverviewQuick startDifferences from After EffectsDeterminism
    JavaScript supportReferences and idsProject scriptsState and timeBudgets and errorsFormatting values
    GlobalTime conversionInterpolationVector mathsRandom and noiseColour conversionOther maths
    LayerCompPropertyKeyframePathGeometryProjectComponentConsoleComponentControlExpressionControl
    The property vocabularyAnimators propertiesAudio propertiesContent propertiesContents propertiesEffects propertiesExpression controls propertiesFills propertiesInstance controls propertiesLayer propertiesLayout propertiesMasks propertiesStrokes propertiesText style propertiesTransform propertiesTrim path properties
    Error codesBudgets
    Changelog
    All docs
    Motion Scripting
    / Properties

    Fills properties

    Per-fill members by fill id: colour, opacity, gradient handles and stops, and the media transform.

    Per-fill members - colour, opacity, gradient handles and stops, media transforms - addressed by fill id.

    Every pattern below is readable from scripts through prop() and layer.prop(); ids in a pattern (like <effect_id>) stand for the entity's real id. Every pattern here is in the drive set: scripts may WRITE each one with set() or a single-output return, per frame.

    PatternWire kindUnitsReadsWrites
    fills.<fill_id>.adjustments.contrastscalarnumber (wire units of the key)yesdrive set
    fills.<fill_id>.adjustments.exposurescalarnumber (wire units of the key)yesdrive set
    fills.<fill_id>.adjustments.highlightsscalarnumber (wire units of the key)yesdrive set
    fills.<fill_id>.adjustments.saturationscalarnumber (wire units of the key)yesdrive set
    fills.<fill_id>.adjustments.shadowsscalarnumber (wire units of the key)yesdrive set
    fills.<fill_id>.adjustments.temperaturescalarnumber (wire units of the key)yesdrive set
    fills.<fill_id>.adjustments.tintscalarnumber (wire units of the key)yesdrive set
    fills.<fill_id>.assetasset_refasset referenceyesdrive set
    fills.<fill_id>.blend_modeenumenum name (string)yesdrive set
    fills.<fill_id>.colourcolour[r, g, b, a] 0..1yesdrive set
    fills.<fill_id>.crop_transformcrop_transformcrop transformyesdrive set
    fills.<fill_id>.gradient_endpoint2[x, y] pxyesdrive set
    fills.<fill_id>.gradient_startpoint2[x, y] pxyesdrive set
    fills.<fill_id>.gradient_width_handlepoint2[x, y] pxyesdrive set
    fills.<fill_id>.modeenumenum name (string)yesdrive set
    fills.<fill_id>.opacityscalarpercent (0..100)yesdrive set
    fills.<fill_id>.stopsgradient_stopsgradient stop listyesdrive set
    fills.<fill_id>.stops.<stop_id>.alphascalarpercent (0..100)yesdrive set
    fills.<fill_id>.stops.<stop_id>.colourcolour[r, g, b, a] 0..1yesdrive set
    fills.<fill_id>.stops.<stop_id>.offsetscalarnumber (wire units of the key)yesdrive set
    fills.<fill_id>.tile_scalescalar[x, y] percent (100 = 1:1)yesdrive set

    Worked examples#

    A layer's paint is a STACK of fills and strokes - the model every shape and frame uses, and the one the quick start's colour cycle drives. Each fill is addressed by its own id: fills.<fill_id>.colour for a colour fill's colour, fills.<fill_id>.opacity for its translucency, the gradient handles and stops for a gradient fill. The id comes from the scene itself (the Scripts panel and the @ pick whip write it for you); the walkthroughs below name each fill by its role and show the id the code stores.

    A plain solid with an empty stack still paints through the older single fill, content.fill_colour on the content family page - the second example keeps that form so both stay executable.

    Worked example: A colour cycle#

    The scene. One 200 by 200 swatch near the centre of a dark 640 by 360 stage, painted by a single coral fill in its fill stack - the paint model shapes and frames use - ready for a script to drive that fill's colour.

    • The comp Swatch: 640 by 360 at 25 fps, 150 frames (6 seconds).
    • Swatch: a solid layer, at [320, 180], 200 by 200.
      • The stack fill Base (fills.fill_1 in scripts): a colour fill, #ff5d73.

    The script. Add a project script named Colour cycle and paste:

    export const outputs = ["layer_1:fills.fill_1.colour"];
    
    const palette = [
      [1, 0.365, 0.451, 1],
      [0.949, 0.659, 0.2, 1],
      [0.18, 0.769, 0.714, 1],
    ];
    
    export function frame() {
      const phase = (time / 2) % 3;
      const from = palette[Math.floor(phase)];
      const to = palette[(Math.floor(phase) + 1) % 3];
      return linear(phase - Math.floor(phase), 0, 1, from, to);
    }
    

    Line by line:

    • Line 1: One output: the colour of the swatch's STACK FILL - the fill named Base in the scene, addressed by the id the document minted for it (fills.fill_1). Shapes and frames paint through a stack of fills like this one, and the Scripts panel and the @ pick whip write the id for you. Colours are writable like any other animatable property - the script hands back [r, g, b, a] in 0..1 (a "#rrggbb" string works too).
    • Lines 3-7: The three colours of the cycle as [r, g, b, a] arrays: coral, gold and teal.
    • Line 10: phase crawls 0, 1, 2 and wraps - one whole colour every two seconds.
    • Lines 11-12: The colour the phase is leaving and the one it is heading for; the modulo wraps teal back round to coral so the loop closes seamlessly.
    • Line 13: linear() works component by component on arrays: the fraction of the way through the current step blends every channel from one colour to the next, and the single-output return drives the fill directly.

    What you see. The one swatch melts through coral, gold and teal on a six second loop, each colour cross-fading smoothly into the next - its stack fill's colour driven by the script.

    The one swatch melts through coral, gold and teal on a six second loop, each colour cross-fading smoothly into the next - its stack fill's colour driven by the script.

    Worked example: The single-fill colour cycle#

    The scene. One coral 200 by 200 swatch near the centre of a dark 640 by 360 stage, ready for a script to drive its fill colour.

    • The comp Swatch: 640 by 360 at 25 fps, 150 frames (6 seconds).
    • Swatch: a solid layer, at [320, 180], 200 by 200, filled #ff5d73.

    The script. Add a project script named Colour cycle (single fill) and paste:

    export const outputs = ["layer_1:content.fill_colour"];
    
    const palette = [
      [1, 0.365, 0.451, 1],
      [0.949, 0.659, 0.2, 1],
      [0.18, 0.769, 0.714, 1],
    ];
    
    export function frame() {
      const phase = (time / 2) % 3;
      const from = palette[Math.floor(phase)];
      const to = palette[(Math.floor(phase) + 1) % 3];
      return linear(phase - Math.floor(phase), 0, 1, from, to);
    }
    

    Line by line:

    • Line 1: One output: the swatch's legacy FILL COLOUR - content.fill_colour, the single fill a plain solid paints with while its stack is empty. The quick start's form drives fills.<fill_id>.colour on a stack fill instead; everything else about the script is identical.
    • Lines 3-7: The three colours of the cycle as [r, g, b, a] arrays: coral, gold and teal.
    • Line 10: phase crawls 0, 1, 2 and wraps - one whole colour every two seconds.
    • Lines 11-12: The colour the phase is leaving and the one it is heading for; the modulo wraps teal back round to coral so the loop closes seamlessly.
    • Line 13: linear() works component by component on arrays: the fraction of the way through the current step blends every channel from one colour to the next, and the single-output return drives the fill directly.

    What you see. The one swatch melts through coral, gold and teal on a six second loop, each colour cross-fading smoothly into the next - its single fill colour driven by the script.

    The one swatch melts through coral, gold and teal on a six second loop, each colour cross-fading smoothly into the next - its single fill colour driven by the script.