[UWP小白日记-12]使用新的Composition API来实现控件的阴影

简介: 原文:[UWP小白日记-12]使用新的Composition API来实现控件的阴影前言 看了好久官方的Windows UI Dev Labs示例好久才有点心得,真是头大。(其实是英语幼儿园水平(⊙﹏⊙)b) 真的网上关于这个API的资料可以说几乎没有。
原文: [UWP小白日记-12]使用新的Composition API来实现控件的阴影

前言

看了好久官方的Windows UI Dev Labs示例好久才有点心得,真是头大。(其实是英语幼儿园水平(⊙﹏⊙)b)

真的网上关于这个API的资料可以说几乎没有。

正文

  首先用这东西的添加WIN2D。其实这个API实现阴影的步骤和正儿八经使用WIN2D差不多,但是我自己感觉比用WIN2D简单,毕竟微软大法做了封装就是要简单粗暴。差不多的实现都是自定义控件,官方的也是。

  其实就这个API做阴影就是用了2个图层来实现的。

  上图是CorelDRAW里的阴影效果图,明显看出是2个图层的堆叠。

  so,用这个API来实现太简单了,只用控制下面几个属性就能完美实现了外加一个动画就搞定了。

前台XAML

<Grid Background="White">
        <Canvas x:Name="ShadowHost"
                Margin="50"/>
        <Image x:Name="CircleImage"
              Margin="50"
            Source="Assets/3275.jpg" Canvas.ZIndex="1"/>
    </Grid>

后退CS

  首先在构造函数中定义一个方法来实现阴影。

 

 public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            DropShadow(ShadowHost, CircleImage);
        }

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

            // 创建阴影
            var dropShadow = compositor.CreateDropShadow();
            dropShadow.Color = Color.FromArgb(255, 255, 0, 0);
            dropShadow.BlurRadius = 20.0f;
            dropShadow.Offset = new Vector3(2.5f, 2.5f, 0.0f);
            dropShadow.Opacity = 50.0f;
            // 拿到要做阴影的元素的外形用来做阴影的形状,比如我这里是矩形,那这个阴影就是矩形阴影,是圆是扁就看这里了
            dropShadow.Mask = shadowTarget.GetAlphaMask();

            // 创建一个视觉树来hold住阴影
            var shadowVisual = compositor.CreateSpriteVisual();
            shadowVisual.Shadow = dropShadow;

            // 把自定义的阴影添加到视觉树
            ElementCompositionPreview.SetElementChildVisual(shadowHost, shadowVisual);

            // 用一个动画来保证阴影和视觉树同步,就是你变我也变,大家一起变。
            var bindSizeAnimation = compositor.CreateExpressionAnimation("hostVisual.Size");
            bindSizeAnimation.SetReferenceParameter("hostVisual", hostVisual);

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

 

  TIPS:GetAlphaMask()这个方法只有3个控件实现了:Image、Shape、TextBlock当时我看到就懵逼了,那么多控件怎么才实现这3个?,最后想想貌似绝大多数控件最外层都是Shape里的各种形状。

是否是发现了,既然阴影是用2个图层来实现的,那么这是不是共同点,有了共同点是不是就有了用户控件和模版控件的表演上了?

用户控件和模版控件我以前一直都懵逼的。最近看了好多别人的代码,最近突然就悟了,真悟了。吗蛋这和平时写的窗口程序有毛线区别- -,以前看的各种相关自定义控件的文章都是很高大上,各种牛逼,然并卵看不懂。

  拿上面的阴影来说,要把他做成类库,在类库里定义一个用户控件,然后把上面的改造下就可以哪里需要哪里搬了。

  自定义控件最让我等小白懵逼的就是依赖属性,看到那一坨就怕- -。

 

   下面用阴影颜色来看看一个完整的依赖属性的定义。

1.

        /// <summary>
        /// 设置阴影的颜色
        /// 默认值为黑色
        /// </summary>
        public Color Color
        {
            get { return (Color)GetValue(ColorProperty); }
            set { SetValue(ColorProperty, value); }
        }

        
        public static readonly DependencyProperty ColorProperty =
            DependencyProperty.Register(nameof(Color), typeof(Color), typeof(CompositionShadow), new PropertyMetadata(Colors.Black,OnBorederColorChaged));

 

2.

 private static void OnBorederColorChaged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((CompositionShadow)d).OnBorederColorChaged((Color)e.NewValue);
        }

3.

 private void OnBorederColorChaged(Color newValue)
        {
            _dropShadow.Color = newValue;
        }

 

 

看看2、3步是不是劫完财、再劫个色的套路,反正我理解能力有限,听到回调根本无法第一时间想到具体的东西,完全没概念。

现在看到回调第一个想法就是畜生,劫财还劫色。

 

  现在要做的就是把上面的属性全撸成依赖属性。然后定义更新方法来更新SIZE、Mask、OFFset的变化就可以了。

