or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ajax-networking.mdbrowser-integration.mdcli-tools.mdhtml-elements.mdindex.mdruntime-engine.mdstorage.mdtimers-animation.mdui-framework.mdwebsocket.md

timers-animation.mddocs/

0

# Timers and Animation

1

2

Timer functions and animation frame requests for time-based functionality and smooth animations in web applications. Provides Python interfaces to browser timing APIs.

3

4

## Capabilities

5

6

### Basic Timers

7

8

Execute functions after delays or at regular intervals.

9

10

```python { .api }

11

def set_timeout(func: Callable, interval: int, *args) -> int:

12

"""

13

Execute function after specified delay.

14

15

Args:

16

func: Function to execute

17

interval: Delay in milliseconds

18

*args: Arguments to pass to function

19

20

Returns:

21

Timer ID for cancellation

22

"""

23

24

def set_interval(func: Callable, interval: int, *args) -> int:

25

"""

26

Execute function repeatedly at specified interval.

27

28

Args:

29

func: Function to execute

30

interval: Interval in milliseconds

31

*args: Arguments to pass to function

32

33

Returns:

34

Timer ID for cancellation

35

"""

36

37

def clear_timeout(timer_id: int) -> None:

38

"""

39

Cancel scheduled timeout.

40

41

Args:

42

timer_id: Timer ID returned by set_timeout

43

"""

44

45

def clear_interval(timer_id: int) -> None:

46

"""

47

Cancel repeating interval.

48

49

Args:

50

timer_id: Timer ID returned by set_interval

51

"""

52

```

53

54

**Usage:**

55

```python

56

from browser.timer import set_timeout, set_interval, clear_timeout, clear_interval

57

58

def delayed_message():

59

print("This message appears after 2 seconds")

60

61

def periodic_update():

62

print("Updating every 5 seconds...")

63

64

# Schedule one-time execution

65

timeout_id = set_timeout(delayed_message, 2000)

66

67

# Schedule repeating execution

68

interval_id = set_interval(periodic_update, 5000)

69

70

# Cancel timers if needed

71

def cancel_timers():

72

clear_timeout(timeout_id)

73

clear_interval(interval_id)

74

print("All timers cancelled")

75

76

# Cancel after 30 seconds

77

set_timeout(cancel_timers, 30000)

78

```

79

80

### Animation Frames

81

82

Smooth animations synchronized with browser refresh rate.

83

84

```python { .api }

85

def request_animation_frame(func: Callable) -> int:

86

"""

87

Request function execution on next animation frame.

88

89

Args:

90

func: Animation function to execute

91

92

Returns:

93

Animation frame ID for cancellation

94

95

The callback function receives timestamp as parameter.

96

"""

97

98

def cancel_animation_frame(frame_id: int) -> None:

99

"""

100

Cancel pending animation frame request.

101

102

Args:

103

frame_id: Frame ID returned by request_animation_frame

104

"""

105

```

106

107

**Usage:**

108

```python

109

from browser.timer import request_animation_frame, cancel_animation_frame

110

from browser import document

111

from browser.html import DIV

112

113

# Create animated element

114

animated_div = DIV("Animated Content", style={

115

'position': 'absolute',

116

'left': '0px',

117

'top': '100px',

118

'width': '100px',

119

'height': '100px',

120

'background': 'blue',

121

'color': 'white',

122

'text-align': 'center'

123

})

124

125

document.body <= animated_div

126

127

# Animation state

128

animation_state = {

129

'x': 0,

130

'direction': 1,

131

'running': False,

132

'frame_id': None

133

}

134

135

def animate_element(timestamp):

136

"""Animation loop function."""

137

if not animation_state['running']:

138

return

139

140

# Update position

141

animation_state['x'] += animation_state['direction'] * 2

142

143

# Reverse direction at boundaries

144

if animation_state['x'] >= 500 or animation_state['x'] <= 0:

145

animation_state['direction'] *= -1

146

147

# Apply position

148

animated_div.style.left = f"{animation_state['x']}px"

149

150

# Continue animation

151

animation_state['frame_id'] = request_animation_frame(animate_element)

152

153

def start_animation():

154

"""Start the animation."""

155

if not animation_state['running']:

156

animation_state['running'] = True

157

animation_state['frame_id'] = request_animation_frame(animate_element)

158

159

def stop_animation():

160

"""Stop the animation."""

161

animation_state['running'] = False

162

if animation_state['frame_id']:

163

cancel_animation_frame(animation_state['frame_id'])

164

animation_state['frame_id'] = None

165

166

# Control buttons

167

from browser.html import BUTTON

168

from browser import bind

169

170

start_btn = BUTTON("Start Animation")

171

stop_btn = BUTTON("Stop Animation")

172

173

@bind(start_btn, 'click')

174

def handle_start(event):

175

start_animation()

176

177

@bind(stop_btn, 'click')

178

def handle_stop(event):

179

stop_animation()

180

181

document.body <= start_btn

182

document.body <= stop_btn

183

```

