The implementation functions are as follows:
- Zoom in and out image containers at the center of the scroll wheel
- Drag the enlarged image
- Control the drag range
Because different images need to be dynamically loaded in subsequent functions, this example is designed to zoom in and out the grid, and the images are automatically filled!
My mind is stupid and I use the simplest principle to implement it. The implementation principle is as follows:
1. Zoom in
Suppose we want to zoom in on the center (1.5, 1.5) point, then after doubling, it should be the position of rectangle 2, which needs to be (3, 3) to the original vertex position, you need to move the rectangle 2 up 1.5, move 1.5 to the left
Scaletransform scales up to 1 time, And translatetransform moves to (-1.5,-1.5), as shown in.
2. Move, zoom, move, and zoom
Looking at the situation: we move the rectangle 1 to the left and then enlarge it by one time.
When we click the point relative to the origin (2.5, 1.5), we actually want to enlarge the point relative to the rectangle 1 (1.5, 1.5! First, we use the inverse transformation of the Matrix to obtain the point relative to the rectangle 1. Then, the point (1.5, 1.5) of rectangle 1 is magnified by one time, and step 1 is repeated ).
Then calculate the offset distance between (2.5, 1.5) and (1.5, 1.5) after the inverse transformation, and move the translatetransform () again ). Obtain the expected rectangle 2, as shown in figure
The following is the implementation code:
At the interface layer, I use grdmapto make changes. grdmap's content is 1.jpg images (or other widgets and other elements ). Grdrelative is used as a reference object (for the origin, the original image position ). Pay attention to the Element Data Binding in it to achieve adaptive screen, with no width or height specified. Slider is usable and can be modified by yourself.
<Window x:Class="WpfMap.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid x:Name="grd"> <Grid x:Name="grdRelative" HorizontalAlignment="Center" VerticalAlignment="Center" Width="{Binding ActualWidth, ElementName=grdMap}" Height="{Binding ActualHeight, ElementName=grdMap}"></Grid> <Grid x:Name="grdMap" MouseWheel="grdMap_MouseWheel" MouseLeave="grdMap_MouseLeave" MouseDown="grdMap_MouseDown" MouseUp="grdMap_MouseUp" MouseMove="grdMap_MouseMove" HorizontalAlignment="Center" VerticalAlignment="Center" RenderTransformOrigin="0,0"> <Grid.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="{Binding Value, ElementName=slider}" ScaleY="{Binding Value, ElementName=slider}" /> <SkewTransform /> <RotateTransform /> <TranslateTransform /> </TransformGroup> </Grid.RenderTransform> <Image Source="1.jpg" /> </Grid> <Slider x:Name="slider" HorizontalAlignment="Left" VerticalAlignment="Center" Orientation="Vertical" Width="20" Height="200" Maximum="3" Minimum="1" /> </Grid></Window>
Background code:
Using system; using system. collections. generic; using system. LINQ; using system. text; using system. windows; using system. windows. controls; using system. windows. data; using system. windows. documents; using system. windows. input; using system. windows. media; using system. windows. media. imaging; using system. windows. navigation; using system. windows. shapes; namespace wpfmap {/// <summary> // mainwindow. interaction logic of XAML // </Summary> Public partial class mainwindow: window {public mainwindow () {initializecomponent (); this. loaded + = new loads (mainwindow_loaded);} scaletransform st; translatetransform tt; transformgroup group; bool isdrag = false; point startpoint; void mainwindow_loaded (Object sender, routedeventargs E) {group = (transformgroup) grdmap. rendertransform; ST = group. children [0] As scaletransform; TT = group. children [3] As translatetransform;} private void grdmap_mousewheel (Object sender, mousewheeleventargs e) {var point = E. getposition (grdrelative); // click var actualpoint = group. inverse. transform (point); // The vertex slider to be scaled. value = slider. value + (double) E. delta/1000; TT. X =-(actualpoint. x * (slider. value-1) + point. x-actualpoint. x; TT. y =-(actualpoint. y * (slider. value-1) + point. y-actualpoint. y;} private void grdmap_mousedown (Object sender, mousebuttoneventargs e) {isdrag = true; startpoint = E. getposition (grdrelative);} private void grdmap_mouseup (Object sender, mousebuttoneventargs e) {isdrag = false;} private void grdmap_mouseleave (Object sender, mouseeventargs e) {isdrag = false ;} private void grdmap_mousemove (Object sender, mouseeventargs e) {If (isdrag) {point P = E. getposition (grdrelative); point toppoint = grdmap. translatepoint (new point (0, 0), grdrelative); point bottompoint = grdmap. translatepoint (new point (grdmap. actualwidth, grdmap. actualheight), grdrelative); double movex = P. x-startpoint. x; double Movey = P. y-startpoint. y; // condition judgment for moving up and down (there will be a small offset. If you want to control it more accurately, you can split it up or down and determine the margin) if (Movey <0 & bottompoint. y> grdrelative. actualheight) | (Movey> 0 & toppoint. Y <0) {TT. Y + = (P. y-startpoint. y); startpoint. y = P. Y ;}// move the condition to the left to the right to judge if (movex <0 & bottompoint. x> grdrelative. actualwidth) | (movex> 0 & toppoint. x <0) {TT. X + = (P. x-startpoint. x); startpoint. X = P. X ;}}}}}
The code is very simple and does not write too many comments!
It takes two credits to download the Code. In fact, the above code snippet already contains all the code!
The following is the source code address, vs2010, which can be run directly!
Http://download.csdn.net/detail/wuwo333/5308725