mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-06-11 05:11:34 +08:00
26
lib/common/widgets/image_viewer/hero.dart
Normal file
26
lib/common/widgets/image_viewer/hero.dart
Normal file
@@ -0,0 +1,26 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
Widget fromHero({
|
||||
required Object tag,
|
||||
required Widget child,
|
||||
}) => Hero(
|
||||
tag: tag,
|
||||
createRectTween: createEndRectTween,
|
||||
child: child,
|
||||
);
|
||||
|
||||
RectTween createEndRectTween(Rect? begin, Rect? end) {
|
||||
if (begin != null && end != null) {
|
||||
final endWidth = end.width;
|
||||
final endHeight = end.height;
|
||||
// TODO: use real image rect
|
||||
final beginRect = Rect.fromLTWH(
|
||||
begin.left + (begin.width - endWidth) / 2,
|
||||
begin.top + (begin.height - endHeight) / 2,
|
||||
endWidth,
|
||||
endHeight,
|
||||
);
|
||||
return RectTween(begin: beginRect, end: end);
|
||||
}
|
||||
return RectTween(begin: begin, end: end);
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:PiliPlus/common/widgets/image_viewer/hero.dart';
|
||||
import 'package:PiliPlus/models/common/image_preview_type.dart';
|
||||
import 'package:PiliPlus/utils/extension/num_ext.dart';
|
||||
import 'package:PiliPlus/utils/image_utils.dart';
|
||||
@@ -54,7 +55,7 @@ Widget htmlRender({
|
||||
imgList: [SourceModel(url: imgUrl)],
|
||||
quality: 60,
|
||||
),
|
||||
child: Hero(
|
||||
child: fromHero(
|
||||
tag: imgUrl,
|
||||
child: CachedNetworkImage(
|
||||
width: width,
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:PiliPlus/common/widgets/gesture/tap_gesture_recognizer.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/cached_network_svg_image.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/custom_grid_view.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/common/widgets/image_viewer/hero.dart';
|
||||
import 'package:PiliPlus/http/constants.dart';
|
||||
import 'package:PiliPlus/models/common/image_preview_type.dart';
|
||||
import 'package:PiliPlus/models/common/image_type.dart';
|
||||
@@ -222,26 +223,28 @@ class OpusContent extends StatelessWidget {
|
||||
? null
|
||||
: width * pic.height! / pic.width!;
|
||||
width ??= maxWidth;
|
||||
Widget child = CachedNetworkImage(
|
||||
width: width,
|
||||
height: height,
|
||||
memCacheWidth: width.cacheSize(context),
|
||||
imageUrl: ImageUtils.thumbnailUrl(pic.url!, 60),
|
||||
fadeInDuration: const Duration(milliseconds: 120),
|
||||
fadeOutDuration: const Duration(milliseconds: 120),
|
||||
placeholder: (_, _) =>
|
||||
Image.asset('assets/images/loading.png'),
|
||||
);
|
||||
if (!(pic.isLongPic ?? false)) {
|
||||
child = fromHero(
|
||||
tag: pic.url!,
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
return GestureDetector(
|
||||
onTap: () => PageUtils.imageView(
|
||||
imgList: [SourceModel(url: pic.url!)],
|
||||
quality: 60,
|
||||
),
|
||||
child: Center(
|
||||
child: Hero(
|
||||
tag: pic.url!,
|
||||
child: CachedNetworkImage(
|
||||
width: width,
|
||||
height: height,
|
||||
memCacheWidth: width.cacheSize(context),
|
||||
imageUrl: ImageUtils.thumbnailUrl(pic.url!, 60),
|
||||
fadeInDuration: const Duration(milliseconds: 120),
|
||||
fadeOutDuration: const Duration(milliseconds: 120),
|
||||
placeholder: (_, _) =>
|
||||
Image.asset('assets/images/loading.png'),
|
||||
),
|
||||
),
|
||||
),
|
||||
child: child,
|
||||
);
|
||||
} else {
|
||||
return CustomGridView(
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:PiliPlus/common/widgets/button/icon_button.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart';
|
||||
import 'package:PiliPlus/common/widgets/gesture/tap_gesture_recognizer.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/common/widgets/image_viewer/hero.dart';
|
||||
import 'package:PiliPlus/common/widgets/progress_bar/audio_video_progress_bar.dart';
|
||||
import 'package:PiliPlus/common/widgets/progress_bar/segment_progress_bar.dart';
|
||||
import 'package:PiliPlus/grpc/bilibili/app/listener/v1.pb.dart';
|
||||
@@ -893,7 +894,7 @@ class _AudioPageState extends State<AudioPage> {
|
||||
onTap: () => PageUtils.imageView(
|
||||
imgList: [SourceModel(url: cover)],
|
||||
),
|
||||
child: Hero(
|
||||
child: fromHero(
|
||||
tag: cover,
|
||||
child: NetworkImgLayer(
|
||||
src: cover,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/widgets/avatars.dart';
|
||||
import 'package:PiliPlus/common/widgets/image_viewer/hero.dart';
|
||||
import 'package:PiliPlus/common/widgets/pendant_avatar.dart';
|
||||
import 'package:PiliPlus/common/widgets/view_safe_area.dart';
|
||||
import 'package:PiliPlus/models/common/image_preview_type.dart';
|
||||
@@ -125,7 +126,7 @@ class UserInfoCard extends StatelessWidget {
|
||||
.http2https;
|
||||
return GestureDetector(
|
||||
onTap: () => PageUtils.imageView(imgList: [SourceModel(url: imgUrl)]),
|
||||
child: Hero(
|
||||
child: fromHero(
|
||||
tag: imgUrl,
|
||||
child: CachedNetworkImage(
|
||||
fit: .cover,
|
||||
@@ -454,7 +455,7 @@ class UserInfoCard extends StatelessWidget {
|
||||
],
|
||||
);
|
||||
|
||||
Widget get _buildAvatar => Hero(
|
||||
Widget get _buildAvatar => fromHero(
|
||||
tag: card.face ?? '',
|
||||
child: PendantAvatar(
|
||||
avatar: card.face,
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:PiliPlus/common/widgets/badge.dart';
|
||||
import 'package:PiliPlus/common/widgets/custom_icon.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/common/widgets/image_viewer/hero.dart';
|
||||
import 'package:PiliPlus/common/widgets/marquee.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/http/music.dart';
|
||||
@@ -439,7 +440,7 @@ class _MusicDetailPageState extends CommonDynPageState<MusicDetailPage> {
|
||||
onTap: () => PageUtils.imageView(
|
||||
imgList: [SourceModel(url: item.mvCover!)],
|
||||
),
|
||||
child: Hero(
|
||||
child: fromHero(
|
||||
tag: item.mvCover!,
|
||||
child: NetworkImgLayer(
|
||||
src: item.mvCover,
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:PiliPlus/common/widgets/badge.dart';
|
||||
import 'package:PiliPlus/common/widgets/button/icon_button.dart';
|
||||
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/common/widgets/image_viewer/hero.dart';
|
||||
import 'package:PiliPlus/common/widgets/stat/stat.dart';
|
||||
import 'package:PiliPlus/models/common/image_preview_type.dart';
|
||||
import 'package:PiliPlus/models/common/image_type.dart';
|
||||
@@ -147,7 +148,7 @@ class _PgcIntroPageState extends State<PgcIntroPage> {
|
||||
onTap: () => PageUtils.imageView(
|
||||
imgList: [SourceModel(url: item.cover!)],
|
||||
),
|
||||
child: Hero(
|
||||
child: fromHero(
|
||||
tag: item.cover!,
|
||||
child: NetworkImgLayer(
|
||||
width: 115,
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:math';
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/widgets/badge.dart';
|
||||
import 'package:PiliPlus/common/widgets/gesture/tap_gesture_recognizer.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/common/widgets/image_viewer/hero.dart';
|
||||
import 'package:PiliPlus/grpc/bilibili/im/interfaces/v1.pb.dart'
|
||||
show EmotionInfo;
|
||||
import 'package:PiliPlus/grpc/bilibili/im/type.pb.dart' show Msg, MsgType;
|
||||
@@ -590,16 +591,24 @@ class ChatItem extends StatelessWidget {
|
||||
|
||||
Widget msgTypePic_2(Map content) {
|
||||
final url = content['url'];
|
||||
final imgWidth = (content['width'] as num).toDouble();
|
||||
final imgHeight = (content['height'] as num).toDouble();
|
||||
final width = math.min(220.0, imgWidth);
|
||||
final ratio = imgHeight / imgWidth;
|
||||
Widget child = NetworkImgLayer(
|
||||
width: width,
|
||||
height: width * ratio,
|
||||
src: url,
|
||||
);
|
||||
if (ratio <= StyleString.imgMaxRatio) {
|
||||
child = fromHero(
|
||||
tag: url,
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
return GestureDetector(
|
||||
onTap: () => PageUtils.imageView(imgList: [SourceModel(url: url)]),
|
||||
child: Hero(
|
||||
tag: url,
|
||||
child: NetworkImgLayer(
|
||||
width: 220,
|
||||
height: 220 * content['height'] / content['width'],
|
||||
src: url,
|
||||
),
|
||||
),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -750,7 +759,7 @@ class ChatItem extends StatelessWidget {
|
||||
final String? url = content['jump_url'];
|
||||
return LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
final maxWidth = max(400.0, constraints.maxWidth);
|
||||
final maxWidth = math.max(400.0, constraints.maxWidth);
|
||||
Widget child = ClipRRect(
|
||||
borderRadius: StyleString.mdRadius,
|
||||
child: CachedNetworkImage(
|
||||
|
||||
Reference in New Issue
Block a user