当前位置: 首页 > 面试题库 >

如何平滑缩放画布?

马承
2023-03-14
问题内容

如何才能平滑地为画布创建缩放动画?GWT提供了onMouseWheel(MouseWheelEvent evt)一种evt.getDeltaY()获取滚轮数量的方法和。

这里的问题是,每个车轮运动都会执行此方法,并且如果我在该方法本身中调用画布重绘,事情会变得很滞后。

因此,我想到了以某种方式制作缩放动画的方法。但是如何?

我考虑过创建一个Timer,但没有真正的主意,因为只有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);
    }
}


 类似资料:
  • 我已经编写了一些代码,可以从高度图中渲染3D世界,现在我也编写了允许行走的代码。问题是,当高度增加时,动画几乎“跳跃”,因为每个单元都相当大。有没有一种简单的方法可以让动画更流畅?(一般来说,我对OpenGL和3D渲染非常陌生,所以我不想讨论插值和更复杂的事情。)

  • 我的出发点如下: FXML: Java FX控制器:

  • 我正在做自己的画布抽屉项目,只是停留在放大/缩小功能上。在我的项目中,我使用缩放和平移来进行缩放,因为我想将所有画布及其元素保持在中心。在画了一点草图(不是数学天才)之后,我成功地画出了下面的公式用于翻译过程,因此缩放后画布将保持在它的视口的中间:旧的宽度和高度/ 2 -新的宽度和高度(这是旧的宽度和高度乘以比例步长,在我的例子中是1.1)/2。从逻辑上讲,这应该行得通。但是在尝试了几次放大和缩小

  • 在最初的谷歌地图上,如果我用两个手指放大或缩小,缩放动画不会在释放屏幕后立即停止。它继续缓慢地放大或缩小。这很好,但在我的谷歌地图api上,当我用两个手指放大或缩小时,一旦我从屏幕上松开手指,缩放动画就会停止。有没有办法启用此功能?可能有。。我只是不知道这个效果的名字。。。也许是zoom echo?:)

  • 我是一名Ruby/PHP web应用程序开发人员已经有一段时间了,我已经习惯了水平缩放服务器实例以处理更多请求的想法。水平缩放-意味着位于负载均衡器后面的应用程序的独立实例,它们什么都不共享,彼此不知道。 由于websocket有效地保持了浏览器和服务器之间的开放式通信线路,那么PHP/Ruby世界中典型的水平缩放架构是否会导致像链接中所解释的那样的聊天应用程序中断--因为新的websocket连

  • 我试图为我的实现一个平滑的动画,但是当我增加时间(30秒)时,动画不再平滑。 5秒钟的例子: 30秒的例子: 我的进步背景: 我的进度布局: 我的动画制作方法: