8 BOOL _wantsPeriodicFrameUpdates;
11 - (id)initWithTarget:(
id)aTarget
13 self = [
super initWithTarget:aTarget];
15 _wantsPeriodicFrameUpdates = NO;
20 - (void)removeFromSuperview
22 [
self _setTargetValue:nil withKeyPath:@"CPAnimationTriggerOrderOut" setter:_cmd];
25 - (void)setHidden:(BOOL)shouldHide
27 if ([_target
isHidden] == shouldHide)
31 return [_target setHidden:NO];
33 [
self _setTargetValue:YES withKeyPath:@"CPAnimationTriggerOrderOut" setter:_cmd];
36 - (void)setAlphaValue:(CGPoint)alphaValue
38 [
self _setTargetValue:alphaValue withKeyPath:@"alphaValue" setter:_cmd];
41 - (void)setBackgroundColor:(
CPColor)aColor
43 [
self _setTargetValue:aColor withKeyPath:@"backgroundColor" setter:_cmd];
46 - (void)setFrameOrigin:(CGPoint)aFrameOrigin
48 [
self _setTargetValue:aFrameOrigin withKeyPath:@"frameOrigin" setter:_cmd];
51 - (void)setFrame:(CGRect)aFrame
53 [
self _setTargetValue:aFrame withKeyPath:@"frame" setter:_cmd];
56 - (void)setFrameSize:(CGSize)aFrameSize
58 [
self _setTargetValue:aFrameSize withKeyPath:@"frameSize" setter:_cmd];
62 - (void)_setTargetValue:(
id)aTargetValue withKeyPath:(
CPString)aKeyPath setter:(
SEL)aSelector
64 var handler =
function()
66 [_target _setForceUpdates:YES];
67 [_target performSelector:aSelector withObject:aTargetValue];
68 [_target _setForceUpdates:NO];
71 [
self _setTargetValue:aTargetValue withKeyPath:aKeyPath fallback:handler completion:handler];
74 - (void)_setTargetValue:(
id)aTargetValue withKeyPath:(
CPString)aKeyPath fallback:(Function)fallback completion:(Function)completion
76 var animation = [_target animationForKey:aKeyPath],
86 [context _enqueueActionForObject:_target keyPath:aKeyPath targetValue:aTargetValue animationCompletion:completion];
94 var transformProperty =
"transform";
97 "backgroundColor" : [@{"property":"background", "value":function(sv, val){return [val cssString];}}],
98 "alphaValue" : [@{"property":"opacity"}],
99 "frame" : [@{"property":transformProperty, "value":frameToCSSTranslationTransformMatrix},
100 @{"property":"width", "value":transformFrameToWidth},
101 @{"property":"height", "value":transformFrameToHeight}],
102 "frameOrigin" : [@{"property":transformProperty, "value":frameOriginToCSSTransformMatrix}],
103 "frameSize" : [@{"property":"width", "value":transformSizeToWidth},
104 @{"property":"height", "value":transformSizeToHeight}]
111 + (void)addAnimations:(CPArray)animations forAction:(
id)anAction
113 var target = anAction.object;
115 return [
self _addAnimations:animations forAction:anAction domElement:[target _DOMElement] identifier:[target UID]];
118 + (void)_addAnimations:(CPArray)animations forAction:(
id)anAction domElement:(Object)aDomElement identifier:(
CPString)anIdentifier
120 var animation = [animations objectPassingTest:function(anim, idx, stop)
122 return anim.identifier == anIdentifier;
125 if (animation == nil)
127 animation =
new CSSAnimation(aDomElement, anIdentifier, [anAction.object debug_description]);
128 [animations addObject:animation];
131 var css_mapping = [
self _cssPropertiesForKeyPath:anAction.keypath];
133 [css_mapping enumerateObjectsUsingBlock:function(aDict, anIndex, stop)
135 var completionFunction = (anIndex == 0) ? anAction.completion : null,
136 property = [aDict objectForKey:@"property"],
137 getter = [aDict objectForKey:@"value"];
139 animation.addPropertyAnimation(property, getter, anAction.duration, anAction.keytimes, anAction.values, anAction.timingfunctions, completionFunction);
143 + (CPArray)_cssPropertiesForKeyPath:(
CPString)aKeyPath
145 return [[
self _defaultCSSProperties] objectForKey:aKeyPath];
148 + (void)addFrameUpdaters:(CPArray)frameUpdaters forAction:(
id)anAction
150 var rootIdentifier = [anAction.root UID];
152 var frameUpdater = [frameUpdaters objectPassingTest:function(updater, idx, stop)
155 return updater.identifier() == rootIdentifier;
158 if (frameUpdater == nil)
161 [frameUpdaters addObject:frameUpdater];
165 frameUpdater.addTarget(anAction.object, anAction.keypath, anAction.duration);
168 + (void)stopUpdaterWithIdentifier:(
CPString)anIdentifier
178 CPLog.warn(
"Could not find FrameUpdater with identifier " + anIdentifier);
181 - (BOOL)needsPeriodicFrameUpdatesForKeyPath:(
CPString)aKeyPath
183 return ((aKeyPath ==
@"frame" || aKeyPath ==
@"frameSize") &&
184 (([_target hasCustomLayoutSubviews] && ![_target implementsSelector:
@selector(frameRectOfView:inSuperviewSize:)])
185 || [_target hasCustomDrawRect]))
193 return current.size.width +
"px";
198 return current.size.height +
"px";
203 return current.width +
"px";
208 return current.height +
"px";
213 return [
CPString stringWithFormat:@"matrix(%d,%d,%d,%d,%d,%d)", anAffineTransform.a, anAffineTransform.b, anAffineTransform.c, anAffineTransform.d, anAffineTransform.tx, anAffineTransform.ty];
232 + (Class)animatorClass
239 return [[
self superclass] animatorClass];
245 _animator = [[[[
self class] animatorClass] alloc] initWithTarget:self];
253 if (aKey ==
@"CPAnimationTriggerOrderIn")
255 CPLog.warn(
"CPView animated key path CPAnimationTriggerOrderIn is not supported yet.");
259 if ([[
self animatorClass] _cssPropertiesForKeyPath:aKey] !== nil)
270 if (!animations || !(animation = [animations objectForKey:aKey]))
272 animation = [[
self class] defaultAnimationForKey:aKey];
280 return _animationsDictionary;
285 _animationsDictionary = [animationsDict
copy];
288 - (Object)_DOMElement
295 return [
self identifier] || [
self className];
302 - (CPArray)objectPassingTest:(Function)aFunction
304 var idx = [
self indexOfObjectPassingTest:aFunction];
307 return [
self objectAtIndex:idx];
315 this._identifier = anIdentifier;
316 this._requestId = null;
320 this._callbacks = [];
322 var frameUpdater =
this;
324 this._updateFunction =
function(timestamp)
326 if (frameUpdater._startDate == null)
327 frameUpdater._startDate = timestamp;
329 if (frameUpdater._stop)
332 for (var i = 0; i < frameUpdater._callbacks.length; i++)
333 frameUpdater._callbacks[i]();
335 if (timestamp - frameUpdater._startDate < frameUpdater._duration * 1000)
336 window.requestAnimationFrame(frameUpdater._updateFunction);
342 this._requestId = window.requestAnimationFrame(this._updateFunction);
347 CPLog.warn(
"STOP FrameUpdater" + this._identifier);
350 if (window.cancelAnimationFrame)
351 window.cancelAnimationFrame(this._requestId);
358 return this._updateFunction;
363 return this._identifier;
368 return "<timer " + this._identifier +
" " + this._targets.map(
function(t){
return [t debug_description];}) +
">";
377 this._duration = MAX(this._duration, duration);
378 this._targets.push(target);
379 this._callbacks.push(callback);
385 if (aKeyPath !==
"frame" && aKeyPath !==
"frameSize" && aKeyPath !==
"frameOrigin")
388 var style = getComputedStyle([aView _DOMElement]),
389 getCSSPropertyValue =
function(prop) {
390 return ROUND(parseFloat(style.getPropertyValue(prop)));
392 initialOrigin = CGPointMakeCopy([aView frameOrigin]),
394 updateFrame =
function(timestamp)
396 if (aKeyPath ===
"frameSize")
398 var
width = getCSSPropertyValue(
"width"),
399 height = getCSSPropertyValue(
"height");
401 [aView setFrameSize:CGSizeMake(width, height)];
405 [aView _setInhibitDOMUpdates:YES];
407 var matrix_value = style[transformProperty];
409 if (matrix_value && matrix_value !==
'none')
411 var matrix_array = matrix_value.split(
'(')[1].split(
')')[0].split(
','),
412 x = ROUND(initialOrigin.x + parseFloat(matrix_array[4])),
413 y = ROUND(initialOrigin.y + parseFloat(matrix_array[5]));
415 if (aKeyPath ===
"frame")
417 var
width = getCSSPropertyValue(
"width"),
418 height = getCSSPropertyValue(
"height");
420 [aView setFrame:CGRectMake(x, y, width, height)];
424 [aView setFrameOrigin:CGPointMake(x, y)];
428 [aView _setInhibitDOMUpdates:NO];
443 - (BOOL)wantsPeriodicFrameUpdates
445 return _wantsPeriodicFrameUpdates;
451 - (void)setWantsPeriodicFrameUpdates:(BOOL)aValue
453 _wantsPeriodicFrameUpdates = aValue;