GWT Canvas和Retina显示缩放问题

时间:2017-10-30 16:26:11

标签: canvas gwt retina-display

我需要应用GWT和html5画布。由于html5画布完全被gwt包裹,我还希望我能够适应视网膜显示器。

我在互联网上搜索但没有找到GWT的任何答案。因此,在javascript中执行此操作的常用方法是将比例因子设置为此Understanding HTML Retina Canvas Support

所以,我在我的gwt项目中尝试过相同的结果并最终:

public void onModuleLoad() {

        Canvas canvas = Canvas.createIfSupported();
        canvas.getElement().setAttribute("width", "800");
        canvas.getElement().setAttribute("height", "500");
        canvas.getElement().getStyle().setProperty("border", "black solid 1px");
        RootPanel.get("root").add(canvas);

        Context2d ctx = canvas.getContext2d();

        //For Retina Displays
        int dpi = dpi();
        ctx.scale(dpi, dpi);

        double posX = 10;
        double posY = 10;
        double width = 200;
        double height = 30;
        double cornerRadius = 2;

        ctx.beginPath();
        ctx.moveTo(posX+(width/2), posY);
        ctx.arcTo(posX+width, posY, posX+width, posY+(height/2), cornerRadius);
        ctx.lineTo(posX+width, posY+(height/2));
        ctx.arcTo(posX+width, posY+height, posX+(width/2), posY+height, cornerRadius);
        ctx.lineTo(posX+(width/2), posY+height);
        ctx.arcTo(posX, posY+height, posX, posY+(height/2), cornerRadius);
        ctx.lineTo(posX, posY+(height/2));
        ctx.arcTo(posX, posY, posX+(width/2), posY, cornerRadius);
        ctx.lineTo(posX+(width/2), posY);
        ctx.setStrokeStyle("rgba(255,255,255,1.0");
        ctx.stroke();
        ctx.closePath();

        ctx.setShadowBlur(2);
        ctx.setShadowColor("rgba(0,0,0,0.5)");
        ctx.setShadowOffsetX(1);
        ctx.setShadowOffsetY(1);

        ctx.setFillStyle("white");
        ctx.fill();
    }


    public static native int dpi() /*-{
        //https://stackoverflow.com/questions/35820750/understanding-html-retina-canvas-support
        var ctx = $wnd.document.createElement("canvas").getContext("2d"),
        dpr = window.devicePixelRatio || 1,
        bsr = ctx.webkitBackingStorePixelRatio ||
              ctx.mozBackingStorePixelRatio ||
              ctx.msBackingStorePixelRatio ||
              ctx.oBackingStorePixelRatio ||
              ctx.backingStorePixelRatio || 1;

        return dpr / bsr;
    }-*/;

但是,它不起作用。相反,圆角矩形现在只是尺寸的两倍。平局看起来仍然很模糊。

我如何调整画布以补偿视网膜显示器上的像素加?

1 个答案:

答案 0 :(得分:0)

好的,我发现要做什么是为了获得一个带有GWT和Retina Display的锐利画布。

与上面相同的代码,但有这些变化:

public void onModuleLoad() {

        int canvasWidth = 800;
        int canvasHeight = 500;
        Canvas canvas = Canvas.createIfSupported();
        canvas.setPixelSize(canvasWidth, canvasHeight);
        canvas.getElement().getStyle().setProperty("border", "black solid 1px");
        RootPanel.get("root").add(canvas);

        //In order to be sharp on a Retina Display, use the following code!
        Context2d ctx = createContext2DNatively(canvas.getElement(), canvasWidth, canvasHeight);

        //Continue as you would normally do...

出于某种原因,我无法弄清楚如何在GWT中调整此选项。因此我用原生Javascript创建它。该方法如下所示:

public static native Context2d createContext2DNatively(Element canvas, int width, int height) /*-{
    //https://stackoverflow.com/questions/35820750/understanding-html-retina-canvas-support
    var ctx = canvas.getContext("2d"),
    dpr = window.devicePixelRatio || 1,
    bsr = ctx.webkitBackingStorePixelRatio ||
          ctx.mozBackingStorePixelRatio ||
          ctx.msBackingStorePixelRatio ||
          ctx.oBackingStorePixelRatio ||
          ctx.backingStorePixelRatio || 1;

    var ratio = dpr / bsr;
    canvas.setAttribute('width', width*ratio);
    canvas.setAttribute('height', height*ratio);
    ctx.scale(ratio, ratio);
    return ctx;
}-*/;

这应该可以解决问题。