XAML과 함께 시각적 계층 사용Using the Visual Layer with XAML

시각적 계층 기능을 사용 하는 대부분의 앱은 XAML을 사용 하 여 기본 UI 콘텐츠를 정의 합니다.Most apps that consume Visual Layer capabilities will use XAML to define the main UI content. Windows 10 기념일 업데이트에는 XAML 프레임 워크 및 시각적 계층에 새로운 기능이 있습니다 .이를 통해 이러한 두 기술을 결합 하 여 뛰어난 사용자 환경을 만들 수 있습니다.In the Windows 10 Anniversary Update, there are new features in the XAML framework and the Visual Layer that make it easier to combine these two technologies to create stunning user experiences. Xaml 및 시각적 계층 interop 기능을 사용 하 여 XAML Api를 단독으로 사용할 수 없는 고급 애니메이션 및 효과를 만들 수 있습니다.XAML and Visual Layer interop functionality can be used to create advanced animations and effects not available using XAML APIs alone. 다음 내용이 포함됩니다.This includes:

  • 흐림 효과 및 frosted 유리와 같은 브러시 효과Brush effects like blur and frosted glass
  • 동적 조명 효과Dynamic lighting effects
  • 스크롤 구동 애니메이션 및 시차Scroll driven animations and parallax
  • 자동 레이아웃 애니메이션Automatic layout animations
  • 픽셀-완벽 한 그림자Pixel-perfect drop shadows

이러한 효과와 애니메이션은 기존 XAML 콘텐츠에 적용 될 수 있으므로 새 기능을 활용 하기 위해 XAML 앱을 크게 재구성할 필요가 없습니다.These effects and animations can be applied to existing XAML content, so you don't have to dramatically restructure your XAML app to take advantage of the new functionality. 레이아웃 애니메이션, 그림자 및 흐림 효과는 아래 조리법 섹션에서 설명 합니다.Layout animations, shadows, and blur effects are covered in the Recipes section below. 시차을 구현 하는 코드 샘플은 ParallaxingListItems 샘플을 참조 하세요.For a code sample implementing parallax, see the ParallaxingListItems sample. Windowsuidevlabs 리포지토리에 는 애니메이션, 그림자 및 효과를 구현 하기 위한 몇 가지 다른 샘플도 있습니다.The WindowsUIDevLabs repository also has several other samples for implementing animations, shadows and effects.

XamlCompositionBrushBase 클래스The XamlCompositionBrushBase class

XamlCompositionBrushCompositionBrush를 사용 하 여 영역을 그리는 XAML 브러시에 대 한 기본 클래스를 제공 합니다.XamlCompositionBrush provides a base class for XAML brushes that paint an area with a CompositionBrush. 이를 사용 하 여 흐림 효과 또는 frosted 유리와 같은 컴퍼지션 효과를 XAML UI 요소에 쉽게 적용할 수 있습니다.This can be used to easily apply composition effects like blur or frosted glass to XAML UI elements.

XAML UI에서 브러시를 사용 하는 방법에 대 한 자세한 내용은 브러시 섹션을 참조 하십시오.See the Brushes section for more info on using brushes with XAML UI.

코드 샘플은 XamlCompositionBrushBase의 참조 페이지를 참조하세요.For code examples, see the reference page for XamlCompositionBrushBase.

XamlLight 클래스The XamlLight class

XamllightCompositionLight영역을 동적으로 밝게 하는 XAML 조명 효과에 대 한 기본 클래스를 제공 합니다.XamlLight provides a base class for XAML lighting effects that dynamically light an area with a CompositionLight.

조명 XAML UI 요소를 비롯 한 광원 사용에 대 한 자세한 내용은 조명 섹션을 참조 하세요.See the Lighting section for more info on using lights, including lighting XAML UI elements.

코드 예제를 보려면 Xamllight에 대 한 참조 페이지를 참조 하세요.For code examples, see the reference page for XamlLight.

ElementCompositionPreview 클래스The ElementCompositionPreview class

