知乎周源微信_每周源代码18-深度缩放(Seadragon)Silverlight 2 MultiScaleImage鼠标滚轮缩放和平移版...

知乎周源微信

知乎周源微信

Dear Reader, I present to you eighteenth in a infinite number of posts of "The Weekly Source Code." Here's some source I was reading - and writing - this week at Mix.

尊敬的读者,我每周源代码的无数帖子中向您介绍了第十八篇。 这是我本周在Mix上阅读和写作的一些资料。

I have been checking out Deep Zoom in Silverlight 2, but I thought it was a bummer that there wasn't (yet) a "Hello DeepZoom World!" example that includes panning, zooming (mouse wheel) support out of the box. The Vertigo example behaves exactly as I'd want my stuff to behave. You can see my working Deep Zoom example here or by clicking the picture at right.

我一直在检查Silverlight 2中的Deep Zoom ,但我认为还没有“ Hello DeepZoom World! 开箱即用的平移,缩放(鼠标滚轮)支持示例。 Vertigo示例的行为与我希望我的东西行为完全一样。 您可以在此处或单击右侧的图片来查看我正在工作的Deep Zoom示例

Adding Mouse Wheel support to Silverlight can happen a couple of ways. Mouse Wheel events are sourced by the browser, not by Silverlight itself (which is the way you'd want it as Silverlight lives inside the browser, it shouldn't replace its behaviors, IMHO).

向Silverlight添加鼠标滚轮支持可以通过两种方式进行。 鼠标滚轮事件是由浏览器的来源,而不是本身的Silverlight(这是你想把它当作生活的Silverlight浏览器的方式,它不能代替自己的行为,恕我直言)

So, you could use the Javascript code from Adomas along with the work that Jeff Prosise did to reach into Silverlight and call methods. The events would be handled in JavaScript and the Zoom method would be called via JavaScript over the bridge into Silverlight managed code.

因此,您可以将Adomas的Javascript代码Jeff Prosise所做的工作结合使用,以达到Silverlight和调用方法的目的。 这些事件将用JavaScript处理,并且Zoom方法将通过JavaScript在跨入Silverlight托管代码的桥上进行调用。

However, you can also reach out from inside managed code and set managed handlers for DOM (JavaScript events) like Pete Blois does with his Mouse Wheel Helper class. I use this class directly by downloading it from Pete's blog and adding it to my project. This is significant because it doesn't require ANY external JavaScript files. All the events are handled by managed code.

但是,您也可以像在Pete Blois的Mouse Wheel Helper类中那样,从托管代码内部访问并设置DOM(JavaScript事件)的托管处理程序。 我可以通过从Pete的博客中下载该类并将其添加到我的项目中来直接使用该类。 这很重要,因为它不需要任何外部JavaScript文件。 所有事件均由托管代码处理。

if (HtmlPage.IsEnabled) {
  HtmlPage.Window.AttachEvent("DOMMouseScroll", this.HandleMouseWheel);
  HtmlPage.Window.AttachEvent("onmousewheel", this.HandleMouseWheel);
  HtmlPage.Document.AttachEvent("onmousewheel", this.HandleMouseWheel);
}

I took this along with snippets from Yasser Makram and John posting in Yasser's blog's comments got me mostly what I needed.

我将其与Yasser Makram的片段以及John在Yasser博客的评论中发布的片段一起带给了我所需的大部分东西。

I've seen some basic examples using either mouse clicking or key-downs to get the zooming effect, but I wanted to support mouse wheel events as well, just like the stuff shown off at Mix.

我已经看到了一些使用鼠标单击或按下键盘来获得缩放效果的基本示例,但是我也想支持鼠标滚轮事件,就像Mix上展示的内容一样。

This more complete example gives you:

这个更完整的示例为您提供:

  • Drag to pan

    拖动以平移
  • Click to zoom in, Shift Click to zoom out

    单击以放大,Shift单击以缩小
  • Mouse wheel to zoom in and out

    鼠标滚轮可放大和缩小
  • No JavaScript dependency at all - everything is in managed code.

    完全没有JavaScript依赖性-一切都在托管代码中。

