GWT Canvas и Retina Display проблема с масштабированием

Мне нужно применить GWT и HTML5 холст. Так как холст html5 полностью обернут gwt, я также ожидал, что смогу приспособиться к дисплею сетчатки.

Я искал в Интернете, но не нашел ответа для GWT. Итак, обычный способ сделать это в javascript - установить коэффициент масштабирования, подобный следующему. Понимание поддержки HTML Retina Canvas

Итак, я попробовал то же самое в моем проекте 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://stackru.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 ответ

Хорошо, я узнал, что нужно сделать, чтобы получить четкий холст с 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://stackru.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;
}-*/;

Это должно решить проблему.

Другие вопросы по тегам