“请问,WPF如何进行缩放?”
“ 问题源于今天一个QQ群的提问,目的是希望对图片进行放大和缩小,类似地图缩放那样。很简单的一个需求,立刻给出了方案:“Viewbox就是干这活儿的”,“用变换ScaleTransform”,到底怎么实现呢?”
印象中我好似做过类似功能,所以不假思索的给出了第二个方法,即ScaleTransform。下面就针对此问题,来复习下Viewbox和变换类ScaleTransform的使用场景,并给出一种实现方式。
01 Viewbox
Viewbox与border类似,可以接受一个子元素,并对子元素进行缩放。Viewbox较多的应用场景是对形状进行缩放处理,例如在Canvas面板中绘制了Ellipse椭圆,当Viewbox的size变化时,椭圆能够跟随变化。而绘制形状具有精确的坐标,即形状是具有固定的大小。如果没有Viewbox,形状的尺寸是不会跟随变化的。
上图中,左侧的圆形在Viewbox下,会随着窗体的大小变化而变化,而右侧在窗体变化时,并不会自动改变。由此可以看到,Viewbox在自身size变化时,会按照比例对子元素进行缩放。
<Viewbox Grid.Column="0">
<Canvas Height="100" Width="100">
<Ellipse Height="35.623" Canvas.Left="23.335" Stroke="Black" Canvas.Top="26.3" Width="35.456">
<Ellipse.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FF68FA4B" Offset="1"/>
LinearGradientBrush>
Ellipse.Fill>
Ellipse>
<Label Content="With Viewbox"/>
Canvas>
Viewbox>
<Canvas Grid.Column="1">
<Ellipse Height="100" Canvas.Left="53.735" Stroke="Black" Canvas.Top="95.9" Width="100">
<Ellipse.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FF68FA4B" Offset="1"/>
LinearGradientBrush>
Ellipse.Fill>
Ellipse>
<Label Content="Without Viewbox" Canvas.Left="44.458" Canvas.Top="44"/>
Canvas>
需要注意的是,viewbox的子元素必须具有显式的size,否则不显示。
02 Transform
每个控件都具有RenderTransform属性,其作用是通过改变控件的坐标系统来使外观发生变化,例如平移、翻转、倾斜、缩放等。与动画结合,可以实现很多常见效果,例如加载动画,如下图中所示,通过绘制ellipse和控制rotatetransform动画,并控制ellipse的可见性即可实现。
Image控件自然也具有这个属性。通过改变image的ScaleTransform就可以实现对图片的缩放。
<Image.RenderTransform>
<ScaleTransform x:Name="zoom" ScaleX="1" ScaleY="1"/>
Image.RenderTransform>
最后总结,viewbox主要用来对其子元素进行缩放,在自身大小变化时,子元素能够跟随变换,子元素通常来放置绘制元素。Transform通过改变坐标系统来改变元素的位置等属性。
回到最初的问题,需求是图片能够像手机地图那样进行放大和缩小,那么图片的缩放显然改变ScaleTransform的ScaleX和ScaleY就可以实现了。
很多图片是从Nasa官网上下载下来的,宇宙是多么的深邃、奥妙,值得去深入探索。有兴趣的可以去看一看。
https://www.nasa.gov/topics/earth/images/index.html