Revert "feat(animation): support animating width/height properties (WIP) (#4917)" (#5136)

This reverts commit 57ed0cf405.
This commit is contained in:
Svetoslav
2017-12-07 12:11:24 +02:00
committed by Vasil Chimev
parent 1615061591
commit 8973a6febd
25 changed files with 56 additions and 941 deletions

View File

@@ -182,7 +182,7 @@ export function install() {
registerOnGlobalContext("Response", "fetch");
// check whether the 'android' namespace is exposed
// if positive - the current device is an Android
// if positive - the current device is an Android
// so a custom implementation of the global 'console' object is attached.
// otherwise do nothing on iOS - the NS runtime provides a native 'console' functionality.
if ((<any>global).android) {

View File

@@ -11,19 +11,16 @@ import { View } from "../core/view";
// Types.
import { Color } from "../../color";
import { isEnabled as traceEnabled, write as traceWrite, categories as traceCategories } from "../../trace";
import { PercentLength } from "../styling/style-properties";
export { Color, traceEnabled, traceWrite, traceCategories };
export { AnimationPromise } from ".";
export module Properties {
export const opacity = "opacity";
export const backgroundColor = "backgroundColor";
export const translate = "translate";
export const rotate = "rotate";
export const scale = "scale";
export const height = "height";
export const width = "width";
export var opacity = "opacity";
export var backgroundColor = "backgroundColor";
export var translate = "translate";
export var rotate = "rotate";
export var scale = "scale";
}
export interface PropertyAnimation {
@@ -166,9 +163,6 @@ export abstract class AnimationBase implements AnimationBaseDefinition {
throw new Error(`Property ${item} must be valid Pair. Value: ${animationDefinition[item]}`);
} else if (item === Properties.backgroundColor && !Color.isValid(animationDefinition.backgroundColor)) {
throw new Error(`Property ${item} must be valid color. Value: ${animationDefinition[item]}`);
} else if (item === Properties.width || item === Properties.height) {
// Coerce input into a PercentLength object in case it's a string.
animationDefinition[item] = PercentLength.parse(<any>animationDefinition[item]);
}
}
@@ -240,34 +234,8 @@ export abstract class AnimationBase implements AnimationBaseDefinition {
});
}
// height
if (animationDefinition.height !== undefined) {
propertyAnimations.push({
target: animationDefinition.target,
property: Properties.height,
value: animationDefinition.height,
duration: animationDefinition.duration,
delay: animationDefinition.delay,
iterations: animationDefinition.iterations,
curve: animationDefinition.curve
});
}
// width
if (animationDefinition.width !== undefined) {
propertyAnimations.push({
target: animationDefinition.target,
property: Properties.width,
value: animationDefinition.width,
duration: animationDefinition.duration,
delay: animationDefinition.delay,
iterations: animationDefinition.iterations,
curve: animationDefinition.curve
});
}
if (propertyAnimations.length === 0) {
throw new Error('No known animation properties specified');
throw new Error("No animation property specified.");
}
return propertyAnimations;
@@ -284,4 +252,4 @@ export abstract class AnimationBase implements AnimationBaseDefinition {
curve: animation.curve
});
}
}
}

View File

