在 PaintApp 中的 2 个图形之间创建橡皮擦

问题描述 投票:0回答:1

在我的代码中有2个图形,Graphics图形和Graphics g。图形用于创建形状,g用于使用箭头键移动形状。在代码中,我有一个橡皮擦,用于通过创建一支笔在单击光标时写出白色来删除所绘制的内容。使用橡皮擦的这种逻辑,我遇到了 0 个问题,直到我引入了用于移动形状的 g 图形。现在我找不到一种方法让橡皮擦在与移动的形状相同的图形上进行擦除(请注意,在创建形状之后将立即以 g 图形绘制)我发现的唯一接近的解决方案(这是我发布的)是这个,但问题是,每当我单击表单,或者单击按钮来选择要绘制的形状时橡皮擦删除的内容消失了(这意味着白色由于某种原因被删除了)

这里我将包含代码中最重要的部分,以便您可以了解一切是如何工作的(橡皮擦代码位于 mousemoves 函数中)

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
    startPoint = e.Location;
    draw = true;

    if (addtext)
    {
        TextBox textBox = new TextBox
        {
            Location = pictureBox1.PointToClient(MousePosition),
            Size = new Size(100, 20),
            ForeColor = Color.Black
        };

        textBox.Leave += (s, ev) =>
        {
            TextBox currentTextBox = (TextBox)s;
        };

        pictureBox1.Controls.Add(textBox);
        textBox.Focus();
        addtext = false;
    }

}


