如何在不裁剪的情况下旋转Windows.UI.Composition.ContainerVisual?

问题描述 投票:0回答:2

在我的 .NET 4.8 WPF 应用程序中,我有一个带有两个

ContainerVisual 
元素的窗口:

  1. _rootContainerVisual
  2. _containerVisualToRotate
    1. _rootContainerVisual

      的孩子
    2. 在实际应用程序中以某种方式彼此相邻的多个精灵上显示多个图像。

    3. 在提供的示例代码中显示填充画笔。

    4. 内容比两者的尺寸都大

      ContainerVisual

我想围绕 z 轴旋转完整的 _containerVisualToRotate。

当我这样做时,我注意到 _containerVisualToRotate 内的部分图像/画笔被剪切,尽管有足够的空间。

在标准 WPF 中,我使用负边距来使其工作。 示例 xaml(不需要后面的代码):

<Window x:Class="PlayingAroundInWpf.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:PlayingAroundInWpf"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800" MouseEnter="Window_MouseEnter" MouseLeave="Window_MouseLeave">
    <Grid Background="AntiqueWhite">
        <Grid x:Name="mainGrid" RenderTransformOrigin="0.5,0.5" Margin="-100">
            <Grid.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform/>
                    <RotateTransform Angle="15"/>
                    <TranslateTransform/>
                </TransformGroup>
            </Grid.RenderTransform>
            <Rectangle Fill="LightBlue" Opacity="0.2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
            <Label HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="72">Test with standard WPF</Label>
        </Grid>
    </Grid>
</Window>

这会导致以下结果:内部内容大于视图的可见部分 -> 内部内容在旋转过程中不会被剪切。

enter image description here

我尝试用

_containerVisualToRotate
by

做类似的事情
  • 使用带负数的 Clip 属性。

  • 将 _containerVisualToRotate 的 Size 属性设置为一个较大的数字

  • 将相对大小调整设置为值 >5.0f

  • 将矩形的 Size 属性设置为一个较高的数字

然而,这一切都没有达到预期的结果。

这是我的示例代码(xaml 实际上是一个空窗口):

public partial class ContainerVisualExample : Window
{
    private IntPtr _hwndHost;
    private Windows.UI.Composition.Compositor _compositor;
    private Windows.UI.Composition.CompositionTarget _target;
    private Windows.UI.Composition.ContainerVisual _rootContainerVisual;
    private Windows.UI.Composition.ContainerVisual _containerVisualToRotate;

    public ContainerVisualExample()
    {
        InitializeComponent();

        Loaded += ContainerVisualExample_Loaded;
    }

    private void ContainerVisualExample_Loaded(object sender, RoutedEventArgs e)
    {
        SetupCompositions();
        AddRectangleToContainer();
        RotateContainerVisual();
    }

    private void SetupCompositions()
    {
        _hwndHost = new System.Windows.Interop.WindowInteropHelper(this).Handle;

        _compositor = new Compositor();
        _target = _compositor.CreateDesktopWindowTarget(_hwndHost, false);

        // Setup the _rootContainerVisual.
        _rootContainerVisual = _compositor.CreateContainerVisual();
        _rootContainerVisual.RelativeSizeAdjustment = Vector2.One;
        _rootContainerVisual.Offset = new Vector3(0, 0, 0);
        _containerVisualToRotate = _compositor.CreateContainerVisual();
        _containerVisualToRotate.RelativeSizeAdjustment = new Vector2(5.0f, 5.5f);
        _containerVisualToRotate.Offset = new Vector3(0, 0, 0);
        _containerVisualToRotate.Size = new Vector2(10000, 10000);
        _containerVisualToRotate.Clip = _compositor.CreateInsetClip(-10000, -10000, -10000, -10000);        
        _containerVisualToRotate.CenterPoint = new Vector3(400, 225, 0);
        _rootContainerVisual.Children.InsertAtTop(_containerVisualToRotate);
        _target.Root = _rootContainerVisual;
    }
    private void AddRectangleToContainer()
    {
        // Create a rectangle element
        Windows.UI.Composition.SpriteVisual rectangleVisual = _compositor.CreateSpriteVisual();
        rectangleVisual.Size = new Vector2(10000, 10000);

        // Set the fill color of the rectangle to light blue
        Windows.UI.Color lightBlueColor = Windows.UI.Color.FromArgb(255, 173, 216, 230);
        Windows.UI.Composition.CompositionColorBrush fillBrush = _compositor.CreateColorBrush(lightBlueColor);
        rectangleVisual.Brush = fillBrush;

        // Add the rectangle to the _containerVisualToRotate
        _containerVisualToRotate.Children.InsertAtTop(rectangleVisual);
    }
    private void RotateContainerVisual()
    {
        _containerVisualToRotate.RotationAngleInDegrees = 45.0f;
    }
}

