Scripting

How to Create a Dynamic Animated Brush in Rive with Path Effect Scripts

Feb 2, 2026

|

8

min read

Full Video Tutorial

Path Effect Scripts are one of the more advanced features in Rive, and they open up a lot of creative possibilities.

In this tutorial, we'll use them to build a dynamic, animated brush effect - the kind of rough, hand-drawn shape you might use behind a UI label or tag.

The goal isn't to create a "perfect" brush. It's to show how a small script can evolve into something flexible, reusable, and animated - something you can keep refining and adapting to your own projects.

Starting With a Simple Shape

We begin with a basic setup: a rectangle used as a background shape behind a text label.

I used Rive's Layouts feature to make sure the rectangle always resizes to fit the text with a bit of padding.
At this stage, the shape is static. No animation, no logic - just a clean, responsive starting point.

From here, we'll gradually add complexity using scripting.

⬇️ Download the starter file to follow along.

Creating the First Path Effect Script

To start working with scripting, we create a Path Effect Script and apply it to the shape's Fill layer.
At first, the shape disappears - and that's expected.
Why? Because the script's update() function returns a new path, and until we define its behavior, that path is empty.

This is actually a good sign. It tells us the script is wired correctly.

Verifying the Script Works

Before building anything complex, it's worth confirming the pipeline works.

Instead of writing logic manually, we ask the Agent to slightly distort the shape along the Y-axis - just enough to see a visible change.

Prompt - Basic distortion test:

Use the existing Script
Modify the path in update() so that all points are slightly offset
on the Y axis using a simple sine function.
Do not use time. Keep the result deterministic

Use the existing Script
Modify the path in update() so that all points are slightly offset
on the Y axis using a simple sine function.
Do not use time. Keep the result deterministic

Use the existing Script
Modify the path in update() so that all points are slightly offset
on the Y axis using a simple sine function.
Do not use time. Keep the result deterministic

Once applied, the shape shows a subtle distortion. Nothing fancy - just confirmation that the script is running and affecting the geometry.

After that, we remove this temporary logic and start fresh.

What Makes a Brush Feel Hand-Drawn?

A hand-drawn brush isn't about perfection.

It's defined by:

  • Slightly uneven edges

  • Inconsistent thickness

  • Small variations that make it feel organic, not mathematical

To simulate that imperfection - and make it dynamic - we introduce three core properties.

Core Brush Properties

Amplitude

Controls how strong the distortion is.

  • Low values = subtle, soft distortion

  • High values = bold, aggressive distortion

You can think of this as how much you allow yourself to "break" the shape.

Frequency

Controls how often the distortion appears along the shape.

  • Low values = wide, loose variations

  • High values = dense, tightly packed variations

Seed

Introduces variation.
Changing the seed gives you different versions of the same brush, preventing everything from looking identical.

Generating the Brush

Instead of implementing all of this manually, we use the Agent again - this time with a more intentional prompt.

We ask it to use the existing script, implement the three properties, keep the distortion soft and UI-friendly, and include sensible default values.

Prompt - Brush generation with Amplitude / Frequency / Seed:

Create a Path Effect Script that produces a static, organic brush-like edge
for a rectangular shape used in UI.

The goal is to gently break the perfect geometry of the shape
so it feels hand-drawn, but still clean, readable, and suitable for UI.

Apply smooth, continuous distortion along all four edges
(top, bottom, left, and right),
with rounded, flowing curves rather than sharp angles.

The distortion should:
- Be strongest near the center of each edge
- Gradually fade out toward the corners
- Keep corners soft and stable
- Avoid sharp spikes, jagged shapes, or visible teeth

Expose exactly three input parameters:

- amplitude (range: 0–50, default: 10)
  Controls how strong the distortion is.
  Low values should be subtle and restrained,
  higher values should feel more hand-drawn but still controlled.

- frequency (range: 0–50, default: 6)
  Controls how often the distortion appears along the edges.
  Favor low-frequency, rounded variations.
  Avoid aggressive or noisy patterns.

- seed (range: 0–50, default: 0)
  Controls deterministic variation of the distortion pattern.
  Changing the seed should slightly shift the brush look
  while keeping the result stable and repeatable.

Keep the effect static and deterministic.
Do not use time or animation.
Geometry changes should occur only in update()

Create a Path Effect Script that produces a static, organic brush-like edge
for a rectangular shape used in UI.

