or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

asset-management.mdcomposition-loading.mdconfiguration-performance.mddynamic-properties.mdindex.mdview-components.md

dynamic-properties.mddocs/

0

# Dynamic Properties

1

2

Runtime animation modification system using keypaths to target specific elements and properties. This powerful system allows you to dynamically change colors, positions, transforms, and other animation properties without modifying the source animation files.

3

4

## Capabilities

5

6

### KeyPath Targeting

7

8

KeyPath system for targeting specific animation elements using hierarchical paths with support for wildcards and globstars.

9

10

```java { .api }

11

/**

12

* Keypath for targeting specific animation elements

13

*/

14

public class KeyPath {

15

// Constructors

16

public KeyPath(String... keys);

17

18

// Static instances

19

public static final KeyPath COMPOSITION; // Targets root composition

20

21

// Path manipulation (internal)

22

@RestrictTo(RestrictTo.Scope.LIBRARY)

23

public KeyPath addKey(String key);

24

@RestrictTo(RestrictTo.Scope.LIBRARY)

25

public KeyPath resolve(KeyPathElement element);

26

@RestrictTo(RestrictTo.Scope.LIBRARY)

27

public KeyPathElement getResolvedElement();

28

29

// Path matching (internal)

30

@RestrictTo(RestrictTo.Scope.LIBRARY)

31

public boolean matches(String key, int depth);

32

@RestrictTo(RestrictTo.Scope.LIBRARY)

33

public int incrementDepthBy(String key, int depth);

34

@RestrictTo(RestrictTo.Scope.LIBRARY)

35

public boolean fullyResolvesTo(String key, int depth);

36

@RestrictTo(RestrictTo.Scope.LIBRARY)

37

public boolean propagateToChildren(String key, int depth);

38

39

// Utility methods

40

public String keysToString();

41

42

@Override

43

public boolean equals(Object o);

44

@Override

45

public int hashCode();

46

@Override

47

public String toString();

48

}

49

```

50

51

**KeyPath Patterns:**

52

53

- **Exact match**: `new KeyPath("Layer Name", "Shape Group", "Fill")`

54

- **Wildcard** (`*`): Matches exactly one element - `new KeyPath("*", "Shape Group", "Fill")`

55

- **Globstar** (`**`): Matches zero or more elements - `new KeyPath("**", "Fill")`

56

- **Root composition**: `KeyPath.COMPOSITION` - targets the entire animation

57

58

**Usage Examples:**

59

60

```java

61

// Target specific layer's fill color

62

KeyPath colorPath = new KeyPath("Character", "Body", "Fill 1");

63

animationView.addValueCallback(colorPath, LottieProperty.COLOR,

64

new LottieValueCallback<>(Color.BLUE));

65

66

// Target all fills in animation

67

KeyPath allFills = new KeyPath("**", "Fill");

68

animationView.addValueCallback(allFills, LottieProperty.COLOR,

69

new LottieValueCallback<>(Color.GREEN));

70

71

// Target specific layer with wildcard

72

KeyPath layerPath = new KeyPath("Layer *", "Transform");

73

animationView.addValueCallback(layerPath, LottieProperty.TRANSFORM_OPACITY,

74

new LottieValueCallback<>(50)); // 50% opacity

75

76

// Target root composition transform

77

animationView.addValueCallback(KeyPath.COMPOSITION, LottieProperty.TRANSFORM_SCALE,

78

new LottieValueCallback<>(new ScaleXY(2.0f, 2.0f)));

79

80

// Resolve keypath to see what elements match

81

List<KeyPath> resolvedPaths = animationView.resolveKeyPath(new KeyPath("**", "Fill"));

82

for (KeyPath path : resolvedPaths) {

83

Log.d("Lottie", "Resolved path: " + path.keysToString());

84

}

85

```

86

87

### LottieProperty Constants

88

89

Constants defining all animatable properties that can be modified through dynamic property callbacks.

90

91