@@ -5,13 +5,12 @@ import { View } from "../core/view";
import { AnimationBase, Properties, PropertyAnimation, CubicBezierAnimationCurve, AnimationPromise, Color, traceWrite, traceEnabled, traceCategories } from "./animation-common";
import {
opacityProperty, backgroundColorProperty, rotateProperty,
translateXProperty, translateYProperty, scaleXProperty, scaleYProperty,
heightProperty, widthProperty, PercentLength
translateXProperty, translateYProperty, scaleXProperty, scaleYProperty
} from "../styling/style-properties";
import { layout } from "../../utils/utils";
import lazy from "../../utils/lazy";
import * as platform from '../../platform';
export * from "./animation-common";
interface AnimationDefinitionInternal extends AnimationDefinition {
@@ -38,8 +37,6 @@ propertyKeys[Properties.opacity] = Symbol(keyPrefix + Properties.opacity);
propertyKeys[Properties.rotate] = Symbol(keyPrefix + Properties.rotate);
propertyKeys[Properties.scale] = Symbol(keyPrefix + Properties.scale);
propertyKeys[Properties.translate] = Symbol(keyPrefix + Properties.translate);
propertyKeys[Properties.height] = Symbol(keyPrefix + Properties.height);
propertyKeys[Properties.width] = Symbol(keyPrefix + Properties.width);
export function _resolveAnimationCurve(curve: string | CubicBezierAnimationCurve | android.view.animation.Interpolator | android.view.animation.LinearInterpolator): android.view.animation.Interpolator {
switch (curve) {
@@ -198,7 +195,7 @@ export class Animation extends AnimationBase {
}
}
private _onAndroidAnimationCancel() { // tslint:disable-line
private _onAndroidAnimationCancel() { // tslint:disable-line
this._propertyResetCallbacks.forEach(v => v());
this._rejectAnimationFinishedPromise();
@@ -304,7 +301,7 @@ export class Animation extends AnimationBase {
} else {
propertyAnimation.target.style[backgroundColorProperty.keyframe] = originalValue1;
}
if (propertyAnimation.target.nativeViewProtected && propertyAnimation.target[backgroundColorProperty.setNative]) {
propertyAnimation.target[backgroundColorProperty.setNative](propertyAnimation.target.style.backgroundColor);
}
@@ -417,55 +414,16 @@ export class Animation extends AnimationBase {
} else {
propertyAnimation.target.style[rotateProperty.keyframe] = originalValue1;
}
if (propertyAnimation.target.nativeViewProtected) {
propertyAnimation.target[rotateProperty.setNative](propertyAnimation.target.style.rotate);
}
}));
animators.push(android.animation.ObjectAnimator.ofFloat(nativeView, "rotation", nativeArray));
break;
case Properties.width:
case Properties.height: {
const isVertical: boolean = propertyAnimation.property === 'height';
const extentProperty = isVertical ? heightProperty : widthProperty;
extentProperty._initDefaultNativeValue(style);
nativeArray = Array.create("float", 2);
let toValue = propertyAnimation.value;
let parent = propertyAnimation.target.parent as View;
if (!parent) {
throw new Error(`cannot animate ${propertyAnimation.property} on root view`);
}
const parentExtent: number = isVertical ? parent.getMeasuredHeight() : parent.getMeasuredWidth();
toValue = PercentLength.toDevicePixels(toValue, parentExtent, parentExtent) / platform.screen.mainScreen.scale;
const nativeHeight: number = isVertical ? nativeView.getHeight() : nativeView.getWidth();
const targetStyle: string = setLocal ? extentProperty.name : extentProperty.keyframe;
originalValue1 = nativeHeight / platform.screen.mainScreen.scale;
nativeArray[0] = originalValue1;
nativeArray[1] = toValue;
let extentAnimator = android.animation.ValueAnimator.ofFloat(nativeArray);
extentAnimator.addUpdateListener(new android.animation.ValueAnimator.AnimatorUpdateListener({
onAnimationUpdate(animator: android.animation.ValueAnimator) {
const argb = (<java.lang.Float>animator.getAnimatedValue()).floatValue();
propertyAnimation.target.style[setLocal ? extentProperty.name : extentProperty.keyframe] = argb;
}
}));
propertyUpdateCallbacks.push(checkAnimation(() => {
propertyAnimation.target.style[targetStyle] = propertyAnimation.value;
}));
propertyResetCallbacks.push(checkAnimation(() => {
propertyAnimation.target.style[targetStyle] = originalValue1;
if (propertyAnimation.target.nativeViewProtected) {
const setter = propertyAnimation.target[extentProperty.setNative];
setter(propertyAnimation.target.style[propertyAnimation.property]);
}
}));
animators.push(extentAnimator);
break;
}
default:
throw new Error(`Animating property '${propertyAnimation.property}' is unsupported`);
throw new Error("Cannot animate " + propertyAnimation.property);
}
for (let i = 0, length = animators.length; i < length; i++) {

View File

@@ -3,7 +3,6 @@
*/ /** */
import { View, Color } from "../core/view";
import {PercentLength} from '../styling/style-properties';
/**
* Defines animation options for the View.animate method.
@@ -34,16 +33,6 @@ export interface AnimationDefinition {
*/
scale?: Pair;
/**
* Animates the height of a view.
*/
height?: PercentLength | string;
/**
* Animates the width of a view.
*/
width?: PercentLength | string;
/**
* Animates the rotate affine transform of the view. Value should be a number specifying the rotation amount in degrees.
*/

View File

@@ -4,12 +4,10 @@ import { View } from "../core/view";
import { AnimationBase, Properties, PropertyAnimation, CubicBezierAnimationCurve, AnimationPromise, traceWrite, traceEnabled, traceCategories } from "./animation-common";
import {
opacityProperty, backgroundColorProperty, rotateProperty,
translateXProperty, translateYProperty, scaleXProperty, scaleYProperty,
heightProperty, widthProperty, PercentLength
translateXProperty, translateYProperty, scaleXProperty, scaleYProperty
} from "../styling/style-properties";
import { ios } from "../../utils/utils";
import * as platform from "../../platform";
export * from "./animation-common";
@@ -86,12 +84,6 @@ class AnimationDelegateImpl extends NSObject implements CAAnimationDelegate {
targetStyle[setLocal ? translateXProperty.name : translateXProperty.keyframe] = value;
targetStyle[setLocal ? translateYProperty.name : translateYProperty.keyframe] = value;
break;
case Properties.height:
targetStyle[setLocal ? heightProperty.name : heightProperty.keyframe] = value;
break;
case Properties.width:
targetStyle[setLocal ? widthProperty.name : widthProperty.keyframe] = value;
break;
case Properties.scale:
targetStyle[setLocal ? scaleXProperty.name : scaleXProperty.keyframe] = value.x === 0 ? 0.001 : value.x;
targetStyle[setLocal ? scaleYProperty.name : scaleYProperty.keyframe] = value.y === 0 ? 0.001 : value.y;
@@ -270,10 +262,8 @@ export class Animation extends AnimationBase {
let nativeView = <UIView>animation.target.nativeViewProtected;
let propertyNameToAnimate = animation.property;
let toValue = animation.value;
let fromValue;
const parent = animation.target.parent as View;
const screenScale: number = platform.screen.mainScreen.scale;
let value = animation.value;
let originalValue;
let tempRotate = (animation.target.rotate || 0) * Math.PI / 180;
let abs;
@@ -286,18 +276,18 @@ export class Animation extends AnimationBase {
animation._propertyResetCallback = (value, valueSource) => {
animation.target.style[setLocal ? backgroundColorProperty.name : backgroundColorProperty.keyframe] = value;
};
fromValue = nativeView.layer.backgroundColor;
originalValue = nativeView.layer.backgroundColor;
if (nativeView instanceof UILabel) {
nativeView.setValueForKey(getter(UIColor, UIColor.clearColor), "backgroundColor");
}
toValue = toValue.CGColor;
value = value.CGColor;
break;
case Properties.opacity:
animation._originalValue = animation.target.opacity;
animation._propertyResetCallback = (value, valueSource) => {
animation.target.style[setLocal ? opacityProperty.name : opacityProperty.keyframe] = value;
};
fromValue = nativeView.layer.opacity;
originalValue = nativeView.layer.opacity;
break;
case Properties.rotate:
animation._originalValue = animation.target.rotate !== undefined ? animation.target.rotate : 0;
@@ -305,44 +295,44 @@ export class Animation extends AnimationBase {
animation.target.style[setLocal ? rotateProperty.name : rotateProperty.keyframe] = value;
};
propertyNameToAnimate = "transform.rotation";
fromValue = nativeView.layer.valueForKeyPath("transform.rotation");
if (animation.target.rotate !== undefined && animation.target.rotate !== 0 && Math.floor(toValue / 360) - toValue / 360 === 0) {
fromValue = animation.target.rotate * Math.PI / 180;
originalValue = nativeView.layer.valueForKeyPath("transform.rotation");
if (animation.target.rotate !== undefined && animation.target.rotate !== 0 && Math.floor(value / 360) - value / 360 === 0) {
originalValue = animation.target.rotate * Math.PI / 180;
}
toValue = toValue * Math.PI / 180;
abs = fabs(fromValue - toValue);
if (abs < 0.001 && fromValue !== tempRotate) {
fromValue = tempRotate;
value = value * Math.PI / 180;
abs = fabs(originalValue - value);
if (abs < 0.001 && originalValue !== tempRotate) {
originalValue = tempRotate;
}
break;
case Properties.translate:
animation._originalValue = {x: animation.target.translateX, y: animation.target.translateY};
animation._originalValue = { x: animation.target.translateX, y: animation.target.translateY };
animation._propertyResetCallback = (value, valueSource) => {
animation.target.style[setLocal ? translateXProperty.name : translateXProperty.keyframe] = value.x;
animation.target.style[setLocal ? translateYProperty.name : translateYProperty.keyframe] = value.y;
};
propertyNameToAnimate = "transform";
fromValue = NSValue.valueWithCATransform3D(nativeView.layer.transform);
toValue = NSValue.valueWithCATransform3D(CATransform3DTranslate(nativeView.layer.transform, toValue.x, toValue.y, 0));
originalValue = NSValue.valueWithCATransform3D(nativeView.layer.transform);
value = NSValue.valueWithCATransform3D(CATransform3DTranslate(nativeView.layer.transform, value.x, value.y, 0));
break;
case Properties.scale:
if (toValue.x === 0) {
toValue.x = 0.001;
if (value.x === 0) {
value.x = 0.001;
}
if (toValue.y === 0) {
toValue.y = 0.001;
if (value.y === 0) {
value.y = 0.001;
}
animation._originalValue = {x: animation.target.scaleX, y: animation.target.scaleY};
animation._originalValue = { x: animation.target.scaleX, y: animation.target.scaleY };
animation._propertyResetCallback = (value, valueSource) => {
animation.target.style[setLocal ? scaleXProperty.name : scaleXProperty.keyframe] = value.x;
animation.target.style[setLocal ? scaleYProperty.name : scaleYProperty.keyframe] = value.y;
};
propertyNameToAnimate = "transform";
fromValue = NSValue.valueWithCATransform3D(nativeView.layer.transform);
toValue = NSValue.valueWithCATransform3D(CATransform3DScale(nativeView.layer.transform, toValue.x, toValue.y, 1));
originalValue = NSValue.valueWithCATransform3D(nativeView.layer.transform);
value = NSValue.valueWithCATransform3D(CATransform3DScale(nativeView.layer.transform, value.x, value.y, 1));
break;
case _transform:
fromValue = NSValue.valueWithCATransform3D(nativeView.layer.transform);
originalValue = NSValue.valueWithCATransform3D(nativeView.layer.transform);
animation._originalValue = {
xs: animation.target.scaleX, ys: animation.target.scaleY,
xt: animation.target.translateX, yt: animation.target.translateY
@@ -354,33 +344,10 @@ export class Animation extends AnimationBase {
animation.target.style[setLocal ? scaleYProperty.name : scaleYProperty.keyframe] = value.ys;
};
propertyNameToAnimate = "transform";
toValue = NSValue.valueWithCATransform3D(Animation._createNativeAffineTransform(animation));
break;
case Properties.width:
case Properties.height:
const direction: string = animation.property;
const isHeight: boolean = direction === 'height';
propertyNameToAnimate = "bounds";
if (!parent) {
throw new Error(`cannot animate ${direction} on root view`);
}
const parentExtent: number = isHeight ? parent.getMeasuredHeight() : parent.getMeasuredWidth();
const asNumber = PercentLength.toDevicePixels(PercentLength.parse(toValue), parentExtent, parentExtent) / screenScale;
let currentBounds = nativeView.layer.bounds;
let extentX = isHeight ? currentBounds.size.width : asNumber;
let extentY = isHeight ? asNumber : currentBounds.size.height;
fromValue = NSValue.valueWithCGRect(currentBounds);
toValue = NSValue.valueWithCGRect(
CGRectMake(currentBounds.origin.x, currentBounds.origin.y, extentX, extentY)
);
animation._originalValue = animation.target.height;
animation._propertyResetCallback = (value, valueSource) => {
const prop = isHeight ? heightProperty : widthProperty;
animation.target.style[setLocal ? prop.name : prop.keyframe] = value;
};
value = NSValue.valueWithCATransform3D(Animation._createNativeAffineTransform(animation));
break;
default:
throw new Error(`Animating property '${animation.property}' is unsupported`);
throw new Error("Cannot animate " + animation.property);
}
let duration = 0.3;
@@ -405,8 +372,8 @@ export class Animation extends AnimationBase {
return {
propertyNameToAnimate: propertyNameToAnimate,
fromValue: fromValue,
toValue: toValue,
fromValue: originalValue,
toValue: value,
duration: duration,
repeatCount: repeatCount,
delay: delay
@@ -482,14 +449,6 @@ export class Animation extends AnimationBase {
case Properties.opacity:
animation.target.opacity = args.toValue;
break;
case Properties.height:
case Properties.width:
animation._originalValue = animation.target[animation.property];
nativeView.layer.setValueForKey(args.toValue, args.propertyNameToAnimate);
animation._propertyResetCallback = function (value) {
animation.target[animation.property] = value;
};
break;
case Properties.rotate:
nativeView.layer.setValueForKey(args.toValue, args.propertyNameToAnimate);
break;
@@ -498,11 +457,11 @@ export class Animation extends AnimationBase {
nativeView.layer.setValueForKey(args.toValue, args.propertyNameToAnimate);
animation._propertyResetCallback = function (value) {
nativeView.layer.transform = value;
};
}
break;
}
}, function (animationDidFinish: boolean) {
if (animationDidFinish) {
}, function (finished: boolean) {
if (finished) {
if (animation.property === _transform) {
if (animation.value[Properties.translate] !== undefined) {
animation.target.translateX = animation.value[Properties.translate].x;
@@ -520,10 +479,10 @@ export class Animation extends AnimationBase {
}
}
if (finishedCallback) {
let cancelled = !animationDidFinish;
let cancelled = !finished;
finishedCallback(cancelled);
}
if (animationDidFinish && nextAnimation) {
if (finished && nextAnimation) {
nextAnimation();
}
});

View File

@@ -19,8 +19,7 @@ import {
backgroundColorProperty,
scaleXProperty, scaleYProperty,
translateXProperty, translateYProperty,
rotateProperty, opacityProperty,
widthProperty, heightProperty, PercentLength
rotateProperty, opacityProperty
} from "../styling/style-properties";
export class Keyframes implements KeyframesDefinition {
@@ -61,8 +60,6 @@ interface Keyframe {
translate?: { x: number, y: number };
rotate?: number;
opacity?: number;
width?: PercentLength;
height?: PercentLength;
valueSource?: "keyframe" | "animation";
duration?: number;
curve?: any;
@@ -210,12 +207,6 @@ export class KeyframeAnimation implements KeyframeAnimationDefinition {
if ("opacity" in animation) {
view.style[opacityProperty.keyframe] = animation.opacity;
}
if ("height" in animation) {
view.style[heightProperty.keyframe] = animation.height;
}
if ("width" in animation) {
view.style[widthProperty.keyframe] = animation.width;
}
setTimeout(() => this.animate(view, 1, iterations), 1);
}
@@ -280,11 +271,5 @@ export class KeyframeAnimation implements KeyframeAnimationDefinition {
if ("opacity" in animation) {
view.style[opacityProperty.keyframe] = unsetValue;
}
if ("height" in animation) {
view.style[heightProperty.keyframe] = unsetValue;
}
if ("width" in animation) {
view.style[widthProperty.keyframe] = unsetValue;
}
}
}

View File

@@ -85,8 +85,8 @@ export const opacityProperty: CssAnimationProperty<Style, number>;
export const minWidthProperty: CssProperty<Style, dip | LengthDipUnit | LengthPxUnit>;
export const minHeightProperty: CssProperty<Style, dip | LengthDipUnit | LengthPxUnit>;
export const widthProperty: CssAnimationProperty<Style, PercentLength>;
export const heightProperty: CssAnimationProperty<Style, PercentLength>;
export const widthProperty: CssProperty<Style, PercentLength>;
export const heightProperty: CssProperty<Style, PercentLength>;
export const lineHeightProperty: CssProperty<Style, number>;
export const marginProperty: ShorthandProperty<Style, string | PercentLength>;
export const marginLeftProperty: CssProperty<Style, PercentLength>;

View File

@@ -48,19 +48,13 @@ function equalsCommon(a: PercentLength, b: PercentLength): boolean {
if (typeof b === "number") {
return a == b; // tslint:disable-line
}
if (!b) {
return false;
}
return b.unit == "dip" && a == b.value; // tslint:disable-line
}
if (b == "auto") { // tslint:disable-line
return false;
}
if (typeof b === "number") {
return a ? (a.unit == "dip" && a.value == b) : false; // tslint:disable-line
}
if (!a || !b) {
return false;
return a.unit == "dip" && a.value == b; // tslint:disable-line
}
return a.value == b.value && a.unit == b.unit; // tslint:disable-line
}
@@ -89,9 +83,6 @@ function toDevicePixelsCommon(length: PercentLength, auto: number = Number.NaN,
if (typeof length === "number") {
return layout.round(layout.toDevicePixels(length));
}
if (!length) {
return auto;
}
switch (length.unit) {
case "px":
return layout.round(length.value);
@@ -117,7 +108,6 @@ export namespace PercentLength {
if (percentIndex !== (stringValue.length - 1) || percentIndex === 0) {
value = Number.NaN;
} else {
// Normalize result to values between -1 and 1
value = parseFloat(stringValue.substring(0, stringValue.length - 1).trim()) / 100;
}
@@ -197,28 +187,10 @@ export const minHeightProperty = new CssProperty<Style, Length>({
});
minHeightProperty.register(Style);
export const widthProperty = new CssAnimationProperty<Style, PercentLength>({
name: "width", cssName: "width", defaultValue: "auto", equalityComparer: Length.equals,
// TODO: CSSAnimationProperty was needed for keyframe (copying other impls), but `affectsLayout` does not exist
// on the animation property, so fake it here. x_x
valueChanged: (target, oldValue, newValue) => {
if (isIOS) {
target.view.requestLayout();
}
}, valueConverter: PercentLength.parse });
export const widthProperty = new CssProperty<Style, PercentLength>({ name: "width", cssName: "width", defaultValue: "auto", affectsLayout: isIOS, equalityComparer: Length.equals, valueConverter: PercentLength.parse });
widthProperty.register(Style);
export const heightProperty = new CssAnimationProperty<Style, PercentLength>({
name: "height", cssName: "height", defaultValue: "auto", equalityComparer: Length.equals,
// TODO: CSSAnimationProperty was needed for keyframe (copying other impls), but `affectsLayout` does not exist
// on the animation property, so fake it here. -_-
valueChanged: (target, oldValue, newValue) => {
if (isIOS) {
target.view.requestLayout();
}
}, valueConverter: PercentLength.parse,
});
export const heightProperty = new CssProperty<Style, PercentLength>({ name: "height", cssName: "height", defaultValue: "auto", affectsLayout: isIOS, equalityComparer: Length.equals, valueConverter: PercentLength.parse });
heightProperty.register(Style);
const marginProperty = new ShorthandProperty<Style, string | PercentLength>({