The goal is to gently break the perfect geometry of the shape
so it feels hand-drawn, but still clean, readable, and suitable for UI.

Apply smooth, continuous distortion along all four edges
(top, bottom, left, and right),
with rounded, flowing curves rather than sharp angles.

The distortion should:
- Be strongest near the center of each edge
- Gradually fade out toward the corners
- Keep corners soft and stable
- Avoid sharp spikes, jagged shapes, or visible teeth

Expose exactly three input parameters:

- amplitude (range: 0–50, default: 10)
  Controls how strong the distortion is.
  Low values should be subtle and restrained,
  higher values should feel more hand-drawn but still controlled.

- frequency (range: 0–50, default: 6)
  Controls how often the distortion appears along the edges.
  Favor low-frequency, rounded variations.
  Avoid aggressive or noisy patterns.

- seed (range: 0–50, default: 0)
  Controls deterministic variation of the distortion pattern.
  Changing the seed should slightly shift the brush look
  while keeping the result stable and repeatable.

Keep the effect static and deterministic.
Do not use time or animation.
Geometry changes should occur only in update()

Create a Path Effect Script that produces a static, organic brush-like edge
for a rectangular shape used in UI.

The goal is to gently break the perfect geometry of the shape
so it feels hand-drawn, but still clean, readable, and suitable for UI.

Apply smooth, continuous distortion along all four edges
(top, bottom, left, and right),
with rounded, flowing curves rather than sharp angles.

The distortion should:
- Be strongest near the center of each edge
- Gradually fade out toward the corners
- Keep corners soft and stable
- Avoid sharp spikes, jagged shapes, or visible teeth

Expose exactly three input parameters:

- amplitude (range: 0–50, default: 10)
  Controls how strong the distortion is.
  Low values should be subtle and restrained,
  higher values should feel more hand-drawn but still controlled.

- frequency (range: 0–50, default: 6)
  Controls how often the distortion appears along the edges.
  Favor low-frequency, rounded variations.
  Avoid aggressive or noisy patterns.

- seed (range: 0–50, default: 0)
  Controls deterministic variation of the distortion pattern.
  Changing the seed should slightly shift the brush look
  while keeping the result stable and repeatable.

Keep the effect static and deterministic.
Do not use time or animation.
Geometry changes should occur only in update()

Adding Direction for a More Natural Feel

Real brush strokes are rarely symmetrical. They usually have a direction - top to bottom or left to right.
To capture that, we add two more properties:

Direction

Defines the dominant stroke direction:

  • 0 = no dominant direction

  • 1 = vertical stroke (top to bottom)

  • 2 = horizontal stroke (left to right)

The distortion becomes stronger perpendicular to the stroke direction.

Direction Strength

Controls how noticeable that directional difference is:

  • Low values = very subtle

  • High values = clearly directional

Together, these properties make the brush feel more natural and intentional.

Prompt - Adding Direction and Direction strength

Extend the existing brush-like path distortion
by adding directional bias to break symmetry.

Add two new input parameters:

- direction (number, default: 0)
  Controls the dominant distortion direction:
  0 = uniform (all edges behave equally)
  1 = horizontal bias (top and bottom edges distort more,
      left and right edges distort less)
  2 = vertical bias (left and right edges distort more,
      top and bottom edges distort less)

- directionStrength (range: 0–10, default: 4)
  Controls how strong the directional bias is.
  Low values should be subtle,
  higher values should clearly emphasize the chosen direction.

Apply the directional bias smoothly and gradually,
without creating sharp transitions or breaking the shape.

The goal is to make the brush feel more hand-drawn
by introducing controlled asymmetry,
while keeping the result clean and suitable for UI

Extend the existing brush-like path distortion
by adding directional bias to break symmetry.

Add two new input parameters:

- direction (number, default: 0)
  Controls the dominant distortion direction:
  0 = uniform (all edges behave equally)
  1 = horizontal bias (top and bottom edges distort more,
      left and right edges distort less)
  2 = vertical bias (left and right edges distort more,
      top and bottom edges distort less)

- directionStrength (range: 0–10, default: 4)
  Controls how strong the directional bias is.
  Low values should be subtle,
  higher values should clearly emphasize the chosen direction.

Apply the directional bias smoothly and gradually,
without creating sharp transitions or breaking the shape.

The goal is to make the brush feel more hand-drawn
by introducing controlled asymmetry,
while keeping the result clean and suitable for UI