```java { .api }

92

/**

93

* Constants for animatable properties

94

*/

95

public interface LottieProperty {

96

// Color properties (ColorInt values)

97

Integer COLOR = 1;

98

Integer STROKE_COLOR = 2;

99

Integer DROP_SHADOW_COLOR = 5;

100

101

// Opacity properties (0-100 to match After Effects)

102

Integer TRANSFORM_OPACITY = 3;

103

Integer OPACITY = 4; // [0,100]

104

Float DROP_SHADOW_OPACITY = 15f; // [0,100]

105

Float TRANSFORM_START_OPACITY = 12f; // [0,100]

106

Float TRANSFORM_END_OPACITY = 12.1f; // [0,100]

107

108

// Transform properties

109

PointF TRANSFORM_ANCHOR_POINT = new PointF(); // In Px

110

PointF TRANSFORM_POSITION = new PointF(); // In Px

111

Float TRANSFORM_POSITION_X = 15f; // In Px (when split dimensions enabled)

112

Float TRANSFORM_POSITION_Y = 16f; // In Px (when split dimensions enabled)

113

ScaleXY TRANSFORM_SCALE = new ScaleXY();

114

Float TRANSFORM_ROTATION = 1f; // In degrees

115

Float TRANSFORM_SKEW = 0f; // 0-85

116

Float TRANSFORM_SKEW_ANGLE = 0f; // In degrees

117

118

// Shape properties

119

PointF ELLIPSE_SIZE = new PointF(); // In Px

120

PointF RECTANGLE_SIZE = new PointF(); // In Px

121

Float CORNER_RADIUS = 0f; // In degrees

122

PointF POSITION = new PointF(); // In Px

123

124

// Stroke properties

125

Float STROKE_WIDTH = 2f; // In Px

126

127

// Polystar properties

128

Float POLYSTAR_POINTS = 6f;

129

Float POLYSTAR_ROTATION = 7f; // In degrees

130

Float POLYSTAR_INNER_RADIUS = 8f; // In Px

131

Float POLYSTAR_OUTER_RADIUS = 9f; // In Px

132

Float POLYSTAR_INNER_ROUNDEDNESS = 10f; // [0,100]

133

Float POLYSTAR_OUTER_ROUNDEDNESS = 11f; // [0,100]

134

135

// Repeater properties

136

Float REPEATER_COPIES = 4f;

137

Float REPEATER_OFFSET = 5f;

138

139

// Text properties

140

Float TEXT_TRACKING = 3f;

141

Float TEXT_SIZE = 14f; // In Dp

142

Typeface TYPEFACE = Typeface.DEFAULT;

143

CharSequence TEXT = "dynamic_text";

144

145

// Time properties

146

Float TIME_REMAP = 13f; // Time value in seconds

147

148

// Effect properties

149

Float BLUR_RADIUS = 17f; // In Px

150

ColorFilter COLOR_FILTER = new ColorFilter();

151

152

// Drop shadow properties (resolved on drawing content)

153

Float DROP_SHADOW_DIRECTION = 16f; // Degrees from 12 o'clock

154

Float DROP_SHADOW_DISTANCE = 17f; // In Px

155

Float DROP_SHADOW_RADIUS = 18f; // In Px

156

157

// Gradient properties

158

Integer[] GRADIENT_COLOR = new Integer[0]; // Array of ARGB colors

159

160

// Image properties

161

Bitmap IMAGE = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);

162

}

163

```

164

165

**Usage Examples:**

166

167

