mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-10-31 04:17:36 +00:00
Fixed: CPViewAnimator was not giving correct frame information (#2502)
Fixed: When only animating frameSize, there’s no matrix defined. This is now correctly handled. New: The animator can explicitly request frames updates when the frameOrigin keyPath changes with the new method [animator setWantsPeriodicFramesUpdates:YES]
This commit is contained in:
1 parent
ef1d6c78ac
commit
eeea21c882
3 files changed
+114
-64
No files matched your search
+13
-5
@@ -252,6 +252,8 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
|
||||
id _animator;
|
||||
CPDictionary _animationsDictionary;
|
||||
BOOL _inhibitDOMUpdates @accessors(setter=_setInhibitDOMUpdates);
|
||||
BOOL _forceUpdates @accessors(setter=_setForceUpdates);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -404,6 +406,9 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
|
||||
[self _setupViewFlags];
|
||||
[self _loadThemeAttributes];
|
||||
|
||||
_inhibitDOMUpdates = NO;
|
||||
_forceUpdates = NO;
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -1013,7 +1018,7 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
*/
|
||||
- (void)setFrame:(CGRect)aFrame
|
||||
{
|
||||
if (CGRectEqualToRect(_frame, aFrame))
|
||||
if (CGRectEqualToRect(_frame, aFrame) && !_forceUpdates)
|
||||
return;
|
||||
|
||||
_inhibitFrameAndBoundsChangedNotifications = YES;
|
||||
@@ -1084,7 +1089,7 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
{
|
||||
var origin = _frame.origin;
|
||||
|
||||
if (!aPoint || CGPointEqualToPoint(origin, aPoint))
|
||||
if (!aPoint || (CGPointEqualToPoint(origin, aPoint) && !_forceUpdates))
|
||||
return;
|
||||
|
||||
origin.x = aPoint.x;
|
||||
@@ -1097,9 +1102,12 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
[[self superview] viewFrameChanged:[[CPNotification alloc] initWithName:CPViewFrameDidChangeNotification object:self userInfo:nil]];
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
var transform = _superview ? _superview._boundsTransform : NULL;
|
||||
if (!_inhibitDOMUpdates)
|
||||
{
|
||||
var transform = _superview ? _superview._boundsTransform : NULL;
|
||||
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMElement, transform, origin.x, origin.y);
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMElement, transform, origin.x, origin.y);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!_inhibitUpdateTrackingAreas && !_inhibitFrameAndBoundsChangedNotifications)
|
||||
@@ -1116,7 +1124,7 @@ var CPViewHighDPIDrawingEnabled = YES;
|
||||
{
|
||||
var size = _frame.size;
|
||||
|
||||
if (!aSize || CGSizeEqualToSize(size, aSize))
|
||||
if (!aSize || (CGSizeEqualToSize(size, aSize) && !_forceUpdates))
|
||||
return;
|
||||
|
||||
var oldSize = CGSizeMakeCopy(size);
|
||||
|
||||
@@ -152,24 +152,32 @@ CPLog.debug(_cmd + "context stack =" + _CPAnimationContextStack);
|
||||
|
||||
duration = [animation duration] || [self duration];
|
||||
|
||||
var needsFrameTimer = (aKeyPath == @"frame" || aKeyPath == @"frameSize") &&
|
||||
([anObject hasCustomLayoutSubviews] || [anObject hasCustomDrawRect]) &&
|
||||
(objectId = [anObject UID]);
|
||||
var needsPeriodicFrameUpdates = (((aKeyPath == @"frame" || aKeyPath == @"frameSize") &&
|
||||
([anObject hasCustomLayoutSubviews] || [anObject hasCustomDrawRect])) || [[anObject animator] wantsPeriodicFrameUpdates]) &&
|
||||
(objectId = [anObject UID]);
|
||||
|
||||
if (_completionHandlerAgent)
|
||||
_completionHandlerAgent.increment();
|
||||
|
||||
var completionFunction = function()
|
||||
{
|
||||
if (needsFrameTimer)
|
||||
if (needsPeriodicFrameUpdates)
|
||||
{
|
||||
[self stopFrameUpdaterWithIdentifier:objectId];
|
||||
|
||||
if ([anObject respondsToSelector:@selector(_setForceUpdates:)])
|
||||
[anObject _setForceUpdates:YES];
|
||||
}
|
||||
|
||||
if (animationCompletion)
|
||||
animationCompletion();
|
||||
|
||||
if (needsFrameTimer || animationCompletion)
|
||||
if (needsPeriodicFrameUpdates || animationCompletion)
|
||||
[[CPRunLoop currentRunLoop] performSelectors];
|
||||
|
||||
if (needsPeriodicFrameUpdates && [anObject respondsToSelector:@selector(_setForceUpdates:)])
|
||||
[anObject _setForceUpdates:NO];
|
||||
|
||||
if (_completionHandlerAgent)
|
||||
_completionHandlerAgent.decrement();
|
||||
};
|
||||
@@ -266,7 +274,7 @@ CPLog.debug(_cmd + "context stack =" + _CPAnimationContextStack);
|
||||
isFrameKeyPath = (keyPath == @"frame" || keyPath == @"frameSize"),
|
||||
customLayout = [aTargetView hasCustomLayoutSubviews],
|
||||
customDrawing = [aTargetView hasCustomDrawRect],
|
||||
needsFrameTimer = isFrameKeyPath && (customLayout || customDrawing);
|
||||
needsPeriodicFrameUpdates = ((isFrameKeyPath && (customLayout || customDrawing)) || [[aTargetView animator] wantsPeriodicFrameUpdates]);
|
||||
|
||||
if (needsCSSAnimation)
|
||||
{
|
||||
@@ -305,7 +313,7 @@ CPLog.debug(_cmd + "context stack =" + _CPAnimationContextStack);
|
||||
}];
|
||||
}
|
||||
|
||||
if (needsFrameTimer)
|
||||
if (needsPeriodicFrameUpdates)
|
||||
{
|
||||
var timer = [self addFrameUpdaterWithIdentifier:[rootView UID] forView:aTargetView keyPath:keyPath duration:anAction.duration];
|
||||
|
||||
@@ -314,35 +322,36 @@ CPLog.debug(_cmd + "context stack =" + _CPAnimationContextStack);
|
||||
}
|
||||
|
||||
var subviews = [aTargetView subviews],
|
||||
count = [subviews count];
|
||||
count = [subviews count],
|
||||
customLayout = [aTargetView hasCustomLayoutSubviews];
|
||||
|
||||
if (count && isFrameKeyPath)
|
||||
{
|
||||
var frameTimerId = [rootView UID],
|
||||
lastIndex = count - 1;
|
||||
lastIndex = count - 1;
|
||||
|
||||
[subviews enumerateObjectsUsingBlock:function(aSubview, idx, stop)
|
||||
{
|
||||
var action = [self actionFromAction:anAction forAnimatedSubview:aSubview],
|
||||
{
|
||||
var action = [self actionFromAction:anAction forAnimatedSubview:aSubview],
|
||||
targetFrame = [action.values lastObject];
|
||||
|
||||
if (CGRectEqualToRect([aSubview frame], targetFrame))
|
||||
return;
|
||||
if (CGRectEqualToRect([aSubview frame], targetFrame))
|
||||
return;
|
||||
|
||||
if ([aSubview hasCustomDrawRect])
|
||||
{
|
||||
action.completion = function()
|
||||
{
|
||||
[aSubview setFrame:targetFrame];
|
||||
CPLog.debug(aSubview + " setFrame: ");
|
||||
if ([aSubview hasCustomDrawRect])
|
||||
{
|
||||
action.completion = function()
|
||||
{
|
||||
[aSubview setFrame:targetFrame];
|
||||
CPLog.debug(aSubview + " setFrame: ");
|
||||
|
||||
if (idx == lastIndex)
|
||||
[self stopFrameUpdaterWithIdentifier:frameTimerId];
|
||||
};
|
||||
}
|
||||
if (idx == lastIndex)
|
||||
[self stopFrameUpdaterWithIdentifier:frameTimerId];
|
||||
};
|
||||
}
|
||||
|
||||
[self getAnimations:cssAnimations getTimers:timers forView:aSubview usingAction:action rootView:rootView cssAnimate:!customLayout];
|
||||
}];
|
||||
[self getAnimations:cssAnimations getTimers:timers forView:aSubview usingAction:action rootView:rootView cssAnimate:!customLayout];
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -422,6 +431,7 @@ CPLog.debug(_cmd + "context stack =" + _CPAnimationContextStack);
|
||||
{
|
||||
var mask = [self autoresizingMask];
|
||||
|
||||
|
||||
if (mask == CPViewNotSizable)
|
||||
return _frame;
|
||||
|
||||
@@ -674,31 +684,43 @@ FrameUpdater.prototype.addTarget = function(target, keyPath, duration)
|
||||
|
||||
var createUpdateFrame = function(aView, aKeyPath)
|
||||
{
|
||||
if (aKeyPath !== "frame" && aKeyPath !== "frameSize")
|
||||
if (aKeyPath !== "frame" && aKeyPath !== "frameSize" && aKeyPath !== "frameOrigin")
|
||||
return nil;
|
||||
|
||||
var style = getComputedStyle(aView._DOMElement),
|
||||
getCSSPropertyValue = function(prop) {
|
||||
return ROUND(parseFloat(style.getPropertyValue(prop)));
|
||||
};
|
||||
|
||||
var updateFrame = function(timestamp)
|
||||
getCSSPropertyValue = function(prop) {
|
||||
return ROUND(parseFloat(style.getPropertyValue(prop)));
|
||||
},
|
||||
initialOrigin = CGPointMakeCopy([aView frameOrigin]),
|
||||
transformProperty = CPBrowserCSSProperty("transform"),
|
||||
updateFrame = function(timestamp)
|
||||
{
|
||||
var width = getCSSPropertyValue("width"),
|
||||
height = getCSSPropertyValue("height");
|
||||
|
||||
if (aKeyPath == "frame")
|
||||
{
|
||||
var left = getCSSPropertyValue("left"),
|
||||
top = getCSSPropertyValue("top"),
|
||||
frame = CGRectMake(left, top, width, height);
|
||||
|
||||
[aView setFrame:frame];
|
||||
}
|
||||
else if (aKeyPath == "frameSize")
|
||||
if (aKeyPath === "frameSize")
|
||||
{
|
||||
[aView setFrameSize:CGSizeMake(width, height)];
|
||||
}
|
||||
else
|
||||
{
|
||||
[aView _setInhibitDOMUpdates:YES];
|
||||
|
||||
var matrix = style[transformProperty].split('(')[1].split(')')[0].split(','),
|
||||
x = ROUND(initialOrigin.x + parseFloat(matrix[4])),
|
||||
y = ROUND(initialOrigin.y + parseFloat(matrix[5]));
|
||||
|
||||
if (aKeyPath === "frame")
|
||||
{
|
||||
[aView setFrame:CGRectMake(x, y, width, height)];
|
||||
}
|
||||
else
|
||||
{
|
||||
[aView setFrameOrigin:CGPointMake(x, y)];
|
||||
}
|
||||
|
||||
[aView _setInhibitDOMUpdates:NO];
|
||||
}
|
||||
|
||||
[[CPRunLoop currentRunLoop] performSelectors];
|
||||
};
|
||||
|
||||
@@ -1,9 +1,20 @@
|
||||
|
||||
@import "_CPObjectAnimator.j"
|
||||
@import "CPView.j"
|
||||
@import "CPCompatibility.j"
|
||||
|
||||
@implementation CPViewAnimator : _CPObjectAnimator
|
||||
{
|
||||
BOOL _wantsPeriodicFrameUpdates @accessors(property=wantsPeriodicFrameUpdates);
|
||||
}
|
||||
|
||||
- (id)initWithTarget:(id)aTarget
|
||||
{
|
||||
self = [super initWithTarget:aTarget];
|
||||
|
||||
_wantsPeriodicFrameUpdates = NO;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)removeFromSuperview
|
||||
@@ -76,16 +87,6 @@
|
||||
|
||||
@end
|
||||
|
||||
var transformOrigin = function(start, current)
|
||||
{
|
||||
return "translate(" + (current.x - start.x) + "px," + (current.y - start.y) + "px)";
|
||||
};
|
||||
|
||||
var transformFrameToTranslate = function(start, current)
|
||||
{
|
||||
return transformOrigin(start.origin, current.origin);
|
||||
};
|
||||
|
||||
var transformFrameToWidth = function(start, current)
|
||||
{
|
||||
return current.size.width + "px";
|
||||
@@ -106,6 +107,25 @@ var transformSizeToHeight = function(start, current)
|
||||
return current.height + "px";
|
||||
};
|
||||
|
||||
var CSSStringFromCGAffineTransform = function(anAffineTransform)
|
||||
{
|
||||
return "matrix(" + anAffineTransform.a + ", " + anAffineTransform.b + ", " + anAffineTransform.c + ", " + anAffineTransform.d + ", " + anAffineTransform.tx + (CPBrowserIsEngine(CPGeckoBrowserEngine) ? "px, " : ", ") + anAffineTransform.ty + (CPBrowserIsEngine(CPGeckoBrowserEngine) ? "px)" : ")");
|
||||
};
|
||||
|
||||
var frameOriginToCSSTransformMatrix = function(start, current)
|
||||
{
|
||||
var affine = CGAffineTransformMakeTranslation(current.x - start.x, current.y - start.y);
|
||||
|
||||
return CSSStringFromCGAffineTransform(affine);
|
||||
};
|
||||
|
||||
var frameToCSSTranslationTransformMatrix = function(start, current)
|
||||
{
|
||||
var affine = CGAffineTransformMakeTranslation(current.origin.x - start.origin.x, current.origin.y - start.origin.y);
|
||||
|
||||
return CSSStringFromCGAffineTransform(affine);
|
||||
};
|
||||
|
||||
var DEFAULT_CSS_PROPERTIES = nil;
|
||||
|
||||
@implementation CPView (CPAnimatablePropertyContainer)
|
||||
@@ -117,15 +137,15 @@ var DEFAULT_CSS_PROPERTIES = nil;
|
||||
var transformProperty = CPBrowserCSSProperty("transform");
|
||||
|
||||
DEFAULT_CSS_PROPERTIES = @{
|
||||
"backgroundColor" : [@{"property":"background", "value":function(sv, val){return [val cssString];}}],
|
||||
"alphaValue" : [@{"property":"opacity"}],
|
||||
"frame" : [@{"property":transformProperty, "value":transformFrameToTranslate},
|
||||
@{"property":"width", "value":transformFrameToWidth},
|
||||
@{"property":"height", "value":transformFrameToHeight}],
|
||||
"frameOrigin" : [@{"property":transformProperty, "value":transformOrigin}],
|
||||
"frameSize" : [@{"property":"width", "value":transformSizeToWidth},
|
||||
@{"property":"height", "value":transformSizeToHeight}]
|
||||
};
|
||||
"backgroundColor" : [@{"property":"background", "value":function(sv, val){return [val cssString];}}],
|
||||
"alphaValue" : [@{"property":"opacity"}],
|
||||
"frame" : [@{"property":transformProperty, "value":frameToCSSTranslationTransformMatrix},
|
||||
@{"property":"width", "value":transformFrameToWidth},
|
||||
@{"property":"height", "value":transformFrameToHeight}],
|
||||
"frameOrigin" : [@{"property":transformProperty, "value":frameOriginToCSSTransformMatrix}],
|
||||
"frameSize" : [@{"property":"width", "value":transformSizeToWidth},
|
||||
@{"property":"height", "value":transformSizeToHeight}]
|
||||
};
|
||||
}
|
||||
|
||||
return DEFAULT_CSS_PROPERTIES;
|
||||
|
||||
Reference in new issue
Block a user