Skip to content

Commit 655dcce

Browse files
authored
fix(BaseViewManager): Ensure transform is applied from view center (microsoft#1202)
We needed to include a hack that applied the transform matrices from the center of the view as opposed to from the top left corner of the view. In some cases, this hack was not applied because the width and height of the view had not yet been set by the layout engine. To work around this, we apply the transforms any time the dimensions of the view are updated. Fixes microsoft#1182
1 parent da9878b commit 655dcce

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

ReactWindows/ReactNative.Shared/UIManager/ViewManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ public Dimensions GetDimensions(TFrameworkElement view)
172172
return new Dimensions
173173
{
174174
X = Canvas.GetLeft(view),
175-
Y = Canvas.GetLeft(view),
175+
Y = Canvas.GetTop(view),
176176
Width = view.Width,
177177
Height = view.Height,
178178
};

ReactWindows/ReactNative/UIManager/BaseViewManager.cs

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using ReactNative.Touch;
33
using ReactNative.UIManager.Annotations;
44
using System;
5+
using System.Collections.Generic;
56
using Windows.UI.Xaml;
67
using Windows.UI.Xaml.Automation;
78
using Windows.UI.Xaml.Automation.Peers;
@@ -23,6 +24,9 @@ public abstract class BaseViewManager<TFrameworkElement, TLayoutShadowNode> :
2324
where TFrameworkElement : FrameworkElement
2425
where TLayoutShadowNode : LayoutShadowNode
2526
{
27+
private readonly IDictionary<TFrameworkElement, Action<TFrameworkElement, Dimensions>> _transforms =
28+
new Dictionary<TFrameworkElement, Action<TFrameworkElement, Dimensions>>();
29+
2630
/// <summary>
2731
/// Set's the <typeparamref name="TFrameworkElement"/> styling layout
2832
/// properties, based on the <see cref="JObject"/> map.
@@ -32,14 +36,16 @@ public abstract class BaseViewManager<TFrameworkElement, TLayoutShadowNode> :
3236
[ReactProp("transform")]
3337
public void SetTransform(TFrameworkElement view, JArray transforms)
3438
{
35-
if (transforms == null)
39+
if (transforms == null && _transforms.Remove(view))
3640
{
3741
ResetProjectionMatrix(view);
3842
ResetRenderTransform(view);
3943
}
4044
else
4145
{
42-
SetProjectionMatrix(view, transforms);
46+
_transforms[view] = (v, d) => SetProjectionMatrix(v, d, transforms);
47+
var dimensions = GetDimensions(view);
48+
SetProjectionMatrix(view, dimensions, transforms);
4349
}
4450
}
4551

@@ -141,6 +147,23 @@ public override void OnDropViewInstance(ThemedReactContext reactContext, TFramew
141147
{
142148
view.PointerEntered -= OnPointerEntered;
143149
view.PointerExited -= OnPointerExited;
150+
_transforms.Remove(view);
151+
}
152+
153+
/// <summary>
154+
/// Sets the dimensions of the view.
155+
/// </summary>
156+
/// <param name="view">The view.</param>
157+
/// <param name="dimensions">The dimensions.</param>
158+
public override void SetDimensions(TFrameworkElement view, Dimensions dimensions)
159+
{
160+
Action<TFrameworkElement, Dimensions> applyTransform;
161+
if (_transforms.TryGetValue(view, out applyTransform))
162+
{
163+
applyTransform(view, dimensions);
164+
}
165+
166+
base.SetDimensions(view, dimensions);
144167
}
145168

146169
/// <summary>
@@ -174,22 +197,22 @@ private void OnPointerExited(object sender, PointerRoutedEventArgs e)
174197
TouchHandler.OnPointerExited(view, e);
175198
}
176199

177-
private static void SetProjectionMatrix(TFrameworkElement view, JArray transforms)
200+
private static void SetProjectionMatrix(TFrameworkElement view, Dimensions dimensions, JArray transforms)
178201
{
179202
var transformMatrix = TransformHelper.ProcessTransform(transforms);
180203

181204
var translateMatrix = Matrix3D.Identity;
182205
var translateBackMatrix = Matrix3D.Identity;
183-
if (!double.IsNaN(view.Width))
206+
if (!double.IsNaN(dimensions.Width))
184207
{
185-
translateMatrix.OffsetX = -view.Width / 2;
186-
translateBackMatrix.OffsetX = view.Width / 2;
208+
translateMatrix.OffsetX = -dimensions.Width / 2;
209+
translateBackMatrix.OffsetX = dimensions.Width / 2;
187210
}
188211

189-
if (!double.IsNaN(view.Height))
212+
if (!double.IsNaN(dimensions.Height))
190213
{
191-
translateMatrix.OffsetY = -view.Height / 2;
192-
translateBackMatrix.OffsetY = view.Height / 2;
214+
translateMatrix.OffsetY = -dimensions.Height / 2;
215+
translateBackMatrix.OffsetY = dimensions.Height / 2;
193216
}
194217

195218
var projectionMatrix = translateMatrix * transformMatrix * translateBackMatrix;

0 commit comments

Comments
 (0)