Skip to main content

Composable layout primitives for MoviePy, with RGBA gradients and asset modes

Project description

moviepy-layout

Composable layout primitives for MoviePy, inspired by Flutter and CSS.

✨ Features

  • 🎨 Gradient backgrounds with directional control
  • 🖼️ Asset resizing (cover, contain, fit, fill)
  • 📦 Box & Container layouts with padding, margin, background color/gradient
  • 📐 Flex layouts (row, column) with alignment & gaps
  • 📚 Stack layouts for overlaying clips by z-index
  • 🔤 Text utilities with alignment, wrapping, gradients, shadows
  • 🎭 Effects like shadow, blur, inner shadow
  • 🎨 Color conversion utilities (hex ↔ rgba)

📦 Installation

pip install moviepy-layout

🚀 Usage Example

from moviepy.editor import ImageClip
from moviepy-layout import Layout, Gradient

# Create a gradient background
gradient = Gradient(
    direction="top_to_bottom",
    stops=[
        ((255, 0, 0, 255), 0.0),
        ((0, 0, 255, 255), 1.0),
    ]
)

bg = ImageClip(gradient.render((1280, 720)), ismask=False)

# Resize with cover mode
clip = Layout.asset(bg, width=720, height=1280, mode="cover")
clip.preview()

🛠️ API Reference

🎨 Gradient

Gradient(
    direction="top_to_bottom",  # gradient direction
    stops=[((r,g,b,a), position), ...]  # color stops
).render((width, height))

Supported directions:

  • top_to_bottom
  • bottom_to_top
  • left_to_right
  • right_to_left
  • top_left_to_bottom_right
  • bottom_right_to_top_left
  • top_right_to_bottom_left
  • bottom_left_to_top_right

🎬 Layout Utilities

Layout.asset(...)

Resize a clip with a given mode.

  • cover: fills container, crops excess
  • contain: fits inside container, maintains aspect ratio
  • fit: resizes to match one dimension
  • fill: stretches to fill container

Layout.box(...)

Create a box with optional child.

Layout.box(
    width=500,
    height=500,
    child=my_clip,
    padding=(10, 20, 10, 20),
    margin=(5, 5, 5, 5),
    bg_color=(255, 255, 255),
    duration=5.0,
    screen_size=(1080, 1920)
)

Layout.container(...)

A more advanced box with alignment, gradient, radius, and border options.

Layout.container(
    child=my_clip,
    padding=20,  # or (top, right, bottom, left)
    margin=10,
    vertical_alignment="center",  # "top" | "center" | "bottom"
    horizontal_alignment="center",  # "left" | "center" | "right"
    gradient=my_gradient,  # optional Gradient instance
    bg_color=(255, 255, 255, 255),
    radius=10,  # rounded corners
    border={"color": (0, 0, 0, 255), "width": 2},
    size=(500, 500),
    duration=5.0
)

Layout.flex(...)

Arrange multiple clips in a row or column.

Layout.flex(
    children=[clip1, clip2, clip3],
    direction="row",  # "row" | "column"
    vertical_alignment="center",  # for "column" direction
    horizontal_alignment="center",  # for "row" direction
    gap=20,  # space between children
    width="fit",   # "full" | "fit"
    height="fit",  # "full" | "fit"
    screen_size=(1080, 1920),
    duration=5.0
)

Layout.stack(...)

Overlay clips with z-order.

Layout.stack(
    children=[(background_clip, 0), (overlay_clip, 1), (text_clip, 2)],
    size=(1080, 1920),
    duration=5.0
)

Layout.text(...)

Create styled text clips with gradient, shadows, alignment, wrapping.

Layout.text(
    text="Hello World",
    font_size=64,
    font="Arial",
    width=500,  # optional, for wrapping
    gradient_hex="#ff0000ff,#0000ffff",  # optional gradient fill
    font_color=(255, 255, 255, 255),
    text_align="center",  # "left" | "center" | "right"
    text_wrap=True,
    shadow={
        "color": (0, 0, 0, 128),
        "offset": (4, 4),
        "blur": 5
    },
    duration=5.0
)

Layout.effect(...)

Apply visual effects (shadow, blur, inner_shadow) to clips.

  • Shadow
Layout.effect(my_clip, effect="shadow", effect_params={"color": (0, 0, 0, 128), "offset": (10, 10)})
  • Blur
Layout.effect(my_clip, effect="blur", effect_params={"radius": 5})
  • Inner Shadow
Layout.effect(my_clip, effect="inner_shadow", effect_params={"color": (0, 0, 0, 128), "offset": (5, 5), "blur": 10})

🎨 Color Utilities

Layout.rgba_to_hex((255, 0, 0, 255))  # "#ff0000ff"
Layout.hex_to_rgba("#ff0000ff")       # (255, 0, 0, 255)

📖 Example Project Ideas

  • Instagram story generators
  • Slideshow editors
  • Dynamic caption overlays
  • UI-style compositions with MoviePy

📜 License

MIT License © 2025 Kmm Hanan

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

moviepy_layout-0.1.0.tar.gz (11.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

moviepy_layout-0.1.0-py3-none-any.whl (10.2 kB view details)

Uploaded Python 3

File details

Details for the file moviepy_layout-0.1.0.tar.gz.

File metadata

  • Download URL: moviepy_layout-0.1.0.tar.gz
  • Upload date:
  • Size: 11.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for moviepy_layout-0.1.0.tar.gz
Algorithm Hash digest
SHA256 716de9bf5e47491be00db0c49ddad830ca2899ea4ed36c207d3c850d91fea7cc
MD5 2cd4092a4b0cfef85388903242dc86d0
BLAKE2b-256 9f7d700f8e7f7ddedc8f64b6b4585cc056344796b8912356fb6935c171619d59

See more details on using hashes here.

File details

Details for the file moviepy_layout-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: moviepy_layout-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for moviepy_layout-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bf72137b9c461bc77a9edcc42c9011d86f042341f093beb3137896c36d48de0a
MD5 08f25dd288350676c5c9b1976753bfef
BLAKE2b-256 483b6ea2328685c0095edd520f84b5abe7c81f0e861f866cb87a124c98479c5a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page