184

185

### Performance Timing

186

187

Monitor and optimize timing performance.

188

189

```python { .api }

190

def set_loop_timeout(seconds: int) -> None:

191

"""

192

Set maximum execution time for loops to prevent blocking.

193

194

Args:

195

seconds: Maximum execution time in seconds

196

"""

197

198

def get_timestamp() -> float:

199

"""

200

Get high-resolution timestamp.

201

202

Returns:

203

Timestamp in milliseconds with microsecond precision

204

"""

205

```

206

207

**Usage:**

208

```python

209

from browser.timer import set_loop_timeout, get_timestamp

210

211

# Set timeout for long-running operations

212

set_loop_timeout(5) # 5 second limit

213

214

def performance_test():

215

"""Measure function execution time."""

216

start_time = get_timestamp()

217

218

# Simulate work

219

total = 0

220

for i in range(1000000):

221

total += i

222

223

end_time = get_timestamp()

224

execution_time = end_time - start_time

225

226

print(f"Execution time: {execution_time:.2f}ms")

227

print(f"Total: {total}")

228

229

performance_test()

230

```

231

232

### Advanced Animation

233

234

Complex animations with easing and chaining.

235

236

```python { .api }

237

class Animator:

238

"""

239

Advanced animation controller.

240

"""

241

242

def __init__(self):

243

"""Initialize animator."""

244

245

def animate(self, element: Element, properties: dict, duration: int,

246

easing: str = 'linear') -> 'Animation':

247

"""

248

Animate element properties.

249

250

Args:

251

element: Target element

252

properties: Properties to animate with end values

253

duration: Animation duration in milliseconds

254

easing: Easing function name

255

256

Returns:

257

Animation object for control

258

"""

259

260

def chain(self, *animations) -> 'AnimationChain':

261

"""Chain multiple animations in sequence."""

262

263

def parallel(self, *animations) -> 'AnimationGroup':

264

"""Run multiple animations in parallel."""

265

266

class Animation:

267

"""Individual animation instance."""

268

269

def start(self) -> None:

270

"""Start animation."""

271

272

def pause(self) -> None:

273

"""Pause animation."""

274

275

def resume(self) -> None:

276

"""Resume paused animation."""

277

278

def stop(self) -> None:

279

"""Stop animation."""

280

281

def on_complete(self, callback: Callable) -> 'Animation':

282

"""Set completion callback."""

283

```

284

285

**Usage:**

286

```python

287

from browser.timer import Animator

288

from browser import document

289

from browser.html import DIV

290

291

# Create animator

292

animator = Animator()

293

294

# Create elements to animate

295

box1 = DIV("Box 1", style={

296

'position': 'absolute',

297

'width': '50px',

298

'height': '50px',

299

'background': 'red',

300

'left': '0px',

301

'top': '200px'

302

})

303

304

box2 = DIV("Box 2", style={

305

'position': 'absolute',

306

'width': '50px',

307

'height': '50px',

308

'background': 'blue',

309

'left': '0px',

310

'top': '260px'

311

})

312

313

document.body <= box1

314

document.body <= box2

315

316

# Create animations

317

move_right = animator.animate(box1, {

318

'left': '300px',

319

'background': 'green'

320

}, 2000, easing='ease-out')

321

322

move_up = animator.animate(box2, {

323

'top': '100px',

324

'width': '100px',

325

'height': '100px'

326

}, 1500, easing='ease-in-out')

327

328

# Chain animations

329

sequence = animator.chain(move_right, move_up)

330

331

# Parallel animations

332

parallel = animator.parallel(

333

animator.animate(box1, {'opacity': '0.5'}, 1000),

334

animator.animate(box2, {'opacity': '0.5'}, 1000)

335

)

336

337

# Start animations with callbacks

338

move_right.on_complete(lambda: print("Box 1 finished moving"))

339

sequence.start()

340

341

def complex_animation():

342

"""Complex multi-stage animation."""

343

344

# Stage 1: Move elements

345

stage1 = animator.parallel(

346

animator.animate(box1, {'left': '200px'}, 1000),

347

animator.animate(box2, {'left': '200px'}, 1000)

348

)

349

350

# Stage 2: Rotate and scale

351

stage2 = animator.parallel(

352

animator.animate(box1, {

353

'transform': 'rotate(180deg) scale(1.5)',

354

'background': 'purple'

355

}, 1500),

356

animator.animate(box2, {

357

'transform': 'rotate(-180deg) scale(0.8)',

358

'background': 'orange'

359

}, 1500)

360

)

361

362

# Stage 3: Return to original

363

stage3 = animator.parallel(

364

animator.animate(box1, {

365

'left': '0px',

366

'transform': 'rotate(0deg) scale(1)',

367

'background': 'red'

368

}, 2000),

369

animator.animate(box2, {

370

'left': '0px',

371

'transform': 'rotate(0deg) scale(1)',

372

'background': 'blue'

373

}, 2000)

374

)

375

376

# Chain all stages

377

full_sequence = animator.chain(stage1, stage2, stage3)

378

full_sequence.on_complete(lambda: print("Complex animation complete"))

379

full_sequence.start()

380

381

# Trigger complex animation

382

from browser.html import BUTTON

383

from browser import bind

384

385

complex_btn = BUTTON("Start Complex Animation")

386

387

@bind(complex_btn, 'click')

388

def handle_complex(event):

389

complex_animation()

390

391

document.body <= complex_btn

392

```