ElementCompositionPreview 는 XAML 및 비주얼 계층 interop 기능을 제공 하는 정적 클래스입니다.ElementCompositionPreview is a static class that provides XAML and Visual Layer interop functionality. 시각적 계층 및 해당 기능에 대 한 개요는 시각적 계층을 참조 하세요.For an overview of the Visual Layer and its functionality, see Visual Layer. ElementCompositionPreview 클래스는 다음 메서드를 제공 합니다.The ElementCompositionPreview class provides the following methods:

  • Getelementvisual개체:이 요소를 렌더링 하는 데 사용 되는 "유인물" 시각적 개체 가져오기GetElementVisual: Get a "handout" Visual that is used to render this element
  • Setelementchildvisual개체: "수동" 시각적 개체를이 요소의 시각적 트리의 마지막 자식으로 설정 합니다.SetElementChildVisual: Sets a "handin" Visual as the last child of this element’s visual tree. 이 시각적 개체는 요소의 나머지 부분 위에 그려집니다.This Visual will draw on top of the rest of the element.
  • GetElementChildVisual: SetElementChildVisual을 사용하여 시각적 개체 설정을 검색합니다.GetElementChildVisual: Retrieve the Visual set using SetElementChildVisual
  • GetScrollViewerManipulationPropertySet: ScrollViewer 에서 스크롤 오프셋을 기반으로 60fps 애니메이션을 만드는 데 사용할 수 있는 개체를 가져옵니다.GetScrollViewerManipulationPropertySet: Get an object that can be used to create 60fps animations based on scroll offset in a ScrollViewer

ElementCompositionPreview에 대 한 설명Remarks on ElementCompositionPreview.GetElementVisual

ElementCompositionPreview 지정 된 UIElement를 렌더링 하는 데 사용 되는 "유인물" 시각적 개체를 반환 합니다.ElementCompositionPreview.GetElementVisual returns a “handout” Visual that is used to render the given UIElement. 표시되는 속성은 UIElement의 상태를 기반으로 하 는 XAML 프레임 워크에 의해 설정 됩니다.Properties such as Visual.Opacity, Visual.Offset, and Visual.Size are set by the XAML framework based on the state of the UIElement. 이렇게 하면 암시적인 애니메이션 위치 변경 ( 조리법참조)과 같은 기술을 사용할 수 있습니다.This enables techniques such as implicit reposition animations (see Recipes).

오프셋과 크기 는 XAML 프레임 워크 레이아웃의 결과로 설정 되므로 개발자는 이러한 속성을 수정 하거나 애니메이션 효과를 적용할 때 주의 해야 합니다.Note that since Offset and Size are set as the result of XAML framework layout, developers should be careful when modifying or animating these properties. 개발자는 요소의 왼쪽 위 모퉁이가 레이아웃의 부모와 동일한 위치인 경우에만 오프셋을 수정 하거나 애니메이션 효과를 적용 해야 합니다.Developers should only modify or animate Offset when the element’s top-left corner has the same position as that of its parent in layout. 크기는 일반적으로 수정 되지 않아야 하지만 속성에 액세스 하는 것이 유용할 수 있습니다.Size should generally not be modified, but accessing the property may be useful. 예를 들어, 아래의 그림자 및 Frosted 유리 샘플은 유인물 시각적 개체의 크기를 애니메이션에 대 한 입력으로 사용 합니다.For example, the Drop Shadow and Frosted Glass samples below use Size of a handout Visual as input to an animation.

추가 주의 사항으로, 유인물 시각적 개체의 업데이트 된 속성은 해당 UIElement에 반영 되지 않습니다.As an additional caveat, updated properties of the handout Visual will not be reflected in the corresponding UIElement. 예를 들어 UIElement 를 0.5로 설정 하면 해당 하는 유인물 시각적 개체의 불투명도가 0.5로 설정 됩니다.So for example, setting UIElement.Opacity to 0.5 will set the corresponding handout Visual’s Opacity to 0.5. 그러나 유인물 시각적 개체의 불투명도 를 0.5로 설정 하면 콘텐츠가 50% 불투명도로 표시 되지만 해당 UIElement의 opacity 속성 값은 변경 되지 않습니다.However, setting the handout Visual’s Opacity to 0.5 will cause the content to appear at 50% opacity, but will not change the value of the corresponding UIElement’s Opacity property.

