6

私はdelphiグラフィックスメソッドに少し慣れていないので、...ビューポートの作成にこだわっています。これは、プロジェクトで実行しているときに呼び出す方法です。申し訳ありませんが、コードを提供できませんが、ロジックの部分で立ち往生しています。グーグルで検索すると、OnPaint、Drawメソッドがいくつか見つかりました。しかし、これらは私が達成しようとしていることではありません。たとえば、次のようなものがあるからです。

  1. クライアントの上下/左右に固定された1600x1000の背景画像。
  2. 設定されたx/y座標に配置された複数のTImage要素。
  3. クリック可能な領域を設定できるHTMLのマップ要素のような「ホットスポット」(ステップ2で配置する画像の場合)
  4. ズームは必要ありません。
  5. そして最も重要なことは、背景をドラッグしている間、背景の上に配置されたTImageもドラッグする必要があるということです。

私のロジック(HTML / jQuery)は、#viewportBinder(ドラッグしていたdiv、transparent bg)を作成し、その後にdiv(TImages)を含む#viewtown(1600x1000、背景)と呼ばれる別のdivを作成することでした。 CSSの設定された座標に配置されます。

したがって、viewportBinderをドラッグしているとき、jQueryは#viewportに新しいx/yを設定します。暗黙的に、親が相対位置に配置されているため、#viewport内のdiv(TImages)が移動しています。

この種のプロジェクトの経験はありますか?コードのスニペットはありますか?

具体的には、私が実装したものとDelphiコードに移植したいもののhtmlの例を示します:http ://www.youtube.com/watch?v = 9iYqzvZFnGA

よくわからない場合は申し訳ありませんが、デルファイでの経験がまったくないため、出発点がありません。(RAD Studio 2010を使用)

4

2 に答える 2

6

簡単な方法でそれを実現する方法の非常に短い例。

ペイントにはPaintboxを使用し、1つのBackimage、情報と透明なpngimagesを含むレコードの配列を使用します。

キャンバスはオフセット/ズーム/回転で操作できます。移動とヒット検出は、mousedownとmousemoveで発生します。

それは完全ではありませんが、それがどのように行われるかについての考えをあなたに与えるかもしれません。

[delphi]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls,PNGImage, StdCtrls;

type
  TBuilding=Record   // record for building informations
    Pos:TPoint;
    PNGImage:TPngImage;
    // what ever needed
  End;

  TBuildingArray=Array of TBuilding; // array of buildings

  TForm1 = class(TForm)
    PaintBox1: TPaintBox;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure PaintBox1Paint(Sender: TObject);
    procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
    FXoffs,FYOffs,FZoom:Double; // offset and zoom for painting
    FMouseDownPoint:TPoint;
    FBackGroundPNG:TPNGImage;
    FBuildingArray:TBuildingArray;
    procedure Check4Hit(X, Y: Integer);
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation
uses Math;
{$R *.dfm}


Procedure SetCanvasZoomAndRotation(ACanvas:TCanvas;Zoom:Double;Angle:Double;CenterpointX,CenterpointY:Double);
var
    form : tagXFORM;
    Winkel:Double;
begin
      Winkel := DegToRad(Angle);
      SetGraphicsMode(ACanvas.Handle, GM_ADVANCED);
      SetMapMode(ACanvas.Handle,MM_ANISOTROPIC);
      form.eM11 := Zoom * cos( Winkel);
      form.eM12 := Zoom *Sin( Winkel)  ;
      form.eM21 := Zoom * (-sin( Winkel));
      form.eM22 := Zoom * cos( Winkel) ;
      form.eDx := CenterpointX;
      form.eDy := CenterpointY;
      SetWorldTransform(ACanvas.Handle,form);
end;

Procedure ResetCanvas(ACanvas:TCanvas);
begin
   SetCanvasZoomAndRotation(ACanvas , 1, 0, 0,0);
end;


procedure TForm1.FormCreate(Sender: TObject);
var
 Path:String;
 i:Integer;
begin
   FZoom := 1;
   DoubleBuffered := true;
   Path := ExtractFilePath(Paramstr(0));
   FBackGroundPNG:=TPNGImage.Create;
   FBackGroundPNG.LoadFromFile(Path + 'infect.png');
   SetLength(FBuildingArray,3);
   for I := 0 to High(FBuildingArray)  do
      begin
         FBuildingArray[i].PNGImage := TPngImage.Create;
         FBuildingArray[i].PNGImage.LoadFromFile(Path + Format('B%d.png',[i]));
         FBuildingArray[i].Pos.X := I * 300;
         FBuildingArray[i].Pos.Y := Random(1000);
      end;

end;
procedure TForm1.FormDestroy(Sender: TObject);
var
 i:Integer;
begin
   for I := 0 to High(FBuildingArray)  do
      begin
         FBuildingArray[i].PNGImage.Free;
      end;
   FBackGroundPNG.Free;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
  if FZoom=0.5 then FZoom := 1 else FZoom := 0.5;
  PaintBox1.Invalidate;
end;

procedure TForm1.Check4Hit(X,Y:Integer);
var
 i,Index:Integer;
 R:TRect;
 P:TPoint;
begin
   index := -1;
   for I := 0 to High(FBuildingArray)  do
      begin
         R := Rect(FBuildingArray[i].Pos.X,FBuildingArray[i].Pos.Y
                    ,FBuildingArray[i].Pos.X + FBuildingArray[i].PNGImage.Width
                    ,FBuildingArray[i].Pos.Y + FBuildingArray[i].PNGImage.Height);
         P := Point(Round((x - FXOffs)/FZoom) ,Round((y - FYOffs)/FZoom));
         if PtInRect(R,P) then Index := i;
      end;
   if index > -1 then
      begin
        Caption := Format('Last hit %d',[index]);
      end
   else Caption := 'No Hit';
end;

procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
   Check4Hit(X,Y);
   FMouseDownPoint.X := X;
   FMouseDownPoint.Y := Y;
end;

procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
   if ssLeft in Shift then
      begin
         FXoffs := -( FMouseDownPoint.X - X) ;
         FYoffs := -( FMouseDownPoint.Y - Y) ;
         if FXoffs>0 then FXoffs := 0;
         if FYoffs>0 then FYoffs := 0;
         PaintBox1.Invalidate;
      end;
end;

procedure TForm1.PaintBox1Paint(Sender: TObject);
var
 i:Integer;
begin
   SetCanvasZoomAndRotation(PaintBox1.Canvas,FZoom,0,FXoffs,FYOffs);
   PaintBox1.Canvas.Draw(0,0,FBackGroundPNG);
   for I := 0 to High(FBuildingArray)  do
      begin
         PaintBox1.Canvas.Draw(FBuildingArray[i].Pos.X,FBuildingArray[i].Pos.Y,FBuildingArray[i].PNGImage);
      end;
end;

end.

[/delphi]
于 2013-01-02T21:48:08.763 に答える
0

申し訳ありませんが、ここ数年、DelphiではなくLazarusを使用しています。ただし、この記事は参考になります。http ://wiki.lazarus.freepascal.org/Developing_with_Graphics#Create_a_custom_control_which_draws_itself 相対座標については言うまでもなく、簡単です。ドラッグについて:はるか昔、はるか遠くの銀河系で..それは次のようなものでした:

// To start dragging
procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
// To stop dragging
procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUP;
// To perform dragging
procedure WMMouseMove(var Message: TWMMouseMove); message WM_MOUSEMOVE;
于 2013-01-02T23:38:00.820 に答える