独立于规模 Canvas
Scale independent Canvas
我有一个可以缩放的 QML Canvas
(更具体地说,它是一个缩放对象的子对象),缩放它会导致它的输出变得混叠。这是因为 Canvas
使用其大小来确定帧缓冲区大小。
我真正想要发生的是让帧缓冲区跟踪 Canvas
大小乘以它的比例,即它的屏幕像素大小。
我最初的想法是将 canvasWindow
和 canvasSize
设置为缩放后的大小,但是 Canvas
'pixel' 大小和 'pixel' 之间似乎没有解耦帧缓冲区的,因为整个图像开始渲染超出 Canvas
.
的范围
在此示例中,黑色圆环在 Canvas
内呈现,该 Canvas
是缩放的灰色矩形的父级:
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
仍然没有真正改变
帧缓冲区的大小...
解决方案是在 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();
}
}
我有一个可以缩放的 QML Canvas
(更具体地说,它是一个缩放对象的子对象),缩放它会导致它的输出变得混叠。这是因为 Canvas
使用其大小来确定帧缓冲区大小。
我真正想要发生的是让帧缓冲区跟踪 Canvas
大小乘以它的比例,即它的屏幕像素大小。
我最初的想法是将 canvasWindow
和 canvasSize
设置为缩放后的大小,但是 Canvas
'pixel' 大小和 'pixel' 之间似乎没有解耦帧缓冲区的,因为整个图像开始渲染超出 Canvas
.
在此示例中,黑色圆环在 Canvas
内呈现,该 Canvas
是缩放的灰色矩形的父级:
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
仍然没有真正改变
帧缓冲区的大小...
解决方案是在 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();
}
}