Tkko / Flutter_dismissible_page

Flutter page widget that is dismissed by swipe gestures, with Hero style animations, Inspired by Facebook and Instagram stories.
https://pub.dev/packages/dismissible_page
MIT License
151 stars 39 forks source link

The Package doesn't work with InteractiveViewer #34

Open Yusufdevv opened 10 months ago

Yusufdevv commented 10 months ago

Hi. The package does'nt work with InteractiveViewer. Please share solution

Code example:

import 'package:dismissible_page/dismissible_page.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:inter_staff/constants/colors.dart';
import 'package:inter_staff/feature/template/widgets/image_provider.dart';
import 'package:photo_view/photo_view.dart';

class InteractiveViewerPage extends StatefulWidget {
  const InteractiveViewerPage({Key? key, required this.path, required this.id}) : super(key: key);
  final String path;
  final int id;
  @override
  State<InteractiveViewerPage> createState() => _InteractiveViewerPageState();

  static const String routeName = '/interactive_viewer_page';
}

class _InteractiveViewerPageState extends State<InteractiveViewerPage> with SingleTickerProviderStateMixin {
  late final TransformationController transformationController;
  late final AnimationController animationController;
  late Animation<Matrix4> animation;

  TapDownDetails doubleTapDetails = TapDownDetails();
  double scale = 5.0;
  final Map<double, int> scaleFactor = {
    3.0: 2,
    5.0: 4,
    6.0: 5,
    9.0: 8,
    12.0: 11,
  };

  @override
  void initState() {
    super.initState();

    transformationController = TransformationController();
    animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 300),
    );
    animationController.addListener(() {
      transformationController.value = animation.value;
    });
  }

  @override
  void dispose() {
    transformationController.dispose();
    animationController.dispose();

    super.dispose();
  }

  void handleDoubleTap() {
    Matrix4 matrix4;
    final position = doubleTapDetails.localPosition;

    if (transformationController.value != Matrix4.identity()) {
      matrix4 = Matrix4.identity();
    } else {
      final sf = scaleFactor[scale] ?? 5;
      matrix4 = Matrix4.identity()
        ..translate(
          -position.dx * sf,
          -position.dy * sf,
        )
        ..scale(scale);
    }

    animation = Matrix4Tween(
      begin: transformationController.value,
      end: matrix4,
    ).animate(CurveTween(
      curve: Curves.easeOut,
    ).animate(animationController));
    animationController.forward(from: 0);
  }

  @override
  Widget build(BuildContext context) {
    return DismissiblePage(
      onDismissed: () {
        Navigator.of(context).pop();
      },
      direction: DismissiblePageDismissDirection.multi,
      isFullScreen: false,
      child: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.transparent,
          leading: BackButton(
            color: sky.white,
          ),
        ),
        extendBodyBehindAppBar: true,
        backgroundColor: ink.darkest,
        body: SizedBox.expand(
          child: GestureDetector(
            onDoubleTapDown: (d) => doubleTapDetails = d,
            onDoubleTap: handleDoubleTap,
            child: Hero(
              tag: widget.path + widget.id.toString(),
              child: InteractiveViewer(
                transformationController: transformationController,
                maxScale: 10.0,
                minScale: 0.5,
                constrained: true,
                scaleEnabled: true,
                scaleFactor: kDefaultMouseScrollToScaleFactor,
                child: AdaptiveImage(path: widget.path, fit: null),
              ),
            ),
          ),
        ),
      ),
    );
  }
}