silverlight 中 MultiScaleImage 与 Canvas绑定

silverlight 中 MultiScaleImage 与 Canvas绑定,第1张

概述1  from http://jimlynn.wordpress.com/2009/09/17/scale-other-content-on-top-of-a-deep-zoom-image/ Marthinus asked, in a comment: “is there ANY way to overwrite this, so that I can make the msi use a mu

1  from http://jimlynn.wordpress.com/2009/09/17/scale-other-content-on-top-of-a-deep-zoom-image/

Marthinus asked,in a comment:

“is there ANY way to overwrite this,so that I can make the msi use a multiscalesubimage WITH an extra canvas ontop (which would then move and scale WITH the subimage)?”

Now,I’ve never done overlays with collections and sub-images,and one thing you definitely can’t do is interleave other content with subimages of a deep zoom image (since the MultiScaleImage is a single UI element). But I have done things which have locked an overlay panel to the movement of the MultiScaleImage. Here’s a sample. First,the Xaml.

<UserControl x:Class="DeepZoomCanvas.MainPage"
 xmlns=" http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x=" http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:d=" http://schemas.microsoft.com/expression/blend/2008" xmlns:mc=" http://schemas.openxmlformats.org/markup-compatibility/2006"
 mc:Ignorable="d" d:DesignWIDth="640" d:DesignHeight="480">
 <GrID x:name="LayoutRoot">
 <MultiScaleImage x:name="msi" Source=" http://www.uslot.com/ClientBin/dzc_output.xml"/>
 <GrID
 IsHitTestVisible="False"
 x:name="overlay">
 <GrID.Rendertransform>
 <transformGroup>
 <Scaletransform x:name="overlayScale"/>
 <Translatetransform x:name="overlayTranslate"/>
 </transformGroup>
 </GrID.Rendertransform>
 <border
 CornerRadius="8"
 Background="#44FFFFFF"
 VerticalAlignment="Center"
 HorizontalAlignment="Center"
 padding="30">
 <StackPanel>
 <TextBlock
 FontFamily="Arial"
 FontSize="24"
 MaxWIDth="400"
 FontWeight="Bold"
 textwrapPing="Wrap">
 This shows some elements which
 scale and translate locked to
 the underlying MultiScaleImage.
 Any layout items can be used here.
 </TextBlock>
 <border Background="#55FF0000" padding="10" HorizontalAlignment="Center" VerticalAlignment="top">
 <StackPanel>
 <TextBlock
 FontFamily="Arial"
 FontSize="0.1"
 >This is a tiny line of text which still scales in concert with the deep zoom image.</TextBlock>
 </StackPanel>
 </border>
 </StackPanel>
 </border>
 </GrID>
 </GrID>
</UserControl>
01 <UserControl x:Class="DeepZoomCanvas.MainPage"
02  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
03  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
04  xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
05  mc:Ignorable="d" d:DesignWIDth="640" d:DesignHeight="480">
06  <GrID x:name="LayoutRoot">
07  <MultiScaleImage x:name="msi" Source="http://www.uslot.com/ClientBin/dzc_output.xml"/>
08  <GrID
09  IsHitTestVisible="False"
10  x:name="overlay">
11  <GrID.Rendertransform>
12  <transformGroup>
13  <Scaletransform x:name="overlayScale"/>
14  <Translatetransform x:name="overlayTranslate"/>
15  </transformGroup>
16  </GrID.Rendertransform>
17  <border
18  CornerRadius="8"
19  Background="#44FFFFFF"
20  VerticalAlignment="Center"
21  HorizontalAlignment="Center"
22  padding="30">
23  <StackPanel>
24  <TextBlock
25  FontFamily="Arial"
26  FontSize="24"
27  MaxWIDth="400"
28  FontWeight="Bold"
29  textwrapPing="Wrap">
30  This shows some elements which
31  scale and translate locked to
32  the underlying MultiScaleImage.
33  Any layout items can be used here.
34  </TextBlock>
35  <border Background="#55FF0000" padding="10" HorizontalAlignment="Center" VerticalAlignment="top">
36  <StackPanel>
37  <TextBlock
38  FontFamily="Arial"
39  FontSize="0.1"
40  >This is a tiny line of text which still scales in concert with the deep zoom image.</TextBlock>
41  </StackPanel>
42  </border>
43  </StackPanel>
44  </border>
45  </GrID>
46  </GrID>
47 </UserControl>

