Почему эти формы выглядят так по-разному?

#delphi #graphics

#delphi #графика

Вопрос:

введите описание изображения здесь

Их свойства во время разработки практически одинаковы:

 object ShpRectangle: TShape
  Left = 272
  Top = 96
  Width = 409
  Height = 473
  Brush.Style = bsClear
  Pen.Color = clWhite
  Pen.Mode = pmMaskPenNot
  Pen.Style = psDash
end
object ShpHorizontal: TShape
  Left = 221
  Top = 420
  Width = 500
  Height = 1
  Brush.Style = bsClear
  Pen.Color = clWhite
  Pen.Mode = pmMaskPenNot
  Pen.Style = psDash
end
object ShpVertical: TShape
  Left = 480
  Top = 50
  Width = 1
  Height = 540
  Brush.Style = bsClear
  Pen.Color = clWhite
  Pen.Mode = pmMaskPenNot
  Pen.Style = psDash
end
  

ShpVertical.Width = 1 и ShpHorizontal.Height = 1 , что может сделать их отличными от ShpRectangle , но они отличаются от всех трех.
Могу ли я сделать эти формы похожими?

Обратите внимание, что я привел их pmMaskPenNot/pmDash , потому что они служат индикаторными линиями, накладывающимися на a TImage .
(В этом случае они все еще выглядят как на картинке).

Ответ №1:

Здесь у меня есть форма, содержащая два TShape прямоугольника с пунктирными границами, один высотой 9 пикселей, а другой высотой 1 пиксель, оба имеют анимированную ширину:

Запись на экране двух фигур с увеличенной шириной.

Как вы можете себе представить, «линия» на самом деле состоит из двух линий — верхней границы и нижней границы — и ее внешний вид зависит от их разности фаз, которая, в свою очередь, зависит от ширины.

Вы действительно мало что можете с этим поделать.

В любом случае, не стоит создавать изображение, комбинируя элементы управления VCL. (Создание анимации таким образом еще хуже!) Вместо этого нарисуйте изображение вручную, используя GDI, GDI или Direct2D. Все эти API имеют очень простые в использовании методы рисования линий. Используя GDI и Direct2D, вы даже можете рисовать не сплошные толстые линии.

Вот пример GDI:

 procedure TForm1.FormPaint(Sender: TObject);
begin

  Canvas.Brush.Color := clWhite;
  Canvas.FillRect(ClientRect);
  Canvas.Pen.Color := clBlack;

  Canvas.Pen.Style := psDashDot;
  Canvas.MoveTo(10, ClientHeight div 2);
  Canvas.LineTo(Round(10   (ClientWidth - 20) * Abs(Sin(x))), ClientHeight div 2);

  Canvas.Pen.Style := psDash;
  Canvas.MoveTo(10, ClientHeight div 2 - 5);
  Canvas.LineTo(Round(10   (ClientWidth - 20) * Abs(Sin(x))), ClientHeight div 2 - 5);

  Canvas.Pen.Style := psDot;
  Canvas.MoveTo(10, ClientHeight div 2   5);
  Canvas.LineTo(Round(10   (ClientWidth - 20) * Abs(Sin(x))), ClientHeight div 2   5);

  x := x   0.01;

end;
  

A TTimer делает недействительной форму 30 раз в секунду или около того.

Запись на экране линий, нарисованных вручную с помощью GDI