private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{

    if (draw)
    {
        if (choice == 1)
        {
            width = e.Location.X - startPoint.X;
            height = e.Location.Y - startPoint.Y;
            Rectangle shape = new Rectangle(startPoint.X, startPoint.Y, width, height);
            graphics.DrawRectangle(pen, shape);
            graphics.DrawRectangle(eraser, shape);
            pictureBox1.Refresh();
            draw = false;
        }
        else if (choice == 2)
        {
            width = e.Location.X - startPoint.X;
            height = e.Location.Y - startPoint.Y;
            Rectangle shape = new Rectangle(startPoint.X, startPoint.Y, width, height);
            graphics.DrawEllipse(pen, shape);
            graphics.DrawEllipse(eraser, shape);
            pictureBox1.Refresh();
            draw = false;
        }
        if (draw && choice == 3)
        {
            createPolygon(graphics, pen, startPoint, e.Location, 6);
            createPolygon(graphics, eraser, startPoint, e.Location, 6);
            draw = false;
        }
        else if (choice == 4)
        {
            createPolygon(graphics, pen, startPoint, e.Location, 4);
            createPolygon(graphics, eraser, startPoint, e.Location, 4);
            draw = false;
        }
        else if (choice == 5)
        {
            endPoint = e.Location;
            graphics.DrawLine(pen, startPoint, endPoint);
            graphics.DrawLine(eraser, startPoint, endPoint);
            draw = false;
        }
        else if (choice == 6)
        {
            graphics.DrawRectangle(pen, startPoint.X, startPoint.Y, Math.Abs(e.X - startPoint.X), Math.Abs(e.X - startPoint.X));
            graphics.DrawRectangle(eraser, startPoint.X, startPoint.Y, Math.Abs(e.X - startPoint.X), Math.Abs(e.X - startPoint.X));
            draw = false;
        }
        else if (choice == 7)
        {
            graphics.DrawEllipse(pen, startPoint.X, startPoint.Y, e.X - startPoint.X, e.X - startPoint.X);
            graphics.DrawEllipse(eraser, startPoint.X, startPoint.Y, e.X - startPoint.X, e.X - startPoint.X);
            draw = false;

        }
        else if (choice == 8)
        {
            Point[] point = { new Point(startPoint.X, startPoint.Y), new Point(startPoint.X, e.Y), new Point(startPoint.X, e.Y) };
            graphics.DrawPolygon(pen, point);
            Point[] point2 = { new Point(startPoint.X, startPoint.Y), new Point(startPoint.X, endPoint.Y), new Point(endPoint.X, endPoint.Y) };
            graphics.DrawPolygon(eraser, point2);
            draw = false;
        }
        else if (choice == 9)
        {
            Point[] point = { new Point(startPoint.X, startPoint.Y), new Point((startPoint.X + e.X) / 2, e.Y), new Point(e.X, startPoint.Y) };
            graphics.DrawPolygon(pen, point);
            graphics.DrawPolygon(eraser, point);
            draw = false;
        }
        else if (choice == 10)
        {
            graphics.DrawEllipse(pen, startPoint.X, startPoint.Y, e.X - startPoint.X, e.X - startPoint.X);
            graphics.DrawEllipse(pen, startPoint.X - 20, startPoint.Y - 20, (e.X - startPoint.X) + 40, (e.X - startPoint.X) + 40);
            graphics.DrawEllipse(eraser, startPoint.X, startPoint.Y, e.X - startPoint.X, e.X - startPoint.X);
            graphics.DrawEllipse(eraser, startPoint.X - 20, startPoint.Y - 20, (e.X - startPoint.X) + 40, (e.X - startPoint.X) + 40);
            draw = false; ;
        }
        Shape newShape = new Shape
        {
            Type = choice,
            StartPoint = startPoint,
            EndPoint = endPoint,
            PenColor = pen.Color
        };
        shapes.Add(newShape);

        pictureBox1.Refresh();
    }
}
private void eraserToolStripMenuItem_Click(object sender, EventArgs e)//This is the box that is used for the erasing part
{
    eraserMode = !eraserMode;
    draw = true;
}

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    if (eraserMode) //Here is the code for the Erasor
    {
        using (Graphics g = pictureBox1.CreateGraphics())
        {
            g.DrawLine(new Pen(Color.White, 6), startPoint, e.Location);
            startPoint = e.Location;

        }
    }
    if (draw && choice == 1)
    {
        width = e.Location.X - startPoint.X;
        height = e.Location.Y - startPoint.Y;
        graphics.DrawRectangle(eraser, startPoint.X, startPoint.Y, endPoint.X - startPoint.X, endPoint.Y - startPoint.Y);
        graphics.DrawRectangle(pen, startPoint.X, startPoint.Y, width, height);
        endPoint = e.Location;
        pictureBox1.Refresh();
    }


    else if (draw && choice == 2)
    {
        width = e.Location.X - startPoint.X;
        height = e.Location.Y - startPoint.Y;
        graphics.DrawEllipse(eraser, startPoint.X, startPoint.Y, endPoint.X - startPoint.X, endPoint.Y - startPoint.Y);
        graphics.DrawEllipse(pen, startPoint.X, startPoint.Y, width, height);
        endPoint = e.Location;
        pictureBox1.Refresh();
    }

    else if (draw && choice == 3)
    {
        createPolygon(graphics, eraser, startPoint, endPoint, 6);
        createPolygon(graphics, pen, startPoint, e.Location, 6);
        endPoint = e.Location;
        pictureBox1.Refresh();
    }
    else if (draw && choice == 4)
    {
        createPolygon(graphics, eraser, startPoint, endPoint, 4);
        createPolygon(graphics, pen, startPoint, e.Location, 4);
        endPoint = e.Location;
        pictureBox1.Refresh();

    }
    else if (draw && choice == 5)
    {
        graphics.DrawLine(eraser, startPoint, endPoint);
        graphics.DrawLine(pen, startPoint, e.Location);
        endPoint = e.Location;
        pictureBox1.Refresh();
    }
    else if (draw && choice == 6)
    {
        graphics.DrawRectangle(eraser, startPoint.X, startPoint.Y, endPoint.X - startPoint.X, endPoint.X - startPoint.X);
        graphics.DrawRectangle(pen, startPoint.X, startPoint.Y, e.X - startPoint.X, e.X - startPoint.X);
        endPoint = e.Location;
        pictureBox1.Refresh();
    }

    else if (draw && choice == 7)
    {
        graphics.DrawEllipse(eraser, startPoint.X, startPoint.Y, endPoint.X - startPoint.X, endPoint.X - startPoint.X);
        graphics.DrawEllipse(pen, startPoint.X, startPoint.Y, e.X - startPoint.X, e.X - startPoint.X);
        endPoint = e.Location;
        pictureBox1.Refresh();
    }
    else if (draw && choice == 8)
    {

        Point[] point2 = { new Point(startPoint.X, startPoint.Y), new Point(startPoint.X, endPoint.Y), new Point(endPoint.X, endPoint.Y) };
        Point[] point = { new Point(startPoint.X, startPoint.Y), new Point(startPoint.X, e.Y), new Point(e.X, e.Y) };
        graphics.DrawPolygon(eraser, point2);
        graphics.DrawPolygon(pen, point);
        endPoint = new Point(e.X, e.Y); // Update endPoint here
        pictureBox1.Refresh();
    }
    else if (draw && choice == 9)
    {

        Point[] point4 = { new Point(startPoint.X, startPoint.Y), new Point((startPoint.X + endPoint.X) / 2, endPoint.Y), new Point(endPoint.X, startPoint.Y) };
        Point[] point3 = { new Point(startPoint.X, startPoint.Y), new Point((startPoint.X + e.X) / 2, e.Y), new Point(e.X, startPoint.Y) };
        graphics.DrawPolygon(eraser, point4);
        graphics.DrawPolygon(pen, point3);
        endPoint = new Point(e.X, e.Y); // Update endPoint here
        pictureBox1.Refresh();
    }
    else if (draw && choice == 10)
    {


        graphics.DrawEllipse(eraser, startPoint.X, startPoint.Y, endPoint.X - startPoint.X, endPoint.X - startPoint.X);
        graphics.DrawEllipse(eraser, startPoint.X - 20, startPoint.Y - 20, (endPoint.X - startPoint.X) + 40, (endPoint.X - startPoint.X) + 40);
        graphics.DrawEllipse(pen, startPoint.X, startPoint.Y, e.X - startPoint.X, e.X - startPoint.X);
        graphics.DrawEllipse(pen, startPoint.X - 20, startPoint.Y - 20, (e.X - startPoint.X) + 40, (e.X - startPoint.X) + 40);
        endPoint = e.Location;
        pictureBox1.Refresh();
    }

} //and the code that follows is the code that draws the shapes in the g graphics
private void pictureBox1_Paint_1(object sender, PaintEventArgs e)
{
    foreach (var shape in shapes)
    {
        DrawShape(e.Graphics, shape);
    }
}
private void DrawShape(Graphics g, Shape shape)
{

    switch (shape.Type)
    {
        case 1:
            g.DrawRectangle(new Pen(shape.PenColor, 3), new Rectangle(shape.StartPoint, new Size(shape.EndPoint.X - shape.StartPoint.X, shape.EndPoint.Y - shape.StartPoint.Y)));
            break;
        case 2:
            g.DrawEllipse(new Pen(shape.PenColor, 3), new Rectangle(shape.StartPoint, new Size(shape.EndPoint.X - shape.StartPoint.X, shape.EndPoint.Y - shape.StartPoint.Y)));
            break;
        case 3:
            // Add logic for drawing hexagon (6-sided polygon)
            createPolygon(g, new Pen(shape.PenColor, 3), shape.StartPoint, shape.EndPoint, 6);
            break;
        case 4:
            // Add logic for drawing square (4-sided polygon)
            createPolygon(g, new Pen(shape.PenColor, 3), shape.StartPoint, shape.EndPoint, 4);
            break;
        case 5:
            g.DrawLine(new Pen(shape.PenColor, 3), shape.StartPoint, shape.EndPoint);
            break;
        case 6:
            g.DrawRectangle(new Pen(shape.PenColor, 3), new Rectangle(shape.StartPoint, new Size(shape.EndPoint.X - shape.StartPoint.X, shape.EndPoint.X - shape.StartPoint.X)));
            break;
        case 7:
            g.DrawEllipse(new Pen(shape.PenColor, 3), new Rectangle(shape.StartPoint, new Size(shape.EndPoint.X - shape.StartPoint.X, shape.EndPoint.X - shape.StartPoint.X)));
            break;
        case 8:
            createPolygon(g, new Pen(shape.PenColor, 3), shape.StartPoint, shape.EndPoint, 3);
            break;
        case 9:
            createPolygon(g, new Pen(shape.PenColor, 3), shape.StartPoint, shape.EndPoint, 3);
            break;
        case 10:
            // Add logic for drawing concentric circles
            g.DrawEllipse(new Pen(shape.PenColor, 3), new Rectangle(shape.StartPoint, new Size(shape.EndPoint.X - shape.StartPoint.X, shape.EndPoint.X - shape.StartPoint.X)));
            g.DrawEllipse(new Pen(shape.PenColor, 3), new Rectangle(new Point(shape.StartPoint.X - 20, shape.StartPoint.Y - 20), new Size(shape.EndPoint.X - shape.StartPoint.X + 40, shape.EndPoint.X - shape.StartPoint.X + 40)));
            break;
    }
}
c# forms paint
1个回答
0
投票

