/// <summary> /// Moves the deep zoom image if the mouse is down. /// </summary> /// <param name="sender">The Deep Zoom viewer.</param> /// <param name="e">Mouse Event Args.</param> private void DeepZoomViewer_MouseMove(object sender, MouseEventArgs e) { if (this.isMouseDown && (Math.Abs(e.GetPosition(this.multiScaleImage).X - this.lastMousePos.X) > 5 || Math.Abs(e.GetPosition(this.multiScaleImage).Y - this.lastMousePos.Y) > 5)) { this.isDragging = true; } this.lastMousePos = e.GetPosition(this.multiScaleImage); Point logicalPosition = this.multiScaleImage.ElementToLogicalPoint(this.lastMousePos); this.currentSubImageUnderMouse = null; foreach (MultiScaleSubImage image in this.multiScaleImage.SubImages) { if (GetLogicalSubImageRect(image).Contains(logicalPosition)) { this.currentSubImageUnderMouse = image; } } if (this.isDragging) { this.Move(this.lastMousePos); } }
/// <summary> /// Moves the image about a point. /// </summary> /// <param name="focalPoint">The point to move to.</param> private void Move(Point focalPoint) { this.focusedSubImage = null; Point newOrigin = new Point(); newOrigin.X = this.currentPosition.X - (((focalPoint.X - this.dragOffset.X) / this.multiScaleImage.ActualWidth) * this.multiScaleImage.ViewportWidth); newOrigin.Y = this.currentPosition.Y - (((focalPoint.Y - this.dragOffset.Y) / this.multiScaleImage.ActualHeight) * this.multiScaleImage.ViewportWidth); this.multiScaleImage.ViewportOrigin = newOrigin; }
/// <summary> /// Zooms in around a point. /// </summary> /// <param name="zoomFactor">The level to zoom.</param> /// <param name="mousePosition">The mouse position in the image.</param> private void Zoom(double zoomFactor, Point mousePosition) { this.focusedSubImage = null; double newZoomLevel = Math.Min(this.zoomMax, Math.Max(this.zoomMin, this.zoomLevel * zoomFactor)); double newZoomFactor = newZoomLevel / this.zoomLevel; this.zoomLevel = newZoomLevel; Point point = this.multiScaleImage.ElementToLogicalPoint(mousePosition); this.multiScaleImage.ZoomAboutLogicalPoint(newZoomFactor, point.X, point.Y); }
/// <summary> /// Perform a hit test on the sub image. /// </summary> /// <param name="subimage">The sub image.</param> private bool HitTest(MultiScaleSubImage subImage) { //ViewportWitdh determines how large the sub image is. //Calculate the width and height of the sub image when its ViewportWidth is 1. That is, the original size. When you zoom out, ViewportWidth will increase, and when you zoom in, ViewportWidth will decrease. double width = this.msi.ActualWidth / (this.msi.ViewportWidth * subImage.ViewportWidth); //There's no ViewportHeight property. It is calculated by ViewportWidth * AspectRatio. double height = this.msi.ActualWidth / (this.msi.ViewportWidth * subImage.ViewportWidth * subImage.AspectRatio); //ViewportOrigin determines where the image is. Note the coordinate is always 0 or negative. Together with ViewportWidth, we can find the top left point of the sub image. Point topLeft = this.msi.LogicalToElementPoint(new Point(-subImage.ViewportOrigin.X / subImage.ViewportWidth, -subImage.ViewportOrigin.Y / subImage.ViewportWidth) ); Rect rect = new Rect(topLeft.X, topLeft.Y, width, height); //Hit. if (rect.Contains(_lastMousePos)) { return(true); } return(false); }
/// <summary> /// Displays a focal point. /// </summary> /// <param name="subImage">The source subimage.</param> /// <param name="focalPoint">The focal point rect.</param> private void DisplayFocalPoint(MultiScaleSubImage subImage, FocalPoint focalPoint) { if (focalPoint == null) { return; } Rect subImageLogicalRect = GetLogicalSubImageRect(subImage); Rect focalPointDisplayRect = new Rect( subImageLogicalRect.X + (subImageLogicalRect.Width * focalPoint.Area.X), subImageLogicalRect.Y + (subImageLogicalRect.Height * focalPoint.Area.Y), subImageLogicalRect.Width * focalPoint.Area.Width, subImageLogicalRect.Height * focalPoint.Area.Height); double width = focalPointDisplayRect.Width; Point origin = new Point(focalPointDisplayRect.Left, focalPointDisplayRect.Top); double focalPointAspectRatio = focalPointDisplayRect.Width / focalPointDisplayRect.Height; double num2 = this.multiScaleImage.ActualWidth / this.multiScaleImage.ActualHeight; if (num2 > focalPointAspectRatio) { width = (num2 / focalPointAspectRatio) * focalPointDisplayRect.Width; origin.X += (focalPointDisplayRect.Width - width) / 2.0; } else { double num3 = (focalPointAspectRatio / num2) * focalPointDisplayRect.Height; origin.Y += (focalPointDisplayRect.Height - num3) / 2.0; } this.CalculateAspectRation(1.3, ref width, ref origin); focalPointDisplayRect.X = origin.X; focalPointDisplayRect.Y = origin.Y; focalPointDisplayRect.Width = width; this.multiScaleImage.ViewportOrigin = new Point(focalPointDisplayRect.Left, focalPointDisplayRect.Top); this.multiScaleImage.ViewportWidth = focalPointDisplayRect.Width; this.zoomLevel = this.defaultWidth / focalPointDisplayRect.Width; }
/// <summary> /// Display the tag for a sub image that hit tested. /// </summary> private void HitTestImage() { for (int i = 0; i < this.msi.SubImages.Count; i++) { MultiScaleSubImage subImage = this.msi.SubImages[i]; if (HitTest(subImage)) { //ZOrder starts from 1 rather than 0. ImageMetadata metadata = this._imageMetadatas[i + 1]; ConversationControl conversationControl = this._conversations[i + 1]; Point topLeft = this.msi.LogicalToElementPoint(new Point(-subImage.ViewportOrigin.X / subImage.ViewportWidth, -subImage.ViewportOrigin.Y / subImage.ViewportWidth + 1 / subImage.ViewportWidth / subImage.AspectRatio)); conversationControl.translate.X = topLeft.X; conversationControl.translate.Y = topLeft.Y; conversationControl.Visibility = Visibility.Visible; } else { ConversationControl conversationControl = this._conversations[i + 1]; conversationControl.Visibility = Visibility.Collapsed; } } }
private static void AnimateImage(MultiScaleSubImage currentImage, Point futurePosition, Storyboard _moveStoryboard) { // Create Keyframe SplinePointKeyFrame endKeyframe = new SplinePointKeyFrame(); endKeyframe.Value = futurePosition; endKeyframe.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1)); KeySpline ks = new KeySpline(); ks.ControlPoint1 = new Point(0, 1); ks.ControlPoint2 = new Point(1, 1); endKeyframe.KeySpline = ks; // Create Animation PointAnimationUsingKeyFrames moveAnimation = new PointAnimationUsingKeyFrames(); moveAnimation.KeyFrames.Add(endKeyframe); Storyboard.SetTarget(moveAnimation, currentImage); Storyboard.SetTargetProperty(moveAnimation, new PropertyPath("ViewportOrigin")); _moveStoryboard.Children.Add(moveAnimation); }
/// <summary> /// Returns the control to the home view. /// </summary> private void GoHome() { this.focusedSubImage = null; this.multiScaleImage.ViewportWidth = this.defaultWidth; this.multiScaleImage.ViewportOrigin = new Point(0, 0); }
/// <summary> /// Gets the logical rect around a sub image. /// </summary> /// <param name="subImage">The sub image to get the rect for.</param> /// <returns>A rect around the sub image.</returns> private static Rect GetLogicalSubImageRect(MultiScaleSubImage subImage) { return(new Rect(subImage.ViewportOrigin.X / -subImage.ViewportWidth, subImage.ViewportOrigin.Y / -subImage.ViewportWidth, 1.0 / subImage.ViewportWidth, 1.0 / (subImage.ViewportWidth * subImage.AspectRatio))); }
internal SubImage(MultiScaleSubImage image) { // Capture the normalized size of each image (fixed height of 1) // This normalization is required since we want the height of all images to be the same but the widths can differ _imageSize.Width = image.AspectRatio; }
/// <summary> /// Displays a focal point. /// </summary> /// <param name="subImage">The source subimage.</param> /// <param name="focalPoint">The focal point rect.</param> private void DisplayFocalPoint(MultiScaleSubImage subImage, Rect focalPoint) { this.focusedSubImage = subImage; Rect subImageLogicalRect = GetLogicalSubImageRect(subImage); Rect focalPointDisplayRect = new Rect( subImageLogicalRect.X + (subImageLogicalRect.Width * focalPoint.X), subImageLogicalRect.Y + (subImageLogicalRect.Height * focalPoint.Y), subImageLogicalRect.Width * focalPoint.Width, subImageLogicalRect.Height * focalPoint.Height); double width = focalPointDisplayRect.Width; Point origin = new Point(focalPointDisplayRect.Left, focalPointDisplayRect.Top); double focalPointAspectRatio = focalPointDisplayRect.Width / focalPointDisplayRect.Height; double num2 = this.multiScaleImage.ActualWidth / this.multiScaleImage.ActualHeight; if (num2 > focalPointAspectRatio) { width = (num2 / focalPointAspectRatio) * focalPointDisplayRect.Width; origin.X += (focalPointDisplayRect.Width - width) / 2.0; } else { double num3 = (focalPointAspectRatio / num2) * focalPointDisplayRect.Height; origin.Y += (focalPointDisplayRect.Height - num3) / 2.0; } this.CalculateAspectRation(1.3, ref width, ref origin); focalPointDisplayRect.X = origin.X; focalPointDisplayRect.Y = origin.Y; focalPointDisplayRect.Width = width; this.multiScaleImage.ViewportOrigin = new Point(focalPointDisplayRect.Left, focalPointDisplayRect.Top); this.multiScaleImage.ViewportWidth = focalPointDisplayRect.Width; this.zoomLevel = this.defaultWidth / focalPointDisplayRect.Width; }
/// <summary> /// Gets the logical rect around a sub image. /// </summary> /// <param name="subImage">The sub image to get the rect for.</param> /// <returns>A rect around the sub image.</returns> private static Rect GetLogicalSubImageRect(MultiScaleSubImage subImage) { return new Rect(subImage.ViewportOrigin.X / -subImage.ViewportWidth, subImage.ViewportOrigin.Y / -subImage.ViewportWidth, 1.0 / subImage.ViewportWidth, 1.0 / (subImage.ViewportWidth * subImage.AspectRatio)); }