第二十一章:变换(九)

简介: 旋转的文字效果轮换很有趣。 旋转动画时更有趣(正如您将在下一章中看到的那样),但即使使用静态图像也很有趣。本章和下一章中的几个旋转示例涉及将视觉元素排列在一个圆圈中,所以让我们首先尝试显示一个简单的圆圈。

旋转的文字效果
轮换很有趣。 旋转动画时更有趣(正如您将在下一章中看到的那样),但即使使用静态图像也很有趣。
本章和下一章中的几个旋转示例涉及将视觉元素排列在一个圆圈中,所以让我们首先尝试显示一个简单的圆圈。 当然,如果没有Xamarin.Forms中的实际图形系统,我们需要有创造力并用BoxView构建这个圆圈。 如果你使用许多小的BoxView元素并正确排列它们,应该可以创建一个看起来像一个光滑的圆形的东西,如下所示:
2019_01_15_140434
每个圆圈由64个BoxView元素组成,每个元素的厚度为4个单位。 这两个值在仅代码的BoxViewCircle程序中定义为常量:

public class BoxViewClockPage : ContentPage
{
    const int COUNT = 64;
    const double THICKNESS = 4;
    public BoxViewClockPage()
    {
        AbsoluteLayout absoluteLayout = new AbsoluteLayout();
        Content = absoluteLayout;
        for (int index = 0; index < COUNT; index++)
        {
            absoluteLayout.Children.Add(new BoxView
            {
                Color = Color.Accent,
            });
        }
        absoluteLayout.SizeChanged += (sender, args) =>
            {
                Point center = new Point(absoluteLayout.Width / 2, absoluteLayout.Height / 2);
                double radius = Math.Min(absoluteLayout.Width, absoluteLayout.Height) / 2;
                double circumference = 2 * Math.PI * radius;
                double length = circumference / COUNT;
                for (int index = 0; index < absoluteLayout.Children.Count; index++)
               {
                    BoxView boxView = (BoxView)absoluteLayout.Children[index];
                    // Position every BoxView at the top.
                    AbsoluteLayout.SetLayoutBounds(boxView,
                        new Rectangle(center.X - length / 2, 
                                      center.Y - radius, 
                                      length, 
                                      THICKNESS));
                    // Set the AnchorX and AnchorY properties so rotation is 
                    // around the center of the AbsoluteLayout.
                    boxView.AnchorX = 0.5;
                    boxView.AnchorY = radius / THICKNESS;
                    // Set a unique Rotation for each BoxView.
                    boxView.Rotation = index * 360.0 / COUNT;
                }
            };
     }
}

所有计算都发生在AbsoluteLayout的SizeChanged处理程序中。 AbsoluteLayout的宽度和高度的最小值是圆的半径。知道半径允许计算周长,因此可以计算每个BoxView的长度。
for循环将每个BoxView定位在相同位置:圆圈的中心顶部。然后必须围绕圆心旋转每个BoxView。这需要设置一个AnchorY属性,该属性对应于从BoxView顶部到圆心的距离。该距离是半径值,但必须以BoxView高度为单位,这意味着半径必须除以THICKNESS。
有一种替代方法可以定位和旋转每个不需要设置AnchorX和AnchorY属性的BoxView。这种方法对iOS更好。 for循环首先计算对应于围绕圆周长的每个BoxView中心的x和y值。这些计算需要使用具有半径值的正弦和余弦函数来补偿BoxView的厚度:

for (int index = 0; index < absoluteLayout.Children.Count; index++)
{
    BoxView boxView = (BoxView)absoluteLayout.Children[index];
    // Find point in center of each positioned BoxView.
    double radians = index * 2 * Math.PI / COUNT;
    double x = center.X + (radius - THICKNESS / 2) * Math.Sin(radians);
    double y = center.Y - (radius - THICKNESS / 2) * Math.Cos(radians);
    // Position each BoxView at that point.
    AbsoluteLayout.SetLayoutBounds(boxView,
        new Rectangle(x - length / 2,
                      y - THICKNESS / 2,
                      length,
                      THICKNESS));
    // Set a unique Rotation for each BoxView.
    boxView.Rotation = index * 360.0 / COUNT;
}

x和y值表示每个BoxView中心所需的位置,而AbsoluteLayout.SetLayoutBounds需要每个BoxView左上角的位置,因此当与SetLayoutBounds一起使用时,这些x和y值会根据该差异进行调整。 然后每个BoxView围绕其自己的中心旋转。
现在让我们旋转一些文字。 RotatedText程序完全在XAML中实现:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="RotatedText.RotatedTextPage">
    <Grid>
        <Grid.Resources>
            <ResourceDictionary>
                <Style TargetType="Label">
                    <Setter Property="Text" Value=" ROTATE" />
                    <Setter Property="FontSize" Value="32" />
                    <Setter Property="Grid.Column" Value="1" />
                    <Setter Property="VerticalOptions" Value="Center" />
                    <Setter Property="HorizontalOptions" Value="Start" />
                    <Setter Property="AnchorX" Value="0" />
                </Style>
            </ResourceDictionary>
        </Grid.Resources>
        <Label Rotation="0" />
        <Label Rotation="22.5" />
        <Label Rotation="45" />
        <Label Rotation="67.5" />
        <Label Rotation="90" />
        <Label Rotation="112.5" />
        <Label Rotation="135" />
        <Label Rotation="157.5" />
        <Label Rotation="180" />
        <Label Rotation="202.5" />
        <Label Rotation="225" />
        <Label Rotation="246.5" />
        <Label Rotation="270" />
        <Label Rotation="292.5" />
        <Label Rotation="315" />
        <Label Rotation="337.5" />
    </Grid>
