there are some usability bugs in this code fix them


// Automatic FlutterFlow imports
import '/backend/backend.dart';
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/widgets/index.dart'; // Imports other custom widgets
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';

class CaptureItem extends StatefulWidget {
  const CaptureItem({
    super.key,
    this.width,
    this.height,
    required this.flyerImageUrl,
    this.baseEmojiSizePercentage = 0.05, // Base emoji size as a percentage of image width
  });

  final double? width; // Width of the image
  final double? height; // Height of the image
  final String flyerImageUrl; // URL of the image to be displayed
  final double baseEmojiSizePercentage; // Percentage for dynamic emoji sizing

  @override
  State<CaptureItem> createState() => _CaptureItemState();
}

class _CaptureItemState extends State<CaptureItem> with TickerProviderStateMixin {
  // Lists to store emoji positions and selected emojis
  List<Offset> emojiPositions = []; // Store original emoji positions
  List<String> selectedEmojis = []; // Store emojis that are placed on the image
  List<String> emojis = ['😄', '🐱', '🎉']; // Options for emojis
  String currentEmoji = '😄'; // Currently selected emoji

  final ScrollController scrollController = ScrollController(); // Controller for scrolling
  TransformationController transformationController = TransformationController(); // Controller for zoom and pan
  double actualImageWidth = 0.0; // Width of the loaded image
  double actualImageHeight = 0.0; // Height of the loaded image
  int? highlightedEmojiIndex; // Track the index of the highlighted emoji

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        // Get the actual size of the image once it has been laid out
        if (actualImageWidth == 0 && actualImageHeight == 0) {
          actualImageWidth = constraints.maxWidth; // Set width from constraints
          actualImageHeight = constraints.maxHeight; // Set height from constraints
        }

