[UWP]UIElement.Clip虽然残废,但它还可以这样玩
1. 复习一下WPF的UIElement.Clip
用了很久很久的WPF,但几乎没有主动用过它的Clip属性,我只记得它很灵活,可以裁剪出多种形状。在官方文档复习了一下,大致用法和效果如下:
<Image
Source="sampleImages\Waterlilies.jpg"
Width="200" Height="150" HorizontalAlignment="Left">
<Image.Clip>
<EllipseGeometry
RadiusX="100"
RadiusY="75"
Center="100,75"/>
</Image.Clip>
</Image>
WPF的Clip是一个Geometry属性,它有多种派生类:
有这么多种Geometry,WPF的UIElement就可以裁剪成各种奇形怪状的形状,过去也有很多示例和文章讲解过如何利用WPF的Clip,这里就割爱了。
2. UWP中的UIElement.Clip
WPF的Clip真的为所欲为,然而到了UWP就变得绑手绑脚了,因为UWP的UIElement.Clip居然是个RectangleGeometry属性,也就是说UIElement只能接受矩形的裁剪区域,这已经不是简单,近乎残废了。具体用法差不多:
<Canvas>
<Image Source="Images/Water_lilies.jpg" Width="200" Height="150">
<Image.Clip>
<RectangleGeometry Rect="100 75 50 50"/>
</Image.Clip>
</Image>
</Canvas>
其实Win2D和CompositionAPI可以做到复杂的裁剪,但用起来也比较复杂啊。也许UWP的理念是将XAML做成一个简单好用的工具,更复杂的内容全部交给Win2D和CompositionAPI实现?
3. 也许用不着Clip?
如果只能简单地剪切出矩形区域的话,很多时候都用不着Clip,在XAML中有其它方法可以实现需要的功能。
例如上面这个长阴影的失败例子,我应该裁剪超过边框的元素,如果要用Clip,XAML要这样写:
<StackPanel Background="#FFE87A69"
x:Name="ShadowBorder">
<StackPanel.Clip>
<RectangleGeometry Rect="0 0 600 160" />
</StackPanel.Clip>
…
…
</StackPanel>
虽然最终实现了我要的想过,但一点都不开心,因为写死的尺寸都不优雅。或者可以绑定到ActualHeight和ActualWidth?反正我没有试过。
在用WPF时我也常常遇到这种问题,但我总是用ScrollViewer解决,ScrollViewer本身就有提供Clip的功能,代码如下:
<ScrollViewer Padding="0"
BorderThickness="0"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Disabled">
<StackPanel Background="#FFE87A69"
x:Name="ShadowBorder">
...
...
</StackPanel>
</ScrollViewer>
XAML胖点就胖点吧,又不会怎样。
不过UWP有个神奇的功能,CornerRadius
设置为大于0的值就会裁剪范围外的内容,毕竟有了圆角不裁剪的话会很难看?所以UWP贴心地帮忙做了这个操作?算了不管原理了,反正一个像素的圆角,你不说我不说没人会看得出来,安心地这样用比自己设置Clip方便多了。
<StackPanel Background="#FFE87A69" CornerRadius="1">
看吧,1像素的圆角真的很难发现。最近WinUI改版,它的圆角做成2像素了,就是因为1像素真的看不出来。
4. Clip还可以这样玩
上面介绍到如何使用、或者不使用Clip裁剪范围内的剧情区域。除此之外,因为可以指定裁剪的起始和结束为止,还是有不少可玩的地方。
上面这个懂的人都懂的中二病红和智障蓝组成的番茄钟就用了Clip,简单地将同一个文字复制出来两份,以中间为届分别裁剪出上半部分和下半部分,再分别向两边做位移的Spring动画,这样就能做出切开的效果:
<Grid Height="1050" Width="1920" x:Name="ContentArea" RenderTransformOrigin="0.5,0.5" >
<Grid.RenderTransform>
<CompositeTransform Rotation="-8"/>
</Grid.RenderTransform>
<Grid >
<Grid x:Name="FocusElementTop">
<Grid.Clip>
<RectangleGeometry Rect="-1000,-1000,3920,1525"/>
</Grid.Clip>
<TextBlock Style="{StaticResource FocusText}" />
</Grid>
<Grid x:Name="FocusElementBottom">
<Grid.Clip>
<RectangleGeometry Rect="-1000,525,3920,1525"/>
</Grid.Clip>
<TextBlock Style="{StaticResource FocusText}" />
</Grid>
<Grid x:Name="RelaxElementTop">
<Grid.Clip>
<RectangleGeometry Rect="-1000,-1000,3920,1525"/>
</Grid.Clip>
<TextBlock Style="{StaticResource RelaxText}"/>
</Grid>
<Grid x:Name="RelaxElementBottom">
<Grid.Clip>
<RectangleGeometry Rect="-1000,525,3920,1525"/>
</Grid.Clip>
<TextBlock Style="{StaticResource RelaxText}"/>
</Grid>
</Grid>
</Grid>
做UWP应用不需要太介意性能,UWP的的性能比WPF好太多,而且都2019年了,那些少内存就不要客气了。上面这个懂的人都懂的五等分配色的番茄钟就毫不客气地叠加再叠加,每个部分用了不同的Clip,背景和文字用了不同时间的Spring动画,出来的效果很有趣。XAML大致上是这样:
<Grid Width="1600"
HorizontalAlignment="Left">
<Grid Background="#f8a9a2">
<UIElement.Clip>
<RectangleGeometry Rect="000,-1000,320,5050" />
</UIElement.Clip>
<controls:HeaderedContentControl Foreground="White"
Header="FOCUS ON JOB"/>
</Grid>
<Grid Background="White">
<UIElement.Clip>
<RectangleGeometry Rect="320,-1000,320,5050" />
</UIElement.Clip>
<controls:HeaderedContentControl Foreground="#ed4e5d"
Header="FOCUS ON JOB"/>
</Grid>
<Grid Background="#974945">
<UIElement.Clip>
<RectangleGeometry Rect="640,-1000,320,5050" />
</UIElement.Clip>
<controls:HeaderedContentControl Foreground="White"
Header="FOCUS ON JOB"/>
</Grid>
<Grid Background="White">
<UIElement.Clip>
<RectangleGeometry Rect="960,-1000,320,5050" />
</UIElement.Clip>
<controls:HeaderedContentControl Foreground="#ef804b"
Header="FOCUS ON JOB"/>
</Grid>
<Grid Background="#e74b36">
<UIElement.Clip>
<RectangleGeometry Rect="1280,-1000,320,5050" />
</UIElement.Clip>
<controls:HeaderedContentControl Foreground="White"
Header="FOCUS ON JOB"/>
</Grid>
</Grid>
5. 也许真用不着Clip?
不要因为学会用Clip了就什么地方都用Clip,有时候并不需要用到。例如上面这个,看上去文字是从Clip外面的区域进入的,但其实并没有用到Clip,只是调整了Canvas.ZIndex
遮住不需要的部分而已。
6. 结语
UWP中其实有几种裁剪方案,最残废的是UIElement.Clip
,也就是这篇文章提到的这个。上一篇文章还讲解了Win2D中裁剪。其实CompositionAPI也有它的裁剪方案,下一篇文章将介绍CompositionAPI的Clip用法。
顺便一提,火火提到WPF可以用UIElement.ClipToBounds。因为Silverlight没有这个属性,而我很多控件SL和WPF都用同一套代码,所以以前很少用到这个属性,很偶尔偶尔才会想起有这个属性,例如这么用:
7. 参考
UIElement.Clip 属性 (System.Windows) _ Microsoft Docs
UIElement.Clip Property (Windows.UI.Xaml) - Windows UWP applications _ Microsoft Docs
RectangleGeometry Class (Windows.UI.Xaml.Media) - Windows UWP applications _ Microsoft Docs
8. 源码
OnePomodoro_DoNotDisturbView.xaml at master
OnePomodoro_SplitTo5View.xaml at master
OnePomodoro_KonosubaView.xaml at master
[UWP]UIElement.Clip虽然残废,但它还可以这样玩的更多相关文章
- 原来css中的border还可以这样玩
原来css中的border还可以这样玩 前面的话: 在看这篇文章之前你可能会觉得border只是简单的绘制边框,看了这篇文章,我相信你也会跟我一样说一句"我靠,原来css中的border还可 ...
- css中的border还可以这样玩
在看这篇文章之前你可能会觉得border只是简单的绘制边框,看了这篇文章,我相信你也会跟我一样说一句"我靠,原来css中的border还可以这样玩".这篇文章主要是很早以前看了别人 ...
- 给表格设置border还可以这样玩
<table width="100%" border="0" cellpadding="0" cellspacing="1& ...
- SQL SERVER 原来还可以这样玩 FOR XML PATH
FOR XML PATH 有的人可能知道有的人可能不知道,其实它就是将查询结果集以XML形式展现,有了它我们可以简化我们的查询语句实现一些以前可能需要借助函数活存储过程来完成的工作.那么以一个实例为主 ...
- 重启Tomcat还可以这样玩的哦
- 学了java,我才发现台球还可以这样玩!
桌球小游戏的尝试 桌球是人们日常生活中都能接触到的一种娱乐活动,随着互联网技术的发展,手机上也有了很多桌球小游戏,让人们随时随地都能打两把. 今天分享一个用java编写的桌球小游戏 代码如下: ...
- 原来VIM还可以这样玩
文章目录 配置文件vimrc vim 状态栏 状态栏配置内容 状态栏常用信息 显示状态栏 终端安全色 vimrc 配置文件 推荐 vi/vim命令大全 vim参阅 配置文件vimrc 在vim文件中执 ...
- [UWP]使用CompositionGeometricClip裁剪复杂图形及进行动画
1. UWP中的其它裁剪方案 之前在 这篇文章 里,我介绍了如何使用UIElement.Clip裁剪UIElement的内容,使用代码如下: <Canvas> <Image Sour ...
- Bing Maps进阶系列六:使用Silverlight剪切(Clip)特性实现Bing Maps的迷你小地图
Bing Maps进阶系列六:使用Silverlight剪切(Clip)特性实现Bing Maps的迷你小地图 Bing Maps Silverlight Control虽然为我们提供了简洁.方面的开 ...
随机推荐
- django-模板之include标签(十五)
就是将一些常用的html代码分离出来,使其可以重复利用,减少代码量 index.html <!DOCTYPE html> <html lang="en"> ...
- 在k8s上安装Jenkins及常见问题
持续集成和部署是DevOps的重要组成部分,Jenkins是一款非常流行的持续集成和部署工具,最近试验了一下Jenkins,发现它是我一段时间以来用过的工具中最复杂的.一个可能的原因是它需要与各种其它 ...
- MySQL存储引擎简介-MyISAM和InnoDB的区别
上篇文章<MySql逻辑结构简介>我们聊到了存储引擎,可以说MySQL可插拔的多元化存储引擎给我们的使用者带来了很灵活的选择. 这篇文章我们来聊一下目前主流的两种存储引擎MyISAM和In ...
- Java 读取properties 配置文件的几种方式
基于ClassLoder读取配置文件 Properties properties = new Properties(); // 使用ClassLoader加载properties配置文件生成对应的输入 ...
- Rust 中的类型转换
1. as 运算符 as 运算符有点像 C 中的强制类型转换,区别在于,它只能用于原始类型(i32 .i64 .f32 . f64 . u8 . u32 . char 等类型),并且它是安全的. 例 ...
- Python实战练习——打印日历教程
很长一段时间没有接触过C语言了,想来做这一行当已经有三两年了. 今天突然想起来以前用C语言在VC6上写代码的日子,想了想以前的一些实战练习. 所以今天打算用Python来写一个C语言以前练习的题目-日 ...
- mysql设计规范二
一.基本规范 必须使用InnoDB存储引擎 必须使用UTF8字符集 数据表.数据字段必须加入中文注释 二.设计规范 库名称.表名称.字段名称必须使用小写,最好不要使用驼峰式,使用“_”区分,例如use ...
- [考试反思]1028csp-s模拟测试91:预估
这一轮是要闹哪样啊???前十都死活进不去??? 能不能不要到联赛前突然连续掉链子啊!!! 总算难得的切掉了T1.然后又一次把T2和T3的难度估反了 结果给T2剩下了30分钟,想到正解来不及打了. 然后 ...
- CF480E Parking Lot(单调队列+dp然鹅并不是优化)
(全英文题面所以直接放化简题意) 题意:在一个二维平面内,初始有一些点,然后每个时间点加入一些点,对每个时间点求平面内最大的无障碍正方形 (这次的题目是真的神仙啊...) 首先,考虑暴力,如果对每一个 ...
- Html5在网页中引入视频音频的方法
1.<video> 标签定义视频,比如电影片段或其他视频流. 一段简单的 HTML5 视频: <video src="movie.ogg" controls=&q ...