달력

082010  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  •  
  •  
  •  
  •  
Deep Zoom 강좌 : 2. Silverlight 프로젝트 만들기

이미지 갤러리를 만들었으면 이젠 실버라이트로 Deep Zoom 프로젝트를 만들어 보도록 하겠습니다.
(깨진 이미지는 클릭하면 원본 크기로 보실수 있습니다.)

1. 실버라이트 프로젝트 생성

사용자 삽입 이미지

Visual Studio 2008을 실행시켜 [새 프로젝트]를 선택합니다. 프로젝트 형식에서 Silverlight - Silverlight Application을 선택하고, 프로젝트 이름과 위치, 솔루션 이름을 설정합니다.

사용자 삽입 이미지

실버라이트 프로젝트와 함께 만들어질 웹 프로젝트입니다. Project Type에서 Web Site 또는 Web Application 프로젝트 중 선택하면 됩니다. 전 Web Application을 사용하도록 하겠습니다.


2. 이미지 갤러리를 웹 프로젝트에 포함

사용자 삽입 이미지

새 프로젝트를 생성했으면 솔루션을 선택한 후 솔루션 빌드를 한번 해줍니다. 그러면 위 이미지를 보는거와 같이 웹프로젝트에 ClientBin 폴더가 자동 생성이됩니다.

사용자 삽입 이미지사용자 삽입 이미지

이전 첫번째 강의해서 만들어 놓은 이미지 갤러리의 폴더를 위에서 자동 생성된 ClientBin 폴더에 복사를 합니다. 그런 후 위 이미지와 같이 프로젝트에 포함을 시킵니다.

ClientBin 폴더에 이미지 갤러리가 있어야만 화면에 표시가 되니 주의하시기 바랍니다.


3. 실버라이트 프로젝트에 이미지 갤러리 포함시키기

실버라이트 프로젝트에서 Page.xaml 파일을 열어 MultiScaleImage 콘트롤을 사용하겠습니다.

<UserControl x:Class="Shblitz.DeepZoom.Page"
    xmlns="http://schemas.microsoft.com/client/2007"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <MultiScaleImage x:Name="objDeepZoom" Source="shblitz/info.bin"></MultiScaleImage>
    </Grid>
</UserControl>

Grid 콘트롤 안에 MultiScaleImage을 추가하고 이름과 소스를 지정합니다. 소스는 웹 프로젝트의 ClientBin에 포함시킨 이미지 갤러리 입니다.

이젠 다시 빌드를 해준 후 브라우저 보기로 확인을 해보도록 하겠습니다.

사용자 삽입 이미지


웹 프로젝트에서 Shblitz.DeepZoomTestPage.aspx 파일을 선택 후 마우스 오른쪽 버튼을 눌러 [브라우저에서 보기]를 선택합니다. 그러면 위와 같이 브라우저에 이미지가 나타나게 됩니다. 만약 이미지가 나오는 않는다면 소스 경로를 다시 확인해 보시기 바랍니다.

여기까지 잘 따라 오셨나요?? 여기가 끝이 아닙니다. 이미지가 확대가 되고 축소가 되고 그래야하는데 아무런 반응이 없을 것입니다. 이제부터 기능을 추가하도록 하겠습니다.


4. 기능을 추가하여 확대 / 축소 기능 사용하기
- 이 기능은 외국사이트(기억안남)에서 참고한 소스입니다.

Page.xaml 파일 소스에서 이벤트를 추가하도록 하겠습니다.

<UserControl x:Class="Shblitz.DeepZoom.Page"
    xmlns="http://schemas.microsoft.com/client/2007"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="400" Height="300"
    MouseMove="Page_MouseMove"
    MouseLeftButtonDown="Page_MouseLeftButtonDown"
    MouseLeftButtonUp="Page_MouseLeftButtonUp">
    <Grid x:Name="LayoutRoot" Background="White">
        <MultiScaleImage x:Name="objDeepZoom" Source="shblitz/info.bin" MouseLeave="objDeepZoom_MouseLeave"></MultiScaleImage>
    </Grid>
</UserControl>

UserControlMouseMove, MouseLeftButtonDown, MouseLeftButtonUp 이렇게 3개의 이벤트를 추가하고 MultiScaleImageMouseLeave를 추가합니다.

다음은 Page.xaml.cs 파일에 각 이벤트에 대한 로직을 추가합니다.

// 각 좌표를 저장할 전역 변수
Point lastMousePos = new Point();
bool mouseButtonPressed = false;
bool mouseIsDragging = false;
Point dragOffset;
Point currentPosition;
public double ZoomFactor { get; set; }

확대 / 축소 기능을 할 함수를 만들어 줍니다.