</ContentPage>

该程序由Grid中的16个Label元素组成,其中隐式Style设置了六个属性,包括Text和FontSize。 虽然这个Grid似乎只是一个单元格,但它实际上是一个双列Grid,因为Style将每个Label的Grid.Column属性设置为1,这是第二列。 样式在第二列中垂直居中每个标签,并在该列的左侧开始,该列是页面的中心。 但是,文本以几个空格开头,因此它似乎从页面中心的右侧开始。

目录
相关文章
|
机器学习/深度学习 传感器 算法
数字图像处理实验(五)|图像复原{逆滤波和伪逆滤波、维纳滤波deconvwnr、大气湍流扰动模型、运动模糊处理fspecial}(附matlab实验代码和截图)
数字图像处理实验(五)|图像复原{逆滤波和伪逆滤波、维纳滤波deconvwnr、大气湍流扰动模型、运动模糊处理fspecial}(附matlab实验代码和截图)
574 0
数字图像处理实验(五)|图像复原{逆滤波和伪逆滤波、维纳滤波deconvwnr、大气湍流扰动模型、运动模糊处理fspecial}(附matlab实验代码和截图)
|
12月前
三维之外的更高维度,数学家发现了无限可能的黑洞形状
三维之外的更高维度,数学家发现了无限可能的黑洞形状
101 0
|
机器学习/深度学习 人工智能 编解码
CVPR 2022 | 逆渲染中的⾼效间接光照建模
CVPR 2022 | 逆渲染中的⾼效间接光照建模
483 0
CVPR 2022 | 逆渲染中的⾼效间接光照建模
Halcon标定系列(5):4点标定之眼在手外项目实践,已知仿射变换矩阵,计算得到旋转角度和缩放因子等参数
Halcon标定系列(5):4点标定之眼在手外项目实践,已知仿射变换矩阵,计算得到旋转角度和缩放因子等参数
822 0
Halcon标定系列(5):4点标定之眼在手外项目实践,已知仿射变换矩阵,计算得到旋转角度和缩放因子等参数
|
Android开发 索引
第二十一章:变换(十)
样式通过将AnchorX值设置为0来结束,该值将旋转中心设置为每个Label的左边缘的垂直中心。 然后每个Label都会获得一个独特的旋转设置:显然,选择“ROTATE”字符串之前的空格,以便R的垂直条组合形成一个看起来几乎像圆的16边多边形。
1019 0
|
Android开发
第二十一章:变换(八)
旋转变换 “旋转”属性旋转屏幕表面上的可视元素。 将“旋转”属性设置为以度为单位的角度(不是弧度)。 正角度顺时针旋转元素。 您可以将“旋转”设置为小于0或大于360的角度。实际旋转角度是旋转属性模数360的值。
821 0
|
Android开发
第二十一章:变换(十四)
3D-ish旋转 即使计算机屏幕是平面和二维的,也可以在这些屏幕上绘制视觉对象,使其具有第三维的外观。 在本章的前面,您看到了一些文本效果,它们提供了第三个维度的提示,而Xamarin.Forms支持两个额外的旋转,名为RotationX和RotationY,它们似乎也突破了屏幕固有的二维平面度。
1349 0
|
Android开发 iOS开发
第二十一章:变换(七)
锚定规模当你尝试使用Scale属性时,你可能已经注意到视觉元素的任何扩展都是从元素的中心向外发生的,如果你将视觉元素缩小到任何东西,它也会向中心收缩。这是另一种思考方式:无论Scale属性的设置如何,视觉元素正中心的点都保持在同一位置。
937 0
|
Android开发 iOS开发 Windows
第二十一章:变换(六)
两个按钮的Clicked处理程序每个都启动一个独立的动画。 第一个Button的Clicked处理程序将其Scale属性从1设置为5并再次返回,而第二个Button的Clicked处理程序将其FontSize属性设置为1到5的比例因子,然后再返回。
940 0
|
JavaScript Android开发
第二十一章:变换(五)
规模变换 VisualElement类定义名为Scale的属性,您可以使用该属性更改元素的呈现大小。 Scale属性不会影响布局(将在ButtonScaler程序中演示)。它不会影响元素的get-only Width和Height属性,也不会影响包含Width和Height值的get-only Bounds属性。
906 0