393

394

### Timer Utilities

395

396

Helper functions for common timing patterns.

397

398

```python { .api }

399

class Timer:

400

"""

401

Timer utility class with advanced features.

402

"""

403

404

def __init__(self):

405

"""Initialize timer."""

406

407

def debounce(self, func: Callable, delay: int) -> Callable:

408

"""

409

Create debounced function that delays execution.

410

411

Args:

412

func: Function to debounce

413

delay: Delay in milliseconds

414

415

Returns:

416

Debounced function

417

"""

418

419

def throttle(self, func: Callable, limit: int) -> Callable:

420

"""

421

Create throttled function that limits execution rate.

422

423

Args:

424

func: Function to throttle

425

limit: Minimum interval between calls in milliseconds

426

427

Returns:

428

Throttled function

429

"""

430

431

def countdown(self, seconds: int, callback: Callable,

432

tick_callback: Callable = None) -> int:

433

"""

434

Create countdown timer.

435

436

Args:

437

seconds: Countdown duration

438

callback: Function to call when complete

439

tick_callback: Function to call each second (receives remaining time)

440

441

Returns:

442

Timer ID for cancellation

443

"""

444

445

timer_utils = Timer()

446

```

447

448

**Usage:**

449

```python

450

from browser.timer import Timer

451

from browser import document, bind

452

from browser.html import INPUT, DIV

453

454

timer = Timer()

455

456

# Debounced search function

457

search_results = DIV()

458

document.body <= search_results

459

460

def perform_search(query):

461

"""Simulate search operation."""

462

print(f"Searching for: {query}")

463

search_results.text = f"Results for: {query}"

464

465

# Debounce search to avoid excessive API calls

466

debounced_search = timer.debounce(perform_search, 500) # 500ms delay

467

468

search_input = INPUT(placeholder="Type to search...")

469

470

@bind(search_input, 'input')

471

def handle_search_input(event):

472

query = event.target.value

473

if query.strip():

474

debounced_search(query)

475

476

document.body <= search_input

477

478

# Throttled scroll handler

479

def handle_scroll():

480

"""Handle scroll events."""

481

scroll_position = window.pageYOffset

482

print(f"Scroll position: {scroll_position}")

483

484

# Throttle scroll events to improve performance

485

throttled_scroll = timer.throttle(handle_scroll, 100) # Max 10 times per second

486

487

@bind(window, 'scroll')

488

def on_scroll(event):

489

throttled_scroll()

490

491

# Countdown timer

492

countdown_display = DIV()

493

document.body <= countdown_display

494

495

def start_countdown():

496

"""Start 10-second countdown."""

497

498

def on_tick(remaining):

499

countdown_display.text = f"Countdown: {remaining} seconds"

500

501

def on_complete():

502

countdown_display.text = "Countdown finished!"

503

print("Timer expired!")

504

505

timer.countdown(10, on_complete, on_tick)

506

507

from browser.html import BUTTON

508

509

countdown_btn = BUTTON("Start 10s Countdown")

510

511

@bind(countdown_btn, 'click')

512

def handle_countdown(event):

513

start_countdown()

514

515

document.body <= countdown_btn

516

```

517

518

### Animation Easing

519

520

Built-in easing functions for natural animations.

521

522

```python { .api }

523

# Available easing functions

524

EASING_FUNCTIONS = {

525

'linear': 'linear progression',

526

'ease': 'default ease',

527

'ease-in': 'slow start',

528

'ease-out': 'slow end',

529

'ease-in-out': 'slow start and end',

530

'cubic-bezier': 'custom cubic bezier curve'

531

}

532

533

def create_easing(p1: float, p2: float, p3: float, p4: float) -> str:

534

"""

535

Create custom cubic-bezier easing function.

536

537

Args:

538

p1, p2, p3, p4: Bezier curve control points

539

540

Returns:

541

CSS cubic-bezier string

542

"""

543

```

544

545

This comprehensive timing system enables sophisticated time-based functionality and smooth animations for creating engaging and responsive user interfaces in Brython applications.