/// <summary>
/// 확대 / 축소
/// </summary>
/// <param name="zoom"></param>
/// <param name="pointToZoom"></param>
public void Zoom(double zoom, Point pointToZoom)
{
    Point logicalPoint = this.objDeepZoom.ElementToLogicalPoint(pointToZoom);
    this.objDeepZoom.ZoomAboutLogicalPoint(zoom, logicalPoint.X, logicalPoint.Y);
}

각 이벤트에 대한 로직을 작성해 줍니다.

/// <summary>
/// 마우스 클릭
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Page_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    mouseButtonPressed = true;
    mouseIsDragging = false;
    dragOffset = e.GetPosition(this);
    currentPosition = objDeepZoom.ViewportOrigin;
}
/// <summary>
/// 마우스 이동
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Page_MouseMove(object sender, MouseEventArgs e)
{
    if (mouseButtonPressed)
    {
        mouseIsDragging = true;
    }
    this.lastMousePos = e.GetPosition(this.objDeepZoom);
    if (mouseIsDragging)
    {
        Point newOrigin = new Point();
        newOrigin.X = currentPosition.X - (((e.GetPosition(objDeepZoom).X - dragOffset.X) / objDeepZoom.ActualWidth) * objDeepZoom.ViewportWidth);
        newOrigin.Y = currentPosition.Y - (((e.GetPosition(objDeepZoom).Y - dragOffset.Y) / objDeepZoom.ActualHeight) * objDeepZoom.ViewportWidth);
        objDeepZoom.ViewportOrigin = newOrigin;
    }
}
/// <summary>
/// 마우스 클릭 해제
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Page_MouseLeftButtonUp(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;
        Zoom(ZoomFactor, this.lastMousePos);
    }
    mouseIsDragging = false;
}
/// <summary>
/// 마우스 객체 읽음
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void objDeepZoom_MouseLeave(object sender, MouseEventArgs e)
{
    mouseIsDragging = false;
}

마우스 휠 기능도 사용할 수 있도록 하겠습니다.
MouseWheelHelper.cs 클래스를 하나 추가하여 아래와 같이 작성해 줍니다.

// 상단에 Browser 참조 추가
using System.Windows.Browser;

// 마우스 휠 전용 이벤트 Args 만들기
public class MouseWheelEventArgs : EventArgs
{
    private double delta;
    private bool handled = false;
    public MouseWheelEventArgs(double delta)
    {
        this.delta = delta;
    }
    public double Delta
    {
        get { return this.delta; }
    }
    // Use handled to prevent the default browser behavior!
    public bool Handled
    {
        get { return this.handled; }
        set { this.handled = value; }
    }
}

// 마우스 휠 클래스 작성
public class MouseWheelHelper
{
    public event EventHandler<MouseWheelEventArgs> Moved;
    private static Worker worker;
    private bool isMouseOver = false;
    public MouseWheelHelper(FrameworkElement element)
    {
        if (MouseWheelHelper.worker == null)
            MouseWheelHelper.worker = new Worker();
        MouseWheelHelper.worker.Moved += this.HandleMouseWheel;
        element.MouseEnter += this.HandleMouseEnter;
        element.MouseLeave += this.HandleMouseLeave;
        element.MouseMove += this.HandleMouseMove;
    }
    private void HandleMouseWheel(object sender, MouseWheelEventArgs args)
    {
        if (this.isMouseOver)
            this.Moved(this, args);
    }
    private void HandleMouseEnter(object sender, EventArgs e)
    {
        this.isMouseOver = true;
    }
    private void HandleMouseLeave(object sender, EventArgs e)
    {
        this.isMouseOver = false;
    }
    private void HandleMouseMove(object sender, EventArgs e)
    {
        this.isMouseOver = true;
    }
    private class Worker
    {
        public event EventHandler<MouseWheelEventArgs> Moved;
        public Worker()
        {
            if (HtmlPage.IsEnabled)
            {
                HtmlPage.Window.AttachEvent("DOMMouseScroll", this.HandleMouseWheel);
                HtmlPage.Window.AttachEvent("onmousewheel", this.HandleMouseWheel);
                HtmlPage.Document.AttachEvent("onmousewheel", this.HandleMouseWheel);
            }
        }
        private void HandleMouseWheel(object sender, HtmlEventArgs args)
        {
            double delta = 0;
            ScriptObject eventObj = args.EventObject;
            if (eventObj.GetProperty("wheelDelta") != null)
            {
                delta = ((double)eventObj.GetProperty("wheelDelta")) / 120;

                if (HtmlPage.Window.GetProperty("opera") != null)
                    delta = -delta;
            }
            else if (eventObj.GetProperty("detail") != null)
            {
                delta = -((double)eventObj.GetProperty("detail")) / 3;
                if (HtmlPage.BrowserInformation.UserAgent.IndexOf("Macintosh") != -1)
                    delta = delta * 3;
            }
            if (delta != 0 && this.Moved != null)
            {
                MouseWheelEventArgs wheelArgs = new MouseWheelEventArgs(delta);
                this.Moved(this, wheelArgs);
                if (wheelArgs.Handled)
                    args.PreventDefault();
            }
        }
    }
}

