4

使用 Delphi XE 2,我试图确定缩放方向以将缩放效果应用于图像 (TImage),但没有找到执行此操作的函数,并且 Image 的 OnGesture 事件中的 EventInfo 属性没有此信息。

我见过很多使用 Direct2d 进行放大和缩小的示例,但它使用 wp_touch 消息直接来执行此操作,并且缩放效果是使用来自直接 2d 的变换矩阵缩放函数执行的,但我不想在这个项目中使用 direct2d因为它只会有这种基于触摸的放大和缩小效果,其他的就是简单的点击。

可以识别存储第一个方向的输入/输出并与当前方向进行比较,因为 EventInfo 参数具有属性 Direction 但我认为这不是很好的方法还是我错了?

那么在那之后是否有任何关于如何在 TImage 中执行缩放效果的建议或示例?我已经这样做了,但是在缩放以提供每个应用程序都具有的捏合效果时它不会平移。

4

2 回答 2

2

在阅读了大量文档后,我发现正确的做法是:

拦截 EventInfo.GestureID 以识别在我的情况下所需的命令缩放命令,之后您应该阅读 EventInfo.Flags 并确定它是否是 gfBegin 以便您可以缓存第一个位置点 (x,y) 和第一个距离,当标志不同时,gfBegin 使用 firstpoint 和 currentpoint (EventInfo.Location) 执行计算

基本命令应该是这样的:

 case EventInfo.GestureID of
  igiZoom:
   begin
     if (EventInfo.Flags = [gfBegin]) then
      begin
        FLastDistance := EventInfo.Distance;
        FFirstPoint.X := EventInfo.Location.X;
        FFirstPoint.Y := EventInfo.Location.Y;
        FFirstPoint := ScreenToClient(FFirstPoint);

        if (FSecondPoint.X = 0) and (FSecondPoint.Y = 0) then
         begin
          FSecondPoint.X := EventInfo.Location.X + 10;
          FSecondPoint.Y := EventInfo.Location.Y + 10;
          FSecondPoint := ScreenToClient(FSecondPoint);
         end;
        //ZoomCenter is a local TPoint var 
        ZoomCenter.Create(((FFirstPoint.X + FSecondPoint.X) div 2),
                          ((FFirstPoint.Y + FSecondPoint.Y) div 2));
        //Apply the zoom to the object  
        FDrawingObject.Zoom(EventInfo.Distance / FLastDistance, ZoomCenter.X, ZoomCenter.Y);

        Invalidate;
      end
       else
         begin
            FSecondPoint.X := EventInfo.Location.X;
            FSecondPoint.Y := EventInfo.Location.Y;
            FSecondPoint := ScreenToClient(FSecondPoint);

            ZoomCenter.Create(((FFirstPoint.X + FSecondPoint.X) div 2),
                              ((FFirstPoint.Y + FSecondPoint.Y) div 2));

            FDrawingObject.Zoom(EventInfo.Distance / FLastDistance, ZoomCenter.X, ZoomCenter.Y);

            Invalidate;
            //Update with the new values for next interaction
            FFirstPoint := FSecondPoint;
            FLastDistance := EventInfo.Distance;
         end;

Windows v7.0 SDK 中有一个用 c# 编写的示例代码,可以作为参考,对我有很大帮助。

于 2012-06-13T22:26:13.887 回答
0

对于最近的 Delphi 版本,EventInfo 有一个 Distance 属性。我们不必计算它。

对于像缩放这样的交互式手势,请查看 docwiki 中的示例代码: http://docwiki.embarcadero.com/CodeExamples/Tokyo/en/FMXInteractiveGestures_(Delphi)

    procedure TForm36.handleZoom(EventInfo: TGestureEventInfo);
var
  LObj: IControl;
  image: TImage;
begin
  LObj := Self.ObjectAtPoint(ClientToScreen(EventInfo.Location));
  if LObj is TImage then
  begin
    if not(TInteractiveGestureFlag.gfBegin in EventInfo.Flags) then
    begin
      image := TImage(LObj.GetObject);
      image.Width := image.Width + (EventInfo.Distance - FLastDIstance)/2;
      image.Height := image.Height + (EventInfo.Distance - FLastDIstance)/2;
      image.Position.X := image.Position.X - (EventInfo.Distance - FLastDIstance)/2;
      image.Position.Y := image.Position.Y - (EventInfo.Distance - FLastDIstance)/2;
    end;
  end;
  FLastDIstance := EventInfo.Distance;
end;
于 2017-12-14T14:38:34.877 回答