```java

168

// Change fill color

169

animationView.addValueCallback(

170

new KeyPath("Layer", "Shape", "Fill"),

171

LottieProperty.COLOR,

172

new LottieValueCallback<>(Color.parseColor("#FF5722"))

173

);

174

175

// Modify transform properties

176

animationView.addValueCallback(

177

new KeyPath("MovingObject"),

178

LottieProperty.TRANSFORM_POSITION,

179

new LottieValueCallback<>(new PointF(100, 200))

180

);

181

182

// Adjust opacity

183

animationView.addValueCallback(

184

new KeyPath("FadingLayer"),

185

LottieProperty.TRANSFORM_OPACITY,

186

new LottieValueCallback<>(75) // 75% opacity

187

);

188

189

// Scale animation

190

animationView.addValueCallback(

191

KeyPath.COMPOSITION,

192

LottieProperty.TRANSFORM_SCALE,

193

new LottieValueCallback<>(new ScaleXY(1.5f, 1.5f))

194

);

195

196

// Change stroke width

197

animationView.addValueCallback(

198

new KeyPath("**", "Stroke"),

199

LottieProperty.STROKE_WIDTH,

200

new LottieValueCallback<>(8.0f) // 8px stroke

201

);

202

203

// Dynamic text replacement

204

animationView.addValueCallback(

205

new KeyPath("TextLayer"),

206

LottieProperty.TEXT,

207

new LottieValueCallback<>("New Dynamic Text")

208

);

209

210

// Apply color filter to entire animation

211

animationView.addValueCallback(

212

KeyPath.COMPOSITION,

213

LottieProperty.COLOR_FILTER,

214

new LottieValueCallback<>(new PorterDuffColorFilter(Color.BLUE, PorterDuff.Mode.SRC_ATOP))

215

);

216

217

// Replace image asset

218

animationView.addValueCallback(

219

new KeyPath("ImageLayer"),

220

LottieProperty.IMAGE,

221

new LottieValueCallback<>(customBitmap)

222

);

223

```

224

225

### LottieValueCallback System

226

227

Base callback system for providing dynamic values to animation properties. Supports both static values and frame-by-frame dynamic values.

228

229

```java { .api }

230

/**

231

* Base class for dynamic property callbacks

232

*/

233

public class LottieValueCallback<T> {

234

// Constructors

235

public LottieValueCallback();

236

public LottieValueCallback(T staticValue);

237

238

// Value provision

239

public T getValue(LottieFrameInfo<T> frameInfo);

240

public final void setValue(T value);

241

242

// Internal animation binding

243

@RestrictTo(RestrictTo.Scope.LIBRARY)

244

public final T getValueInternal(

245

float startFrame,

246

float endFrame,

247

T startValue,

248

T endValue,

249

float linearKeyframeProgress,

250

float interpolatedKeyframeProgress,

251

float overallProgress);

252

@RestrictTo(RestrictTo.Scope.LIBRARY)

253

public final void setAnimation(BaseKeyframeAnimation<?, ?> animation);

254

}

255

256

/**

257

* Frame information provided to value callbacks

258

*/

259

public class LottieFrameInfo<T> {

260

// Frame timing

261

public float getStartFrame();

262

public float getEndFrame();

263

264

// Keyframe values

265

public T getStartValue();

266

public T getEndValue();

267

268

// Progress information

269

public float getLinearKeyframeProgress(); // Linear progress 0-1

270

public float getInterpolatedKeyframeProgress(); // Eased progress 0-1

271

public float getOverallProgress(); // Overall animation progress 0-1

272

273

// Internal state management

274

@RestrictTo(RestrictTo.Scope.LIBRARY)

275

public LottieFrameInfo<T> set(

276

float startFrame, float endFrame,

277

T startValue, T endValue,

278

float linearKeyframeProgress,

279

float interpolatedKeyframeProgress,

280

float overallProgress);

281

}

282

```

283

284

**Usage Examples:**

285

286

