我有一个带漫画书布局的.bmp图片.目前我的代码是这样的.如果我右键单击并按住鼠标按钮,我可以在漫画书页面上的其中一个框架周围绘制一个选框类型框.当我释放按钮时,它将放大到该帧.但它的瞬间.我希望它有动画效果.
因此,而不是将PicRect的值设置为"结束值"
PicRect.Left
PicRect.right
PicRect.top
PicRect.bottom
Run Code Online (Sandbox Code Playgroud)
如下面的代码所示,我需要一种慢慢到达那里的方法,某种类型的while循环一次设置一些这些值,直到它达到"最终值"但是我不是100%肯定这个数学如何工作中.也没有任何我的while循环尝试做任何事情,但放大太远.这是程序.
procedure TZImage.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
var coef:Double;
t:integer;
begin
if FMouse=mNone then Exit;
if x>ShowRect.Right then x:=ShowRect.Right;
if y>ShowRect.Bottom then y:=ShowRect.Bottom;
if FMouse=mZoom then begin //calculate new PicRect
t:=startx;
startx:=Min(startx,x);
x:=Max(t,x);
t:=starty;
starty:=Min(starty,y);
y:=Max(t,y);
FMouse:=mNone;
MouseCapture:=False;
//enable the following if you want to zoom-out by dragging in the opposite direction}
{ if Startx>x then begin
DblClick;
Exit;
end;}
if Abs(x-startx)<5 then Exit;
if (x - startx < y - starty) then
begin
while (x - startx < y - starty) do
begin
x := x + 100;
startx := startx - 100;
end;
end
else if (x - startx > y - starty) then
begin
while (x - startx > y - starty) do
begin
y := y + 100;
starty := starty - 100;
end;
end;
//This is were it sets the zoom info. This is were
//I have to change to slowly get the PICRECT.Left/right/top/bottom
if (PicRect.Right=PicRect.Left)
then
coef := 100000
else
coef:=ShowRect.Right/(PicRect.Right-PicRect.Left);
PicRect.Left:=Round(PicRect.Left+startx/coef);
PicRect.Right:=PicRect.Left+Round((x-startx)/coef);
if (PicRect.Bottom=PicRect.Top)
then
coef := 100000
else
coef:=ShowRect.Bottom/(PicRect.Bottom-PicRect.Top);
PicRect.Top:=Round(PicRect.Top+starty/coef);
PicRect.Bottom:=PicRect.Top+Round((y-starty)/coef);
end;
if FMouse=mDrag then begin
FMouse:=mNone;
Canvas.Pen.Mode:=pmCopy;
Screen.Cursor:=crDefault;
end;
Invalidate;
end;
Run Code Online (Sandbox Code Playgroud)
我相信这可以在上面的代码中完成.但也想添加这个有用的东西.
type
TZImage = class(TGraphicControl)
private
FBitmap : TBitmap;
PicRect : TRect;
ShowRect : TRect;
FShowBorder : boolean;
FBorderWidth : integer;
FForceRepaint : boolean;
FMouse : (mNone, mDrag, mZoom);
FProportional : boolean;
FDblClkEnable : boolean;
startx, starty,
oldx, oldy : integer;
Run Code Online (Sandbox Code Playgroud)
感谢任何帮助让这个工作.
我有一些建议; 我不确定它们是否足以解决您的问题,但我希望它可以帮助您实现目标.
首先,你的while循环正在进行相当多的有趣的摆弄:
if (x - startx < y - starty) then
begin
while (x - startx < y - starty) do
begin
x := x + 100;
startx := startx - 100;
end;
end
else if (x - startx > y - starty) then
/* similar code */
Run Code Online (Sandbox Code Playgroud)
请注意,x - start == y - starty案件完全被忽视了.我不知道这是否重要.
其次,这可能是在没有循环的情况下重写的.我在这里猜测,它需要一些测试,看看这是否正确,但这感觉就像正确的道路:
foo := (x - startx) - (y - starty)
if (foo > 200 || foo < -200)
bar = foo / 200 # I assume integer truncation
x += bar * 100
startx += bar * 100
Run Code Online (Sandbox Code Playgroud)
我不完全确定你为什么试图达到(x-startx) - (y-starty)彼此200之内; 可能还有更好的东西.
这部分代码有点令人困惑:
if (PicRect.Right=PicRect.Left)
then
coef := 100000
else
coef:=ShowRect.Right/(PicRect.Right-PicRect.Left);
PicRect.Left:=Round(PicRect.Left+startx/coef);
PicRect.Right:=PicRect.Left+Round((x-startx)/coef);
if (PicRect.Bottom=PicRect.Top)
then
coef := 100000
else
coef:=ShowRect.Bottom/(PicRect.Bottom-PicRect.Top);
PicRect.Top:=Round(PicRect.Top+starty/coef);
PicRect.Bottom:=PicRect.Top+Round((y-starty)/coef);
end;
Run Code Online (Sandbox Code Playgroud)
是coef应该是从早期的覆盖?或者,你应该不是计算coefx和coefy,然后挑(大?小?更接近100000?)价值,以服务为两个.Left,.Right,.Top,和.Bottom计算?我不得不认为,这样的代码,更有可能导致内容的笨拙延伸,这种方式可能会惹恼用户和作者.
现在,为了解决你在这里的真正原因,为缩放设置动画 - 你可能需要彻底改变一些东西.我觉得你的while循环可能是为了进行缩放,但它们是在coef计算之后出现的,所以我认为它们是用于其他东西的.但是,一旦你弄清楚确切地放置循环的位置来计算coef从"无缩放"到"最终缩放"范围内的不同值,你还需要添加调用以重新绘制显示 - 或者,取决于你的环境,可能需要每隔50毫秒添加一些定时器触发的回调代码,或者用更新的coef值重新绘制.
由于两个问题,请勿使用while循环更新缩放级别:
Sleep),代码也在主线程中运行,程序没有响应.就像sarnold和Elling已经说过的那样:使用计时装置(例如a TTimer)在每个间隔上执行一次总变焦操作.现在,有两种方法来计算这些部分:
我在回答您的相关问题时使用了第二个解决方案,从中获取以下相关摘要:
procedure TZImage.Animate(Sender: TObject);
var
Done: Single;
begin
Done := (GetTickCount - FAnimStartTick) / FAnimDuration;
if Done >= 1.0 then
begin
FAnimTimer.Enabled := False;
FAnimRect := FCropRect;
end
else
with FPrevCropRect do
FAnimRect := Rect(
Left + Round(Done * (FCropRect.Left - Left)),
Top + Round(Done * (FCropRect.Top - Top)),
Right + Round(Done * (FCropRect.Right - Right)),
Bottom + Round(Done * (FCropRect.Bottom - Bottom)));
Invalidate;
end;
procedure TZImage.Zoom(const ACropRect: TRect);
begin
FPrevCropRect := FCropRect;
FAnimRect := FPrevCropRect;
FCropRect := ACropRect;
FAnimStartTick := GetTickCount;
FAnimTimer.Enabled := True;
end;
Run Code Online (Sandbox Code Playgroud)
说明:
FCropRect是新的缩放矩形,FPrevCropRect是前一个,FAnimRect 是两者之间的矩形,取决于动画的进度,FAnimStartTick是通过调用启动缩放操作的时间Zoom,Animate被称为,Done 是动画进度的百分比,Invalidate触发一个将图形绘制成的重绘FAnimRect.| 归档时间: |
|
| 查看次数: |
760 次 |
| 最近记录: |