但是,这仍然会导致削波:

enter image description here

现在,我不知道如何让它发挥作用。

正如我上面所写:旋转内部内容(在示例中为矩形)并不是真正的选择,因为它包含多个精灵,这些精灵都需要围绕同一中心点单独旋转。

还有其他办法吗?

.net wpf composition
2个回答
0
投票

我无法添加评论, 你试过了吗

LayoutTransform

<Grid.LayoutTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform/>
                    <RotateTransform Angle="15"/>
                    <TranslateTransform/>
                </TransformGroup>
</Grid.LayoutTransform>

0
投票
    public partial class ContainerVisualExample : Window
    {
        private Windows.UI.Composition.Compositor _compositor;
        private Windows.UI.Composition.ContainerVisual _rootContainerVisual;
        private Windows.UI.Composition.ContainerVisual _containerVisualToRotate;

        public ContainerVisualExample()
        {
            InitializeComponent();

            Loaded += ContainerVisualExample_Loaded;
        }

        private void ContainerVisualExample_Loaded(object sender, RoutedEventArgs e)
        {
            SetupCompositions();
            AddRectangleToContainer();
            RotateContainerVisual();
            AdjustRootContainerSize();
        }

        private void SetupCompositions()
        {
            // Create a Compositor instance
            _compositor = new Compositor();

            // Create the root ContainerVisual
            _rootContainerVisual = _compositor.CreateContainerVisual();
            _rootContainerVisual.RelativeSizeAdjustment = Vector2.One;

            // Create the ContainerVisual to rotate
            _containerVisualToRotate = _compositor.CreateContainerVisual();
            _containerVisualToRotate.RelativeSizeAdjustment = Vector2.One;

            // Add the ContainerVisuals to the visual tree
            ElementCompositionPreview.SetElementChildVisual(mainCanvas, _rootContainerVisual);
            _rootContainerVisual.Children.InsertAtTop(_containerVisualToRotate);
        }

        private void AddRectangleToContainer()
        {
            // Create a solid color brush
            var brush = _compositor.CreateColorBrush(Windows.UI.Colors.LightBlue);

            // Create a SpriteVisual to represent the rectangle
            var rectangleVisual = _compositor.CreateSpriteVisual();
            rectangleVisual.Size = new Vector2(300, 200); // Set size as per your requirement
            rectangleVisual.Brush = brush;

            // Add the rectangle to the container to rotate
            _containerVisualToRotate.Children.InsertAtTop(rectangleVisual);
        }

        private void RotateContainerVisual()
        {
            // Rotate the _containerVisualToRotate
            var rotationAnimation = _compositor.CreateScalarKeyFrameAnimation();
            rotationAnimation.InsertKeyFrame(1.0f, 360.0f, _compositor.CreateLinearEasingFunction());
            rotationAnimation.Duration = TimeSpan.FromSeconds(5);
            rotationAnimation.IterationBehavior = AnimationIterationBehavior.Forever;

            _containerVisualToRotate.StartAnimation(nameof(Visual.RotationAngleInDegrees), rotationAnimation);
        }

        private void AdjustRootContainerSize()
        {
            // Adjust the size of _rootContainerVisual to accommodate the rotated content
            var size = new Vector2(400, 300); // Adjust as per your content size
            _rootContainerVisual.Size = size;
        }
    }


   

我们创建一个 Compositor 实例并初始化根和子 ContainerVisuals。 将矩形视觉对象添加到 _containerVisualToRotate 来表示要旋转的内容。 我们将旋转动画应用于 _containerVisualToRotate。 调整 _rootContainerVisual 大小以适应旋转的内容。 您需要确保为 Windows.UI.Composition 命名空间导入必要的引用和命名空间。此外,mainCanvas 应该是 XAML 文件中要在其中显示合成视觉效果的画布的名称。根据您的应用程序要求调整视觉效果的大小和内容。

© www.soinside.com 2019 - 2024. All rights reserved.