Java 如何平滑缩放画布?

Java 如何平滑缩放画布?,java,gwt,canvas,Java,Gwt,Canvas,如何为画布平滑创建缩放动画? GWT提供了一个onMouseWheel(mouseWheeleEvent evt)方法和一个evt.getDeltaY()来获取滚轮的数量 这里的问题是,每个轮子的移动都会执行这个方法,如果我在方法本身中调用画布重画,事情就会变得非常滞后 所以我想以某种方式制作一个用于缩放的动画。但是怎么做呢 我想创建一个计时器,但没有真正的想法,因为只有mousewheelevent作为起点,但没有用户用滚轮完成缩放的终点…这是我用来缩放图像的可缩放图像类,它非常快速且响应迅速

如何为画布平滑创建缩放动画? GWT提供了一个
onMouseWheel(mouseWheeleEvent evt)
方法和一个
evt.getDeltaY()
来获取滚轮的数量

这里的问题是,每个轮子的移动都会执行这个方法,如果我在方法本身中调用画布重画,事情就会变得非常滞后

所以我想以某种方式制作一个用于缩放的动画。但是怎么做呢


我想创建一个
计时器,但没有真正的想法,因为只有mousewheelevent作为起点,但没有用户用滚轮完成缩放的终点…

这是我用来缩放图像的可缩放图像类,它非常快速且响应迅速。我在某处找到了一个例子,并做了一些小的修改,使它更具响应性。我不记得最初的来源,否则我会在这里赞扬他们

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);
    }
}
公共类ScalableImage扩展复合实现MouseWheelHandler、MouseDownHandler、MouseMoveHandler、MouseHandler{
Canvas Canvas=Canvas.createIfSupported();
Context2d context=canvas.getContext2d();
Canvas backCanvas=Canvas.createIfSupported();
Context2d backContext=backCanvas.getContext2d();
整数宽度;
内部高度;
图像;
图像元素图像元素;
双变焦=1;
双重总缩放=1;
双偏移量x=0;
双偏置=0;
布尔mouseDown=false;
双鼠标向下xpos=0;
双鼠标DOWNYPOS=0;
公共可缩放图像(图像){
initWidget(画布);
//宽度=窗口。getClientWidth()-50;
宽度=image.getWidth()+200;
高度=image.getHeight()+200;
//canvas.setWidth(宽度+px);
//canvas.setHeight(高度+px);
canvas.setCoordinateSpaceWidth(宽度);
canvas.setCoordinateSpaceHeight(高度);
//backCanvas.setWidth(宽度+px);
//背景画布。设置高度(高度+像素);
backCanvas.setCoordinateSpaceWidth(宽度);
backCanvas.setCoordinateSpaceHeight(高度);
canvas.addMouseWheelHandler(此);
addMouseMoveHandler(this);
addMouseDownHandler(这个);
canvas.addMouseUpHandler(此);
这个图像=图像;
this.imageElement=(imageElement)image.getElement().cast();
mainDraw();
}
MouseWheel上的公共无效(MouseWheelEvent事件){
int move=event.getDeltaY();
double xPos=(event.getRelativeX(canvas.getElement());
double yPos=(event.getRelativeY(canvas.getElement());
如果(移动<0){
缩放=1.1;
}否则{
缩放=1/1.1;
}
双newX=(xPos-offsetX)/totalZoom;
double newY=(yPos-offsetY)/totalZoom;
双X位置=(-newX*缩放)+newX;
双Y位置=(-newY*缩放)+newY;
clearRect(0,0,宽度,高度);
翻译(xPosition,yPosition);
缩放(缩放,缩放);
mainDraw();
偏移量x+=(xPosition*totalZoom);
offsetY+=(yPosition*totalZoom);
totalZoom=totalZoom*缩放;
缓冲区(backContext,context);
}
MouseDown上的公共无效(MouseDownEvent事件){
this.mouseDown=true;
mouseDownXPos=event.getRelativeX(image.getElement());
mouseDownYPos=event.getRelativeY(image.getElement());
}
MouseMove上的公共无效(MouseMoveEvent事件){
如果(鼠标向下){
backContext.setFillStyle(“白色”);
fillRect(-5,-5,宽度+5,高度+5);
backContext.setFillStyle(“黑色”);
double xPos=event.getRelativeX(image.getElement());
double yPos=event.getRelativeY(image.getElement());
translate((xPos-mouseDownXPos)/totalZoom,(yPos-mouseDownYPos)/totalZoom);
offsetX+=(xPos-鼠标向下xPos);
offsetY+=(yPos-mouseDownYPos);
mainDraw();
mouseDownXPos=xPos;
mouseDownYPos=yPos;
}
}
MouseUp上的公共无效(MouseUpEvent事件){
this.mouseDown=false;
}
公众假期{
drawImage(imageElement,100100);
缓冲区(backContext,context);
}
公共无效缓冲区(Context2d背面,Context2d正面){
front.beginPath();
前.clearRect(0,0,宽度,高度);
front.drawImage(back.getCanvas(),0,0);
}
}

这是我用来放大图像的可缩放图像类,它非常快速且响应迅速。我在某处找到了一个例子,并做了一些小的修改,使它更具响应性。我不记得最初的来源,否则我会在这里赞扬他们

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);
    }
}
公共类ScalableImage扩展复合实现MouseWheelHandler、MouseDownHandler、MouseMoveHandler、MouseHandler{
Canvas Canvas=Canvas.createIfSupported();
Context2d context=canvas.getContext2d();
Canvas backCanvas=Canvas.createIfSupported();
Context2d backContext=backCanvas.getContext2d();
整数宽度;
内部高度;
图像;
图像元素图像元素;
双变焦=1;
双重总缩放=1;
双偏移量x=0;
双偏置=0;
布尔mouseDown=false;
双鼠标向下xpos=0;
双鼠标DOWNYPOS=0;
公共可缩放图像(图像){
initWidget(画布);
//宽度=窗口。getClientWidth()-50;
宽度=image.getWidth()+200;
高度=image.getHeight()+200;
//canvas.setWidth(宽度+px);
//canvas.setHeight(高度+px);
canvas.setCoordinateSpaceWidth(宽度);
canvas.setCoordinateSpaceHeight(高度);
//backCanvas.setWidth(宽度+px);
//背景画布。设置高度(高度+像素);
backCanvas.setCoordinateSpaceWidth(宽度);
backCanvas.setCoordinateSpaceHeight(高度);