오프셋 애니메이션의 예Example of Offset animation

틀렸습니다.Incorrect

<Border>
      <Image x:Name="MyImage" Margin="5" />
</Border>
// Doesn’t work because Image has a margin!
ElementCompositionPreview.GetElementVisual(MyImage).StartAnimation("Offset", parallaxAnimation);

정답입니다.Correct

<Border>
    <Canvas Margin="5">
        <Image x:Name="MyImage" />
    </Canvas>
</Border>
// This works because the Canvas parent doesn’t generate a layout offset.
ElementCompositionPreview.GetElementVisual(MyImage).StartAnimation("Offset", parallaxAnimation);

ElementCompositionPreview. SetElementChildVisualThe ElementCompositionPreview.SetElementChildVisual method

ElementCompositionPreview 개발자는 요소 시각적 트리의 일부로 표시 되는 "수동" 시각적 개체를 제공할 수 있습니다.ElementCompositionPreview.SetElementChildVisual allows the developer to supply a “handin” Visual that will appear as part of an element’s Visual Tree. 이를 통해 개발자는 시각적 기반 콘텐츠가 XAML UI 내에 표시 될 수 있는 "컴퍼지션 섬"을 만들 수 있습니다.This allows developers to create a “Composition Island” where Visual-based content can appear inside a XAML UI. 시각적 개체 기반 콘텐츠는 XAML 콘텐츠에 대 한 액세스 가능성 및 사용자 환경이 동일 하지 않기 때문에 개발자는이 기법을 사용 하는 것이 좋습니다.Developers should be conservative about using this technique because Visual-based content will not have the same accessibility and user experience guarantees of XAML content. 따라서 일반적으로이 기법은 아래의 조리법 섹션에서 볼 수 있는 것과 같은 사용자 지정 효과를 구현 하는 데 필요한 경우에만 사용 하는 것이 좋습니다.Therefore, it is generally recommended that this technique only be used when necessary to implement custom effects such as those found in the Recipes section below.

GetAlphaMask 메서드GetAlphaMask methods

이미지, TextBlockshape 는 각각 요소의 모양의 회색조 이미지를 나타내는 CompositionBrush 을 반환 하는 GetAlphaMask 라는 메서드를 구현 합니다.Image, TextBlock, and Shape each implement a method called GetAlphaMask that returns a CompositionBrush representing a grayscale image with the shape of the element. CompositionBrush 는 컴퍼지션 dropshadow의 입력으로 사용할 수 있으므로 그림자는 사각형 대신 요소의 모양을 반영할 수 있습니다.This CompositionBrush can serve as an input for a Composition DropShadow, so the shadow can reflect the shape of the element instead of a rectangle. 이를 통해 텍스트, 알파 및 모양이 포함 된 이미지에 대해 픽셀을 완벽 하 게 배분 된 그림자를 사용할 수 있습니다.This enables pixel perfect, contour-based shadows for text, images with alpha, and shapes. 이 API에 대 한 예제는 아래 그림자 삭제 를 참조 하세요.See Drop Shadow below for an example of this API.

레시피Recipes

애니메이션 위치 변경Reposition animation

개발자는 컴퍼지션 암시적 애니메이션을 사용 하 여 부모를 기준으로 요소 레이아웃의 변경 내용에 자동으로 애니메이션 효과를 적용할 수 있습니다.Using Composition Implicit Animations, a developer can automatically animate changes in an element’s layout relative to its parent. 예를 들어 아래 단추의 여백을 변경 하면 새 레이아웃 위치에 자동으로 애니메이션 효과가 적용 됩니다.For example, if you change the Margin of the button below, it will automatically animate to its new layout position.

구현 개요Implementation overview

  1. 대상 요소에 대 한 유인물 시각적 개체 가져오기Get the handout Visual for the target element
  2. Offset 속성의 변경 내용에 자동으로 애니메이션 효과를 주는 ImplicitAnimationCollection 만들기Create an ImplicitAnimationCollection that automatically animates changes in the Offset property
  3. ImplicitAnimationCollection 을 지원 되는 시각적 개체와 연결Associate the ImplicitAnimationCollection with the backing Visual