        return Column(
          children: [
            // Preview section for placed emojis
            Container(
              height: 100, // Fixed height for the preview section
              color: Colors.grey[200], // Light grey background color
              child: (emojiPositions.isNotEmpty)
                  ? ListView.builder(
                      scrollDirection: Axis.horizontal, // Horizontal scroll for emoji previews
                      itemCount: emojiPositions.length,
                      itemBuilder: (context, index) {
                        return GestureDetector(
                          onTap: () {
                            scrollToEmoji(index); // Scroll to the corresponding emoji when tapped
                            setState(() {
                              highlightedEmojiIndex = index; // Set the highlighted emoji
                            });
                          },
                          child: Padding(
                            padding: const EdgeInsets.all(8.0),
                            child: ClipRRect(
                              borderRadius: BorderRadius.circular(8.0), // Rounded corners
                              child: Container(
                                width: 100, // Fixed width for the preview
                                height: 100, // Fixed height for the preview
                                decoration: BoxDecoration(
                                  border: Border.all(color: Colors.blueAccent), // Blue border around preview
                                ),
                                child: Stack(
                                  children: [
                                    // Small zoomed-in view of the area surrounding the emoji
                                    Image.network(
                                      widget.flyerImageUrl, // Load the main image
                                      fit: BoxFit.cover,
                                      alignment: Alignment(
                                        (emojiPositions[index].dx * 2) - 1, // Centered alignment based on position
                                        (emojiPositions[index].dy * 2) - 1, // Centered alignment based on position
                                      ),
                                    ),
                                    Positioned(
                                      top: 25,
                                      left: 25,
                                      child: Text(
                                        selectedEmojis[index], // Display the emoji
                                        style: TextStyle(fontSize: 24),
                                      ),
                                    ),
                                  ],
                                ),
                              ),
                            ),
                          ),
                        );
                      },
                    )
                  : Center(child: Text('No Emojis Placed Yet')), // Message when no emojis are placed
            ),
            Expanded(
              child: InteractiveViewer(
                transformationController: transformationController, // Controller for scaling and translation
                boundaryMargin: EdgeInsets.all(80.0), // Margin for boundary of the interactive viewer
                minScale: 0.5, // Minimum zoom level
                maxScale: 4.0, // Maximum zoom level
                child: GestureDetector(
                  onTapDown: (details) {
                    // Calculate the relative position of the tap
                    Offset relativePosition = _getRelativePosition(details);
                    setState(() {
                      emojiPositions.add(relativePosition); // Store original coordinates
                      selectedEmojis.add(currentEmoji); // Store the currently selected emoji
                    });
                  },
                  child: Stack(
                    children: [
                      // Main image displayed
                      Image.network(
                        widget.flyerImageUrl, // Load the main image
                        width: widget.width,
                        height: widget.height,
                        fit: BoxFit.cover,
                      ),
                      // Placed emojis
                      ...emojiPositions.asMap().entries.map((entry) {
                        int index = entry.key; // Get the index of the emoji
                        Offset relativePosition = entry.value; // Get the relative position

                        // Use the original coordinates to position the emojis
                        Offset actualPosition = _getActualPosition(relativePosition);

                        return Positioned(
                          left: actualPosition.dx - (actualImageWidth * widget.baseEmojiSizePercentage / 2),
                          top: actualPosition.dy - (actualImageHeight * widget.baseEmojiSizePercentage / 2),
                          child: Container(
                            child: Text(
                              selectedEmojis[index], // Display the emoji
                              style: TextStyle(
                                fontSize: actualImageWidth * widget.baseEmojiSizePercentage, // Size based on image width
                                color: index == highlightedEmojiIndex ? Colors.red : Colors.black, // Highlight the current emoji
                              ),
                            ),
                          ),
                        );
                      }).toList(),
                    ],
                  ),
                ),
              ),
            ),
            // Emoji selection section at the bottom
            Container(
              padding: EdgeInsets.symmetric(vertical: 10), // Padding for the selection section
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: emojis.map((emoji) {
                  return GestureDetector(
                    onTap: () {
                      setState(() {
                        currentEmoji = emoji; // Change current emoji
                      });
                    },
                    child: Container(
                      padding: EdgeInsets.all(10), // Padding around each emoji
                      decoration: BoxDecoration(
                        color: currentEmoji == emoji ? Colors.blueAccent : Colors.white, // Highlight selected emoji
                        borderRadius: BorderRadius.circular(10), // Rounded corners
                        border: Border.all(color: Colors.grey), // Grey border
                      ),
                      child: Text(
                        emoji, // Display emoji
                        style: TextStyle(fontSize: 24),
                      ),
                    ),
                  );
                }).toList(),
              ),
            ),
          ],
        );
      },
    );
  }

  /// Convert the tap location to original image-relative coordinates.
  Offset _getRelativePosition(TapDownDetails details) {
    RenderBox renderBox = context.findRenderObject() as RenderBox;
    Offset localOffset = renderBox.globalToLocal(details.globalPosition); // Convert global position to local

    double relativeX = localOffset.dx / actualImageWidth; // Calculate relative X coordinate
    double relativeY = localOffset.dy / actualImageHeight; // Calculate relative Y coordinate

    return Offset(relativeX, relativeY); // Return as a fraction of the image dimensions
  }

  /// Convert relative coordinates back to actual screen coordinates.
  Offset _getActualPosition(Offset relativePosition) {
    Matrix4 matrix = transformationController.value;

    // Use individual scale factors from the transformation matrix
    double x = relativePosition.dx * actualImageWidth * matrix.getRow(0)[0] + matrix.getRow(0)[3]; // Scale X + Translate X
    double y = relativePosition.dy * actualImageHeight * matrix.getRow(1)[1] + matrix.getRow(1)[3]; // Scale Y + Translate Y

    return Offset(x, y); // Return the calculated position
  }

  /// Scroll to the emoji's position based on its original coordinates.
  void scrollToEmoji(int index) {
    final Offset relativePosition = emojiPositions[index]; // Get the relative position of the emoji
    final Offset absolutePosition = _getActualPosition(relativePosition); // Convert to absolute position

    scrollController.animateTo(
      absolutePosition.dy - (widget.height ?? 0) / 2, // Scroll to the emoji's vertical position
      duration: Duration(milliseconds: 300), // Animation duration
      curve: Curves.easeInOut, // Animation curve
    );

    // Set the highlighted emoji index for visual feedback
    setState(() {
      highlightedEmojiIndex = index; // Highlight the emoji in the preview
    });
  }
}