public override UICollectionViewLayoutAttributes[] LayoutAttributesForElementsInRect(RectangleF rect) { var layoutAttributes = base.LayoutAttributesForElementsInRect(rect); var modified = new List <UICollectionViewLayoutAttributes>(); var horizontalCenter = CollectionView.Bounds.Width / 2.0; foreach (var layout in layoutAttributes) { var originInCollectionView = new PointF(layout.Frame.Location.X, layout.Frame.Location.Y); var originInMainView = _superView.ConvertPointFromView(originInCollectionView, CollectionView); var centerInCollectionView = layout.Center; // new PointF(layout.c.Frame.Left + layout.Frame.Width/2, //layout.Frame.Top + layout.Frame.Height/2); var centerInMainView = _superView.ConvertPointFromView(centerInCollectionView, CollectionView); var rotateBy = 0.0f; var translateBy = PointF.Empty; // we find out where this cell is relative to the center of the viewport, and invoke private methods to deduce the // amount of rotation to apply if (originInMainView.X < CollectionView.Frame.Width + 80.0f) { translateBy = CalculateTranslateBy(horizontalCenter, layout); rotateBy = CalculateRotationFromViewPortDistance(originInMainView.X); var rotationPoint = new PointF(CollectionView.Frame.Width / 2, CollectionView.Frame.Height); // there are two transforms and one rotation. this is needed to make the view appear to have rotated around // a certain point. CATransform3D transform = CATransform3D.Identity; transform = transform.Translate(rotationPoint.X - centerInMainView.X, rotationPoint.Y - centerInMainView.Y, 0.0f); transform = transform.Rotate(Maths.DegreesToRadians(-rotateBy), 0.0f, 0.0f, -1.0f); // -30.0f to lift the cards up a bit transform = transform.Translate(centerInMainView.X - rotationPoint.X, centerInMainView.Y - rotationPoint.Y - 30.0f, 0.0f); layout.Transform3D = transform; // right card is always on top layout.ZIndex = layout.IndexPath.Item; modified.Add(layout); } } return(modified.ToArray()); }
void ApplyMaskScale(float scale) { // ultimately this scales the layer from the center out (rather than top/left) // create a transform that translates the layer by half its width/height // and then scales it CATransform3D translateScale = new CATransform3D(); translateScale = CATransform3D.Identity; translateScale = translateScale.Scale(scale); translateScale = translateScale.Translate(-(Label.Layer.Mask.Bounds.Width / 2), -(Label.Layer.Mask.Bounds.Height / 2), 0); // now apply a transform that puts it back by its width/height, effectively re-centering it. CATransform3D postScale = new CATransform3D(); postScale = CATransform3D.Identity; postScale = postScale.Translate((Label.Layer.Mask.Bounds.Width / 2), (Label.Layer.Mask.Bounds.Height / 2), 0); // and now concat the post scale and apply Label.Layer.Mask.Transform = translateScale.Concat(postScale); }
private void OnUpdateNativeControl(CALayer caLayer) { VisualElement view = this.Renderer.Element; NSView nativeView = this.Renderer.NativeView; if (view == null || view.Batched) { return; } if (this.inputTransparent != view.InputTransparent) { // TODO: WT.? //nativeView.UserInteractionEnabled = !view.InputTransparent; this.inputTransparent = view.InputTransparent; } bool boundsChanged = this.lastBounds != view.Bounds; int num = boundsChanged ? 0 : (!caLayer.Frame.IsEmpty ? 1 : 0); float anchorX = (float)view.AnchorX; float anchorY = (float)view.AnchorY; float translationX = (float)view.TranslationX; float translationY = (float)view.TranslationY; float rotationX = (float)view.RotationX; float rotationY = (float)view.RotationY; float rotation = (float)view.Rotation; float scale = (float)view.Scale; float width = (float)view.Width; float height = (float)view.Height; float x = (float)view.X; float y = (float)view.Y; float opacity = (float)view.Opacity; bool isVisible = (view.IsVisible ? 1 : 0) != 0; int updateTarget = Interlocked.Increment(ref this.updateCount); Action action = (Action)(() => { if (updateTarget != this.updateCount) { return; } VisualElement visualElement = view; Element parent = view.Parent; bool flag = false; if (isVisible && caLayer.Hidden) { caLayer.Hidden = false; if (!caLayer.Frame.IsEmpty) { flag = true; } } if (!isVisible && !caLayer.Hidden) { caLayer.Hidden = true; flag = true; } CATransform3D caTransform3D = CATransform3D.Identity; if (((visualElement is Page && !(visualElement is ContentPage) || ((double)width <= 0.0 || (double)height <= 0.0) ? 0 : (parent != null ? 1 : 0)) & (boundsChanged ? 1 : 0)) != 0) { RectangleF rectangleF = new RectangleF(x, y, width, height); caLayer.Transform = caTransform3D; caLayer.Frame = (CGRect)rectangleF; if (flag) { caLayer.LayoutSublayers(); } } else if ((double)width <= 0.0 || (double)height <= 0.0) { caLayer.Hidden = true; return; } caLayer.AnchorPoint = (CGPoint) new PointF(anchorX, anchorY); caLayer.Opacity = opacity; if (Math.Abs((double)anchorX - 0.5) > 0.001) { caTransform3D = caTransform3D.Translate((nfloat)((anchorX - 0.5f) * width), (nfloat)0, (nfloat)0); } if (Math.Abs((double)anchorY - 0.5) > 0.001) { caTransform3D = caTransform3D.Translate((nfloat)0, (nfloat)((anchorY - 0.5f) * height), (nfloat)0); } if ((double)Math.Abs(translationX) > 0.001 || (double)Math.Abs(translationY) > 0.001) { caTransform3D = caTransform3D.Translate((nfloat)translationX, (nfloat)translationY, (nfloat)0); } if ((double)Math.Abs(scale - 1f) > 0.001) { caTransform3D = caTransform3D.Scale((nfloat)scale); } if ((double)Math.Abs(rotationY % 180f) > 0.001 || (double)Math.Abs(rotationX % 180f) > 0.001) { caTransform3D.m34 = (nfloat)(-1.0 / 400.0); } if ((double)Math.Abs(rotationX % 360f) > 0.001) { caTransform3D = caTransform3D.Rotate((nfloat)((float)((double)rotationX * 3.14159274101257 / 180.0)), (nfloat)1f, (nfloat)0.0f, (nfloat)0.0f); } if ((double)Math.Abs(rotationY % 360f) > 0.001) { caTransform3D = caTransform3D.Rotate((nfloat)((float)((double)rotationY * 3.14159274101257 / 180.0)), (nfloat)0.0f, (nfloat)1f, (nfloat)0.0f); } caTransform3D = caTransform3D.Rotate((nfloat)((float)((double)rotation * 3.14159274101257 / 180.0)), (nfloat)0.0f, (nfloat)0.0f, (nfloat)1f); caLayer.Transform = caTransform3D; }); // TODO: Figure this out /* * if (num != 0) * CADisplayLinkTicker.Default.Invoke (action); * else */ action(); this.lastBounds = view.Bounds; }