```java

287

// Static value callback

288

animationView.addValueCallback(

289

new KeyPath("Layer"),

290

LottieProperty.COLOR,

291

new LottieValueCallback<>(Color.RED) // Always red

292

);

293

294

// Dynamic value callback

295

animationView.addValueCallback(

296

new KeyPath("PulsingCircle"),

297

LottieProperty.TRANSFORM_SCALE,

298

new LottieValueCallback<ScaleXY>() {

299

@Override

300

public ScaleXY getValue(LottieFrameInfo<ScaleXY> frameInfo) {

301

// Pulse between 0.8x and 1.2x based on progress

302

float progress = frameInfo.getOverallProgress();

303

float scale = 1.0f + 0.2f * (float) Math.sin(progress * Math.PI * 4);

304

return new ScaleXY(scale, scale);

305

}

306

}

307

);

308

309

// Color interpolation based on progress

310

animationView.addValueCallback(

311

new KeyPath("ColorChangingShape"),

312

LottieProperty.COLOR,

313

new LottieValueCallback<Integer>() {

314

@Override

315

public Integer getValue(LottieFrameInfo<Integer> frameInfo) {

316

float progress = frameInfo.getOverallProgress();

317

// Interpolate from red to blue

318

int red = (int) (255 * (1 - progress));

319

int blue = (int) (255 * progress);

320

return Color.rgb(red, 0, blue);

321

}

322

}

323

);

324

325

// Position animation following circular path

326

animationView.addValueCallback(

327

new KeyPath("CircularMotion"),

328

LottieProperty.TRANSFORM_POSITION,

329

new LottieValueCallback<PointF>() {

330

@Override

331

public PointF getValue(LottieFrameInfo<PointF> frameInfo) {

332

float progress = frameInfo.getOverallProgress();

333

float angle = progress * 2 * (float) Math.PI;

334

float radius = 100f;

335

float centerX = 200f;

336

float centerY = 200f;

337

338

return new PointF(

339

centerX + radius * (float) Math.cos(angle),

340

centerY + radius * (float) Math.sin(angle)

341

);

342

}

343

}

344

);

345

346

// Using keyframe interpolation values

347

animationView.addValueCallback(

348

new KeyPath("BlendingShape"),

349

LottieProperty.COLOR,

350

new LottieValueCallback<Integer>() {

351

@Override

352

public Integer getValue(LottieFrameInfo<Integer> frameInfo) {

353

// Use original keyframe values with custom blending

354

Integer startColor = frameInfo.getStartValue();

355

Integer endColor = frameInfo.getEndValue();

356

float interpolatedProgress = frameInfo.getInterpolatedKeyframeProgress();

357

358

if (startColor == null || endColor == null) {

359

return Color.WHITE; // Fallback

360

}

361

362

// Custom color interpolation

363

return interpolateColor(startColor, endColor, interpolatedProgress);

364

}

365

366

private Integer interpolateColor(Integer startColor, Integer endColor, float progress) {

367

int startRed = Color.red(startColor);

368

int startGreen = Color.green(startColor);

369

int startBlue = Color.blue(startColor);

370

371

int endRed = Color.red(endColor);

372

int endGreen = Color.green(endColor);

373

int endBlue = Color.blue(endColor);

374

375

int red = (int) (startRed + (endRed - startRed) * progress);

376

int green = (int) (startGreen + (endGreen - startGreen) * progress);

377

int blue = (int) (startBlue + (endBlue - startBlue) * progress);

378

379

return Color.rgb(red, green, blue);

380

}

381

}

382

);

383

384

// Update static value dynamically

385

LottieValueCallback<Integer> colorCallback = new LottieValueCallback<>(Color.RED);

386

animationView.addValueCallback(path, LottieProperty.COLOR, colorCallback);

387

388

// Later, change the static value

389

colorCallback.setValue(Color.BLUE); // Animation will update automatically

390

```

391

392

### Specialized Value Callbacks

393

394

Pre-built callback implementations for common use cases involving relative values and interpolation.

395

396

