mirror of
https://github.com/gabehf/Fladder.git
synced 2026-03-07 21:48:14 -08:00
124 lines
3.3 KiB
Dart
124 lines
3.3 KiB
Dart
import 'dart:async';
|
|
import 'dart:io';
|
|
import 'dart:ui' as ui;
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:http/http.dart' as http;
|
|
|
|
import 'package:fladder/models/items/trick_play_model.dart';
|
|
|
|
class TrickPlayImage extends ConsumerStatefulWidget {
|
|
final TrickPlayModel trickPlay;
|
|
final Duration? position;
|
|
|
|
const TrickPlayImage(this.trickPlay, {this.position, super.key});
|
|
|
|
@override
|
|
ConsumerState<ConsumerStatefulWidget> createState() => _TrickPlayImageState();
|
|
}
|
|
|
|
class _TrickPlayImageState extends ConsumerState<TrickPlayImage> {
|
|
ui.Image? image;
|
|
late TrickPlayModel model = widget.trickPlay;
|
|
late Duration time = widget.position ?? Duration.zero;
|
|
late Offset currentOffset = const Offset(0, 0);
|
|
String? currentUrl;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
loadImage();
|
|
}
|
|
|
|
@override
|
|
void didUpdateWidget(covariant TrickPlayImage oldWidget) {
|
|
super.didUpdateWidget(oldWidget);
|
|
if (oldWidget.position?.inMilliseconds != widget.position?.inMilliseconds) {
|
|
time = widget.position ?? Duration.zero;
|
|
model = widget.trickPlay;
|
|
loadImage();
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Container(
|
|
child: image != null
|
|
? CustomPaint(
|
|
painter: _TrickPlayPainter(image!, currentOffset, widget.trickPlay),
|
|
)
|
|
: const SizedBox.shrink(),
|
|
);
|
|
}
|
|
|
|
Future<void> loadImage() async {
|
|
if (model.images.isEmpty) return;
|
|
final newUrl = model.getTile(time);
|
|
currentOffset = model.offset(time);
|
|
if (newUrl != currentUrl) {
|
|
currentUrl = newUrl;
|
|
final tempUrl = currentUrl;
|
|
if (tempUrl == null) return;
|
|
if (tempUrl.startsWith('http')) {
|
|
await loadNetworkImage(tempUrl);
|
|
} else {
|
|
await loadFileImage(tempUrl);
|
|
}
|
|
}
|
|
}
|
|
|
|
Future<void> loadNetworkImage(String url) async {
|
|
final http.Response response = await http.get(Uri.parse(url));
|
|
if (response.statusCode == 200) {
|
|
final Uint8List bytes = response.bodyBytes;
|
|
final ui.Codec codec = await ui.instantiateImageCodec(bytes);
|
|
final ui.FrameInfo frameInfo = await codec.getNextFrame();
|
|
if (context.mounted) {
|
|
setState(() {
|
|
image = frameInfo.image;
|
|
});
|
|
}
|
|
} else {
|
|
throw Exception('Failed to load network image');
|
|
}
|
|
}
|
|
|
|
Future<void> loadFileImage(String path) async {
|
|
final Uint8List bytes = await File(path).readAsBytes();
|
|
final ui.Codec codec = await ui.instantiateImageCodec(bytes);
|
|
final ui.FrameInfo frameInfo = await codec.getNextFrame();
|
|
setState(() {
|
|
image = frameInfo.image;
|
|
});
|
|
}
|
|
}
|
|
|
|
class _TrickPlayPainter extends CustomPainter {
|
|
final ui.Image image;
|
|
final Offset offset;
|
|
final TrickPlayModel model;
|
|
|
|
_TrickPlayPainter(this.image, this.offset, this.model);
|
|
|
|
@override
|
|
void paint(Canvas canvas, Size size) {
|
|
Rect srcRect = Rect.fromLTWH(
|
|
offset.dx,
|
|
offset.dy,
|
|
model.width.toDouble(),
|
|
model.height.toDouble(),
|
|
);
|
|
|
|
Paint paint = Paint();
|
|
Rect dstRect = Rect.fromLTWH(0, 0, size.width, size.height);
|
|
canvas.drawImageRect(image, srcRect, dstRect, paint);
|
|
}
|
|
|
|
@override
|
|
bool shouldRepaint(CustomPainter oldDelegate) {
|
|
return false;
|
|
}
|
|
}
|