And the corresponding C# code:

 
using System;using System.Collections.Generic;using System.linq;using System.Net;using System.windows;using System.windows.Controls;using System.windows.documents;using System.windows.input;using System.windows.Media;using System.windows.Media.Animation;using System.windows.Shapes;namespace DeepZoomCanvas{ public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); msi.MouseleftbuttonDown += new MousebuttonEventHandler(msi_MouseleftbuttonDown); msi.MouseMove += new MouseEventHandler(msi_MouseMove); msi.MouseleftbuttonUp += new MousebuttonEventHandler(msi_MouseleftbuttonUp); msi.MouseWheel += new MouseWheelEventHandler(msi_MouseWheel); // Track changes to the multi scale image msi.VIEwportChanged += new RoutedEventHandler(msi_VIEwportChanged); } /// <summary> /// This is the code which locks the overlay to the underlying deep zoom image. /// All it really does is set the scale factor and offset of the overlay /// based on the current setting of the deep zoom image. /// </summary> ///<param name="sender">event sender</param> ///<param name="e">event args</param> voID msi_VIEwportChanged(object sender,RoutedEventArgs e) { // This event is called during animations of the image. // Match the scaling of the canvas with the image Point vIEwportOrigin = msi.VIEwportOrigin; double vIEwportWIDth = msi.VIEwportWIDth; // The scale factor is just the inverse of the VIEwportWIDth overlayScale.ScaleX = 1 / vIEwportWIDth; overlayScale.ScaleY = 1 / vIEwportWIDth; // The offset is calculated by finding the location of the origin of the dzi // in element coordinates. Point newO = LogicaltoElement(new Point(),vIEwportOrigin,vIEwportWIDth); overlayTranslate.X = newO.X; overlayTranslate.Y = newO.Y; } private Point LogicaltoElement(Point p,Point Origin,double WIDth) { return new Point(((p.X - Origin.X) / WIDth) * msi.ActualWIDth,((p.Y - Origin.Y) / WIDth) * msi.ActualWIDth); } public Point ElementTological(Point p,double WIDth) { return new Point(Origin.X + (p.X * WIDth) / msi.ActualWIDth,Origin.Y + (p.Y * WIDth) / msi.ActualWIDth); }#region Mouse handling voID msi_MouseWheel(object sender,MouseWheelEventArgs e) { if (e.Delta < 0) { Point logicalPoint = msi.ElementTologicalPoint(lastMousePos); msi.ZoomAboutLogicalPoint(0.8,logicalPoint.X,logicalPoint.Y); } else { Point logicalPoint = msi.ElementTologicalPoint(lastMousePos); msi.ZoomAboutLogicalPoint(1.2,logicalPoint.Y); } } voID msi_MouseleftbuttonUp(object sender,MousebuttonEventArgs e) { if (IsMouseDown) { msi.ReleaseMouseCapture(); if (IsDrag == false) { if ((Keyboard.ModifIErs & ModifIErKeys.Control) == ModifIErKeys.Control) { Point logicalPoint = msi.ElementTologicalPoint(lastMousePos); msi.ZoomAboutLogicalPoint(0.8,logicalPoint.Y); } else { Point logicalPoint = msi.ElementTologicalPoint(lastMousePos); msi.ZoomAboutLogicalPoint(1.2,logicalPoint.Y); } } IsMouseDown = false; IsDrag = false; } } voID msi_MouseMove(object sender,MouseEventArgs e) { lastMousePos = e.Get@R_419_4612@(msi); if (IsMouseDown) { IsDrag = true; } if (IsDrag) { Point newPoint = lastMouseVIEwPort; newPoint.X += (lastMouseDownPos.X - lastMousePos.X) / msi.ActualWIDth * msi.VIEwportWIDth; newPoint.Y += (lastMouseDownPos.Y - lastMousePos.Y) / msi.ActualWIDth * msi.VIEwportWIDth; msi.VIEwportOrigin = newPoint; } } bool IsMouseDown = false; bool IsDrag = false; private Point lastMouseDownPos = new Point(); private Point lastMouseVIEwPort = new Point(); private Point lastMousePos = new Point(); voID msi_MouseleftbuttonDown(object sender,MousebuttonEventArgs e) { IsMouseDown = true; msi.CaptureMouse(); lastMouseDownPos = e.Get@R_419_4612@(msi); lastMouseVIEwPort = msi.VIEwportOrigin; } #endregion     }}
001 using System;
002 using System.Collections.Generic;
003 using System.linq;
004 using System.Net;
005 using System.windows;
006 using System.windows.Controls;
007 using System.windows.documents;
008 using System.windows.input;
009 using System.windows.Media;
010 using System.windows.Media.Animation;
011 using System.windows.Shapes;
012   
013 namespace DeepZoomCanvas
014 {
015  public partial class MainPage : UserControl
016  {
017  public MainPage()
018  {
019  InitializeComponent();
020  msi.MouseleftbuttonDown += new MousebuttonEventHandler(msi_MouseleftbuttonDown);
021  msi.MouseMove += new MouseEventHandler(msi_MouseMove);
022  msi.MouseleftbuttonUp += new MousebuttonEventHandler(msi_MouseleftbuttonUp);
023  msi.MouseWheel += new MouseWheelEventHandler(msi_MouseWheel);
024   
025  // Track changes to the multi scale image
026  msi.VIEwportChanged += new RoutedEventHandler(msi_VIEwportChanged);
027  }
028   
029  /// <summary>
030  /// This is the code which locks the overlay to the underlying deep zoom image.
031  /// All it really does is set the scale factor and offset of the overlay
032  /// based on the current setting of the deep zoom image.
033  /// </summary>
034  ///
035 <param name="sender">event sender</param>
036  ///
037 <param name="e">event args</param>
038  voID msi_VIEwportChanged(object sender,RoutedEventArgs e)
039  {
040  // This event is called during animations of the image.
041  // Match the scaling of the canvas with the image
042  Point vIEwportOrigin = msi.VIEwportOrigin;
043  double vIEwportWIDth = msi.VIEwportWIDth;
044   
045  // The scale factor is just the inverse of the VIEwportWIDth
046  overlayScale.ScaleX = 1 / vIEwportWIDth;
047  overlayScale.ScaleY = 1 / vIEwportWIDth;
048   
049  // The offset is calculated by finding the location of the origin of the dzi
050  // in element coordinates.
051  Point newO = LogicaltoElement(new Point(),vIEwportWIDth);
052  overlayTranslate.X = newO.X;
053  overlayTranslate.Y = newO.Y;
054  }
055   
056  private Point LogicaltoElement(Point p,double WIDth)
057  {
058  return new Point(((p.X - Origin.X) / WIDth) * msi.ActualWIDth,
059  ((p.Y - Origin.Y) / WIDth) * msi.ActualWIDth);
060  }
061   
062  public Point ElementTological(Point p,double WIDth)
063  {
064  return new Point(Origin.X + (p.X * WIDth) / msi.ActualWIDth,
065  Origin.Y + (p.Y * WIDth) / msi.ActualWIDth);
066  }
067   
068 #region Mouse handling
069  voID msi_MouseWheel(object sender,MouseWheelEventArgs e)
070  {
071  if (e.Delta < 0)
072  {
073  Point logicalPoint = msi.ElementTologicalPoint(lastMousePos);
074  msi.ZoomAboutLogicalPoint(0.8,logicalPoint.Y);
075   
076  }
077  else
078  {
079  Point logicalPoint = msi.ElementTologicalPoint(lastMousePos);
080  msi.ZoomAboutLogicalPoint(1.2,logicalPoint.Y);
081  }
082  }
083   
084  voID msi_MouseleftbuttonUp(object sender,MousebuttonEventArgs e)
085  {
086  if (IsMouseDown)
087  {
088  msi.ReleaseMouseCapture();
089  if (IsDrag == false)
090  {
091  if ((Keyboard.ModifIErs & ModifIErKeys.Control) == ModifIErKeys.Control)
092  {
093  Point logicalPoint = msi.ElementTologicalPoint(lastMousePos);
094  msi.ZoomAboutLogicalPoint(0.8,logicalPoint.Y);
095  }
096  else
097  {
098  Point logicalPoint = msi.ElementTologicalPoint(lastMousePos);
099  msi.ZoomAboutLogicalPoint(1.2,logicalPoint.Y);
100  }
101  }
102  IsMouseDown = false;
103  IsDrag = false;
104  }
105  }
106   
107  voID msi_MouseMove(object sender,MouseEventArgs e)
108  {
109  lastMousePos = e.Get@R_419_4612@(msi);
110  if (IsMouseDown)
111  {
112  IsDrag = true;
113  }
114  if (IsDrag)
115  {
116  Point newPoint = lastMouseVIEwPort;
117  newPoint.X += (lastMouseDownPos.X - lastMousePos.X) / msi.ActualWIDth * msi.VIEwportWIDth;
118  newPoint.Y += (lastMouseDownPos.Y - lastMousePos.Y) / msi.ActualWIDth * msi.VIEwportWIDth;
119  msi.VIEwportOrigin = newPoint;
120  }
121  }
122   
123  bool IsMouseDown = false;
124  bool IsDrag = false;
125  private Point lastMouseDownPos = new Point();
126  private Point lastMouseVIEwPort = new Point();
127  private Point lastMousePos = new Point();
128   
129  voID msi_MouseleftbuttonDown(object sender,MousebuttonEventArgs e)
130  {
131  IsMouseDown = true;
132  msi.CaptureMouse();
133  lastMouseDownPos = e.Get@R_419_4612@(msi);
134  lastMouseVIEwPort = msi.VIEwportOrigin;
135  }
136   
137  #endregion    
138  }
139 }

