import 'dart:ui'; import 'package:freezed_annotation/freezed_annotation.dart'; part 'trick_play_model.freezed.dart'; part 'trick_play_model.g.dart'; @Freezed(copyWith: true) abstract class TrickPlayModel with _$TrickPlayModel { factory TrickPlayModel({ required int width, required int height, required int tileWidth, required int tileHeight, required int thumbnailCount, required Duration interval, @Default([]) List images, }) = _TrickPlayModel; const TrickPlayModel._(); int get imagesPerTile => tileWidth * tileHeight; String? getTile(Duration position) { final int currentIndex = (position.inMilliseconds ~/ interval.inMilliseconds).clamp(0, thumbnailCount); final int indexOfTile = (currentIndex ~/ imagesPerTile).clamp(0, images.length); return images.elementAtOrNull(indexOfTile); } Offset offset(Duration position) { final int currentIndex = (position.inMilliseconds ~/ interval.inMilliseconds).clamp(0, thumbnailCount - 1); final int tileIndex = currentIndex % imagesPerTile; final int column = tileIndex % tileWidth; final int row = tileIndex ~/ tileWidth; return Offset( (width * column).toDouble(), (height * row).toDouble(), ); } static Map toTrickPlayMap(Map map) { Map newMap = {}; final firstMap = (((map.entries.first as MapEntry).value as Map)); newMap.addEntries(firstMap.entries.map( (e) { final map = e.value as Map; return MapEntry( e.key, TrickPlayModel( width: map['Width'] as int? ?? 0, height: map['Height'] as int? ?? 0, tileWidth: map['TileWidth'] as int? ?? 0, tileHeight: map['TileHeight'] as int? ?? 0, thumbnailCount: map['ThumbnailCount'] as int? ?? 0, interval: Duration(milliseconds: map['Interval'] as int? ?? 0), ), ); }, )); return newMap; } factory TrickPlayModel.fromJson(Map json) => _$TrickPlayModelFromJson(json); }