12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- import 'package:flutter/material.dart';
- class SnapToGridCanvas extends StatefulWidget {
- @override
- _SnapToGridCanvasState createState() => _SnapToGridCanvasState();
- }
- class _SnapToGridCanvasState extends State<SnapToGridCanvas> {
- final double snappingThreshold = 10.0;
- final List<Rect> elements = []; // Store elements' bounds
- Offset selectedElementPosition = Offset(100, 100);
- Size selectedElementSize = Size(100, 100);
- Offset? snapToElementOrCanvas(Offset newPosition, Size canvasSize) {
- for (var element in elements) {
- // Snap to other elements
- if ((newPosition.dx - element.right).abs() <= snappingThreshold) {
- return Offset(element.right, newPosition.dy); // Snap to the right of another element
- } else if ((newPosition.dx - element.left).abs() <= snappingThreshold) {
- return Offset(element.left, newPosition.dy); // Snap to the left of another element
- } else if ((newPosition.dy - element.bottom).abs() <= snappingThreshold) {
- return Offset(newPosition.dx, element.bottom); // Snap to the bottom of another element
- } else if ((newPosition.dy - element.top).abs() <= snappingThreshold) {
- return Offset(newPosition.dx, element.top); // Snap to the top of another element
- }
- }
- // Snap to canvas center
- final canvasCenter = Offset(canvasSize.width / 2, canvasSize.height / 2);
- if ((newPosition.dx - canvasCenter.dx).abs() <= snappingThreshold) {
- return Offset(canvasCenter.dx, newPosition.dy); // Snap horizontally to canvas center
- } else if ((newPosition.dy - canvasCenter.dy).abs() <= snappingThreshold) {
- return Offset(newPosition.dx, canvasCenter.dy); // Snap vertically to canvas center
- }
- return null; // No snapping
- }
- @override
- Widget build(BuildContext context) {
- final canvasSize = MediaQuery.of(context).size;
- return Scaffold(
- appBar: AppBar(title: Text("Snap to Grid Canvas")),
- body: GestureDetector(
- onPanUpdate: (details) {
- setState(() {
- final newPosition = selectedElementPosition + details.delta;
- // Check for snapping
- final snappedPosition = snapToElementOrCanvas(newPosition, canvasSize);
- if (snappedPosition != null) {
- selectedElementPosition = snappedPosition;
- } else {
- selectedElementPosition = newPosition;
- }
- });
- },
- child: Stack(
- children: [
- // Canvas background
- Container(color: Colors.grey[200]),
- // Render all elements
- ...elements.map((element) {
- return Positioned(
- left: element.left,
- top: element.top,
- child: Container(
- width: element.width,
- height: element.height,
- color: Colors.blue,
- ),
- );
- }).toList(),
- // Selected element
- Positioned(
- left: selectedElementPosition.dx,
- top: selectedElementPosition.dy,
- child: Container(
- width: selectedElementSize.width,
- height: selectedElementSize.height,
- color: Colors.red,
- child: Center(child: Text("Drag Me")),
- ),
- ),
- ],
- ),
- ),
- );
- }
- }
|