diff --git a/AppKit/CPAnimation.j b/AppKit/CPAnimation.j index 712d5f7af..032a05df9 100644 --- a/AppKit/CPAnimation.j +++ b/AppKit/CPAnimation.j @@ -300,13 +300,47 @@ ACTUAL_FRAME_RATE = 0; */ - (float)currentValue { + var t = [self currentProgress]; + if ([_delegate respondsToSelector:@selector(animation:valueForProgress:)]) - return [_delegate animation:self valueForProgress:_progress]; + return [_delegate animation:self valueForProgress:t]; - if (_animationCurve == CPAnimationLinear) - return _progress; - - alert("IMPLEMENT ANIMATION CURVES!!!"); + var c1 = [], + c2 = []; + + [_timingFunction getControlPointAtIndex:1 values:c1]; + [_timingFunction getControlPointAtIndex:2 values:c2]; + + return CubicBezierAtTime(t,c1[0],c1[1],c2[0],c2[1],_duration); } @end + +// currently used function to determine time +// 1:1 conversion to js from webkit source files +// UnitBezier.h, WebCore_animation_AnimationBase.cpp +var CubicBezierAtTime = function CubicBezierAtTime(t,p1x,p1y,p2x,p2y,duration) +{ + var ax=0,bx=0,cx=0,ay=0,by=0,cy=0; + // `ax t^3 + bx t^2 + cx t' expanded using Horner's rule. + function sampleCurveX(t) {return ((ax*t+bx)*t+cx)*t;}; + function sampleCurveY(t) {return ((ay*t+by)*t+cy)*t;}; + function sampleCurveDerivativeX(t) {return (3.0*ax*t+2.0*bx)*t+cx;}; + // The epsilon value to pass given that the animation is going to run over |duration| seconds. The longer the animation, the more precision is needed in the timing function result to avoid ugly discontinuities. + function solveEpsilon(duration) {return 1.0/(200.0*duration);}; + function solve(x,epsilon) {return sampleCurveY(solveCurveX(x,epsilon));}; + // Given an x value, find a parametric value it came from. + function solveCurveX(x,epsilon) {var t0,t1,t2,x2,d2,i; + function fabs(n) {if(n>=0) {return n;}else {return 0-n;}}; + // First try a few iterations of Newton's method -- normally very fast. + for(t2=x, i=0; i<8; i++) {x2=sampleCurveX(t2)-x; if(fabs(x2)t1) {return t1;} + while(t0x2) {t0=t2;}else {t1=t2;} t2=(t1-t0)*.5+t0;} + return t2; // Failure. + }; + // Calculate the polynomial coefficients, implicit first and last control points are (0,0) and (1,1). + cx=3.0*p1x; bx=3.0*(p2x-p1x)-cx; ax=1.0-cx-bx; cy=3.0*p1y; by=3.0*(p2y-p1y)-cy; ay=1.0-cy-by; + // Convert from input time to parametric value in curve, then from that to output time. + return solve(t, solveEpsilon(duration)); +}; diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index b1c7b76d0..0b0d1bee0 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -1787,7 +1787,7 @@ CPTexturedBackgroundWindowMask [aSheet setFrame:startFrame]; _sheetContext["opened"] = YES; - [aSheet _setFrame:endFrame delegate:self duration:0.3 curve:CPAnimationEaseOut]; + [aSheet _setFrame:endFrame delegate:self duration:0.2 curve:CPAnimationEaseOut]; // Should run the main loop here until _isAnimating = FALSE [aSheet becomeKeyWindow]; @@ -1808,7 +1808,7 @@ CPTexturedBackgroundWindowMask [self _setUpMasksForView:sheetContent]; _sheetContext["opened"] = NO; - [sheet _setFrame:endFrame delegate:self duration:0.2 curve:CPAnimationLinear]; + [sheet _setFrame:endFrame delegate:self duration:0.2 curve:CPAnimationEaseIn]; } /* @ignore */