你需要一个类来保存“擦除部分”的两个点:

public class ErasePoint {

    public Point ptA;
    public Point ptB;

    public ErasePoint(Point a, Point b) {
        ptA = a;
        ptB = b;
    }

}

然后你需要一个列表来保存它们,在与“形状”列表相同的位置声明:

List<ErasePoint> erasePoints = new List<ErasePoint>();

现在,在您的擦除代码中,创建一个 ErasePoint 实例,将其添加到列表中,然后

Invalidate()
您的 PictureBox 强制它重新绘制自身:

if (eraserMode) //Here is the code for the Erasor
{
    ErasePoint erase = new ErasePoint(startPoint, e.Location);
    erasePoints.Add(erase);
    startPoint = e.Location;
    pictureBox1.Invalidate();
}

Paint()
事件中,首先绘制所有形状,然后通过在其顶部绘制白色来“擦除”部分:

private void pictureBox1_Paint_1(object sender, PaintEventArgs e)
{
    // Draw all the shapes first
    foreach (var shape in shapes)
    {
        DrawShape(e.Graphics, shape);
    }
    
    // Draw the "erased" parts:
    using (Pen p = new Pen(Color.White, 6) {
    foreach(ErasePoint ep in erasePoints) {
        e.Graphics.DrawLine(p, ep.ptA, ep.ptB);
    }
}

这就是基本思想;当然,完全未经测试...

© www.soinside.com 2019 - 2024. All rights reserved.