<Button x:Name="RepositionTarget" Content="Click Me" />
public MainPage()
{
    InitializeComponent();
    InitializeRepositionAnimation(RepositionTarget);
}

private void InitializeRepositionAnimation(UIElement repositionTarget)
{
    var targetVisual = ElementCompositionPreview.GetElementVisual(repositionTarget);
    Compositor compositor = targetVisual.Compositor;

    // Create an animation to animate targetVisual's Offset property to its final value
    var repositionAnimation = compositor.CreateVector3KeyFrameAnimation();
    repositionAnimation.Duration = TimeSpan.FromSeconds(0.66);
    repositionAnimation.Target = "Offset";
    repositionAnimation.InsertExpressionKeyFrame(1.0f, "this.FinalValue");

    // Run this animation when the Offset Property is changed
    var repositionAnimations = compositor.CreateImplicitAnimationCollection();
    repositionAnimations["Offset"] = repositionAnimation;

    targetVisual.ImplicitAnimations = repositionAnimations;
}

그림자Drop shadow

예를 들어 그림을 포함 하는 타원과 같은 픽셀 수준의 완벽 한 그림자를 UIElement에 적용 합니다.Apply a pixel-perfect drop shadow to a UIElement, for example an Ellipse containing a picture. 섀도를 사용 하려면 앱에서 만든 SpriteVisual 가 필요 하므로 ElementCompositionPreview를 사용 하 여 SpriteVisual 를 포함 하는 "host" 요소를 만들어야 합니다.Since the shadow requires a SpriteVisual created by the app, we need to create a “host” element which will contain the SpriteVisual using ElementCompositionPreview.SetElementChildVisual.

구현 개요Implementation overview

  1. 호스트 요소에 대 한 유인물 시각적 개체 가져오기Get the handout Visual for the host element
  2. Windows. a u. 컴퍼지션 Dropshadow 를 만듭니다.Create a Windows.UI.Composition DropShadow
  3. 마스크를 통해 대상 요소에서 셰이프를 가져오도록 Dropshadow 를 구성 합니다.Configure the DropShadow to get its shape from the target element via a mask
    • Dropshadow 는 기본적으로 사각형 이므로 대상이 사각형 인 경우에는 필요 하지 않습니다.DropShadow is rectangular by default, so this is not necessary if the target is rectangular
  4. SpriteVisual에 그림자를 연결 하 고 SpriteVisual 를 host 요소의 자식으로 설정 합니다.Attach shadow to a new SpriteVisual, and set the SpriteVisual as the child of the host element
  5. SpriteVisual 크기를 expressionanimation 을 사용 하 여 호스트 크기에 바인딩Bind size of the SpriteVisual to the size of the host using an ExpressionAnimation
<Grid Width="200" Height="200">
    <Canvas x:Name="ShadowHost" />
    <Ellipse x:Name="CircleImage">
        <Ellipse.Fill>
            <ImageBrush ImageSource="Assets/Images/2.jpg" Stretch="UniformToFill" />
        </Ellipse.Fill>
    </Ellipse>
</Grid>
public MainPage()
{
    InitializeComponent();
    InitializeDropShadow(ShadowHost, CircleImage);
}

private void InitializeDropShadow(UIElement shadowHost, Shape shadowTarget)
{
    Visual hostVisual = ElementCompositionPreview.GetElementVisual(shadowHost);
    Compositor compositor = hostVisual.Compositor;

    // Create a drop shadow
    var dropShadow = compositor.CreateDropShadow();
    dropShadow.Color = Color.FromArgb(255, 75, 75, 80);
    dropShadow.BlurRadius = 15.0f;
    dropShadow.Offset = new Vector3(2.5f, 2.5f, 0.0f);
    // Associate the shape of the shadow with the shape of the target element
    dropShadow.Mask = shadowTarget.GetAlphaMask();

    // Create a Visual to hold the shadow
    var shadowVisual = compositor.CreateSpriteVisual();
    shadowVisual.Shadow = dropShadow;

    // Add the shadow as a child of the host in the visual tree
   ElementCompositionPreview.SetElementChildVisual(shadowHost, shadowVisual);

    // Make sure size of shadow host and shadow visual always stay in sync
    var bindSizeAnimation = compositor.CreateExpressionAnimation("hostVisual.Size");
    bindSizeAnimation.SetReferenceParameter("hostVisual", hostVisual);

    shadowVisual.StartAnimation("Size", bindSizeAnimation);
}

