次の方法で共有


XAML でのビジュアル レイヤーの使用

Visual Layer 機能を使用するほとんどのアプリでは、XAML を使用してメイン UI コンテンツを定義します。 Windows 10 Anniversary Update には、XAML フレームワークとビジュアル レイヤーに新しい機能があり、これら 2 つのテクノロジを簡単に組み合わせて魅力的なユーザー エクスペリエンスを作成できます。 XAML と Visual Layer の相互運用機能を使用して、XAML API だけでは使用できない高度なアニメーションと効果を作成できます。 これには次のものが含まれます。

  • ぼかしやすりガラスのようなブラシ効果
  • 動的な照明効果
  • スクロール 駆動型アニメーションと視差
  • 自動レイアウト アニメーション
  • ピクセル単位で完璧なドロップシャドウ

これらの効果とアニメーションは既存の XAML コンテンツに適用できるため、新しい機能を利用するために XAML アプリを大幅に再構築する必要はありません。 レイアウトアニメーション、影、ぼかし効果については、以下の「レシピ」セクションで説明します。 視差を実装するコード サンプルについては、 ParallaxingListItems サンプルを参照してください。 WindowsCompositionSamples リポジトリには、アニメーション、シャドウ、効果を実装するための他のいくつかのサンプルもあります。

XamlCompositionBrushBase クラス

XamlCompositionBrush は、 CompositionBrush で領域を描画する XAML ブラシの基本クラスを提供します。 これを使用すると、ぼかしやフロスト ガラスなどの合成効果を XAML UI 要素に簡単に適用できます。

XAML UI で ブラシを 使用する方法の詳細については、「ブラシ」セクションを参照してください。

コード例については、 XamlCompositionBrushBase のリファレンス ページを参照してください。

XamlLight クラス

XamlLight には、 CompositionLight を使用して領域を動的に照らす XAML 照明効果の基本クラスが用意されています。

照明 XAML UI 要素など、ライトの使用方法の詳細については、「 ライティング 」セクションを参照してください。

コード例については、 XamlLight のリファレンス ページを参照してください。

ElementCompositionPreview クラス

ElementCompositionPreview は、XAML と Visual Layer 相互運用機能を提供する静的クラスです。 ビジュアル レイヤーとその機能の概要については、「 ビジュアル レイヤー」を参照してください。 ElementCompositionPreview クラスには、次のメソッドがあります。

  • GetElementVisual: この要素のレンダリングに使用される "配布資料" ビジュアルを取得します
  • SetElementChildVisual: "handin" ビジュアルをこの要素のビジュアル ツリーの最後の子として設定します。 このビジュアル要素は、他の要素の上に重ねて描画されます。
  • GetElementChildVisual: SetElementChildVisual を使用してビジュアル セットを取得する
  • GetScrollViewerManipulationPropertySet: ScrollViewer のスクロール オフセットに基づいて 60fps アニメーションを作成するために使用できるオブジェクトを取得します。

ElementCompositionPreview.GetElementVisual に関する解説

ElementCompositionPreview.GetElementVisual は、指定された UIElement のレンダリングに使用される "配布資料" ビジュアルを返します。 Visual.Opacity、Visual.OffsetVisual.Size などのプロパティは、UIElement の状態に基づいて XAML フレームワークによって設定されます。 これにより、暗黙的な再配置アニメーションなどの手法が可能になります ( レシピを参照)。

オフセットサイズは XAML フレームワーク レイアウトの結果として設定されるため、開発者はこれらのプロパティを変更またはアニメーション化する際に注意する必要があります。 開発者は、要素の左上隅がレイアウト内の親と同じ位置にある場合にのみ、Offset を変更またはアニメーション化する必要があります。 通常、サイズは変更しないでくださいが、プロパティにアクセスすると便利な場合があります。 たとえば、下のドロップ シャドウとフロスト ガラスのサンプルでは、配布資料ビジュアルのサイズをアニメーションへの入力として使用します。

