fix(mobile): improve hero animation (#3636)

This commit is contained in:
X 2023-08-10 21:38:49 +08:00 committed by GitHub
parent a8b01dc21a
commit e9b0840f01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 73 additions and 81 deletions

View File

@ -62,11 +62,17 @@ class ThumbnailImage extends HookConsumerWidget {
} }
Widget buildImage(Asset asset) { Widget buildImage(Asset asset) {
var image = ImmichImage( var image = SizedBox(
asset,
width: 300, width: 300,
height: 300, height: 300,
useGrayBoxPlaceholder: useGrayBoxPlaceholder, child: Hero(
tag: asset.id + heroOffset,
child: ImmichImage(
asset,
useGrayBoxPlaceholder: useGrayBoxPlaceholder,
fit: BoxFit.cover,
),
),
); );
if (!multiselectEnabled || !isSelected) { if (!multiselectEnabled || !isSelected) {
return image; return image;
@ -114,73 +120,70 @@ class ThumbnailImage extends HookConsumerWidget {
onSelect?.call(); onSelect?.call();
HapticFeedback.heavyImpact(); HapticFeedback.heavyImpact();
}, },
child: Hero( child: Stack(
tag: asset.id + heroOffset, children: [
child: Stack( Container(
children: [ decoration: BoxDecoration(
Container( border: multiselectEnabled && isSelected
decoration: BoxDecoration( ? Border.all(
border: multiselectEnabled && isSelected color: onDeselect == null
? Border.all( ? Colors.grey
color: onDeselect == null : assetContainerColor,
? Colors.grey width: 8,
: assetContainerColor, )
width: 8, : const Border(),
)
: const Border(),
),
child: buildImage(asset),
), ),
if (multiselectEnabled) child: buildImage(asset),
Padding( ),
padding: const EdgeInsets.all(3.0), if (multiselectEnabled)
child: Align( Padding(
alignment: Alignment.topLeft, padding: const EdgeInsets.all(3.0),
child: buildSelectionIcon(asset), child: Align(
), alignment: Alignment.topLeft,
child: buildSelectionIcon(asset),
), ),
if (showStorageIndicator) ),
Positioned( if (showStorageIndicator)
right: 10, Positioned(
bottom: 5, right: 10,
child: Icon( bottom: 5,
storageIcon(asset), child: Icon(
color: Colors.white, storageIcon(asset),
size: 18, color: Colors.white,
), size: 18,
), ),
if (asset.isFavorite) ),
const Positioned( if (asset.isFavorite)
left: 10, const Positioned(
bottom: 5, left: 10,
child: Icon( bottom: 5,
Icons.favorite, child: Icon(
color: Colors.white, Icons.favorite,
size: 18, color: Colors.white,
), size: 18,
), ),
if (!asset.isImage) ),
Positioned( if (!asset.isImage)
top: 5, Positioned(
right: 5, top: 5,
child: Row( right: 5,
children: [ child: Row(
Text( children: [
asset.duration.toString().substring(0, 7), Text(
style: const TextStyle( asset.duration.toString().substring(0, 7),
color: Colors.white, style: const TextStyle(
fontSize: 10,
),
),
const Icon(
Icons.play_circle_outline_rounded,
color: Colors.white, color: Colors.white,
fontSize: 10,
), ),
], ),
), const Icon(
Icons.play_circle_outline_rounded,
color: Colors.white,
),
],
), ),
], ),
), ],
), ),
); );
} }

View File

@ -25,7 +25,7 @@ typedef PhotoViewGalleryPageChangedCallback = void Function(int index);
/// A type definition for a [Function] that defines a page in [PhotoViewGallery.build] /// A type definition for a [Function] that defines a page in [PhotoViewGallery.build]
typedef PhotoViewGalleryBuilder = PhotoViewGalleryPageOptions Function( typedef PhotoViewGalleryBuilder = PhotoViewGalleryPageOptions Function(
BuildContext context, BuildContext context,
int index, int index,
); );
@ -276,6 +276,7 @@ class _PhotoViewGalleryState extends State<PhotoViewGallery> {
filterQuality: pageOption.filterQuality, filterQuality: pageOption.filterQuality,
basePosition: pageOption.basePosition, basePosition: pageOption.basePosition,
disableGestures: pageOption.disableGestures, disableGestures: pageOption.disableGestures,
heroAttributes: pageOption.heroAttributes,
child: pageOption.child, child: pageOption.child,
) )
: PhotoView( : PhotoView(
@ -306,21 +307,9 @@ class _PhotoViewGalleryState extends State<PhotoViewGallery> {
basePosition: pageOption.basePosition, basePosition: pageOption.basePosition,
disableGestures: pageOption.disableGestures, disableGestures: pageOption.disableGestures,
errorBuilder: pageOption.errorBuilder, errorBuilder: pageOption.errorBuilder,
heroAttributes: pageOption.heroAttributes,
); );
if (pageOption.heroAttributes != null) {
return Hero(
tag: pageOption.heroAttributes!.tag,
createRectTween: pageOption.heroAttributes!.createRectTween,
flightShuttleBuilder: pageOption.heroAttributes!.flightShuttleBuilder,
placeholderBuilder: pageOption.heroAttributes!.placeholderBuilder,
transitionOnUserGestures: pageOption.heroAttributes!.transitionOnUserGestures,
child: ClipRect(
child: photoView,
),
);
}
return ClipRect( return ClipRect(
child: photoView, child: photoView,
); );

View File

@ -359,13 +359,13 @@ class PhotoViewCoreState extends State<PhotoViewCore>
onScaleStart: onScaleStart, onScaleStart: onScaleStart,
onScaleUpdate: onScaleUpdate, onScaleUpdate: onScaleUpdate,
onScaleEnd: onScaleEnd, onScaleEnd: onScaleEnd,
onDragStart: widget.onDragStart != null onDragStart: widget.onDragStart != null
? (details) => widget.onDragStart!(context, details, value) ? (details) => widget.onDragStart!(context, details, value)
: null, : null,
onDragEnd: widget.onDragEnd != null onDragEnd: widget.onDragEnd != null
? (details) => widget.onDragEnd!(context, details, value) ? (details) => widget.onDragEnd!(context, details, value)
: null, : null,
onDragUpdate: widget.onDragUpdate != null onDragUpdate: widget.onDragUpdate != null
? (details) => widget.onDragUpdate!(context, details, value) ? (details) => widget.onDragUpdate!(context, details, value)
: null, : null,
hitDetector: this, hitDetector: this,
@ -405,7 +405,7 @@ class PhotoViewCoreState extends State<PhotoViewCore>
gaplessPlayback: widget.gaplessPlayback ?? false, gaplessPlayback: widget.gaplessPlayback ?? false,
filterQuality: widget.filterQuality, filterQuality: widget.filterQuality,
width: scaleBoundaries.childSize.width * scale, width: scaleBoundaries.childSize.width * scale,
fit: BoxFit.contain, fit: BoxFit.cover,
); );
} }
} }