First, start with the output of the DeepZoom composer (I just used the Windows Wallpapers I had on this machine to compose a DeepZoom image in the editor) and copy the resulting exported folder structure somewhere (I put it under bin/debug for ease, but you can put it wherever as long as the source attribute lines up in your XAML:

首先,从DeepZoom编写器的输出开始(我只是使用这台计算机上的Windows墙纸在编辑器中合成了DeepZoom图像),然后将生成的导出文件夹结构复制到某处(为方便起见,将其放在bin / debug下,但您可以将其放在XAML中,只要将source属性排成一行即可:

<UserControl
	xmlns="http://schemas.microsoft.com/client/2007"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	x:Class="SilverlightApplication1.Page"
	Width="800" Height="600" >
  <Grid
    x:Name="LayoutRoot"
    Background="Gray">
    <MultiScaleImage 
      x:Name="msi"
      ViewportWidth="1.0"
      Source="http://www.yourdomain.com/foo/items.bin" />
  </Grid>
</UserControl>

RANDOM NOTE: Here's a cool switch you can set on MultiScaleImage. It's UseSprings="false" and it'll turn off the zooming animation. Why would you want to do this?  Well, that very zoom-in/zoom-out animation gives DeepZoom an opportunity to perform its "visual slight of hand" and transition between images. When the animation happens, you are less likely to notice the transition between tiles (a good thing). Of course, I want to get my head around how it all works so I liked seeing the transitions.

随机注意:这是一个很酷的开关,您可以在MultiScaleImage上进行设置。 它是UseSprings =“ false”,它将关闭缩放动画。 你为什么想做这个? 好吧,非常放大/缩小的动画使DeepZoom有机会执行其“视觉效果”并在图像之间进行过渡。 动画发生时,您不太可能注意到图块之间的过渡(一件好事)。 当然,我想了解所有工作原理,因此我喜欢看到过渡。

Keep in mind it's four in the morning, so this code is a little wonky and not at all thought-out and I've only been at it for an hour. I'm REALLY interested in what you, Dear Reader, can do with it and make it better so we all have a canonical example to start from. This is NOT that example, I'm actually kind of reticent to post it here because it's so hacked together, but that's half the fun, right? It works OK, I think.

请记住,现在是凌晨四点,所以这段代码有点古怪,根本没有考虑过,而我只花了一个小时。 亲爱的读者,我真的对您的功能感兴趣,并希望它做得更好,所以我们都有一个典范的例子。 这不是那个例子,实际上我不太愿意在这里发布它,因为它被黑了,但这只是乐趣的一半,对吗? 我认为它可以正常工作。

One thing to point out, note that the name of the control is "msi," set in the XAML above via x:name="msi" so you'll see me referencing properties like msi.thisandthat in the managed XAML code-behind below. Also, the "using akadia" below is Pete's MouseHandler code's namespace referenced from my page.

需要指出的一件事,请注意,控件的名称是“ msi”,它是通过x:name =“ msi”在上面的XAML中设置的,因此您将看到我引用了诸如msi.this之类的属性,并且该属性在托管的XAML代码背后下面。 另外,下面的“ using akadia”是从我的页面引用的Pete的MouseHandler代码的名称空间。

My code hooks up a bunch of events from the constructor using anonymous delegates, and those work together to call a single Zoom() helper method.

我的代码使用匿名委托从构造函数中连接了一堆事件,这些事件一起工作以调用单个Zoom()帮助器方法。

using System; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Documents; 
using System.Windows.Ink; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Animation; 
using System.Windows.Shapes; 
using System.Windows.Threading; 
using akadia; 

namespace SilverlightApplication1 
{ 
    public partial class Page : UserControl 
    { 
        Point lastMousePos = new Point(); 
        double _zoom = 1; 
        bool mouseButtonPressed = false; 
        bool mouseIsDragging = false; 
        Point dragOffset; 
        Point currentPosition; 

        public double ZoomFactor 
        { 
            get { return _zoom; } 
            set { _zoom = value; } 
        } 

        public Page() 
        { 
            this.InitializeComponent(); 

            this.MouseMove += delegate(object sender, MouseEventArgs e) 
            { 
                if (mouseButtonPressed) 
                { 
                    mouseIsDragging = true; 
                } 
                this.lastMousePos = e.GetPosition(this.msi);   
            }; 

            this.MouseLeftButtonDown += delegate(object sender, MouseButtonEventArgs e) 
            { 
                mouseButtonPressed = true; 
                mouseIsDragging = false; 
                dragOffset = e.GetPosition(this); 
                currentPosition = msi.ViewportOrigin; 
            }; 

            this.msi.MouseLeave += delegate(object sender, MouseEventArgs e) 
            { 
                mouseIsDragging = false; 
            }; 

            this.MouseLeftButtonUp += delegate(object sender, MouseButtonEventArgs e) 
            { 
                mouseButtonPressed = false; 
                if (mouseIsDragging == false) 
                { 
                    bool shiftDown = (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift; 

                    ZoomFactor = 2.0; 
                    if(shiftDown) ZoomFactor = 0.5; //back out when shift is down 
                    Zoom(ZoomFactor, this.lastMousePos); 
                } 
                mouseIsDragging = false; 
            }; 

            this.MouseMove += delegate(object sender, MouseEventArgs e) 
            { 
                if (mouseIsDragging) 
                { 
                    Point newOrigin = new Point(); 
                    newOrigin.X = currentPosition.X - (((e.GetPosition(msi).X - dragOffset.X) / msi.ActualWidth) * msi.ViewportWidth); 
                    newOrigin.Y = currentPosition.Y - (((e.GetPosition(msi).Y - dragOffset.Y) / msi.ActualHeight) * msi.ViewportWidth); 
                    msi.ViewportOrigin = newOrigin; 
                } 
            }; 

            new MouseWheelHelper(this).Moved += delegate(object sender, MouseWheelEventArgs e) 
            { 
                e.Handled = true; 
                if (e.Delta > 0) 
                    ZoomFactor = 1.2; 
                else 
                    ZoomFactor = .80; 

                Zoom(ZoomFactor, this.lastMousePos); 
            }; 
        } 

        public void Zoom(double zoom, Point pointToZoom) 
        { 
            Point logicalPoint = this.msi.ElementToLogicalPoint(pointToZoom); 
            this.msi.ZoomAboutLogicalPoint(zoom, logicalPoint.X, logicalPoint.Y); 
        } 
    } 
}

Three One thing I am having trouble with, but I haven't run this under a debugger yet as I haven't installed the single Silverlight 2 Beta 1 Tools Installer (Troubleshooting Silverlight 2 Beta 1 Tools Installer). I just built it in Expression Blend 2.5 and Notepad2. I was enjoying myself so much I didn't want to stop and install anything. ;)

我有麻烦的一件事,但是由于尚未安装单个Silverlight 2 Beta 1 Tools Installer (对Silverlight 2 Beta 1 Tools Installer进行故障排除) ,因此我还没有在调试器下运行它。 我刚刚在Expression Blend 2.5和Notepad2中构建了它。 我非常开心,不想停下来安装任何东西。 ;)

  • One, if you scroll WHILE the "spring zoom" animation is happening, something goes wrong and you'll continue zooming in, no matter what direction you're scrolling.

    第一,如果在“弹簧缩放”动画发生时滚动,则出问题 了,无论滚动方向如何,都将继续 放大

  • Second, more subtlety, if you scroll in, stop, then start scrolling out, it'll scroll in a step, then start scrolling out, so there's clearly a state issue I'm goofing up. Stated another way, if a managed event comes in WHILE the animation is happening, the direction it's currently zooming just keeps going. (Maybe a subtle bug, or my code needs to be debounced because it seems like the mouse wheel events are coming in too fast.) In my example, you have to let the animation "settle down" in order to zoom the other way. Of course, if you just F5 to Refresh you can get back to home and reset the zoom.

    其次,更微妙的是,如果您滚动,停止,然后开始滚动,它将逐步滚动,然后开始滚动,因此很明显存在我正在忙碌的状态问题。 换句话说,如果在动画发生时发生了托管事件,则当前缩放的方向将一直保持下去。 (也许是一个细微的错误,或者我的代码需要去抖动,因为似乎鼠标滚轮事件来的太快了。)在我的示例中,您必须让动画“停下来”以便以另一种方式缩放。 当然,如果您仅按F5即可刷新,则可以回到家中并重置缩放比例。

  • I figured it out, I was using a relative calculated ZoomFactor when I should have used an absolute factor.

    我知道了,当我应该使用绝对因子时,我正在使用相对计算的ZoomFactor。
  • Third, I want to prevent the image from panning outside the viewable area (meaning, I don't want folks to get lost) and I'd like to stop the zooming in and out at some reasonable max/min.

    第三,我想防止图像在可见区域之外平移(意味着,我不想让人们迷路),并且我想以合理的最大/最小速度停止放大和缩小。
  • Don't forget to setup .xap files as the mime type application/x-silverlight-app on on your hoster's IIS instance.

    不要忘记在主机的IIS实例上将.xap文件设置为mime类型application / x-silverlight-app

Very cool and fairly easy considering all that's going on. I'll look into other ways this can be exploited in the morning.

考虑到所有情况,这非常酷并且相当容易。 我将研究早晨可以利用的其他方式。

翻译自: https://www.hanselman.com/blog/the-weekly-source-code-18-deep-zoom-seadragon-silverlight-2-multiscaleimage-mouse-wheel-zooming-and-panning-edition

知乎周源微信

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值