Graphics32:通过鼠标拖动平移,用鼠标滚轮放大到鼠标光标 [英] Graphics32: Pan with mouse-drag, zoom to mouse cursor with mouse wheel
问题描述
当我点击并拖动鼠标,并且使用鼠标滚轮的鼠标光标放大/缩小时,我需要实现一个平移。 (在Delphi 2010中,将图像锚定到左,右,顶部,底部的形式。)
我刚刚安装了Graphics32,并看到它的内置滚动酒吧和.Scale允许其中的一些。
问题:
Graphics32是一款很好的工具的东西?有没有其他(可能更简单?)工具,我可以研究一下?
有没有人有任何指针或示例代码如何实现上述?
谢谢。
Graphics32提供了一个名为TImgView32的组件,可以通过设置比例财产。这样做的恰当方法是使用OnMouseWheelUp和-Down事件。将TabStop设置为True以触发这些事件并将居中设为假。但是以这种方式缩放不符合您希望将缩放操作置于鼠标光标的位置。所以在这一点上重新定位和调整大小是一个更好的解决方案。此外,据了解,图像始终对齐在组件的左上角,因此平移也必须通过重新定位组件来完成。
使用
Windows,类,控件,表单,GR32_Image,GR32_Layers,Jpeg;
类型
TForm1 =类(TForm)
ImgView:TImgView32;
procedure FormCreate(Sender:TObject);
procedure ImgViewMouseWheel(Sender:TObject; Shift:TShiftState;
WheelDelta:Integer; MousePos:TPoint; var Handled:Boolean);
procedure ImgViewMouseDown(Sender:TObject; Button:TMouseButton;
Shift:TShiftState; X,Y:Integer; Layer:TCustomLayer);
procedure FormMouseMove(Sender:TObject; Shift:TShiftState; X,
Y:Integer);
procedure FormMouseUp(Sender:TObject; Button:TMouseButton;
Shift:TShiftState; X,Y:Integer);
private
FDragging:Boolean;
FFrom:TPoint;
结束
实现
{$ R * .dfm}
程序TForm1.FormCreate(发件人:TObject);
begin
ImgView.Bitmap.LoadFromFile('D:\Pictures\Mona_Lisa.jpg');
ImgView.TabStop:= True;
ImgView.ScrollBars.Visibility:= svHidden;
ImgView.ScaleMode:= smResize;
结束
procedure TForm1.ImgViewMouseWheel(Sender:TObject; Shift:TShiftState;
WheelDelta:Integer; MousePos:TPoint; var Handled:Boolean);
const
ZoomFactor:Array [Boolean]为Single =(0.9,1.1);
var
R:TRect;
begin
MousePos:= ImgView.ScreenToClient(MousePos);
与ImgView,MousePos do
如果PtInRect(ClientRect,MousePos)然后
开始
R:= BoundsRect;
R.Left:= Left + X - Round(ZoomFactor [WheelDelta> 0] * X);
R.Top:= Top + Y - Round(ZoomFactor [WheelDelta> 0] * Y);
R.Right:= R.Left + Round(ZoomFactor [WheelDelta> 0] * Width);
R.Bottom:= R.Top + Round(ZoomFactor [WheelDelta> 0] * Height);
BoundsRect:= R;
处理:= True;
结束
结束
procedure TForm1.ImgViewMouseDown(Sender:TObject; Button:TMouseButton;
Shift:TShiftState; X,Y:Integer; Layer:TCustomLayer);
begin
FDragging:= True;
ImgView.Enabled:= False; {临时地将MouseMove转移到父项}
FFrom:= Point(X,Y);
结束
procedure TForm1.FormMouseMove(Sender:TObject; Shift:TShiftState; X,
Y:Integer);
begin
如果FDragging然后
ImgView.SetBounds(X - FFrom.X,Y - FFrom.Y,ImgView.Width,ImgView.Height);
结束
procedure TForm1.FormMouseUp(Sender:TObject; Button:TMouseButton;
Shift:TShiftState; X,Y:Integer);
begin
FDragging:= False;
ImgView.Enabled:= True;
ImgView.SetFocus;
结束
编辑:替代TImage而不是TImgView32:
使用
Windows,Classes,Controls,Forms,Jpeg,ExtCtrls;
type
TForm1 = class(TForm)
图片:TImage;
procedure FormCreate(Sender:TObject);
procedure FormMouseWheel(Sender:TObject; Shift:TShiftState;
WheelDelta:Integer; MousePos:TPoint; var Handled:Boolean);
procedure FormMouseMove(Sender:TObject; Shift:TShiftState; X,
Y:Integer);
procedure FormMouseUp(Sender:TObject; Button:TMouseButton;
Shift:TShiftState; X,Y:Integer);
程序ImageDblClick(Sender:TObject);
procedure ImageMouseDown(Sender:TObject; Button:TMouseButton;
Shift:TShiftState; X,Y:Integer);
private
FDragging:Boolean;
FFrom:TPoint;
FOrgImgBounds:TRect;
结束
实现
{$ R * .dfm}
程序TForm1.FormCreate(发件人:TObject);
begin
DoubleBuffered:= True;
Image.Picture.LoadFromFile('D:\Pictures\Mona_Lisa.jpg');
Image.Stretch:= True;
Image.Height:= Round(Image.Width * Image.Picture.Height / Image.Picture.Width);
FOrgImgBounds:= Image.BoundsRect;
结束
procedure TForm1.FormMouseWheel(Sender:TObject; Shift:TShiftState;
WheelDelta:Integer; MousePos:TPoint; var Handled:Boolean);
const
ZoomFactor:Array [Boolean]为Single =(0.9,1.1);
var
R:TRect;
begin
MousePos:= Image.ScreenToClient(MousePos);如果PtInRect(ClientRect,MousePos)和((WheelDelta> 0)和
(Height< Self.ClientHeight)和(Width< Self.ClientWidth))的
与Image,MousePos do
)或
((WheelDelta <0)和(Height> 20)和(Width> 20))然后
begin
R:= BoundsRect;
R.Left:= Left + X - Round(ZoomFactor [WheelDelta> 0] * X);
R.Top:= Top + Y - Round(ZoomFactor [WheelDelta> 0] * Y);
R.Right:= R.Left + Round(ZoomFactor [WheelDelta> 0] * Width);
R.Bottom:= R.Top + Round(ZoomFactor [WheelDelta> 0] * Height);
BoundsRect:= R;
处理:= True;
结束
结束
procedure TForm1.FormMouseMove(Sender:TObject; Shift:TShiftState; X,
Y:Integer);
begin
如果FDragging然后
Image.SetBounds(X - FFrom.X,Y - FFrom.Y,Image.Width,Image.Height);
结束
procedure TForm1.FormMouseUp(Sender:TObject; Button:TMouseButton;
Shift:TShiftState; X,Y:Integer);
begin
Image.Enabled:= True;
FDragging:= False;
结束
procedure TForm1.ImageDblClick(Sender:TObject);
begin
Image.BoundsRect:= FOrgImgBounds;
结束
procedure TForm1.ImageMouseDown(Sender:TObject; Button:TMouseButton;
Shift:TShiftState; X,Y:Integer);
开始
如果没有(ssDouble在Shift)然后
开始
FDragging:= True;
Image.Enabled:= False;
FFrom:=点(X,Y);
MouseCapture:= True;
结束
结束
I need to implement a pan as I click and drag the mouse, and zoom/unzoom towards/away from the mouse cursor that uses the mouse wheel. (In Delphi 2010, with the image anchored to left,right,top,bottom the form.)
I've just installed Graphics32 and seen how its built-in scroll bars and .Scale allow some of this. It's tantalizingly easy to at least get that far.
Questions:
Is Graphics32 a good tool for this kind of thing? Are there other (perhaps more simple?) tools that I might look into?
Does anyone have any pointers or sample code on how to implement the above?
Thanks.
Graphics32 provides a component named TImgView32 which can zoom by setting the Scale property. The appropriate way to do so is by using the OnMouseWheelUp and -Down events. Set TabStop to True for triggering these events and set Centered to False. But scaling in this manner does not comply with your wish to center the zooming operation at the mouse cursor. So repositioning and resizing around that point is a nicer solution. Further, as I understand, the image is always aligned in the top-left corner of the component, so panning must also be accomplished by repositioning the component.
uses
Windows, Classes, Controls, Forms, GR32_Image, GR32_Layers, Jpeg;
type
TForm1 = class(TForm)
ImgView: TImgView32;
procedure FormCreate(Sender: TObject);
procedure ImgViewMouseWheel(Sender: TObject; Shift: TShiftState;
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
procedure ImgViewMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
FDragging: Boolean;
FFrom: TPoint;
end;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
ImgView.Bitmap.LoadFromFile('D:\Pictures\Mona_Lisa.jpg');
ImgView.TabStop := True;
ImgView.ScrollBars.Visibility := svHidden;
ImgView.ScaleMode := smResize;
end;
procedure TForm1.ImgViewMouseWheel(Sender: TObject; Shift: TShiftState;
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
const
ZoomFactor: array[Boolean] of Single = (0.9, 1.1);
var
R: TRect;
begin
MousePos := ImgView.ScreenToClient(MousePos);
with ImgView, MousePos do
if PtInRect(ClientRect, MousePos) then
begin
R := BoundsRect;
R.Left := Left + X - Round(ZoomFactor[WheelDelta > 0] * X);
R.Top := Top + Y - Round(ZoomFactor[WheelDelta > 0] * Y);
R.Right := R.Left + Round(ZoomFactor[WheelDelta > 0] * Width);
R.Bottom := R.Top + Round(ZoomFactor[WheelDelta > 0] * Height);
BoundsRect := R;
Handled := True;
end;
end;
procedure TForm1.ImgViewMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
begin
FDragging := True;
ImgView.Enabled := False; { Temporarily, to get MouseMove to the parent }
FFrom := Point(X, Y);
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if FDragging then
ImgView.SetBounds(X - FFrom.X, Y - FFrom.Y, ImgView.Width, ImgView.Height);
end;
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
FDragging := False;
ImgView.Enabled := True;
ImgView.SetFocus;
end;
Edit: Alternative with TImage instead of TImgView32:
uses
Windows, Classes, Controls, Forms, Jpeg, ExtCtrls;
type
TForm1 = class(TForm)
Image: TImage;
procedure FormCreate(Sender: TObject);
procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure ImageDblClick(Sender: TObject);
procedure ImageMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
FDragging: Boolean;
FFrom: TPoint;
FOrgImgBounds: TRect;
end;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
DoubleBuffered := True;
Image.Picture.LoadFromFile('D:\Pictures\Mona_Lisa.jpg');
Image.Stretch := True;
Image.Height := Round(Image.Width * Image.Picture.Height / Image.Picture.Width);
FOrgImgBounds := Image.BoundsRect;
end;
procedure TForm1.FormMouseWheel(Sender: TObject; Shift: TShiftState;
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
const
ZoomFactor: array[Boolean] of Single = (0.9, 1.1);
var
R: TRect;
begin
MousePos := Image.ScreenToClient(MousePos);
with Image, MousePos do
if PtInRect(ClientRect, MousePos) and ((WheelDelta > 0) and
(Height < Self.ClientHeight) and (Width < Self.ClientWidth)) or
((WheelDelta < 0) and (Height > 20) and (Width > 20)) then
begin
R := BoundsRect;
R.Left := Left + X - Round(ZoomFactor[WheelDelta > 0] * X);
R.Top := Top + Y - Round(ZoomFactor[WheelDelta > 0] * Y);
R.Right := R.Left + Round(ZoomFactor[WheelDelta > 0] * Width);
R.Bottom := R.Top + Round(ZoomFactor[WheelDelta > 0] * Height);
BoundsRect := R;
Handled := True;
end;
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if FDragging then
Image.SetBounds(X - FFrom.X, Y - FFrom.Y, Image.Width, Image.Height);
end;
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Image.Enabled := True;
FDragging := False;
end;
procedure TForm1.ImageDblClick(Sender: TObject);
begin
Image.BoundsRect := FOrgImgBounds;
end;
procedure TForm1.ImageMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if not (ssDouble in Shift) then
begin
FDragging := True;
Image.Enabled := False;
FFrom := Point(X, Y);
MouseCapture := True;
end;
end;
这篇关于Graphics32:通过鼠标拖动平移,用鼠标滚轮放大到鼠标光标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!