Extend the existing brush-like path distortion
by adding directional bias to break symmetry.

Add two new input parameters:

- direction (number, default: 0)
  Controls the dominant distortion direction:
  0 = uniform (all edges behave equally)
  1 = horizontal bias (top and bottom edges distort more,
      left and right edges distort less)
  2 = vertical bias (left and right edges distort more,
      top and bottom edges distort less)

- directionStrength (range: 0–10, default: 4)
  Controls how strong the directional bias is.
  Low values should be subtle,
  higher values should clearly emphasize the chosen direction.

Apply the directional bias smoothly and gradually,
without creating sharp transitions or breaking the shape.

The goal is to make the brush feel more hand-drawn
by introducing controlled asymmetry,
while keeping the result clean and suitable for UI

Adding Animation (Stop Motion Style)

At this point, we have a solid brush effect. We could keep refining it - adding more properties and logic - but instead, we move on to animation.

Because this brush is meant to feel rough and hand-made, a stop-motion style animation works well.

Stop motion uses small, stepped movements, creating a slightly jittery, imperfect motion that complements the brush aesthetic.

Prompt - Animation logic:

Extend the existing brush-like path distortion
by adding optional stop-motion style animation.

Add two new input parameters:

- animate (boolean, default: false)
  Enables or disables animation.

- animationSpeed (number, default: 0.5)
  Controls how often the distortion updates.
  Lower values should result in slower, subtler motion,
  higher values in faster, more noticeable changes.

When animation is enabled:
- Update the distortion only at discrete time intervals
  (not every frame) to create a stop-motion feel.
- Slightly offset the existing distortion pattern
  (for example by shifting the seed)
  rather than generating a completely new shape.
- Keep each frame stable until the next update.

When animation is disabled:
- The brush should remain completely static and deterministic.

The animation should feel subtle, hand-drawn,
and suitable for UI not fluid or noisy

Extend the existing brush-like path distortion
by adding optional stop-motion style animation.

Add two new input parameters:

- animate (boolean, default: false)
  Enables or disables animation.

- animationSpeed (number, default: 0.5)
  Controls how often the distortion updates.
  Lower values should result in slower, subtler motion,
  higher values in faster, more noticeable changes.

When animation is enabled:
- Update the distortion only at discrete time intervals
  (not every frame) to create a stop-motion feel.
- Slightly offset the existing distortion pattern
  (for example by shifting the seed)
  rather than generating a completely new shape.
- Keep each frame stable until the next update.

When animation is disabled:
- The brush should remain completely static and deterministic.

The animation should feel subtle, hand-drawn,
and suitable for UI not fluid or noisy

Extend the existing brush-like path distortion
by adding optional stop-motion style animation.

Add two new input parameters:

- animate (boolean, default: false)
  Enables or disables animation.

- animationSpeed (number, default: 0.5)
  Controls how often the distortion updates.
  Lower values should result in slower, subtler motion,
  higher values in faster, more noticeable changes.

When animation is enabled:
- Update the distortion only at discrete time intervals
  (not every frame) to create a stop-motion feel.
- Slightly offset the existing distortion pattern
  (for example by shifting the seed)
  rather than generating a completely new shape.
- Keep each frame stable until the next update.

When animation is disabled:
- The brush should remain completely static and deterministic.

The animation should feel subtle, hand-drawn,
and suitable for UI not fluid or noisy

Once applied, we can enable animation, adjust speed live, and see the effect update in real time.
If the animation feels too slow, a simple follow-up works:

Can you make the animation faster
Can you make the animation faster
Can you make the animation faster

Using the Brush in Real UI

Finally, we can turn this effect into something reusable.

The brush becomes a component, connected to Data Binding, and reused across multiple UI elements - for example, "New" and "On Sale" labels.

The same script drives:

  • Shape distortion

  • Animation

  • Responsiveness

  • Visual consistency

This is where scripting really shines. A small piece of logic becomes a reusable, expressive UI system.

Wrapping Up

Path Effect Scripts can turn simple shapes into dynamic, animated, and reusable UI elements.

The brush we built isn't "final" - and that's the point. You can keep refining it, extending it, and adapting it to your own needs.

🎓 Ready to Master Rive?

Learn to build production-ready interactive animations in the
Rive Masterclass for Designers.

Learn to build interactive animations in
the Rive Masterclass for Designers.

Related articles