追加の注意事項として、配布資料ビジュアルの更新されたプロパティは、対応する UIElement には反映されません。 たとえば、 UIElement.Opacity を 0.5 に設定すると、対応する配布資料ビジュアルの不透明度が 0.5 に設定されます。 ただし、配布資料ビジュアルの 不透明度 を 0.5 に設定すると、コンテンツは 50% 不透明度で表示されますが、対応する UIElement の Opacity プロパティの値は変更されません。

オフセット アニメーションの例

不正解です

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

正解です

<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.SetElementChildVisual メソッド

ElementCompositionPreview.SetElementChildVisual を使用すると、開発者は、要素のビジュアル ツリーの一部として表示される "handin" ビジュアルを提供できます。 これにより、開発者は、XAML UI 内にビジュアル ベースのコンテンツを表示できる "コンポジション アイランド" を作成できます。 開発者は、ビジュアル ベースのコンテンツに XAML コンテンツのアクセシビリティとユーザー エクスペリエンスの保証が同じではないため、この手法の使用については控えめにする必要があります。 そのため、一般に、この手法は、以下の「レシピ」セクションにあるようなカスタム効果を実装するために必要な場合にのみ使用することをお勧めします。

GetAlphaMask メソッド

ImageTextBlock、および Shape はそれぞれ、要素の図形を持つグレースケールイメージを表す CompositionBrush を返す、GetAlphaMask というメソッドを実装します。 この CompositionBrush は、コンポジション DropShadow の入力として機能できるため、影は四角形ではなく要素の形状を反映できます。 これにより、テキスト、アルファを含む画像、図形に対してピクセルの完璧な輪郭ベースの影が可能になります。 この API の例については、下の 「ドロップ シャドウ 」を参照してください。

レシピ

アニメーションの位置を変更する

コンポジション暗黙的アニメーションを使用すると、開発者は要素のレイアウトの変更を親に対して自動的にアニメーション化できます。 たとえば、下のボタンの 余白 を変更すると、新しいレイアウト位置に自動的にアニメーション化されます。

実装の概要

  1. ターゲット要素の Visual 配布資料を取得する
  2. Offset プロパティの変更を自動的にアニメーション化する ImplicitAnimationCollection を作成する
  3. ImplicitAnimationCollection をバッキング ビジュアルに関連付ける
<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;
}

ドロップ シャドウ

UIElement にピクセル完璧なドロップ シャドウ (画像を含む楕円など) を適用します。 シャドウにはアプリによって作成された SpriteVisual が必要であるため、ElementCompositionPreview.SetElementChildVisual を使用して SpriteVisual を含む "host" 要素を作成する必要があります。

実装の概要

  1. ホスト要素の 配布資料 Visual を取得する
  2. Windows.UI.Composition で DropShadow を作成する
  3. マスクを介してターゲット要素から図形を取得するように DropShadow を構成する
    • DropShadow は既定で四角形であるため、ターゲットが四角形の場合は必要ありません
  4. 新しい SpriteVisual にシャドウをアタッチし、 SpriteVisual をホスト要素の子として設定します
  5. ExpressionAnimation を使用して SpriteVisual のサイズをホストのサイズにバインドする
<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);
}

次の 2 つの一覧は、同じ XAML 構造体を使用した前の C# コードと同等の C++/ WinRT と C ++/CX を示しています。

#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);
}

曇りガラス

背景コンテンツをぼかし、濃淡する効果を作成します。 開発者は、効果を使用するために Win2D NuGet パッケージをインストールする必要があることに注意してください。 インストール手順については、 Win2D のホームページ を参照してください。

実装の概要

  1. ホスト要素の配布資料 ビジュアル を取得する
  2. Win2D と CompositionEffectSourceParameter を使用してぼかし効果ツリーを作成する
  3. エフェクト ツリーに基づいて CompositionEffectBrush を作成する
  4. CompositionEffectBrush の入力を CompositionBackdropBrush に設定します。これにより、SpriteVisual の背後にあるコンテンツに効果を適用できます。
  5. CompositionEffectBrush を新しい SpriteVisual のコンテンツとして設定し、SpriteVisual をホスト要素の子として設定します。 代わりに XamlCompositionBrushBase を使用することもできます。
  6. ExpressionAnimation を使用して SpriteVisual のサイズをホストのサイズにバインドする
<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);
}

その他のリソース