2013-04-29 3 views
0

캔버스의 확대/축소 애니메이션을 어떻게 원활하게 만들 수 있습니까? GWT는 onMouseWheel(MouseWheelEvent evt) 메서드와 evt.getDeltaY() 메서드를 제공하여 스크롤 휠의 크기를 가져옵니다.캔버스를 부드럽게 줌하는 방법은 무엇입니까?

문제는 모든 바퀴 이동이이 메서드를 실행하고, 메서드 자체에서 캔버스 다시 그리기를 호출하면 상황이 매우 느려진다는 것입니다.

그래서 나는 어떻게 든 확대/축소를위한 애니메이션을 만들 것을 생각했습니다. 그러나 어떻게?

은 내가 Timer를 만드는 방법에 대해 생각하지만 출발점으로 만 MouseWheelEvent가이 있으므로, 실제 생각이 없지만, 사용자가 휠 확대 완료 끝 지점 ... 여기

답변

4

내 확장 성이 없다 이미지를 확대하는 데 사용하는 이미지 클래스는 매우 빠르고 반응이 좋습니다. 어딘가에서 예를 발견하고 좀 더 반응 적으로 만들기 위해 약간의 수정을했습니다. 나는 원래의 출처를 기억하지 못한다.

public class ScalableImage extends Composite implements MouseWheelHandler, MouseDownHandler, MouseMoveHandler, MouseUpHandler { 

    Canvas canvas = Canvas.createIfSupported(); 
    Context2d context = canvas.getContext2d(); 

    Canvas backCanvas = Canvas.createIfSupported(); 
    Context2d backContext = backCanvas.getContext2d(); 

    int width; 
    int height; 
    Image image; 
    ImageElement imageElement; 

    double zoom = 1; 
    double totalZoom = 1; 
    double offsetX = 0; 
    double offsetY = 0; 

    boolean mouseDown = false; 
    double mouseDownXPos = 0; 
    double mouseDownYPos = 0; 


    public ScalableImage(Image image) { 
     initWidget(canvas); 

     //width = Window.getClientWidth() - 50; 

     width = image.getWidth() + 200; 
     height = image.getHeight() + 200; 


     //canvas.setWidth(width + "px"); 
     //canvas.setHeight(height + "px"); 
     canvas.setCoordinateSpaceWidth(width); 
     canvas.setCoordinateSpaceHeight(height); 

     //backCanvas.setWidth(width + "px"); 
     //backCanvas.setHeight(height + "px"); 
     backCanvas.setCoordinateSpaceWidth(width); 
     backCanvas.setCoordinateSpaceHeight(height); 

     canvas.addMouseWheelHandler(this); 
     canvas.addMouseMoveHandler(this); 
     canvas.addMouseDownHandler(this); 
     canvas.addMouseUpHandler(this); 

     this.image = image; 
     this.imageElement = (ImageElement) image.getElement().cast(); 

     mainDraw(); 
    } 

    public void onMouseWheel(MouseWheelEvent event) { 
     int move = event.getDeltaY(); 

     double xPos = (event.getRelativeX(canvas.getElement())); 
     double yPos = (event.getRelativeY(canvas.getElement())); 

     if (move < 0) { 
      zoom = 1.1; 
     } else { 
      zoom = 1/1.1; 
     } 

     double newX = (xPos - offsetX)/totalZoom; 
     double newY = (yPos - offsetY)/totalZoom; 

     double xPosition = (-newX * zoom) + newX; 
     double yPosition = (-newY * zoom) + newY; 

     backContext.clearRect(0, 0, width, height); 

     backContext.translate(xPosition, yPosition); 

     backContext.scale(zoom, zoom); 

     mainDraw(); 

     offsetX += (xPosition * totalZoom); 
     offsetY += (yPosition * totalZoom); 

     totalZoom = totalZoom * zoom; 

     buffer(backContext, context); 
    } 

    public void onMouseDown(MouseDownEvent event) { 
     this.mouseDown = true; 
     mouseDownXPos = event.getRelativeX(image.getElement()); 
     mouseDownYPos = event.getRelativeY(image.getElement()); 
    } 

    public void onMouseMove(MouseMoveEvent event) { 
     if (mouseDown) { 
      backContext.setFillStyle("white"); 
      backContext.fillRect(-5, -5, width + 5, height + 5); 
      backContext.setFillStyle("black"); 
      double xPos = event.getRelativeX(image.getElement()); 
      double yPos = event.getRelativeY(image.getElement()); 
      backContext.translate((xPos - mouseDownXPos)/totalZoom, (yPos - mouseDownYPos)/totalZoom); 

      offsetX += (xPos - mouseDownXPos); 
      offsetY += (yPos - mouseDownYPos); 

      mainDraw(); 
      mouseDownXPos = xPos; 
      mouseDownYPos = yPos; 
     } 
    } 

    public void onMouseUp(MouseUpEvent event) { 
     this.mouseDown = false; 
    } 

    public void mainDraw() { 
     backContext.drawImage(imageElement, 100, 100); 

     buffer(backContext, context); 
    } 

    public void buffer(Context2d back, Context2d front) { 
     front.beginPath(); 
     front.clearRect(0, 0, width, height); 
     front.drawImage(back.getCanvas(), 0, 0); 
    } 
} 
+0

광범위한 애니메이션이있는 다른 캔버스 위젯을 만들었으므로 이러한 애니메이션을 한 번 렌더링 한 다음 나중에 캔버스에 다시 저장하는 것이 좋습니다. 이것은 훨씬 더 효율적인 빠른 렌더링을 가능하게합니다. –

+0

이것은 캔버스 요소를 최적화하는 데 사용한 캔버스 성능에 대한 훌륭한 자습서입니다. http://www.html5rocks.com/en/tutorials/canvas/performance/ –

관련 문제