Page.xaml.cs 파일의 Page() 함수에 위에서 작성한 마우스 휠 기능을 추가하도록 하겠습니다.

public Page()
{
    InitializeComponent();
    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);
    };

}

휴!!~~ 모든 로직을 추가 했습니다. 이젠 다시 빌드 후 브라우저로 보시기 바랍니다.

사용자 삽입 이미지
 
오!!~~ 확대가 되었습니다.. 성공입니다.. 실패 하신분은 천천히 로직을 다시 살펴 보시기 바랍니다.

마우스 왼쪽을 클릭하면 확대, Shift 를 누르고 클릭하면 축소입니다.
그리고 휠도 위/아래 이동해 보세요!! 확대 / 축소가 됩니다.
또, 마우스 클릭 후 이동하면 중심점이 바뀌게 됩니다!!~~

프로젝트 예제 소스 :


이것으로 강좌를 마치도록 하겠습니다. 지금까지 정말 수고하셨습니다!!~~ 짝짝짝!!

작성자 : 상현넘™ [http://www.shblitz.net]
Posted by 상현넘™

댓글을 달아 주세요

  1. 슈퍼낙훈  댓글주소 수정/삭제 댓글쓰기 2008/03/11 17:20

    안녕하세요!

    정말 좋은 강좌와 소스 감사합니다~

    시간 날때 꼭 공부해 볼게요!

  2. 스페샬존  댓글주소 수정/삭제 댓글쓰기 2008/03/11 23:29

    낼름 구경 하고 갑니다~

    저도 컴퓨터 밀어버리면 그때 도전 해보도록 하겠습니다!!

  3. 요원  댓글주소 수정/삭제 댓글쓰기 2008/03/12 01:13

    ㅎㅎ 좋은글 감사해요~
    찾고있었는데.. 보고 바로 해봤어요 -_-b

    근데, 캠프에서 공도님이 3줄만에 했다는건 멀까요?;;;;

  4. 공도  댓글주소 수정/삭제 댓글쓰기 2008/03/20 10:03

    ^^ 약간의 트릭이랄까요...
    물론 내부로는 저런 로직을 넣었지만 한번 만들면 변경할 일이 없죠.
    즉, 유저 컨트롤을 만들어서 실제로 사용할 때에는 3줄만 있으면 돼요^^
    늦었지만, 강좌 잘 봤습니다. :D

    • 상현넘™  댓글주소 수정/삭제 2008/03/21 00:16

      하하^^ 유저 컨트롤로 만들어 놓으면
      간단하게 사용할 수 있죠^^..
      저도 자주 쓸수 있는것이나 유용한것들은
      편하게 빼서 재사용을 많이 이용합니다^^

  5. 도리도리  댓글주소 수정/삭제 댓글쓰기 2008/05/06 15:44

    좋은 강좌 너무 감사합니다..^_^

  6. 폴라리스  댓글주소 수정/삭제 댓글쓰기 2008/05/19 16:20

    강좌 잘 봤습니다.
    머가 잘못되었는지 잘 안되서 수정해가면서..
    여튼 잘 보고 갑니다.

  7. 왕초초초보  댓글주소 수정/삭제 댓글쓰기 2008/09/07 17:35

    전 안되는데.. 저기 Export 시키는 화면이 저랑 다른데요 어떤식으로 해야하는지
    너무 막막 합니다.. info.bin 파일이 안생겨요.. ㅠ
    버전이 다른가요 8월 3일 버전이네요

    • 상현넘™  댓글주소 수정/삭제 2008/09/08 09:44

      최근 버전에서는 어떻게 변경이 되었는지는 잘 모르겠네요!!
      바쁘다보니 새 버전을 테스트를 못해봤습니다..

  8. 쇼너짱  댓글주소 수정/삭제 댓글쓰기 2008/11/26 13:44

    멋진 강좌 잘봤습니다^^
    위에 왕초초초보님 말씀처럼 컴포저 새버전은 많이 업그레이드가 되었더군요,
    제가 방금해보니깐 최근 버전에서는 자동으로 실버라이트 프로젝트파일까지 생성이되어서,
    훨씬 편해진듯해요...위의 강좌에서 하나하나 코딩했던것을 아예 기본 아웃풋 파일에 생성이 되어 있더군요^^