Skip to content

Commit 5aeaac7

Browse files
committed
Merge remote-tracking branch 'origin/main' into refactor/circular-deps
2 parents 3c1995c + 8652422 commit 5aeaac7

File tree

21 files changed

+437
-332
lines changed

21 files changed

+437
-332
lines changed

apps/automated/src/ui/animation/animation-tests.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,8 @@ export function test_ChainingAnimations(done) {
159159
.then(() => label.animate({ translate: { x: 0, y: 0 }, duration: duration }))
160160
.then(() => label.animate({ scale: { x: 5, y: 5 }, duration: duration }))
161161
.then(() => label.animate({ scale: { x: 1, y: 1 }, duration: duration }))
162-
.then(() => label.animate({ rotate: { x: 90, y: 0, z: 180 }, duration: duration }))
163-
.then(() => label.animate({ rotate: { x: 0, y: 0, z: 0 }, duration: duration }))
162+
.then(() => label.animate({ rotate: 180, duration: duration }))
163+
.then(() => label.animate({ rotate: 0, duration: duration }))
164164
.then(() => {
165165
//console.log("Animation finished");
166166
// >> (hide)

apps/automated/src/ui/view/view-tests.ios.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,16 +109,11 @@ export function testBackgroundInternalChangedOnceOnResize() {
109109

110110
TKUnit.assertEqual(trackCount(), 1, 'Expected background to be re-applied at most once when the view is laid-out on 0 0 200 200.');
111111

112-
// Ignore safe area as it may result in re-calculating view frame, thus trigger a size change regardless
113-
layout.iosIgnoreSafeArea = true;
114-
115112
layout.requestLayout();
116113
layout.layout(50, 50, 250, 250);
117114

118115
TKUnit.assertEqual(trackCount(), 0, 'Expected background to NOT change when view is laid-out from 0 0 200 200 to 50 50 250 250.');
119116

120-
layout.iosIgnoreSafeArea = false;
121-
122117
layout.requestLayout();
123118
layout.layout(0, 0, 250, 250);
124119

233 Bytes
Binary file not shown.

packages/core/ui/animation/index.ios.ts

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ class AnimationDelegateImpl extends NSObject implements CAAnimationDelegate {
7979
targetStyle[setLocal ? widthProperty.name : widthProperty.keyframe] = value;
8080
break;
8181
case Properties.scale:
82-
targetStyle[setLocal ? scaleXProperty.name : scaleXProperty.keyframe] = value.x === 0 ? 1e-6 : value.x;
83-
targetStyle[setLocal ? scaleYProperty.name : scaleYProperty.keyframe] = value.y === 0 ? 1e-6 : value.y;
82+
targetStyle[setLocal ? scaleXProperty.name : scaleXProperty.keyframe] = value.x === 0 ? 0.001 : value.x;
83+
targetStyle[setLocal ? scaleYProperty.name : scaleYProperty.keyframe] = value.y === 0 ? 0.001 : value.y;
8484
break;
8585
case _transform:
8686
if (value[Properties.translate] !== undefined) {
@@ -95,8 +95,8 @@ class AnimationDelegateImpl extends NSObject implements CAAnimationDelegate {
9595
if (value[Properties.scale] !== undefined) {
9696
const x = value[Properties.scale].x;
9797
const y = value[Properties.scale].y;
98-
targetStyle[setLocal ? scaleXProperty.name : scaleXProperty.keyframe] = x === 0 ? 1e-6 : x;
99-
targetStyle[setLocal ? scaleYProperty.name : scaleYProperty.keyframe] = y === 0 ? 1e-6 : y;
98+
targetStyle[setLocal ? scaleXProperty.name : scaleXProperty.keyframe] = x === 0 ? 0.001 : x;
99+
targetStyle[setLocal ? scaleYProperty.name : scaleYProperty.keyframe] = y === 0 ? 0.001 : y;
100100
}
101101
break;
102102
}
@@ -309,6 +309,7 @@ export class Animation extends AnimationBase {
309309
const parent = view.parent as View;
310310

311311
let propertyNameToAnimate = animation.property;
312+
let subPropertyNameToAnimate;
312313
let toValue = animation.value;
313314
let fromValue;
314315
if (nativeView) {
@@ -334,6 +335,8 @@ export class Animation extends AnimationBase {
334335
};
335336
fromValue = nativeView.layer.opacity;
336337
break;
338+
// In the case of rotation, avoid animating affine transform directly as it will animate to the closest result
339+
// that is visually the same. For example, 0 -> 360 will leave view as is.
337340
case Properties.rotate:
338341
animation._originalValue = {
339342
x: view.rotateX,
@@ -346,9 +349,30 @@ export class Animation extends AnimationBase {
346349
style[setLocal ? rotateYProperty.name : rotateYProperty.keyframe] = value.y;
347350
};
348351

349-
propertyNameToAnimate = 'transform';
350-
fromValue = NSValue.valueWithCATransform3D(nativeView.layer.transform);
351-
toValue = NSValue.valueWithCATransform3D(iosHelper.applyRotateTransform(nativeView.layer.transform, toValue.x, toValue.y, toValue.z));
352+
propertyNameToAnimate = 'transform.rotation';
353+
subPropertyNameToAnimate = ['x', 'y', 'z'];
354+
fromValue = {
355+
x: nativeView.layer.valueForKeyPath('transform.rotation.x'),
356+
y: nativeView.layer.valueForKeyPath('transform.rotation.y'),
357+
z: nativeView.layer.valueForKeyPath('transform.rotation.z'),
358+
};
359+
360+
if (animation.target.rotateX !== undefined && animation.target.rotateX !== 0 && Math.floor(toValue / 360) - toValue / 360 === 0) {
361+
fromValue.x = (animation.target.rotateX * Math.PI) / 180;
362+
}
363+
if (animation.target.rotateY !== undefined && animation.target.rotateY !== 0 && Math.floor(toValue / 360) - toValue / 360 === 0) {
364+
fromValue.y = (animation.target.rotateY * Math.PI) / 180;
365+
}
366+
if (animation.target.rotate !== undefined && animation.target.rotate !== 0 && Math.floor(toValue / 360) - toValue / 360 === 0) {
367+
fromValue.z = (animation.target.rotate * Math.PI) / 180;
368+
}
369+
370+
// Respect only value.z for back-compat until 3D rotations are implemented
371+
toValue = {
372+
x: (toValue.x * Math.PI) / 180,
373+
y: (toValue.y * Math.PI) / 180,
374+
z: (toValue.z * Math.PI) / 180,
375+
};
352376
break;
353377
case Properties.translate:
354378
animation._originalValue = {
@@ -365,10 +389,10 @@ export class Animation extends AnimationBase {
365389
break;
366390
case Properties.scale:
367391
if (toValue.x === 0) {
368-
toValue.x = 1e-6;
392+
toValue.x = 0.001;
369393
}
370394
if (toValue.y === 0) {
371-
toValue.y = 1e-6;
395+
toValue.y = 0.001;
372396
}
373397
animation._originalValue = { x: view.scaleX, y: view.scaleY };
374398
animation._propertyResetCallback = (value, valueSource) => {
@@ -451,6 +475,7 @@ export class Animation extends AnimationBase {
451475
return {
452476
propertyNameToAnimate: propertyNameToAnimate,
453477
fromValue: fromValue,
478+
subPropertiesToAnimate: subPropertyNameToAnimate,
454479
toValue: toValue,
455480
duration: duration,
456481
repeatCount: repeatCount,
@@ -496,10 +521,10 @@ export class Animation extends AnimationBase {
496521
}
497522

498523
private static _createGroupAnimation(args: AnimationInfo, animation: PropertyAnimation) {
499-
const animations = NSMutableArray.alloc<CAAnimation>().initWithCapacity(args.subPropertiesToAnimate.length);
500524
const groupAnimation = CAAnimationGroup.new();
501-
groupAnimation.duration = args.duration;
525+
const animations = NSMutableArray.alloc<CAAnimation>().initWithCapacity(args.subPropertiesToAnimate.length);
502526

527+
groupAnimation.duration = args.duration;
503528
if (args.repeatCount !== undefined) {
504529
groupAnimation.repeatCount = args.repeatCount;
505530
}
@@ -651,30 +676,16 @@ export class Animation extends AnimationBase {
651676
}
652677

653678
if (value[Properties.scale] !== undefined) {
654-
const x = value[Properties.scale].x || 1e-6;
655-
const y = value[Properties.scale].y || 1e-6;
656-
result = CATransform3DScale(result, x, y, 1);
657-
}
658-
659-
if (value[Properties.rotate] !== undefined) {
660-
const x = value[Properties.rotate].x;
661-
const y = value[Properties.rotate].y;
662-
const z = value[Properties.rotate].z;
663-
const perspective = animation.target.perspective || 300;
664-
665-
// Set perspective in case of rotation since we use z
666-
if (x || y) {
667-
result.m34 = -1 / perspective;
668-
}
669-
670-
result = iosHelper.applyRotateTransform(result, x, y, z);
679+
const x = value[Properties.scale].x;
680+
const y = value[Properties.scale].y;
681+
result = CATransform3DScale(result, x === 0 ? 0.001 : x, y === 0 ? 0.001 : y, 1);
671682
}
672683

673684
return result;
674685
}
675686

676687
private static _isAffineTransform(property: string): boolean {
677-
return property === _transform || property === Properties.translate || property === Properties.scale || property === Properties.rotate;
688+
return property === _transform || property === Properties.translate || property === Properties.scale;
678689
}
679690

680691
private static _canBeMerged(animation1: PropertyAnimation, animation2: PropertyAnimation) {
@@ -941,8 +952,7 @@ function calculateTransform(view: View): CATransform3D {
941952
// Order is important: translate, rotate, scale
942953
let expectedTransform = new CATransform3D(CATransform3DIdentity);
943954

944-
// TODO: Add perspective property to transform animations (not just rotation)
945-
// Set perspective in case of rotation since we use z
955+
// Only set perspective if there is 3D rotation
946956
if (view.rotateX || view.rotateY) {
947957
expectedTransform.m34 = -1 / perspective;
948958
}

packages/core/ui/core/properties/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ export class Property<T extends ViewBase, U> implements TypedPropertyDescriptor<
150150
public readonly key: symbol;
151151

152152
public readonly getDefault: symbol;
153-
public readonly setNative: any;
153+
public readonly setNative: symbol;
154154

155155
public readonly defaultValueKey: symbol;
156156
public readonly defaultValue: U;
@@ -351,7 +351,7 @@ export class CoercibleProperty<T extends ViewBase, U> extends Property<T, U> imp
351351
const propertyName = options.name;
352352
const key = this.key;
353353
const getDefault: symbol = this.getDefault;
354-
const setNative: any = this.setNative;
354+
const setNative: symbol = this.setNative;
355355
const defaultValueKey = this.defaultValueKey;
356356
const defaultValue: U = this.defaultValue;
357357

@@ -566,7 +566,7 @@ export class CssProperty<T extends Style, U> {
566566

567567
public readonly key: symbol;
568568
public readonly getDefault: symbol;
569-
public readonly setNative: any;
569+
public readonly setNative: symbol;
570570
public readonly sourceKey: symbol;
571571
public readonly defaultValueKey: symbol;
572572
public readonly defaultValue: U;
@@ -833,7 +833,7 @@ export class CssAnimationProperty<T extends Style, U> implements CssAnimationPro
833833
public readonly cssLocalName: string;
834834

835835
public readonly getDefault: symbol;
836-
public readonly setNative: any;
836+
public readonly setNative: symbol;
837837

838838
public readonly register: (cls: { prototype }) => void;
839839

packages/core/ui/core/view-base/index.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,13 @@ export interface ShowModalOptions {
105105
* @param criterion - The type of ancestor view we are looking for. Could be a string containing a class name or an actual type.
106106
* Returns an instance of a view (if found), otherwise undefined.
107107
*/
108-
export function getAncestor(view: ViewBase, criterion: string | { new () }): ViewBase {
109-
let matcher: (view: ViewBase) => boolean = null;
108+
export function getAncestor<T extends ViewBase = ViewBase>(view: T, criterion: string | { new () }): T {
109+
let matcher: (view: ViewBase) => view is T;
110+
110111
if (typeof criterion === 'string') {
111-
matcher = (view: ViewBase) => view.typeName === criterion;
112+
matcher = (view: ViewBase): view is T => view.typeName === criterion;
112113
} else {
113-
matcher = (view: ViewBase) => view instanceof criterion;
114+
matcher = (view: ViewBase): view is T => view instanceof criterion;
114115
}
115116

116117
for (let parent = view.parent; parent != null; parent = parent.parent) {

0 commit comments

Comments
 (0)