firemonkey - Delphi FMX TAnimator. How to animate a TPointF -
i have tscrollbox on form. placed onto scrollbox tlayout wider , taller device viewport horiz , vert scrollbars show , user can manually move layout.
i have gesture setup user can longpress scrollbox , layout origin (0,0).
procedure tfrmmain.scrollbox1gesture(sender: tobject; const eventinfo: tgestureeventinfo; var handled: boolean); begin if eventinfo.gestureid = system.uitypes.igilongtap begin scrollbox1.viewportposition := pointf(0, 0); scrollbox1.realigncontent; end;
now works great, happens rather quickly. thought perhaps use:
tanimator.animatefloat(scrollbox1, 'scrollbox1.viewportposition.x', 0, 0.3);
to make movement current position 0 bit more gentle, of course, that's never going work because can't assign value pointf.x
or pointf.y
directly (and therefore neither can animator).
so how can done? thanks
as built-in pointanimation missing, here self written one.
type tpointanimation = class(tcustompropertyanimation) private fstartfloat: tpointf; fstartfromcurrent: boolean; fstopfloat: tpointf; protected procedure firstframe; override; procedure processanimation; override; public constructor create(aowner: tcomponent); override; published property animationtype default tanimationtype.in; property autoreverse default false; property delay; property duration nodefault; property enabled default false; property interpolation default tinterpolationtype.linear; property inverse default false; property loop default false; property onfinish; property onprocess; property propertyname; property startfromcurrent: boolean read fstartfromcurrent write fstartfromcurrent default false; property startvalue: tpointf read fstartfloat write fstartfloat stored true; property stopvalue: tpointf read fstopfloat write fstopfloat stored true; property trigger; property triggerinverse; end; constructor tpointanimation.create(aowner: tcomponent); begin inherited; duration := 0.2; fstartfloat := pointf(0, 0); fstopfloat := pointf(0, 0); end; procedure tpointanimation.firstframe; var t: trttitype; p: trttiproperty; begin if startfromcurrent begin t := sharedcontext.gettype(finstance.classinfo); if t <> nil begin p := t.getproperty(fpath); if (p <> nil) , (p.propertytype.typekind = tkrecord) startvalue := p.getvalue(finstance).astype<tpointf>; end; end; end; procedure tpointanimation.processanimation; var newpoint: tpointf; t: trttitype; p: trttiproperty; begin if finstance <> nil begin t := sharedcontext.gettype(finstance.classinfo); if t <> nil begin p := t.getproperty(fpath); if (p <> nil) , (p.propertytype.typekind = tkrecord) begin newpoint := pointf(interpolatesingle(fstartfloat.x, fstopfloat.x, normalizedtime), interpolatesingle(fstartfloat.y, fstopfloat.y, normalizedtime)); p.setvalue(finstance, tvalue.from<tpointf>(newpoint)); end; end; end; end;
declare field inside forms private section
ani: tpointanimation;
create instance during formcreate
ani := tpointanimation.create(self); ani.propertyname := 'viewportposition'; ani.startfromcurrent := true; ani.duration := 0.3; scrollbox1.addobject(ani);
and start when needed
ani.start;
Comments
Post a Comment