Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to drag multiple objects inside a Container

I'm trying to have multiple images inside a big container and be able to move them around and rotate them, as shown in the image below:

enter image description here

I've been playing around with CostumePainter and this is my result whilst following this guide and

enter image description here

Does anyone have an idea on how to do this with Images and multiple of them?

My code:

  dynamic _balls;

  double xPos = 100;
  double yPos = 100;

  bool isClick = false;

  @override
  Widget build(BuildContext context) {
    _balls = _paint(xPosition: xPos, yPosition: yPos, ballRad: 20);

    return Scaffold(
      appBar: AppBar(
        title: const Text("Drag and Drop"),
      ),
      body: Center(
        child: GestureDetector(
          onHorizontalDragDown: (details) {
            setState(() {
              if (_balls.isBallRegion(
                  details.localPosition.dx, details.localPosition.dy)) {
                isClick = true;
              }
            });
          },
          onHorizontalDragEnd: (details) {
            setState(() {
              isClick = false;
            });
          },
          onHorizontalDragUpdate: (details) {
            if (isClick) {
              setState(() {
                xPos = details.localPosition.dx;
                yPos = details.localPosition.dy;
              });
            }
          },
          child: Container(
            height: 300,
            width: 300,
            color: Colors.lightBlueAccent,
            child: CustomPaint(
              painter: _balls,
            ),
          ),
        ),
      ),
    );
  }
like image 670
PandaCórdoba Avatar asked Feb 11 '26 00:02

PandaCórdoba


2 Answers

I followed this guide and it helped me, btw this is the blog.

Here is the code btw:

// @dart=2.9
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(),
    );
  }
}

class ContainerList {
  double height;
  double width;
  double scale;
  double rotation;
  double xPosition;
  double yPosition;

  ContainerList({
    this.height,
    this.rotation,
    this.scale,
    this.width,
    this.xPosition,
    this.yPosition,
  });
}

class HomePage extends StatefulWidget {
  const HomePage({Key key}) : super(key: key);

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List<ContainerList> list = [];
  Offset _initPos;
  Offset _currentPos = Offset(0, 0);
  double _currentScale;
  double _currentRotation;
  Size screen;

  @override
  void initState() {
    screen = Size(400, 500);
    list.add(ContainerList(
      height: 200.0,
      width: 200.0,
      rotation: 0.0,
      scale: 1.0,
      xPosition: 0.1,
      yPosition: 0.1,
    ));
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Container(
        padding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0),
        height: 500.0,
        color: Colors.blue.withOpacity(0.8),
        width: double.infinity,
        child: Stack(
          children: list.map((value) {
            return GestureDetector(
              onScaleStart: (details) {
                if (value == null) return;
                _initPos = details.focalPoint;
                _currentPos = Offset(value.xPosition, value.yPosition);
                _currentScale = value.scale;
                _currentRotation = value.rotation;
              },
              onScaleUpdate: (details) {
                if (value == null) return;
                final delta = details.focalPoint - _initPos;
                final left = (delta.dx / screen.width) + _currentPos.dx;
                final top = (delta.dy / screen.height) + _currentPos.dy;

                setState(() {
                  value.xPosition = Offset(left, top).dx;
                  value.yPosition = Offset(left, top).dy;
                  value.rotation = details.rotation + _currentRotation;
                  value.scale = details.scale * _currentScale;
                });
              },
              child: Stack(
                children: [
                  Positioned(
                    left: value.xPosition * screen.width,
                    top: value.yPosition * screen.height,
                    child: Transform.scale(
                      scale: value.scale,
                      child: Transform.rotate(
                        angle: value.rotation,
                        child: Container(
                          height: value.height,
                          width: value.width,
                          child: FittedBox(
                            fit: BoxFit.fill,
                            child: Listener(
                              onPointerDown: (details) {
                                // if (_inAction) return;
                                // _inAction = true;
                                // _activeItem = val;
                                _initPos = details.position;
                                _currentPos =
                                    Offset(value.xPosition, value.yPosition);
                                _currentScale = value.scale;
                                _currentRotation = value.rotation;
                              },
                              onPointerUp: (details) {
                                // _inAction = false;
                              },
                              child: Container(
                                height: value.height,
                                width: value.width,
                                color: Colors.red,
                              ),
                              // child: Image.network(value.name),
                            ),
                          ),
                        ),
                      ),
                    ),
                  )
                ],
              ),
            );
          }).toList(),
        ),
      ),
    );
  }
}
like image 61
PandaCórdoba Avatar answered Feb 13 '26 12:02

PandaCórdoba


As a learning exercise, I created a basic flutter app that at least demonstrates dragging around a number of independent items and doing a couple of things like selecting, deleting, and re-ordering. The rotation function is a little buggy.

https://github.com/SpiRaiL/emoji_party_2

enter image description here

like image 31
SpiRail Avatar answered Feb 13 '26 14:02

SpiRail