Initial commit

This commit is contained in:
Konstantin Kollar
2022-09-30 20:12:39 +02:00
commit 043112a574
9 changed files with 507 additions and 0 deletions
+72
View File
@@ -0,0 +1,72 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.packages
.pub-cache/
.pub/
build/
# Android related
**/android/**/gradle-wrapper.jar
**/android/.gradle
**/android/captures/
**/android/gradlew
**/android/gradlew.bat
**/android/local.properties
**/android/**/GeneratedPluginRegistrant.java
# iOS/XCode related
**/ios/**/*.mode1v3
**/ios/**/*.mode2v3
**/ios/**/*.moved-aside
**/ios/**/*.pbxuser
**/ios/**/*.perspectivev3
**/ios/**/*sync/
**/ios/**/.sconsign.dblite
**/ios/**/.tags*
**/ios/**/.vagrant/
**/ios/**/DerivedData/
**/ios/**/Icon?
**/ios/**/Pods/
**/ios/**/.symlinks/
**/ios/**/profile
**/ios/**/xcuserdata
**/ios/.generated/
**/ios/Flutter/App.framework
**/ios/Flutter/Flutter.framework
**/ios/Flutter/Generated.xcconfig
**/ios/Flutter/app.flx
**/ios/Flutter/app.zip
**/ios/Flutter/flutter_assets/
**/ios/ServiceDefinitions.json
**/ios/Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!**/ios/**/default.mode1v3
!**/ios/**/default.mode2v3
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
+10
View File
@@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: b712a172f9694745f50505c93340883493b505e5
channel: stable
project_type: package
+9
View File
@@ -0,0 +1,9 @@
## [0.0.1] - TODO: Add release date.
* TODO: Describe initial release.
## 1.0.0
* init release
## 1.0.1
* add check mounted when setState
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 Jpeng
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+86
View File
@@ -0,0 +1,86 @@
# flutter_gifimage
We should know that in order to achieve Gif in flutter, we can use Image, but we have no way to manipulate Gif, for example: change its speed, control it has been playing in a frame,
in which frame range loop. These problems can be solved by this widget,it also help you contain gif cache,avoid load frame every time.
# Screenshots
![](arts/gif.gif)
# Usage(Simple)
add in pubspec
```dart
flutter_gifimage: ^1.0.0
```
simple usage
```dart
GifController controller= GifController(vsync: this);
GifImage(
controller: controller,
image: AssetImage("images/animate.gif"),
)
```
list the most common operate in GifController:
```dart
// loop from 0 frame to 29 frame
controller.repeat(min:0,max:29,period:Duration(millseconds:300));
// jumpTo thrid frame(index from 0)
controller.value = 0;
// from current frame to 26 frame
controller.animateTo(26);
```
If you need to preCache gif,try this
```dart
// put imageProvider
fetchGif(AssetImage("images/animate.gif"));
```
# Thanks
* [gif_ani](https://github.com/hyz1992/gif_ani) (thanks for giving me idea)
# License
```
MIT License
Copyright (c) 2019 Jpeng
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

+245
View File
@@ -0,0 +1,245 @@
/*
author: Jpeng
email: peng8350@gmail.com
time:2019-7-26 3:30
*/
library flutter_gifimage;
import 'dart:io';
import 'dart:ui' as ui show Codec;
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
/// cache gif fetched image
class GifCache {
final Map<String, List<ImageInfo>?> caches = Map();
void clear() {
caches.clear();
}
bool evict(Object key) {
final List<ImageInfo>? pendingImage = caches.remove(key);
if (pendingImage != null) {
return true;
}
return false;
}
}
/// controll gif
class GifController extends AnimationController {
GifController(
{required TickerProvider vsync,
double value = 0.0,
Duration? reverseDuration,
Duration? duration,
AnimationBehavior? animationBehavior})
: super.unbounded(
value: value,
reverseDuration: reverseDuration,
duration: duration,
animationBehavior: animationBehavior ?? AnimationBehavior.normal,
vsync: vsync);
@override
void reset() {
value = 0.0;
}
}
class GifImage extends StatefulWidget {
GifImage({
required this.image,
required this.controller,
this.semanticLabel,
this.excludeFromSemantics = false,
this.width,
this.height,
this.onFetchCompleted,
this.color,
this.colorBlendMode,
this.fit,
this.alignment = Alignment.center,
this.repeat = ImageRepeat.noRepeat,
this.centerSlice,
this.matchTextDirection = false,
this.gaplessPlayback = false,
});
final VoidCallback? onFetchCompleted;
final GifController controller;
final ImageProvider image;
final double? width;
final double? height;
final Color? color;
final BlendMode? colorBlendMode;
final BoxFit? fit;
final AlignmentGeometry alignment;
final ImageRepeat repeat;
final Rect? centerSlice;
final bool matchTextDirection;
final bool gaplessPlayback;
final String? semanticLabel;
final bool excludeFromSemantics;
@override
State<StatefulWidget> createState() {
return new GifImageState();
}
static GifCache cache = GifCache();
}
class GifImageState extends State<GifImage> {
List<ImageInfo>? _infos;
int _curIndex = 0;
bool _fetchComplete = false;
ImageInfo? get _imageInfo {
if (!_fetchComplete) return null;
return _infos == null ? null : _infos![_curIndex];
}
@override
void initState() {
super.initState();
widget.controller.addListener(_listener);
}
@override
void dispose() {
super.dispose();
widget.controller.removeListener(_listener);
}
@override
void didUpdateWidget(GifImage oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.image != oldWidget.image) {
fetchGif(widget.image).then((imageInfors) {
if (mounted)
setState(() {
_infos = imageInfors;
_fetchComplete = true;
_curIndex = widget.controller.value.toInt();
if (widget.onFetchCompleted != null) {
widget.onFetchCompleted!();
}
});
});
}
if (widget.controller != oldWidget.controller) {
oldWidget.controller.removeListener(_listener);
widget.controller.addListener(_listener);
}
}
void _listener() {
if (_curIndex != widget.controller.value && _fetchComplete) {
if (mounted)
setState(() {
_curIndex = widget.controller.value.toInt();
});
}
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
if (_infos == null) {
fetchGif(widget.image).then((imageInfors) {
if (mounted)
setState(() {
_infos = imageInfors;
_fetchComplete = true;
_curIndex = widget.controller.value.toInt();
if (widget.onFetchCompleted != null) {
widget.onFetchCompleted!();
}
});
});
}
}
@override
Widget build(BuildContext context) {
final RawImage image = new RawImage(
image: _imageInfo?.image,
width: widget.width,
height: widget.height,
scale: _imageInfo?.scale ?? 1.0,
color: widget.color,
colorBlendMode: widget.colorBlendMode,
fit: widget.fit,
alignment: widget.alignment,
repeat: widget.repeat,
centerSlice: widget.centerSlice,
matchTextDirection: widget.matchTextDirection,
);
if (widget.excludeFromSemantics) return image;
return new Semantics(
container: widget.semanticLabel != null,
image: true,
label: widget.semanticLabel == null ? '' : widget.semanticLabel,
child: image,
);
}
}
final HttpClient _sharedHttpClient = HttpClient()..autoUncompress = false;
HttpClient get _httpClient {
HttpClient client = _sharedHttpClient;
assert(() {
if (debugNetworkImageHttpClientProvider != null)
client = debugNetworkImageHttpClientProvider!();
return true;
}());
return client;
}
Future<List<ImageInfo>?> fetchGif(ImageProvider provider) async {
List<ImageInfo>? infos = [];
late dynamic data;
String key = provider is NetworkImage
? provider.url
: provider is AssetImage
? provider.assetName
: provider is MemoryImage
? provider.bytes.toString()
: "";
if (GifImage.cache.caches.containsKey(key)) {
infos = GifImage.cache.caches[key];
return infos;
}
if (provider is NetworkImage) {
final Uri resolved = Uri.base.resolve(provider.url);
final HttpClientRequest request = await _httpClient.getUrl(resolved);
provider.headers?.forEach((String name, String value) {
request.headers.add(name, value);
});
final HttpClientResponse response = await request.close();
data = await consolidateHttpClientResponseBytes(
response,
);
} else if (provider is AssetImage) {
AssetBundleImageKey key = await provider.obtainKey(ImageConfiguration());
data = await key.bundle.load(key.name);
} else if (provider is FileImage) {
data = await provider.file.readAsBytes();
} else if (provider is MemoryImage) {
data = provider.bytes;
}
ui.Codec codec = await PaintingBinding.instance
.instantiateImageCodec(data.buffer.asUint8List());
infos = [];
for (int i = 0; i < codec.frameCount; i++) {
FrameInfo frameInfo = await codec.getNextFrame();
//scale ??
infos.add(ImageInfo(image: frameInfo.image));
}
GifImage.cache.caches.putIfAbsent(key, () => infos);
return infos;
}
+50
View File
@@ -0,0 +1,50 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.16.0"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.4"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
sdks:
dart: ">=2.14.0 <3.0.0"
+14
View File
@@ -0,0 +1,14 @@
name: flutter_gifimage
description: a gifimage for flutter,for solving gif cannot be controlled speed,progress
version: 1.0.1
homepage: https://github.com/peng8350/flutter_gifimage
environment:
sdk: ">=2.12.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
dev_dependencies:
flutter: