Source code for camtasia.effects.source

"""Source effects for shader videos."""
from __future__ import annotations

from typing import Any

from camtasia.effects.base import Effect, register_effect


[docs] @register_effect("SourceEffect") class SourceEffect(Effect): """Source effect for shader video parameters. Parameters: Color0-3 (RGBA via separate keys), MidPointX, MidPointY, Speed, sourceFileType. """ def _color_key_prefix(self, index: int) -> str: """Get the correct color key prefix (Color0 or Color000 for Lottie).""" short_key = f"Color{index}" padded_key = f"Color{index:03d}" # Check which format exists in the parameters params = self._data.get('parameters', {}) if f"{padded_key}-red" in params: return padded_key # pragma: no cover return short_key def _get_color(self, index: int) -> tuple[float, float, float, float]: """Get RGBA for Color{index}.""" prefix = self._color_key_prefix(index) return ( self.get_parameter(f"{prefix}-red"), self.get_parameter(f"{prefix}-green"), self.get_parameter(f"{prefix}-blue"), self.get_parameter(f"{prefix}-alpha"), ) def _set_color(self, index: int, rgba: tuple[float, float, float, float]) -> None: """Set RGBA for Color{index}.""" prefix = self._color_key_prefix(index) self.set_parameter(f"{prefix}-red", rgba[0]) self.set_parameter(f"{prefix}-green", rgba[1]) self.set_parameter(f"{prefix}-blue", rgba[2]) self.set_parameter(f"{prefix}-alpha", rgba[3]) @property def color0(self) -> tuple[float, float, float, float]: """First shader color as RGBA floats.""" return self._get_color(0) @color0.setter def color0(self, rgba: tuple[float, float, float, float]) -> None: """Set the first shader color.""" self._set_color(0, rgba) @property def color1(self) -> tuple[float, float, float, float]: """Second shader color as RGBA floats.""" return self._get_color(1) @color1.setter def color1(self, rgba: tuple[float, float, float, float]) -> None: """Set the second shader color.""" self._set_color(1, rgba) def _get_value(self, val: Any) -> float: """Extract scalar from a parameter value (dict or raw).""" return float(val['defaultValue'] if isinstance(val, dict) else val) @property def color2(self) -> tuple[float, float, float, float] | None: """Third shader color as RGBA floats, or None if not present.""" try: return self._get_color(2) except KeyError: return None @color2.setter def color2(self, rgba: tuple[float, float, float, float]) -> None: """Set the third shader color.""" self._set_color(2, rgba) @property def color3(self) -> tuple[float, float, float, float] | None: """Fourth shader color as RGBA floats, or None if not present.""" try: return self._get_color(3) except KeyError: return None @color3.setter def color3(self, rgba: tuple[float, float, float, float]) -> None: """Set the fourth shader color.""" self._set_color(3, rgba) @property def mid_point(self) -> tuple[float, float] | float: """Mid point position. Returns (x, y) tuple for four-corner gradients or a single float for radial gradients.""" params = self._data.get('parameters', {}) if 'MidPointX' in params: x = self._get_value(params.get('MidPointX', 0.5)) y = self._get_value(params.get('MidPointY', 0.5)) return (x, y) elif 'MidPoint' in params: return self._get_value(params.get('MidPoint', 0.5)) return (0.5, 0.5) @mid_point.setter def mid_point(self, value: tuple[float, float] | float) -> None: """Set the mid point position.""" params = self._data.setdefault('parameters', {}) if isinstance(value, (int, float)): params['MidPoint'] = value else: params['MidPointX'] = value[0] params['MidPointY'] = value[1] @property def speed(self) -> float: """Shader animation speed.""" return float(self.get_parameter("Speed")) @speed.setter def speed(self, value: float) -> None: """Set the shader animation speed.""" self.set_parameter("Speed", value) @property def source_file_type(self) -> str: """Source file type identifier for the shader.""" return str(self.get_parameter("sourceFileType"))
[docs] def set_shader_colors(self, *colors: tuple[int, int, int]) -> None: """Set shader colours from 0-255 RGB tuples. Accepts 2 colors (radial gradient) or 4 colors (four-corner gradient). Alpha is set to 1.0 for all colours. Args: colors: ``(r, g, b)`` tuples with values 0–255. """ params = self._data.setdefault('parameters', {}) for i, rgb in enumerate(colors): prefix = self._color_key_prefix(i) r, g, b = rgb[0] / 255, rgb[1] / 255, rgb[2] / 255 params[f'{prefix}-red'] = r params[f'{prefix}-green'] = g params[f'{prefix}-blue'] = b params[f'{prefix}-alpha'] = 1.0