다음 두 목록은 동일한 XAML 구조를 사용 하 여 이전 C# 코드와 동일한 c + +/Winrtc + +/cx 를 보여 줍니다.The following two listings show the C++/WinRT and C++/CX equivalents of the previous C# code using the same XAML structure.

#include <winrt/Windows.UI.Composition.h>
#include <winrt/Windows.UI.Xaml.h>
#include <winrt/Windows.UI.Xaml.Hosting.h>
#include <winrt/Windows.UI.Xaml.Shapes.h>
...
MainPage()
{
    InitializeComponent();
    InitializeDropShadow(ShadowHost(), CircleImage());
}

int32_t MyProperty();
void MyProperty(int32_t value);

void InitializeDropShadow(Windows::UI::Xaml::UIElement const& shadowHost, Windows::UI::Xaml::Shapes::Shape const& shadowTarget)
{
    auto hostVisual{ Windows::UI::Xaml::Hosting::ElementCompositionPreview::GetElementVisual(shadowHost) };
    auto compositor{ hostVisual.Compositor() };

    // Create a drop shadow
    auto dropShadow{ compositor.CreateDropShadow() };
    dropShadow.Color(Windows::UI::ColorHelper::FromArgb(255, 75, 75, 80));
    dropShadow.BlurRadius(15.0f);
    dropShadow.Offset(Windows::Foundation::Numerics::float3{ 2.5f, 2.5f, 0.0f });
    // Associate the shape of the shadow with the shape of the target element
    dropShadow.Mask(shadowTarget.GetAlphaMask());

    // Create a Visual to hold the shadow
    auto shadowVisual = compositor.CreateSpriteVisual();
    shadowVisual.Shadow(dropShadow);

    // Add the shadow as a child of the host in the visual tree
    Windows::UI::Xaml::Hosting::ElementCompositionPreview::SetElementChildVisual(shadowHost, shadowVisual);

    // Make sure size of shadow host and shadow visual always stay in sync
    auto bindSizeAnimation{ compositor.CreateExpressionAnimation(L"hostVisual.Size") };
    bindSizeAnimation.SetReferenceParameter(L"hostVisual", hostVisual);

    shadowVisual.StartAnimation(L"Size", bindSizeAnimation);
}
#include "WindowsNumerics.h"

MainPage::MainPage()
{
    InitializeComponent();
    InitializeDropShadow(ShadowHost, CircleImage);
}

void MainPage::InitializeDropShadow(Windows::UI::Xaml::UIElement^ shadowHost, Windows::UI::Xaml::Shapes::Shape^ shadowTarget)
{
    auto hostVisual = Windows::UI::Xaml::Hosting::ElementCompositionPreview::GetElementVisual(shadowHost);
    auto compositor = hostVisual->Compositor;

    // Create a drop shadow
    auto dropShadow = compositor->CreateDropShadow();
    dropShadow->Color = Windows::UI::ColorHelper::FromArgb(255, 75, 75, 80);
    dropShadow->BlurRadius = 15.0f;
    dropShadow->Offset = Windows::Foundation::Numerics::float3(2.5f, 2.5f, 0.0f);
    // Associate the shape of the shadow with the shape of the target element
    dropShadow->Mask = shadowTarget->GetAlphaMask();

    // Create a Visual to hold the shadow
    auto shadowVisual = compositor->CreateSpriteVisual();
    shadowVisual->Shadow = dropShadow;

    // Add the shadow as a child of the host in the visual tree
    Windows::UI::Xaml::Hosting::ElementCompositionPreview::SetElementChildVisual(shadowHost, shadowVisual);

    // Make sure size of shadow host and shadow visual always stay in sync
    auto bindSizeAnimation = compositor->CreateExpressionAnimation("hostVisual.Size");
    bindSizeAnimation->SetReferenceParameter("hostVisual", hostVisual);

    shadowVisual->StartAnimation("Size", bindSizeAnimation);
}

