Home > Blockchain >  How can i make sure that my Container does not go outside my screen using Transform.transalte
How can i make sure that my Container does not go outside my screen using Transform.transalte

Time:05-29

I am using Transform.translate to animate a Container as much as my finger move around on screen and I am using Listener widget to increase my offset. but I noticed that if I keep move my container outside the screen it also will keep go through outside the screen. I also wrapped it into safe area but it also keeps going outside the border.

How can I prevent this behavior?

import 'package:flutter/material.dart';

class Test extends StatefulWidget {
  const Test({Key? key}) : super(key: key);
  @override
  State<Test> createState() => _TestState();
}

class _TestState extends State<Test> {

  late Offset offsetLocal=  const Offset(0,0);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Listener(
          onPointerMove:(t){
            offsetLocal =t.delta;
            setState(() {});
          },
          child: Center(
            child: Transform.translate(
                offset: offsetLocal,
                child: Container(
                  color: Colors.red,
                  width: 200,
                  height: 200,
                )
            ),
          ),
        ),

      ),
    );
  }
}

CodePudding user response:

The update position using Transform.translate will be based on user tap location.

 ///Tap position needed to be centered
  updatePositionOnTransform(BoxConstraints constraints, PointerMoveEvent t) {
    debugPrint(t.position.toString());
   
    //* using single condition force to one dimension
    // if (t.position.dx < constraints.maxWidth - boxSize.width / 2 &&
    //     t.position.dx > boxSize.width / 2 &&
    //     t.localPosition.dy > boxSize.height / 2 &&
    //     t.localPosition.dy < constraints.maxHeight - boxSize.height / 2) {
    //   offsetLocal  = t.delta;
    //   setState(() {});
    // }

    double dx = 0;
    double dy = 0;

    if (t.position.dx < constraints.maxWidth - boxSize.width / 2 &&
        t.position.dx > boxSize.width / 2) {
      dx = t.delta.dx;
    }
    if (t.localPosition.dy > boxSize.height / 2 &&
        t.localPosition.dy < constraints.maxHeight - boxSize.height / 2) {
      dy = t.delta.dy;
    }
    offsetLocal  = Offset(dx, dy);
    setState(() {});
  }

using Stack user can tap anywhere

 updatePosition(BoxConstraints constraints, offset) {
    double dx = offset.dx;
    double dy = offset.dy;

    //* -100 is coming from half container size
    if (dx < constraints.maxWidth - boxSize.width / 2 &&
        dx > boxSize.width / 2) {
      offsetLocal = Offset(dx - (boxSize.width / 2), offsetLocal.dy);
    }
    if (dy > boxSize.height / 2 &&
        dy < constraints.maxHeight - boxSize.height / 2) {
      offsetLocal = Offset(offsetLocal.dx, dy - (boxSize.height / 2));
    }

    setState(() {});
  }

You can follow the example and select the one you prefer.

class _TestState extends State<Test> {
  late Offset offsetLocal = const Offset(0, 0);

  updatePosition(BoxConstraints constraints, offset) {
    double dx = offset.dx;
    double dy = offset.dy;

    //* -100 is coming from half container size
    if (dx < constraints.maxWidth - boxSize.width / 2 &&
        dx > boxSize.width / 2) {
      offsetLocal = Offset(dx - (boxSize.width / 2), offsetLocal.dy);
    }
    if (dy > boxSize.height / 2 &&
        dy < constraints.maxHeight - boxSize.height / 2) {
      offsetLocal = Offset(offsetLocal.dx, dy - (boxSize.height / 2));
    }

    setState(() {});
  }

  ///Tap position needed to be centered
  updatePositionOnTransform(BoxConstraints constraints, PointerMoveEvent t) {
    debugPrint(t.position.toString());
   
    //* using single condition force to one dimension
    // if (t.position.dx < constraints.maxWidth - boxSize.width / 2 &&
    //     t.position.dx > boxSize.width / 2 &&
    //     t.localPosition.dy > boxSize.height / 2 &&
    //     t.localPosition.dy < constraints.maxHeight - boxSize.height / 2) {
    //   offsetLocal  = t.delta;
    //   setState(() {});
    // }

    double dx = 0;
    double dy = 0;

    if (t.position.dx < constraints.maxWidth - boxSize.width / 2 &&
        t.position.dx > boxSize.width / 2) {
      dx = t.delta.dx;
    }
    if (t.localPosition.dy > boxSize.height / 2 &&
        t.localPosition.dy < constraints.maxHeight - boxSize.height / 2) {
      dy = t.delta.dy;
    }
    offsetLocal  = Offset(dx, dy);
    setState(() {});
  }

  final Size boxSize = const Size(200, 200);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: LayoutBuilder(
        builder: (context, constraints) => SafeArea(
          // child: usingTransform(constraints),
          child: usingStack(constraints),
        ),
      ),
    );
  }

  Listener usingTransform(constraints) {
    return Listener(
      onPointerMove: (t) {
        updatePositionOnTransform(constraints, t);
      },
      child: Center(
        child: Transform.translate(
            offset: offsetLocal,
            child: Container(
              color: Colors.red,
              width: 200,
              height: 200,
            )),
      ),
    );
  }

  GestureDetector usingStack(BoxConstraints constraints) {
    return GestureDetector(
      onPanUpdate: (details) {
        updatePosition(constraints, details.localPosition);
      },
      child: Stack(
        children: [
          Positioned(
            // duration: const Duration(milliseconds: 100), //you can use `AnimatedPositioned`
            left: offsetLocal.dx,
            top: offsetLocal.dy,
            child: Container(
              color: Colors.red,
              width: boxSize.width,
              height: boxSize.height,
            ),
          ),
        ],
      ),
    );
  }
}


  • Related