How to create panning from a composite image in Delphi

Iโ€™m kind of new to delphi graphical methods, and Iโ€™m stuck in creating ... viewport, thatโ€™s what I call it while I did it for the project. Sorry, I canโ€™t provide any code for it, but I was stuck in the logical part and a google search showed me some OnPaint, Draw methods. But this is not what I am trying to accomplish, as I have, for example:

  • Background image 1600x1000, tied to the client top / bottom / right and left.
  • Several TImage elements placed at specified x / y coordinates.
  • "hotspot", as a map element in HTML, where I can set areas available for clicks (for the images that I post in step 2)
  • No scaling needed.
  • And most importantly, while the background is being dragged, those TImages placed on top of the background also need to be dragged.

My logic (in HTML / jQuery) was to create a #viewportBinder (which was a div that was drag and drop, transparent bg) and then another div inside it called #viewtown (1600x1000, background) that contains divs (those TImages) placed to given coordinates in CSS.

So when I drag the viewportBinder, jQuery sets the new x / y to #viewport. Implicitly, divs (TImages) inside #viewport are moved because the parent was relative.

Does anyone have experience in this project? Any piece of code?

To be more specific, I will give you my html example of what I did and what I want to port to Delphi code: http://www.youtube.com/watch?v=9iYqzvZFnGA

Sorry if I'm not clear enough, I have no starting point, since I have no experience with this in delphi at all. (using RAD Studio 2010)

+6
source share
2 answers

A very short example of how this could be implemented in a simple way.

You should use Paintbox for drawing, 1 Backimage, an array of records with information and transparent pngimages.

Canvas can be manipulated using offset / zoom / rotate. Moving and detecting a hit will happen in the mousetrap and musmov.

This is not complete, but may give you an idea of โ€‹โ€‹how this can be done.

[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] 
+6
source

Sorry, but over the past few years I have been working with Lazarus instead of Delphi. But this article will be informative: http://wiki.lazarus.freepascal.org/Developing_with_Graphics#Create_a_custom_control_which_draws_itself Saying nothing about relative coordinates is easy. About drag and drop: long in the galaxy far, far ... it was something like:

 // 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; 
0
source

All Articles