```java { .api }

397

/**

398

* Simple static value callback

399

*/

400

public class SimpleLottieValueCallback<T> extends LottieValueCallback<T> {

401

public SimpleLottieValueCallback(T value);

402

}

403

404

/**

405

* Relative float value callback

406

*/

407

public class LottieRelativeFloatValueCallback extends LottieValueCallback<Float> {

408

public LottieRelativeFloatValueCallback();

409

public LottieRelativeFloatValueCallback(Float staticValue);

410

public Float getOffset(LottieFrameInfo<Float> frameInfo);

411

}

412

413

/**

414

* Relative integer value callback

415

*/

416

public class LottieRelativeIntegerValueCallback extends LottieValueCallback<Integer> {

417

public LottieRelativeIntegerValueCallback();

418

public LottieRelativeIntegerValueCallback(Integer staticValue);

419

public Integer getOffset(LottieFrameInfo<Integer> frameInfo);

420

}

421

422

/**

423

* Relative point value callback

424

*/

425

public class LottieRelativePointValueCallback extends LottieValueCallback<PointF> {

426

public LottieRelativePointValueCallback();

427

public LottieRelativePointValueCallback(PointF staticValue);

428

public PointF getOffset(LottieFrameInfo<PointF> frameInfo);

429

}

430

431

/**

432

* Interpolated float value

433

*/

434

public class LottieInterpolatedFloatValue extends LottieValueCallback<Float> {

435

public LottieInterpolatedFloatValue(Float startValue, Float endValue);

436

public LottieInterpolatedFloatValue(Float startValue, Float endValue, Interpolator interpolator);

437

}

438

439

/**

440

* Interpolated integer value

441

*/

442

public class LottieInterpolatedIntegerValue extends LottieValueCallback<Integer> {

443

public LottieInterpolatedIntegerValue(Integer startValue, Integer endValue);

444

public LottieInterpolatedIntegerValue(Integer startValue, Integer endValue, Interpolator interpolator);

445

}

446

447

/**

448

* Interpolated point value

449

*/

450

public class LottieInterpolatedPointValue extends LottieValueCallback<PointF> {

451

public LottieInterpolatedPointValue(PointF startValue, PointF endValue);

452

public LottieInterpolatedPointValue(PointF startValue, PointF endValue, Interpolator interpolator);

453

}

454

```

455

456

**Usage Examples:**

457

458

```java

459

// Simple static callback

460

animationView.addValueCallback(

461

path,

462

LottieProperty.COLOR,

463

new SimpleLottieValueCallback<>(Color.MAGENTA)

464

);

465

466

// Relative offset - adds to original animation values

467

animationView.addValueCallback(

468

new KeyPath("MovingObject"),

469

LottieProperty.TRANSFORM_POSITION,

470

new LottieRelativePointValueCallback(new PointF(50, 100)) // Offset by 50,100

471

);

472

473

// Interpolated values with custom interpolation

474

animationView.addValueCallback(

475

new KeyPath("FadingElement"),

476

LottieProperty.TRANSFORM_OPACITY,

477

new LottieInterpolatedFloatValue(

478

100f, 0f, // From 100% to 0% opacity

479

new AccelerateDecelerateInterpolator()

480

)

481

);

482

483

// Dynamic relative positioning

484

animationView.addValueCallback(

485

new KeyPath("FollowingElement"),

486

LottieProperty.TRANSFORM_POSITION,

487

new LottieRelativePointValueCallback() {

488

@Override

489

public PointF getOffset(LottieFrameInfo<PointF> frameInfo) {

490

// Dynamic offset based on animation progress

491

float progress = frameInfo.getOverallProgress();

492

return new PointF(progress * 200f, (float) Math.sin(progress * Math.PI) * 50f);

493

}

494

}

495

);

496

```

497

498

## Utility Classes

499

500

```java { .api }

501

public class ScaleXY {

502

public ScaleXY();

503

public ScaleXY(float scaleX, float scaleY);

504

505

public float getScaleX();

506

public float getScaleY();

507

public void set(float scaleX, float scaleY);

508

509

@Override

510

public String toString();

511

}

512

513

public interface KeyPathElement {

514

void resolveKeyPath(KeyPath keyPath, int depth, List<KeyPath> accumulator, KeyPath currentPartialKeyPath);

515

void addValueCallback(T property, LottieValueCallback<T> callback);

516

}

517

```