private void UpdateShadowMask()
        {
            if (_castingElement != null)
            {
                CompositionBrush mask = null;
                if (_castingElement is Image)
                {
                    mask = ((Image)_castingElement).GetAlphaMask();
                }
                else if (_castingElement is Shape)
                {
                    mask = ((Shape)_castingElement).GetAlphaMask();
                }
                else if (_castingElement is TextBlock)
                {
                    mask = ((TextBlock)_castingElement).GetAlphaMask();
                }

                _dropShadow.Mask = mask;
            }
            else
            {
                _dropShadow.Mask = null;
            }
        }

        private void UpdateShadowOffset(float x, float y, float z)
        {
            _dropShadow.Offset = new Vector3(x, y, z);
        }

        private void UpdateShadowSize()
        {
            Vector2 newSize = new Vector2(0, 0);
            if (_castingElement != null)
            {
                newSize = new Vector2((float)_castingElement.ActualWidth, (float)_castingElement.ActualHeight);
            }

            _shadowVisual.Size = newSize;
        }

        private FrameworkElement _castingElement;
        private readonly DropShadow _dropShadow;
        private readonly SpriteVisual _shadowVisual;

 

总结

  其实上面的代码在微软爸爸的各种示例代码中都有。大家搜索下Windows UI dev labs这个GitHub上。全是Composition API的使用例子

 

目录
相关文章
|
2月前
|
JavaScript 前端开发 API
Vue.js 3中的Composition API:提升你的组件开发体验
Vue.js 3中的Composition API:提升你的组件开发体验
|
3月前
|
缓存 JavaScript 前端开发
深入理解 Vue 3 的 Composition API 与新特性
本文详细探讨了 Vue 3 中的 Composition API,包括 setup 函数的使用、响应式数据管理(ref、reactive、toRefs 和 toRef)、侦听器(watch 和 watchEffect)以及计算属性(computed)。我们还介绍了自定义 Hooks 的创建与使用,分析了 Vue 2 与 Vue 3 在响应式系统上的重要区别,并概述了组件生命周期钩子、Fragments、Teleport 和 Suspense 等新特性。通过这些内容,读者将能更深入地理解 Vue 3 的设计理念及其在构建现代前端应用中的优势。
64 1
深入理解 Vue 3 的 Composition API 与新特性
|
2月前
|
JavaScript 前端开发 API
Vue 3新特性详解:Composition API的威力
【10月更文挑战第25天】Vue 3 引入的 Composition API 是一组用于组织和复用组件逻辑的新 API。相比 Options API,它提供了更灵活的结构,便于逻辑复用和代码组织,特别适合复杂组件。本文将探讨 Composition API 的优势,并通过示例代码展示其基本用法,帮助开发者更好地理解和应用这一强大工具。
43 2
|
4月前
|
存储 JavaScript 前端开发
敲黑板!vue3重点!一文了解Composition API新特性:ref、toRef、toRefs
该文章深入探讨了Vue3中Composition API的关键特性,包括`ref`、`toRef`、`toRefs`的使用方法与场景,以及它们如何帮助开发者更好地管理组件状态和促进逻辑复用。
敲黑板!vue3重点!一文了解Composition API新特性:ref、toRef、toRefs
|
3月前
|
JavaScript API
|
3月前
|
API
《vue3第四章》Composition API 的优势,包含Options API 存在的问题、Composition API 的优势
《vue3第四章》Composition API 的优势,包含Options API 存在的问题、Composition API 的优势
34 0
|
5月前
|
JavaScript 前端开发 API
Vue.js 3.x新纪元:Composition API引领潮流,Options API何去何从?前端开发者必看的抉择指南!
【8月更文挑战第30天】Vue.js 3.x 引入了 Composition API,为开发者提供了更多灵活性和控制力。本文通过示例代码对比 Composition API 与传统 Options API 的差异,帮助理解两者在逻辑复用、代码组织、类型推断及性能优化方面的不同,并指导在不同场景下的选择。Composition API 改善了代码可读性和维护性,尤其在大型项目中优势明显,同时结合 TypeScript 提供更好的类型推断和代码提示,减少错误并提升开发效率。尽管如此,在选择 API 时仍需考虑项目复杂性、团队熟悉度等因素。
62 0
|
1天前
|
JSON 前端开发 搜索推荐
关于商品详情 API 接口 JSON 格式返回数据解析的示例
本文介绍商品详情API接口返回的JSON数据解析。最外层为`product`对象,包含商品基本信息(如id、name、price)、分类信息(category)、图片(images)、属性(attributes)、用户评价(reviews)、库存(stock)和卖家信息(seller)。每个字段详细描述了商品的不同方面,帮助开发者准确提取和展示数据。具体结构和字段含义需结合实际业务需求和API文档理解。
|
7天前
|
JSON API 数据格式
京东商品SKU价格接口(Jd.item_get)丨京东API接口指南
京东商品SKU价格接口(Jd.item_get)是京东开放平台提供的API,用于获取商品详细信息及价格。开发者需先注册账号、申请权限并获取密钥,随后通过HTTP请求调用API,传入商品ID等参数,返回JSON格式的商品信息,包括价格、原价等。接口支持GET/POST方式,适用于Python等语言的开发环境。
50 11
|
1月前
|
人工智能 自然语言处理 API
Multimodal Live API:谷歌推出新的 AI 接口,支持多模态交互和低延迟实时互动
谷歌推出的Multimodal Live API是一个支持多模态交互、低延迟实时互动的AI接口,能够处理文本、音频和视频输入,提供自然流畅的对话体验,适用于多种应用场景。
80 3
Multimodal Live API:谷歌推出新的 AI 接口,支持多模态交互和低延迟实时互动

热门文章

最新文章