缩放独立画布

时间:2015-02-17 17:26:21

标签: qt qml

我有一个可以缩放的QML Canvas(更具体地说,它是一个被缩放的对象的子节点),并且缩放它会导致它的输出变为别名。这是因为Canvas使用其大小来确定帧缓冲区大小。

我真正希望发生的是帧缓冲跟踪Canvas大小乘以其比例,即屏幕上的像素大小。

我最初的想法是将canvasWindowcanvasSize设置为缩放尺寸,但似乎Canvas'像素'之间没有脱钩。尺寸和帧缓冲,因为整个图像开始渲染超出Canvas的范围。

在此示例中,在Canvas内呈现的黑色圆环是缩放灰色矩形的父级:

Before After

Canvas {
    id: borderCanvas
    anchors {
        fill: parent
        margins: 4
    }

    antialiasing: true
    canvasWindow: Qt.rect( 0,0,
                           width * parent.scale,
                           height * parent.scale );
    canvasSize: Qt.size( width * parent.scale,
                         height * parent.scale );

    onCanvasWindowChanged: {
        requestPaint();
    }

    onPaint: {
        var ctx = getContext( "2d" );
        ctx.save();
        ctx.clearRect( 0, 0, canvasWindow.width, canvasWindow.height );

        ctx.strokeStyle = Sy_application_qml.paletteObject.buttonText;
        ctx.lineWidth = 4 * parent.scale;

        ctx.beginPath();
        ctx.arc( canvasWindow.width / 2,
                 canvasWindow.height / 2,
                 ( canvasWindow.width / 2 ) - ctx.lineWidth,
                 0,
                 Math.PI * 2 );
        ctx.stroke();

        ctx.restore();
    }
}

那么无论如何设置Canvas帧缓冲区大小以使缩放变换不会影响它吗?

修改

如果我将canvasWindow保留为默认值,只更新canvasSize,那么我就不会让帧缓冲区渲染超出Canvas范围 - 但输出仍然是低分辨率因此canvasSize仍然没有实际改变 帧缓冲的大小...

1 个答案:

答案 0 :(得分:3)

解决方案是在Canvas上反转继承的比例变换,然后按比例增加高度和宽度。这会使Canvas在屏幕上保持相同的大小,但需要使用帧缓冲区来匹配。

Canvas {
    id: borderCanvas
    anchors {
        top: parent.top
        left: parent.left
        margins: 4
    }

    property real viewScale: base.parent.scale

    scale: 1.0 / viewScale
    height: ( parent.height - ( anchors.margins * 2 ) ) * viewScale
    width:  ( parent.width  - ( anchors.margins * 2 ) ) * viewScale

    antialiasing: true
    transformOrigin: Item.TopLeft

    onPaint: {
        var ctx = getContext( "2d" );
        ctx.save();
        ctx.clearRect( 0, 0, width, height );

        ctx.strokeStyle = Sy_application_qml.paletteObject.buttonText;
        ctx.lineWidth = 4 * viewScale;

        ctx.beginPath();
        ctx.arc( width / 2,
                 height / 2,
                 ( width / 2 ) - ctx.lineWidth,
                 0,
                 Math.PI * 2 );
        ctx.stroke();

        ctx.restore();
    }
}

Before After

相关问题