불투명한 유리Frosted glass

배경 내용의 흐린 및 색조로 효과를 만듭니다.Create an effect that blurs and tints background content. 개발자는 효과를 사용 하려면 Win2D NuGet 패키지를 설치 해야 합니다.Note that developers need to install the Win2D NuGet package to use effects. 설치 지침은 Win2D 홈 페이지 를 참조 하세요.See the Win2D homepage for installation instructions.

구현 개요Implementation overview

  1. 호스트 요소에 대 한 유인물 시각적 개체 가져오기Get handout Visual for the host element
  2. Win2D 및 CompositionEffectSourceParameter 를 사용 하 여 흐림 효과 트리 만들기Create a blur effect tree using Win2D and CompositionEffectSourceParameter
  3. 효과 트리를 기반으로 CompositionEffectBrush 만들기Create a CompositionEffectBrush based on the effect tree
  4. CompositionEffectBrush 의 입력을 CompositionBackdropBrush로 설정 하 여 효과를 SpriteVisual 뒤의 내용에 적용할 수 있도록 합니다.Set input of the CompositionEffectBrush to a CompositionBackdropBrush, which allows an effect to be applied to the content behind a SpriteVisual
  5. CompositionEffectBrush 을 새 SpriteVisual의 콘텐츠로 설정 하 고 SpriteVisual 를 host 요소의 자식으로 설정 합니다.Set the CompositionEffectBrush as the content of a new SpriteVisual, and set the SpriteVisual as the child of the host element. XamlCompositionBrushBase를 사용할 수도 있습니다.You could alternative use a XamlCompositionBrushBase.
  6. SpriteVisual 크기를 expressionanimation 을 사용 하 여 호스트 크기에 바인딩Bind size of the SpriteVisual to the size of the host using an ExpressionAnimation
<Grid Width="300" Height="300" Grid.Column="1">
    <Image
        Source="Assets/Images/2.jpg"
        Width="200"
        Height="200" />
    <Canvas
        x:Name="GlassHost"
        Width="150"
        Height="300"
        HorizontalAlignment="Right" />
</Grid>
public MainPage()
{
    InitializeComponent();
    InitializeFrostedGlass(GlassHost);
}

private void InitializeFrostedGlass(UIElement glassHost)
{
    Visual hostVisual = ElementCompositionPreview.GetElementVisual(glassHost);
    Compositor compositor = hostVisual.Compositor;

    // Create a glass effect, requires Win2D NuGet package
    var glassEffect = new GaussianBlurEffect
    { 
        BlurAmount = 15.0f,
        BorderMode = EffectBorderMode.Hard,
        Source = new ArithmeticCompositeEffect
        {
            MultiplyAmount = 0,
            Source1Amount = 0.5f,
            Source2Amount = 0.5f,
            Source1 = new CompositionEffectSourceParameter("backdropBrush"),
            Source2 = new ColorSourceEffect
            {
                Color = Color.FromArgb(255, 245, 245, 245)
            }
        }
    };

    //  Create an instance of the effect and set its source to a CompositionBackdropBrush
    var effectFactory = compositor.CreateEffectFactory(glassEffect);
    var backdropBrush = compositor.CreateBackdropBrush();
    var effectBrush = effectFactory.CreateBrush();

    effectBrush.SetSourceParameter("backdropBrush", backdropBrush);

    // Create a Visual to contain the frosted glass effect
    var glassVisual = compositor.CreateSpriteVisual();
    glassVisual.Brush = effectBrush;

    // Add the blur as a child of the host in the visual tree
    ElementCompositionPreview.SetElementChildVisual(glassHost, glassVisual);

    // Make sure size of glass host and glass visual always stay in sync
    var bindSizeAnimation = compositor.CreateExpressionAnimation("hostVisual.Size");
    bindSizeAnimation.SetReferenceParameter("hostVisual", hostVisual);

    glassVisual.StartAnimation("Size", bindSizeAnimation);
}

추가 리소스Additional Resources