All the work is done in the VIEwportChanged event handler (which fires every time the vIEwport changes,even during animations). I’ve set a scale transform and a translate transform on the grID (which Could be a canvas if you want) and we adjust the scale and translate values to match the underlying image.

All the rest of the code is just bog-standard deep zoom image mouse handling.

Try zooming into the red square to see a very small line of text.

Hope this helps.

 

 

2 From http://blogs.msdn.com/b/lutzg/archive/2008/08/19/synchronizing-images-with-the-deep-zoom-content.aspx

 

Synchronizing other content with Deep Zoom

When you set VIEwportOrigin or VIEwportWIDth (or use the ZoomAboutPoint helper),deep zoom simply kicks off an animation to the new location. This animation happens entirely under the hood and is transparent to the developer. That's very nice for the dead simple zooming application,since the developer doesn't have to worry about making pretty animations when zooming and panning. Pretty animations are built in.

However,this behavior does cause a problem if you want to make other things in Silverlight move along with zooming and panning of the Deep Zoom image.

So what's the trick? Everytime a user pans or zooms,this application sets of a 0-length-storyboard that tracks what Deep Zoom is doing,and adjust size and @R_419_4612@ for the pins. The 0-length-storyboard does its thing for 1500 ms,which is exactly the amount of time Deep Zoom allocates for each animation.

Using powerlaw scaling

Another nifty little feature that was put into this application is powerlaw scaling. The size of the pins only grows at a fraction of the rate of the rest of the map. This needs to be done,since if the size of the pins is kept constant,our eyes fall victim to an optical illusion: when zooming in,the pins would look like they are shrinking,and when zooming out,the appear to be growing.Power-law scaling makes this visual effect much less noticeable.

总结

以上是内存溢出为你收集整理的silverlight 中 MultiScaleImage 与 Canvas绑定全部内容,希望文章能够帮你解决silverlight 中 MultiScaleImage 与 Canvas绑定所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1024134.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存